diff options
Diffstat (limited to 'usr/src/cmd')
520 files changed, 68223 insertions, 33732 deletions
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile index 36ef810055..9257bd06e7 100644 --- a/usr/src/cmd/Makefile +++ b/usr/src/cmd/Makefile @@ -21,8 +21,8 @@ # # Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright (c) 2018, Joyent, Inc. -# Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright (c) 2019, Joyent, Inc. +# Copyright (c) 2012, 2015 by Delphix. All rights reserved. # Copyright (c) 2013 DEY Storage Systems, Inc. All rights reserved. # Copyright 2014 Garrett D'Amore <garrett@damore.org> # Copyright 2016 Toomas Soome <tsoome@me.com> @@ -34,8 +34,8 @@ include ../Makefile.master # -# Note that the commands 'lp', and 'perl' are first in -# the list, violating alphabetical order. This is because they are very +# Note that if the 'lp' command were built, it would be first in +# the list, violating alphabetical order. This is because it is very # long-running and should be given the most wall-clock time for a # parallel build. # @@ -56,7 +56,6 @@ FIRST_SUBDIRS= \ COMMON_SUBDIRS= \ allocate \ availdevs \ - lp \ perl \ Adm \ abi \ @@ -97,7 +96,9 @@ COMMON_SUBDIRS= \ cmd-crypto \ cmd-inet \ col \ + column \ compress \ + connstat \ consadm \ coreadm \ cpio \ @@ -195,7 +196,6 @@ COMMON_SUBDIRS= \ growfs \ grpck \ gss \ - hal \ halt \ head \ hostid \ @@ -232,7 +232,6 @@ COMMON_SUBDIRS= \ kvmstat \ last \ lastcomm \ - latencytop \ ldap \ ldapcachemgr \ lgrpinfo \ @@ -254,6 +253,7 @@ COMMON_SUBDIRS= \ ls \ luxadm \ mach \ + machid \ mail \ mailwrapper \ mailx \ @@ -288,6 +288,7 @@ COMMON_SUBDIRS= \ news \ newtask \ nice \ + nicstat \ nl \ nlsadmin \ nohup \ @@ -312,15 +313,14 @@ COMMON_SUBDIRS= \ picl \ plimit \ policykit \ - pools \ power \ powertop \ ppgsz \ pg \ plockstat \ + pptadm \ pr \ prctl \ - print \ printf \ priocntl \ profiles \ @@ -338,7 +338,6 @@ COMMON_SUBDIRS= \ pwck \ pwconv \ pwd \ - pyzfs \ raidctl \ ramdiskadm \ rcap \ @@ -388,7 +387,6 @@ COMMON_SUBDIRS= \ srchtxt \ srptadm \ srptsvc \ - ssh \ stat \ stmfadm \ stmfproxy \ @@ -440,8 +438,11 @@ COMMON_SUBDIRS= \ utmpd \ uuidgen \ valtools \ + varpd \ vgrind \ vi \ + vndadm \ + vndstat \ volcheck \ volrmmount \ vrrpadm \ @@ -482,6 +483,8 @@ i386_SUBDIRS= \ acpihpd \ addbadsec \ ahciem \ + bhyve \ + bhyvectl \ biosdev \ cxgbetool \ diskscan \ @@ -508,11 +511,14 @@ sparc_SUBDIRS= \ vntsd # -# Commands that are messaged. Note that 'lp' comes first -# (see previous comment about 'lp'.) +# Commands that are messaged. Note that 'lp' comes first (see previous comment +# about 'lp'.) +# +# We purposefully leave out auditrecord's messages from illumos-joyent: it +# attempts to use Perl modules constructed as part of the build alongside the +# native Perl. # MSGSUBDIRS= \ - lp \ abi \ acctadm \ allocate \ @@ -521,7 +527,6 @@ MSGSUBDIRS= \ audit \ auditconfig \ auditd \ - auditrecord \ auditset \ auths \ autopush \ @@ -547,6 +552,7 @@ MSGSUBDIRS= \ cmd-inet \ col \ compress \ + connstat \ consadm \ coreadm \ cpio \ @@ -648,11 +654,9 @@ MSGSUBDIRS= \ pg \ pgrep \ picl \ - pools \ power \ pr \ praudit \ - print \ profiles \ projadd \ projects \ @@ -663,7 +667,6 @@ MSGSUBDIRS= \ ptools \ pwconv \ pwd \ - pyzfs \ raidctl \ ramdiskadm \ rcap \ diff --git a/usr/src/cmd/Makefile.check b/usr/src/cmd/Makefile.check index 2ad038596b..2914437f40 100644 --- a/usr/src/cmd/Makefile.check +++ b/usr/src/cmd/Makefile.check @@ -118,16 +118,12 @@ MANIFEST_SUBDIRS= \ krb5/krb5kdc \ krb5/kwarn \ krb5/slave \ - lp/cmd/lpsched \ picl/picld \ pools/poold \ - print/bsd-sysv-commands \ - print/ppdmgr \ rcap/rcapd \ rpcsvc/rpc.bootparamd \ sendmail/lib \ smbsrv/smbd \ - ssh/etc \ svc/milestone \ tsol/labeld \ tsol/tnctl \ diff --git a/usr/src/cmd/auditrecord/Makefile b/usr/src/cmd/auditrecord/Makefile index 4f4670dfc9..fdf5213b3f 100644 --- a/usr/src/cmd/auditrecord/Makefile +++ b/usr/src/cmd/auditrecord/Makefile @@ -22,13 +22,15 @@ # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright (c) 2018, Joyent, Inc. +# include $(SRC)/cmd/Makefile.cmd ATTR = audit_record_attr ROOTAUDITDIR = $(ROOT)/usr/lib/audit -SECURITYFILES = $(ATTR:%=$(ROOTAUDITDIR)/%) +SECURITYFILES = $(ATTR:%=$(ROOTAUDITDIR)/%) $(SECURITYFILES) := FILEMODE = $(LIBFILEMODE) PROG = auditrecord @@ -41,7 +43,7 @@ ADTXMLFILE = $(LIBBSMDIR)/common/adt.xml .KEEP_STATE: -all: $(PROG) $(ATTR) +all: $(PROG) $(ATTR) install: all $(ROOTUSRSBINPROG) install_data @@ -59,7 +61,7 @@ clean: $(RM) $(ATTR) $(STRIPTEXT) $(AGETTEXT) $(ATTR): $(STRIPTEXT) $(ATTRPROC) $(ADTXMLFILE) $(ATTR).txt - ./$(STRIPTEXT) < $(ATTR).txt > $(ATTR) + $(PERL) ./$(STRIPTEXT) < $(ATTR).txt > $(ATTR) $(PERL) -I $(LIBBSMDIR) ./$(ATTRPROC) $(ADTXMLFILE) >> $(ATTR) $(ROOTUSRSBINPROG): $(PROG) diff --git a/usr/src/cmd/bhyve/Makefile b/usr/src/cmd/bhyve/Makefile new file mode 100644 index 0000000000..0ad066e6d4 --- /dev/null +++ b/usr/src/cmd/bhyve/Makefile @@ -0,0 +1,167 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2014 Pluribus Networks Inc. +# Copyright (c) 2018, Joyent, Inc. +# + +PROG = bhyve + +include ../Makefile.cmd +include ../Makefile.cmd.64 +include ../Makefile.ctf + +SUBDIRS = test + +all := TARGET = all +install := TARGET = install +clean := TARGET = clean +clobber := TARGET = clobber +lint := TARGET = lint + +SRCS = acpi.c \ + atkbdc.c \ + bhyvegc.c \ + bhyverun.c \ + block_if.c \ + bootrom.c \ + console.c \ + consport.c \ + dbgport.c \ + fwctl.c \ + gdb.c \ + inout.c \ + ioapic.c \ + mem.c \ + mevent.c \ + mptbl.c \ + pci_ahci.c \ + pci_e82545.c \ + pci_emul.c \ + pci_fbuf.c \ + pci_hostbridge.c \ + pci_irq.c \ + pci_lpc.c \ + pci_nvme.c \ + pci_passthru.c \ + pci_uart.c \ + pci_virtio_block.c \ + pci_virtio_console.c \ + pci_virtio_net.c \ + pci_virtio_rnd.c \ + pci_virtio_viona.c \ + pci_xhci.c \ + pm.c \ + post.c \ + ps2kbd.c \ + ps2mouse.c \ + rfb.c \ + rtc.c \ + smbiostbl.c \ + sockstream.c \ + task_switch.c \ + uart_emul.c \ + usb_emul.c \ + usb_mouse.c \ + vga.c \ + virtio.c \ + vmm_instruction_emul.c \ + xmsr.c \ + spinup_ap.c \ + iov.c \ + bhyve_sol_glue.c + +# The virtio-scsi driver appears to include a slew of materials from FreeBSD's +# native SCSI implementation. We will omit that complexity for now. + #ctl_util.c \ + #ctl_scsi_all.c \ + #pci_virtio_scsi.c \ + + +OBJS = $(SRCS:.c=.o) + +CLOBBERFILES = $(ROOTUSRSBINPROG) $(ZHYVE) + +ZHYVE_DIR = $(ROOT)/usr/lib/brand/bhyve +ZHYVE_PROG = zhyve +ZHYVE = $(ZHYVE_DIR)/$(ZHYVE_PROG) + +MEVENT_TEST_PROG = mevent_test +MEVENT_TEST_SRCS = mevent.c mevent_test.c +MEVENT_TEST_OBJS = $(MEVENT_TEST_SRCS:.c=.o) + +CLEANFILES = $(PROG) $(ZHYVE_PROG) $(MEVENT_TEST_PROG) $(MEVENT_TEST_OBJS) + +CFLAGS += $(CCVERBOSE) -_gcc=-Wimplicit-function-declaration -_gcc=-Wno-parentheses +CPPFLAGS = -I$(COMPAT)/freebsd -I$(CONTRIB)/freebsd \ + -I$(COMPAT)/freebsd/amd64 -I$(CONTRIB)/freebsd/amd64 \ + -I$(CONTRIB)/freebsd/dev/usb/controller \ + -I$(CONTRIB)/freebsd/dev/mii \ + -I$(SRC)/uts/common/io/e1000api \ + $(CPPFLAGS.master) \ + -I$(ROOT)/usr/platform/i86pc/include \ + -I$(SRC)/uts/i86pc/io/vmm \ + -I$(SRC)/uts/common \ + -I$(SRC)/uts/i86pc \ + -I$(SRC)/lib/libdladm/common \ + -DWITHOUT_CAPSICUM + +# Disable the crypto code until it is wired up +CPPFLAGS += -DNO_OPENSSL + +pci_nvme.o := CERRWARN += -_gcc=-Wno-pointer-sign + +# Force c99 for everything +CSTD= $(CSTD_GNU99) +C99MODE= -xc99=%all +C99LMODE= -Xc99=%all + +$(PROG) := LDLIBS += -lsocket -lnsl -ldlpi -ldladm -lmd -luuid -lvmmapi -lz +$(ZHYVE_PROG) := LDLIBS += -lnvpair +$(MEVENT_TEST_PROG) := LDLIBS += -lsocket + +POST_PROCESS += ; $(GENSETDEFS) $@ + +.KEEP_STATE: + +all: $(PROG) $(MEVENT_TEST_PROG) $(ZHYVE_PROG) $(SUBDIRS) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS) + $(POST_PROCESS) + +$(MEVENT_TEST_PROG): $(MEVENT_TEST_OBJS) + $(LINK.c) -o $@ $(MEVENT_TEST_OBJS) $(LDFLAGS) $(LDLIBS) + +install: all $(ZHYVE) $(ROOTUSRSBINPROG) $(SUBDIRS) + +clean: $(SUBDIRS) + $(RM) $(OBJS) $(CLEANFILES) + +clobber: clean $(SUBDIRS) + $(RM) $(CLOBBERFILES) + +lint: lint_SRCS $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ + +$(ZHYVE_DIR)/%: % + $(INS.file) + +%.o: $(SRC)/uts/i86pc/io/vmm/%.c + $(COMPILE.c) $< + $(POST_PROCESS_O) diff --git a/usr/src/cmd/bhyve/acpi.c b/usr/src/cmd/bhyve/acpi.c new file mode 100644 index 0000000000..309ba98a11 --- /dev/null +++ b/usr/src/cmd/bhyve/acpi.c @@ -0,0 +1,983 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +/* + * bhyve ACPI table generator. + * + * Create the minimal set of ACPI tables required to boot FreeBSD (and + * hopefully other o/s's) by writing out ASL template files for each of + * the tables and the compiling them to AML with the Intel iasl compiler. + * The AML files are then read into guest memory. + * + * The tables are placed in the guest's ROM area just below 1MB physical, + * above the MPTable. + * + * Layout + * ------ + * RSDP -> 0xf2400 (36 bytes fixed) + * RSDT -> 0xf2440 (36 bytes + 4*7 table addrs, 4 used) + * XSDT -> 0xf2480 (36 bytes + 8*7 table addrs, 4 used) + * MADT -> 0xf2500 (depends on #CPUs) + * FADT -> 0xf2600 (268 bytes) + * HPET -> 0xf2740 (56 bytes) + * MCFG -> 0xf2780 (60 bytes) + * FACS -> 0xf27C0 (64 bytes) + * DSDT -> 0xf2800 (variable - can go up to 0x100000) + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/errno.h> +#include <sys/stat.h> + +#include <paths.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <machine/vmm.h> +#include <vmmapi.h> + +#include "bhyverun.h" +#include "acpi.h" +#include "pci_emul.h" + +/* + * Define the base address of the ACPI tables, and the offsets to + * the individual tables + */ +#define BHYVE_ACPI_BASE 0xf2400 +#define RSDT_OFFSET 0x040 +#define XSDT_OFFSET 0x080 +#define MADT_OFFSET 0x100 +#define FADT_OFFSET 0x200 +#define HPET_OFFSET 0x340 +#define MCFG_OFFSET 0x380 +#define FACS_OFFSET 0x3C0 +#define DSDT_OFFSET 0x400 + +#define BHYVE_ASL_TEMPLATE "bhyve.XXXXXXX" +#define BHYVE_ASL_SUFFIX ".aml" +#define BHYVE_ASL_COMPILER "/usr/sbin/iasl" + +static int basl_keep_temps; +static int basl_verbose_iasl; +static int basl_ncpu; +static uint32_t basl_acpi_base = BHYVE_ACPI_BASE; +static uint32_t hpet_capabilities; + +/* + * Contains the full pathname of the template to be passed + * to mkstemp/mktemps(3) + */ +static char basl_template[MAXPATHLEN]; +static char basl_stemplate[MAXPATHLEN]; + +/* + * State for dsdt_line(), dsdt_indent(), and dsdt_unindent(). + */ +static FILE *dsdt_fp; +static int dsdt_indent_level; +static int dsdt_error; + +struct basl_fio { + int fd; + FILE *fp; + char f_name[MAXPATHLEN]; +}; + +#define EFPRINTF(...) \ + if (fprintf(__VA_ARGS__) < 0) goto err_exit; + +#define EFFLUSH(x) \ + if (fflush(x) != 0) goto err_exit; + +static int +basl_fwrite_rsdp(FILE *fp) +{ + EFPRINTF(fp, "/*\n"); + EFPRINTF(fp, " * bhyve RSDP template\n"); + EFPRINTF(fp, " */\n"); + EFPRINTF(fp, "[0008]\t\tSignature : \"RSD PTR \"\n"); + EFPRINTF(fp, "[0001]\t\tChecksum : 43\n"); + EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); + EFPRINTF(fp, "[0001]\t\tRevision : 02\n"); + EFPRINTF(fp, "[0004]\t\tRSDT Address : %08X\n", + basl_acpi_base + RSDT_OFFSET); + EFPRINTF(fp, "[0004]\t\tLength : 00000024\n"); + EFPRINTF(fp, "[0008]\t\tXSDT Address : 00000000%08X\n", + basl_acpi_base + XSDT_OFFSET); + EFPRINTF(fp, "[0001]\t\tExtended Checksum : 00\n"); + EFPRINTF(fp, "[0003]\t\tReserved : 000000\n"); + + EFFLUSH(fp); + + return (0); + +err_exit: + return (errno); +} + +static int +basl_fwrite_rsdt(FILE *fp) +{ + EFPRINTF(fp, "/*\n"); + EFPRINTF(fp, " * bhyve RSDT template\n"); + EFPRINTF(fp, " */\n"); + EFPRINTF(fp, "[0004]\t\tSignature : \"RSDT\"\n"); + EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); + EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); + EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); + EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); + EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVRSDT \"\n"); + EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); + /* iasl will fill in the compiler ID/revision fields */ + EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); + EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); + EFPRINTF(fp, "\n"); + + /* Add in pointers to the MADT, FADT and HPET */ + EFPRINTF(fp, "[0004]\t\tACPI Table Address 0 : %08X\n", + basl_acpi_base + MADT_OFFSET); + EFPRINTF(fp, "[0004]\t\tACPI Table Address 1 : %08X\n", + basl_acpi_base + FADT_OFFSET); + EFPRINTF(fp, "[0004]\t\tACPI Table Address 2 : %08X\n", + basl_acpi_base + HPET_OFFSET); + EFPRINTF(fp, "[0004]\t\tACPI Table Address 3 : %08X\n", + basl_acpi_base + MCFG_OFFSET); + + EFFLUSH(fp); + + return (0); + +err_exit: + return (errno); +} + +static int +basl_fwrite_xsdt(FILE *fp) +{ + EFPRINTF(fp, "/*\n"); + EFPRINTF(fp, " * bhyve XSDT template\n"); + EFPRINTF(fp, " */\n"); + EFPRINTF(fp, "[0004]\t\tSignature : \"XSDT\"\n"); + EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); + EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); + EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); + EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); + EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVXSDT \"\n"); + EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); + /* iasl will fill in the compiler ID/revision fields */ + EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); + EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); + EFPRINTF(fp, "\n"); + + /* Add in pointers to the MADT, FADT and HPET */ + EFPRINTF(fp, "[0004]\t\tACPI Table Address 0 : 00000000%08X\n", + basl_acpi_base + MADT_OFFSET); + EFPRINTF(fp, "[0004]\t\tACPI Table Address 1 : 00000000%08X\n", + basl_acpi_base + FADT_OFFSET); + EFPRINTF(fp, "[0004]\t\tACPI Table Address 2 : 00000000%08X\n", + basl_acpi_base + HPET_OFFSET); + EFPRINTF(fp, "[0004]\t\tACPI Table Address 3 : 00000000%08X\n", + basl_acpi_base + MCFG_OFFSET); + + EFFLUSH(fp); + + return (0); + +err_exit: + return (errno); +} + +static int +basl_fwrite_madt(FILE *fp) +{ + int i; + + EFPRINTF(fp, "/*\n"); + EFPRINTF(fp, " * bhyve MADT template\n"); + EFPRINTF(fp, " */\n"); + EFPRINTF(fp, "[0004]\t\tSignature : \"APIC\"\n"); + EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); + EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); + EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); + EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); + EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVMADT \"\n"); + EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); + + /* iasl will fill in the compiler ID/revision fields */ + EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); + EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0004]\t\tLocal Apic Address : FEE00000\n"); + EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); + EFPRINTF(fp, "\t\t\tPC-AT Compatibility : 1\n"); + EFPRINTF(fp, "\n"); + + /* Add a Processor Local APIC entry for each CPU */ + for (i = 0; i < basl_ncpu; i++) { + EFPRINTF(fp, "[0001]\t\tSubtable Type : 00\n"); + EFPRINTF(fp, "[0001]\t\tLength : 08\n"); + /* iasl expects hex values for the proc and apic id's */ + EFPRINTF(fp, "[0001]\t\tProcessor ID : %02x\n", i); + EFPRINTF(fp, "[0001]\t\tLocal Apic ID : %02x\n", i); + EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); + EFPRINTF(fp, "\t\t\tProcessor Enabled : 1\n"); + EFPRINTF(fp, "\n"); + } + + /* Always a single IOAPIC entry, with ID 0 */ + EFPRINTF(fp, "[0001]\t\tSubtable Type : 01\n"); + EFPRINTF(fp, "[0001]\t\tLength : 0C\n"); + /* iasl expects a hex value for the i/o apic id */ + EFPRINTF(fp, "[0001]\t\tI/O Apic ID : %02x\n", 0); + EFPRINTF(fp, "[0001]\t\tReserved : 00\n"); + EFPRINTF(fp, "[0004]\t\tAddress : fec00000\n"); + EFPRINTF(fp, "[0004]\t\tInterrupt : 00000000\n"); + EFPRINTF(fp, "\n"); + + /* Legacy IRQ0 is connected to pin 2 of the IOAPIC */ + EFPRINTF(fp, "[0001]\t\tSubtable Type : 02\n"); + EFPRINTF(fp, "[0001]\t\tLength : 0A\n"); + EFPRINTF(fp, "[0001]\t\tBus : 00\n"); + EFPRINTF(fp, "[0001]\t\tSource : 00\n"); + EFPRINTF(fp, "[0004]\t\tInterrupt : 00000002\n"); + EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0005\n"); + EFPRINTF(fp, "\t\t\tPolarity : 1\n"); + EFPRINTF(fp, "\t\t\tTrigger Mode : 1\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0001]\t\tSubtable Type : 02\n"); + EFPRINTF(fp, "[0001]\t\tLength : 0A\n"); + EFPRINTF(fp, "[0001]\t\tBus : 00\n"); + EFPRINTF(fp, "[0001]\t\tSource : %02X\n", SCI_INT); + EFPRINTF(fp, "[0004]\t\tInterrupt : %08X\n", SCI_INT); + EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0000\n"); + EFPRINTF(fp, "\t\t\tPolarity : 3\n"); + EFPRINTF(fp, "\t\t\tTrigger Mode : 3\n"); + EFPRINTF(fp, "\n"); + + /* Local APIC NMI is connected to LINT 1 on all CPUs */ + EFPRINTF(fp, "[0001]\t\tSubtable Type : 04\n"); + EFPRINTF(fp, "[0001]\t\tLength : 06\n"); + EFPRINTF(fp, "[0001]\t\tProcessorId : FF\n"); + EFPRINTF(fp, "[0002]\t\tFlags (decoded below) : 0005\n"); + EFPRINTF(fp, "\t\t\tPolarity : 1\n"); + EFPRINTF(fp, "\t\t\tTrigger Mode : 1\n"); + EFPRINTF(fp, "[0001]\t\tInterrupt : 01\n"); + EFPRINTF(fp, "\n"); + + EFFLUSH(fp); + + return (0); + +err_exit: + return (errno); +} + +static int +basl_fwrite_fadt(FILE *fp) +{ + EFPRINTF(fp, "/*\n"); + EFPRINTF(fp, " * bhyve FADT template\n"); + EFPRINTF(fp, " */\n"); + EFPRINTF(fp, "[0004]\t\tSignature : \"FACP\"\n"); + EFPRINTF(fp, "[0004]\t\tTable Length : 0000010C\n"); + EFPRINTF(fp, "[0001]\t\tRevision : 05\n"); + EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); + EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); + EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVFACP \"\n"); + EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); + /* iasl will fill in the compiler ID/revision fields */ + EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); + EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0004]\t\tFACS Address : %08X\n", + basl_acpi_base + FACS_OFFSET); + EFPRINTF(fp, "[0004]\t\tDSDT Address : %08X\n", + basl_acpi_base + DSDT_OFFSET); + EFPRINTF(fp, "[0001]\t\tModel : 01\n"); + EFPRINTF(fp, "[0001]\t\tPM Profile : 00 [Unspecified]\n"); + EFPRINTF(fp, "[0002]\t\tSCI Interrupt : %04X\n", + SCI_INT); + EFPRINTF(fp, "[0004]\t\tSMI Command Port : %08X\n", + SMI_CMD); + EFPRINTF(fp, "[0001]\t\tACPI Enable Value : %02X\n", + BHYVE_ACPI_ENABLE); + EFPRINTF(fp, "[0001]\t\tACPI Disable Value : %02X\n", + BHYVE_ACPI_DISABLE); + EFPRINTF(fp, "[0001]\t\tS4BIOS Command : 00\n"); + EFPRINTF(fp, "[0001]\t\tP-State Control : 00\n"); + EFPRINTF(fp, "[0004]\t\tPM1A Event Block Address : %08X\n", + PM1A_EVT_ADDR); + EFPRINTF(fp, "[0004]\t\tPM1B Event Block Address : 00000000\n"); + EFPRINTF(fp, "[0004]\t\tPM1A Control Block Address : %08X\n", + PM1A_CNT_ADDR); + EFPRINTF(fp, "[0004]\t\tPM1B Control Block Address : 00000000\n"); + EFPRINTF(fp, "[0004]\t\tPM2 Control Block Address : 00000000\n"); + EFPRINTF(fp, "[0004]\t\tPM Timer Block Address : %08X\n", + IO_PMTMR); + EFPRINTF(fp, "[0004]\t\tGPE0 Block Address : 00000000\n"); + EFPRINTF(fp, "[0004]\t\tGPE1 Block Address : 00000000\n"); + EFPRINTF(fp, "[0001]\t\tPM1 Event Block Length : 04\n"); + EFPRINTF(fp, "[0001]\t\tPM1 Control Block Length : 02\n"); + EFPRINTF(fp, "[0001]\t\tPM2 Control Block Length : 00\n"); + EFPRINTF(fp, "[0001]\t\tPM Timer Block Length : 04\n"); + EFPRINTF(fp, "[0001]\t\tGPE0 Block Length : 00\n"); + EFPRINTF(fp, "[0001]\t\tGPE1 Block Length : 00\n"); + EFPRINTF(fp, "[0001]\t\tGPE1 Base Offset : 00\n"); + EFPRINTF(fp, "[0001]\t\t_CST Support : 00\n"); + EFPRINTF(fp, "[0002]\t\tC2 Latency : 0000\n"); + EFPRINTF(fp, "[0002]\t\tC3 Latency : 0000\n"); + EFPRINTF(fp, "[0002]\t\tCPU Cache Size : 0000\n"); + EFPRINTF(fp, "[0002]\t\tCache Flush Stride : 0000\n"); + EFPRINTF(fp, "[0001]\t\tDuty Cycle Offset : 00\n"); + EFPRINTF(fp, "[0001]\t\tDuty Cycle Width : 00\n"); + EFPRINTF(fp, "[0001]\t\tRTC Day Alarm Index : 00\n"); + EFPRINTF(fp, "[0001]\t\tRTC Month Alarm Index : 00\n"); + EFPRINTF(fp, "[0001]\t\tRTC Century Index : 32\n"); + EFPRINTF(fp, "[0002]\t\tBoot Flags (decoded below) : 0000\n"); + EFPRINTF(fp, "\t\t\tLegacy Devices Supported (V2) : 0\n"); + EFPRINTF(fp, "\t\t\t8042 Present on ports 60/64 (V2) : 0\n"); + EFPRINTF(fp, "\t\t\tVGA Not Present (V4) : 1\n"); + EFPRINTF(fp, "\t\t\tMSI Not Supported (V4) : 0\n"); + EFPRINTF(fp, "\t\t\tPCIe ASPM Not Supported (V4) : 1\n"); + EFPRINTF(fp, "\t\t\tCMOS RTC Not Present (V5) : 0\n"); + EFPRINTF(fp, "[0001]\t\tReserved : 00\n"); + EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000000\n"); + EFPRINTF(fp, "\t\t\tWBINVD instruction is operational (V1) : 1\n"); + EFPRINTF(fp, "\t\t\tWBINVD flushes all caches (V1) : 0\n"); + EFPRINTF(fp, "\t\t\tAll CPUs support C1 (V1) : 1\n"); + EFPRINTF(fp, "\t\t\tC2 works on MP system (V1) : 0\n"); + EFPRINTF(fp, "\t\t\tControl Method Power Button (V1) : 0\n"); + EFPRINTF(fp, "\t\t\tControl Method Sleep Button (V1) : 1\n"); + EFPRINTF(fp, "\t\t\tRTC wake not in fixed reg space (V1) : 0\n"); + EFPRINTF(fp, "\t\t\tRTC can wake system from S4 (V1) : 0\n"); + EFPRINTF(fp, "\t\t\t32-bit PM Timer (V1) : 1\n"); + EFPRINTF(fp, "\t\t\tDocking Supported (V1) : 0\n"); + EFPRINTF(fp, "\t\t\tReset Register Supported (V2) : 1\n"); + EFPRINTF(fp, "\t\t\tSealed Case (V3) : 0\n"); + EFPRINTF(fp, "\t\t\tHeadless - No Video (V3) : 1\n"); + EFPRINTF(fp, "\t\t\tUse native instr after SLP_TYPx (V3) : 0\n"); + EFPRINTF(fp, "\t\t\tPCIEXP_WAK Bits Supported (V4) : 0\n"); + EFPRINTF(fp, "\t\t\tUse Platform Timer (V4) : 0\n"); + EFPRINTF(fp, "\t\t\tRTC_STS valid on S4 wake (V4) : 0\n"); + EFPRINTF(fp, "\t\t\tRemote Power-on capable (V4) : 0\n"); + EFPRINTF(fp, "\t\t\tUse APIC Cluster Model (V4) : 0\n"); + EFPRINTF(fp, "\t\t\tUse APIC Physical Destination Mode (V4) : 1\n"); + EFPRINTF(fp, "\t\t\tHardware Reduced (V5) : 0\n"); + EFPRINTF(fp, "\t\t\tLow Power S0 Idle (V5) : 0\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, + "[0012]\t\tReset Register : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000CF9\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0001]\t\tValue to cause reset : 06\n"); + EFPRINTF(fp, "[0002]\t\tARM Flags (decoded below): 0000\n"); + EFPRINTF(fp, "\t\t\tPSCI Compliant : 0\n"); + EFPRINTF(fp, "\t\t\tMust use HVC for PSCI : 0\n"); + EFPRINTF(fp, "[0001]\t\tFADT Minor Revision : 01\n"); + EFPRINTF(fp, "[0008]\t\tFACS Address : 00000000%08X\n", + basl_acpi_base + FACS_OFFSET); + EFPRINTF(fp, "[0008]\t\tDSDT Address : 00000000%08X\n", + basl_acpi_base + DSDT_OFFSET); + EFPRINTF(fp, + "[0012]\t\tPM1A Event Block : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 20\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 02 [Word Access:16]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 00000000%08X\n", + PM1A_EVT_ADDR); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, + "[0012]\t\tPM1B Event Block : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, + "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, + "[0012]\t\tPM1A Control Block : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 10\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 02 [Word Access:16]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 00000000%08X\n", + PM1A_CNT_ADDR); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, + "[0012]\t\tPM1B Control Block : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, + "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, + "[0012]\t\tPM2 Control Block : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, + "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); + EFPRINTF(fp, "\n"); + + /* Valid for bhyve */ + EFPRINTF(fp, + "[0012]\t\tPM Timer Block : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 20\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, + "[0001]\t\tEncoded Access Width : 03 [DWord Access:32]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 00000000%08X\n", + IO_PMTMR); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0012]\t\tGPE0 Block : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0012]\t\tGPE1 Block : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, + "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, + "[0012]\t\tSleep Control Register : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, + "[0012]\t\tSleep Status Register : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 01 [SystemIO]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 08\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, "[0001]\t\tEncoded Access Width : 01 [Byte Access:8]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 0000000000000000\n"); + + EFFLUSH(fp); + + return (0); + +err_exit: + return (errno); +} + +static int +basl_fwrite_hpet(FILE *fp) +{ + EFPRINTF(fp, "/*\n"); + EFPRINTF(fp, " * bhyve HPET template\n"); + EFPRINTF(fp, " */\n"); + EFPRINTF(fp, "[0004]\t\tSignature : \"HPET\"\n"); + EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); + EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); + EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); + EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); + EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVHPET \"\n"); + EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); + + /* iasl will fill in the compiler ID/revision fields */ + EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); + EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0004]\t\tTimer Block ID : %08X\n", hpet_capabilities); + EFPRINTF(fp, + "[0012]\t\tTimer Block Register : [Generic Address Structure]\n"); + EFPRINTF(fp, "[0001]\t\tSpace ID : 00 [SystemMemory]\n"); + EFPRINTF(fp, "[0001]\t\tBit Width : 00\n"); + EFPRINTF(fp, "[0001]\t\tBit Offset : 00\n"); + EFPRINTF(fp, + "[0001]\t\tEncoded Access Width : 00 [Undefined/Legacy]\n"); + EFPRINTF(fp, "[0008]\t\tAddress : 00000000FED00000\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0001]\t\tHPET Number : 00\n"); + EFPRINTF(fp, "[0002]\t\tMinimum Clock Ticks : 0000\n"); + EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000001\n"); + EFPRINTF(fp, "\t\t\t4K Page Protect : 1\n"); + EFPRINTF(fp, "\t\t\t64K Page Protect : 0\n"); + EFPRINTF(fp, "\n"); + + EFFLUSH(fp); + + return (0); + +err_exit: + return (errno); +} + +static int +basl_fwrite_mcfg(FILE *fp) +{ + EFPRINTF(fp, "/*\n"); + EFPRINTF(fp, " * bhyve MCFG template\n"); + EFPRINTF(fp, " */\n"); + EFPRINTF(fp, "[0004]\t\tSignature : \"MCFG\"\n"); + EFPRINTF(fp, "[0004]\t\tTable Length : 00000000\n"); + EFPRINTF(fp, "[0001]\t\tRevision : 01\n"); + EFPRINTF(fp, "[0001]\t\tChecksum : 00\n"); + EFPRINTF(fp, "[0006]\t\tOem ID : \"BHYVE \"\n"); + EFPRINTF(fp, "[0008]\t\tOem Table ID : \"BVMCFG \"\n"); + EFPRINTF(fp, "[0004]\t\tOem Revision : 00000001\n"); + + /* iasl will fill in the compiler ID/revision fields */ + EFPRINTF(fp, "[0004]\t\tAsl Compiler ID : \"xxxx\"\n"); + EFPRINTF(fp, "[0004]\t\tAsl Compiler Revision : 00000000\n"); + EFPRINTF(fp, "[0008]\t\tReserved : 0\n"); + EFPRINTF(fp, "\n"); + + EFPRINTF(fp, "[0008]\t\tBase Address : %016lX\n", pci_ecfg_base()); + EFPRINTF(fp, "[0002]\t\tSegment Group: 0000\n"); + EFPRINTF(fp, "[0001]\t\tStart Bus: 00\n"); + EFPRINTF(fp, "[0001]\t\tEnd Bus: FF\n"); + EFPRINTF(fp, "[0004]\t\tReserved : 0\n"); + EFFLUSH(fp); + return (0); +err_exit: + return (errno); +} + +static int +basl_fwrite_facs(FILE *fp) +{ + EFPRINTF(fp, "/*\n"); + EFPRINTF(fp, " * bhyve FACS template\n"); + EFPRINTF(fp, " */\n"); + EFPRINTF(fp, "[0004]\t\tSignature : \"FACS\"\n"); + EFPRINTF(fp, "[0004]\t\tLength : 00000040\n"); + EFPRINTF(fp, "[0004]\t\tHardware Signature : 00000000\n"); + EFPRINTF(fp, "[0004]\t\t32 Firmware Waking Vector : 00000000\n"); + EFPRINTF(fp, "[0004]\t\tGlobal Lock : 00000000\n"); + EFPRINTF(fp, "[0004]\t\tFlags (decoded below) : 00000000\n"); + EFPRINTF(fp, "\t\t\tS4BIOS Support Present : 0\n"); + EFPRINTF(fp, "\t\t\t64-bit Wake Supported (V2) : 0\n"); + EFPRINTF(fp, + "[0008]\t\t64 Firmware Waking Vector : 0000000000000000\n"); + EFPRINTF(fp, "[0001]\t\tVersion : 02\n"); + EFPRINTF(fp, "[0003]\t\tReserved : 000000\n"); + EFPRINTF(fp, "[0004]\t\tOspmFlags (decoded below) : 00000000\n"); + EFPRINTF(fp, "\t\t\t64-bit Wake Env Required (V2) : 0\n"); + + EFFLUSH(fp); + + return (0); + +err_exit: + return (errno); +} + +/* + * Helper routines for writing to the DSDT from other modules. + */ +void +dsdt_line(const char *fmt, ...) +{ + va_list ap; + + if (dsdt_error != 0) + return; + + if (strcmp(fmt, "") != 0) { + if (dsdt_indent_level != 0) + EFPRINTF(dsdt_fp, "%*c", dsdt_indent_level * 2, ' '); + va_start(ap, fmt); + if (vfprintf(dsdt_fp, fmt, ap) < 0) { + va_end(ap); + goto err_exit; + } + va_end(ap); + } + EFPRINTF(dsdt_fp, "\n"); + return; + +err_exit: + dsdt_error = errno; +} + +void +dsdt_indent(int levels) +{ + + dsdt_indent_level += levels; + assert(dsdt_indent_level >= 0); +} + +void +dsdt_unindent(int levels) +{ + + assert(dsdt_indent_level >= levels); + dsdt_indent_level -= levels; +} + +void +dsdt_fixed_ioport(uint16_t iobase, uint16_t length) +{ + + dsdt_line("IO (Decode16,"); + dsdt_line(" 0x%04X, // Range Minimum", iobase); + dsdt_line(" 0x%04X, // Range Maximum", iobase); + dsdt_line(" 0x01, // Alignment"); + dsdt_line(" 0x%02X, // Length", length); + dsdt_line(" )"); +} + +void +dsdt_fixed_irq(uint8_t irq) +{ + + dsdt_line("IRQNoFlags ()"); + dsdt_line(" {%d}", irq); +} + +void +dsdt_fixed_mem32(uint32_t base, uint32_t length) +{ + + dsdt_line("Memory32Fixed (ReadWrite,"); + dsdt_line(" 0x%08X, // Address Base", base); + dsdt_line(" 0x%08X, // Address Length", length); + dsdt_line(" )"); +} + +static int +basl_fwrite_dsdt(FILE *fp) +{ + dsdt_fp = fp; + dsdt_error = 0; + dsdt_indent_level = 0; + + dsdt_line("/*"); + dsdt_line(" * bhyve DSDT template"); + dsdt_line(" */"); + dsdt_line("DefinitionBlock (\"bhyve_dsdt.aml\", \"DSDT\", 2," + "\"BHYVE \", \"BVDSDT \", 0x00000001)"); + dsdt_line("{"); + dsdt_line(" Name (_S5, Package ()"); + dsdt_line(" {"); + dsdt_line(" 0x05,"); + dsdt_line(" Zero,"); + dsdt_line(" })"); + + pci_write_dsdt(); + + dsdt_line(""); + dsdt_line(" Scope (_SB.PC00)"); + dsdt_line(" {"); + dsdt_line(" Device (HPET)"); + dsdt_line(" {"); + dsdt_line(" Name (_HID, EISAID(\"PNP0103\"))"); + dsdt_line(" Name (_UID, 0)"); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_indent(4); + dsdt_fixed_mem32(0xFED00000, 0x400); + dsdt_unindent(4); + dsdt_line(" })"); + dsdt_line(" }"); + dsdt_line(" }"); + dsdt_line("}"); + + if (dsdt_error != 0) + return (dsdt_error); + + EFFLUSH(fp); + + return (0); + +err_exit: + return (errno); +} + +static int +basl_open(struct basl_fio *bf, int suffix) +{ + int err; + + err = 0; + + if (suffix) { + strlcpy(bf->f_name, basl_stemplate, MAXPATHLEN); + bf->fd = mkstemps(bf->f_name, strlen(BHYVE_ASL_SUFFIX)); + } else { + strlcpy(bf->f_name, basl_template, MAXPATHLEN); + bf->fd = mkstemp(bf->f_name); + } + + if (bf->fd > 0) { + bf->fp = fdopen(bf->fd, "w+"); + if (bf->fp == NULL) { + unlink(bf->f_name); + close(bf->fd); + } + } else { + err = 1; + } + + return (err); +} + +static void +basl_close(struct basl_fio *bf) +{ + + if (!basl_keep_temps) + unlink(bf->f_name); + fclose(bf->fp); +} + +static int +basl_start(struct basl_fio *in, struct basl_fio *out) +{ + int err; + + err = basl_open(in, 0); + if (!err) { + err = basl_open(out, 1); + if (err) { + basl_close(in); + } + } + + return (err); +} + +static void +basl_end(struct basl_fio *in, struct basl_fio *out) +{ + + basl_close(in); + basl_close(out); +} + +static int +basl_load(struct vmctx *ctx, int fd, uint64_t off) +{ + struct stat sb; + void *gaddr; + + if (fstat(fd, &sb) < 0) + return (errno); + + gaddr = paddr_guest2host(ctx, basl_acpi_base + off, sb.st_size); + if (gaddr == NULL) + return (EFAULT); + + if (read(fd, gaddr, sb.st_size) < 0) + return (errno); + + return (0); +} + +static int +basl_compile(struct vmctx *ctx, int (*fwrite_section)(FILE *), uint64_t offset) +{ + struct basl_fio io[2]; + static char iaslbuf[3*MAXPATHLEN + 10]; + char *fmt; + int err; + + err = basl_start(&io[0], &io[1]); + if (!err) { + err = (*fwrite_section)(io[0].fp); + + if (!err) { + /* + * iasl sends the results of the compilation to + * stdout. Shut this down by using the shell to + * redirect stdout to /dev/null, unless the user + * has requested verbose output for debugging + * purposes + */ + fmt = basl_verbose_iasl ? + "%s -p %s %s" : + "/bin/sh -c \"%s -p %s %s\" 1> /dev/null"; + + snprintf(iaslbuf, sizeof(iaslbuf), + fmt, + BHYVE_ASL_COMPILER, + io[1].f_name, io[0].f_name); + err = system(iaslbuf); + + if (!err) { + /* + * Copy the aml output file into guest + * memory at the specified location + */ + err = basl_load(ctx, io[1].fd, offset); + } + } + basl_end(&io[0], &io[1]); + } + + return (err); +} + +static int +basl_make_templates(void) +{ + const char *tmpdir; + int err; + int len; + + err = 0; + + /* + * + */ + if ((tmpdir = getenv("BHYVE_TMPDIR")) == NULL || *tmpdir == '\0' || + (tmpdir = getenv("TMPDIR")) == NULL || *tmpdir == '\0') { + tmpdir = _PATH_TMP; + } + + len = strlen(tmpdir); + + if ((len + sizeof(BHYVE_ASL_TEMPLATE) + 1) < MAXPATHLEN) { + strcpy(basl_template, tmpdir); + while (len > 0 && basl_template[len - 1] == '/') + len--; + basl_template[len] = '/'; + strcpy(&basl_template[len + 1], BHYVE_ASL_TEMPLATE); + } else + err = E2BIG; + + if (!err) { + /* + * len has been intialized (and maybe adjusted) above + */ + if ((len + sizeof(BHYVE_ASL_TEMPLATE) + 1 + + sizeof(BHYVE_ASL_SUFFIX)) < MAXPATHLEN) { + strcpy(basl_stemplate, tmpdir); + basl_stemplate[len] = '/'; + strcpy(&basl_stemplate[len + 1], BHYVE_ASL_TEMPLATE); + len = strlen(basl_stemplate); + strcpy(&basl_stemplate[len], BHYVE_ASL_SUFFIX); + } else + err = E2BIG; + } + + return (err); +} + +static struct { + int (*wsect)(FILE *fp); + uint64_t offset; +} basl_ftables[] = +{ + { basl_fwrite_rsdp, 0}, + { basl_fwrite_rsdt, RSDT_OFFSET }, + { basl_fwrite_xsdt, XSDT_OFFSET }, + { basl_fwrite_madt, MADT_OFFSET }, + { basl_fwrite_fadt, FADT_OFFSET }, + { basl_fwrite_hpet, HPET_OFFSET }, + { basl_fwrite_mcfg, MCFG_OFFSET }, + { basl_fwrite_facs, FACS_OFFSET }, + { basl_fwrite_dsdt, DSDT_OFFSET }, + { NULL } +}; + +int +acpi_build(struct vmctx *ctx, int ncpu) +{ + int err; + int i; + + basl_ncpu = ncpu; + + err = vm_get_hpet_capabilities(ctx, &hpet_capabilities); + if (err != 0) + return (err); + + /* + * For debug, allow the user to have iasl compiler output sent + * to stdout rather than /dev/null + */ + if (getenv("BHYVE_ACPI_VERBOSE_IASL")) + basl_verbose_iasl = 1; + + /* + * Allow the user to keep the generated ASL files for debugging + * instead of deleting them following use + */ + if (getenv("BHYVE_ACPI_KEEPTMPS")) + basl_keep_temps = 1; + + i = 0; + err = basl_make_templates(); + + /* + * Run through all the ASL files, compiling them and + * copying them into guest memory + */ + while (!err && basl_ftables[i].wsect != NULL) { + err = basl_compile(ctx, basl_ftables[i].wsect, + basl_ftables[i].offset); + i++; + } + + return (err); +} diff --git a/usr/src/cmd/bhyve/acpi.h b/usr/src/cmd/bhyve/acpi.h new file mode 100644 index 0000000000..4c6d86d091 --- /dev/null +++ b/usr/src/cmd/bhyve/acpi.h @@ -0,0 +1,56 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _ACPI_H_ +#define _ACPI_H_ + +#define SCI_INT 9 + +#define SMI_CMD 0xb2 +#define BHYVE_ACPI_ENABLE 0xa0 +#define BHYVE_ACPI_DISABLE 0xa1 + +#define PM1A_EVT_ADDR 0x400 +#define PM1A_CNT_ADDR 0x404 + +#define IO_PMTMR 0x408 /* 4-byte i/o port for the timer */ + +struct vmctx; + +int acpi_build(struct vmctx *ctx, int ncpu); +void dsdt_line(const char *fmt, ...); +void dsdt_fixed_ioport(uint16_t iobase, uint16_t length); +void dsdt_fixed_irq(uint8_t irq); +void dsdt_fixed_mem32(uint32_t base, uint32_t length); +void dsdt_indent(int levels); +void dsdt_unindent(int levels); +void sci_init(struct vmctx *ctx); + +#endif /* _ACPI_H_ */ diff --git a/usr/src/cmd/bhyve/ahci.h b/usr/src/cmd/bhyve/ahci.h new file mode 100644 index 0000000000..691d4bd438 --- /dev/null +++ b/usr/src/cmd/bhyve/ahci.h @@ -0,0 +1,324 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 1998 - 2008 Søren Schmidt <sos@FreeBSD.org> + * Copyright (c) 2009-2012 Alexander Motin <mav@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _AHCI_H_ +#define _AHCI_H_ + +/* ATA register defines */ +#define ATA_DATA 0 /* (RW) data */ + +#define ATA_FEATURE 1 /* (W) feature */ +#define ATA_F_DMA 0x01 /* enable DMA */ +#define ATA_F_OVL 0x02 /* enable overlap */ + +#define ATA_COUNT 2 /* (W) sector count */ + +#define ATA_SECTOR 3 /* (RW) sector # */ +#define ATA_CYL_LSB 4 /* (RW) cylinder# LSB */ +#define ATA_CYL_MSB 5 /* (RW) cylinder# MSB */ +#define ATA_DRIVE 6 /* (W) Sector/Drive/Head */ +#define ATA_D_LBA 0x40 /* use LBA addressing */ +#define ATA_D_IBM 0xa0 /* 512 byte sectors, ECC */ + +#define ATA_COMMAND 7 /* (W) command */ + +#define ATA_ERROR 8 /* (R) error */ +#define ATA_E_ILI 0x01 /* illegal length */ +#define ATA_E_NM 0x02 /* no media */ +#define ATA_E_ABORT 0x04 /* command aborted */ +#define ATA_E_MCR 0x08 /* media change request */ +#define ATA_E_IDNF 0x10 /* ID not found */ +#define ATA_E_MC 0x20 /* media changed */ +#define ATA_E_UNC 0x40 /* uncorrectable data */ +#define ATA_E_ICRC 0x80 /* UDMA crc error */ +#define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */ + +#define ATA_IREASON 9 /* (R) interrupt reason */ +#define ATA_I_CMD 0x01 /* cmd (1) | data (0) */ +#define ATA_I_IN 0x02 /* read (1) | write (0) */ +#define ATA_I_RELEASE 0x04 /* released bus (1) */ +#define ATA_I_TAGMASK 0xf8 /* tag mask */ + +#define ATA_STATUS 10 /* (R) status */ +#define ATA_ALTSTAT 11 /* (R) alternate status */ +#define ATA_S_ERROR 0x01 /* error */ +#define ATA_S_INDEX 0x02 /* index */ +#define ATA_S_CORR 0x04 /* data corrected */ +#define ATA_S_DRQ 0x08 /* data request */ +#define ATA_S_DSC 0x10 /* drive seek completed */ +#define ATA_S_SERVICE 0x10 /* drive needs service */ +#define ATA_S_DWF 0x20 /* drive write fault */ +#define ATA_S_DMA 0x20 /* DMA ready */ +#define ATA_S_READY 0x40 /* drive ready */ +#define ATA_S_BUSY 0x80 /* busy */ + +#define ATA_CONTROL 12 /* (W) control */ +#define ATA_A_IDS 0x02 /* disable interrupts */ +#define ATA_A_RESET 0x04 /* RESET controller */ +#define ATA_A_4BIT 0x08 /* 4 head bits */ +#define ATA_A_HOB 0x80 /* High Order Byte enable */ + +/* SATA register defines */ +#define ATA_SSTATUS 13 +#define ATA_SS_DET_MASK 0x0000000f +#define ATA_SS_DET_NO_DEVICE 0x00000000 +#define ATA_SS_DET_DEV_PRESENT 0x00000001 +#define ATA_SS_DET_PHY_ONLINE 0x00000003 +#define ATA_SS_DET_PHY_OFFLINE 0x00000004 + +#define ATA_SS_SPD_MASK 0x000000f0 +#define ATA_SS_SPD_NO_SPEED 0x00000000 +#define ATA_SS_SPD_GEN1 0x00000010 +#define ATA_SS_SPD_GEN2 0x00000020 +#define ATA_SS_SPD_GEN3 0x00000030 + +#define ATA_SS_IPM_MASK 0x00000f00 +#define ATA_SS_IPM_NO_DEVICE 0x00000000 +#define ATA_SS_IPM_ACTIVE 0x00000100 +#define ATA_SS_IPM_PARTIAL 0x00000200 +#define ATA_SS_IPM_SLUMBER 0x00000600 +#define ATA_SS_IPM_DEVSLEEP 0x00000800 + +#define ATA_SERROR 14 +#define ATA_SE_DATA_CORRECTED 0x00000001 +#define ATA_SE_COMM_CORRECTED 0x00000002 +#define ATA_SE_DATA_ERR 0x00000100 +#define ATA_SE_COMM_ERR 0x00000200 +#define ATA_SE_PROT_ERR 0x00000400 +#define ATA_SE_HOST_ERR 0x00000800 +#define ATA_SE_PHY_CHANGED 0x00010000 +#define ATA_SE_PHY_IERROR 0x00020000 +#define ATA_SE_COMM_WAKE 0x00040000 +#define ATA_SE_DECODE_ERR 0x00080000 +#define ATA_SE_PARITY_ERR 0x00100000 +#define ATA_SE_CRC_ERR 0x00200000 +#define ATA_SE_HANDSHAKE_ERR 0x00400000 +#define ATA_SE_LINKSEQ_ERR 0x00800000 +#define ATA_SE_TRANSPORT_ERR 0x01000000 +#define ATA_SE_UNKNOWN_FIS 0x02000000 +#define ATA_SE_EXCHANGED 0x04000000 + +#define ATA_SCONTROL 15 +#define ATA_SC_DET_MASK 0x0000000f +#define ATA_SC_DET_IDLE 0x00000000 +#define ATA_SC_DET_RESET 0x00000001 +#define ATA_SC_DET_DISABLE 0x00000004 + +#define ATA_SC_SPD_MASK 0x000000f0 +#define ATA_SC_SPD_NO_SPEED 0x00000000 +#define ATA_SC_SPD_SPEED_GEN1 0x00000010 +#define ATA_SC_SPD_SPEED_GEN2 0x00000020 +#define ATA_SC_SPD_SPEED_GEN3 0x00000030 + +#define ATA_SC_IPM_MASK 0x00000f00 +#define ATA_SC_IPM_NONE 0x00000000 +#define ATA_SC_IPM_DIS_PARTIAL 0x00000100 +#define ATA_SC_IPM_DIS_SLUMBER 0x00000200 +#define ATA_SC_IPM_DIS_DEVSLEEP 0x00000400 + +#define ATA_SACTIVE 16 + +#define AHCI_MAX_PORTS 32 +#define AHCI_MAX_SLOTS 32 +#define AHCI_MAX_IRQS 16 + +/* SATA AHCI v1.0 register defines */ +#define AHCI_CAP 0x00 +#define AHCI_CAP_NPMASK 0x0000001f +#define AHCI_CAP_SXS 0x00000020 +#define AHCI_CAP_EMS 0x00000040 +#define AHCI_CAP_CCCS 0x00000080 +#define AHCI_CAP_NCS 0x00001F00 +#define AHCI_CAP_NCS_SHIFT 8 +#define AHCI_CAP_PSC 0x00002000 +#define AHCI_CAP_SSC 0x00004000 +#define AHCI_CAP_PMD 0x00008000 +#define AHCI_CAP_FBSS 0x00010000 +#define AHCI_CAP_SPM 0x00020000 +#define AHCI_CAP_SAM 0x00080000 +#define AHCI_CAP_ISS 0x00F00000 +#define AHCI_CAP_ISS_SHIFT 20 +#define AHCI_CAP_SCLO 0x01000000 +#define AHCI_CAP_SAL 0x02000000 +#define AHCI_CAP_SALP 0x04000000 +#define AHCI_CAP_SSS 0x08000000 +#define AHCI_CAP_SMPS 0x10000000 +#define AHCI_CAP_SSNTF 0x20000000 +#define AHCI_CAP_SNCQ 0x40000000 +#define AHCI_CAP_64BIT 0x80000000 + +#define AHCI_GHC 0x04 +#define AHCI_GHC_AE 0x80000000 +#define AHCI_GHC_MRSM 0x00000004 +#define AHCI_GHC_IE 0x00000002 +#define AHCI_GHC_HR 0x00000001 + +#define AHCI_IS 0x08 +#define AHCI_PI 0x0c +#define AHCI_VS 0x10 + +#define AHCI_CCCC 0x14 +#define AHCI_CCCC_TV_MASK 0xffff0000 +#define AHCI_CCCC_TV_SHIFT 16 +#define AHCI_CCCC_CC_MASK 0x0000ff00 +#define AHCI_CCCC_CC_SHIFT 8 +#define AHCI_CCCC_INT_MASK 0x000000f8 +#define AHCI_CCCC_INT_SHIFT 3 +#define AHCI_CCCC_EN 0x00000001 +#define AHCI_CCCP 0x18 + +#define AHCI_EM_LOC 0x1C +#define AHCI_EM_CTL 0x20 +#define AHCI_EM_MR 0x00000001 +#define AHCI_EM_TM 0x00000100 +#define AHCI_EM_RST 0x00000200 +#define AHCI_EM_LED 0x00010000 +#define AHCI_EM_SAFTE 0x00020000 +#define AHCI_EM_SES2 0x00040000 +#define AHCI_EM_SGPIO 0x00080000 +#define AHCI_EM_SMB 0x01000000 +#define AHCI_EM_XMT 0x02000000 +#define AHCI_EM_ALHD 0x04000000 +#define AHCI_EM_PM 0x08000000 + +#define AHCI_CAP2 0x24 +#define AHCI_CAP2_BOH 0x00000001 +#define AHCI_CAP2_NVMP 0x00000002 +#define AHCI_CAP2_APST 0x00000004 +#define AHCI_CAP2_SDS 0x00000008 +#define AHCI_CAP2_SADM 0x00000010 +#define AHCI_CAP2_DESO 0x00000020 + +#define AHCI_OFFSET 0x100 +#define AHCI_STEP 0x80 + +#define AHCI_P_CLB 0x00 +#define AHCI_P_CLBU 0x04 +#define AHCI_P_FB 0x08 +#define AHCI_P_FBU 0x0c +#define AHCI_P_IS 0x10 +#define AHCI_P_IE 0x14 +#define AHCI_P_IX_DHR 0x00000001 +#define AHCI_P_IX_PS 0x00000002 +#define AHCI_P_IX_DS 0x00000004 +#define AHCI_P_IX_SDB 0x00000008 +#define AHCI_P_IX_UF 0x00000010 +#define AHCI_P_IX_DP 0x00000020 +#define AHCI_P_IX_PC 0x00000040 +#define AHCI_P_IX_MP 0x00000080 + +#define AHCI_P_IX_PRC 0x00400000 +#define AHCI_P_IX_IPM 0x00800000 +#define AHCI_P_IX_OF 0x01000000 +#define AHCI_P_IX_INF 0x04000000 +#define AHCI_P_IX_IF 0x08000000 +#define AHCI_P_IX_HBD 0x10000000 +#define AHCI_P_IX_HBF 0x20000000 +#define AHCI_P_IX_TFE 0x40000000 +#define AHCI_P_IX_CPD 0x80000000 + +#define AHCI_P_CMD 0x18 +#define AHCI_P_CMD_ST 0x00000001 +#define AHCI_P_CMD_SUD 0x00000002 +#define AHCI_P_CMD_POD 0x00000004 +#define AHCI_P_CMD_CLO 0x00000008 +#define AHCI_P_CMD_FRE 0x00000010 +#define AHCI_P_CMD_CCS_MASK 0x00001f00 +#define AHCI_P_CMD_CCS_SHIFT 8 +#define AHCI_P_CMD_ISS 0x00002000 +#define AHCI_P_CMD_FR 0x00004000 +#define AHCI_P_CMD_CR 0x00008000 +#define AHCI_P_CMD_CPS 0x00010000 +#define AHCI_P_CMD_PMA 0x00020000 +#define AHCI_P_CMD_HPCP 0x00040000 +#define AHCI_P_CMD_MPSP 0x00080000 +#define AHCI_P_CMD_CPD 0x00100000 +#define AHCI_P_CMD_ESP 0x00200000 +#define AHCI_P_CMD_FBSCP 0x00400000 +#define AHCI_P_CMD_APSTE 0x00800000 +#define AHCI_P_CMD_ATAPI 0x01000000 +#define AHCI_P_CMD_DLAE 0x02000000 +#define AHCI_P_CMD_ALPE 0x04000000 +#define AHCI_P_CMD_ASP 0x08000000 +#define AHCI_P_CMD_ICC_MASK 0xf0000000 +#define AHCI_P_CMD_NOOP 0x00000000 +#define AHCI_P_CMD_ACTIVE 0x10000000 +#define AHCI_P_CMD_PARTIAL 0x20000000 +#define AHCI_P_CMD_SLUMBER 0x60000000 +#define AHCI_P_CMD_DEVSLEEP 0x80000000 + +#define AHCI_P_TFD 0x20 +#define AHCI_P_SIG 0x24 +#define AHCI_P_SSTS 0x28 +#define AHCI_P_SCTL 0x2c +#define AHCI_P_SERR 0x30 +#define AHCI_P_SACT 0x34 +#define AHCI_P_CI 0x38 +#define AHCI_P_SNTF 0x3C +#define AHCI_P_FBS 0x40 +#define AHCI_P_FBS_EN 0x00000001 +#define AHCI_P_FBS_DEC 0x00000002 +#define AHCI_P_FBS_SDE 0x00000004 +#define AHCI_P_FBS_DEV 0x00000f00 +#define AHCI_P_FBS_DEV_SHIFT 8 +#define AHCI_P_FBS_ADO 0x0000f000 +#define AHCI_P_FBS_ADO_SHIFT 12 +#define AHCI_P_FBS_DWE 0x000f0000 +#define AHCI_P_FBS_DWE_SHIFT 16 +#define AHCI_P_DEVSLP 0x44 +#define AHCI_P_DEVSLP_ADSE 0x00000001 +#define AHCI_P_DEVSLP_DSP 0x00000002 +#define AHCI_P_DEVSLP_DETO 0x000003fc +#define AHCI_P_DEVSLP_DETO_SHIFT 2 +#define AHCI_P_DEVSLP_MDAT 0x00007c00 +#define AHCI_P_DEVSLP_MDAT_SHIFT 10 +#define AHCI_P_DEVSLP_DITO 0x01ff8000 +#define AHCI_P_DEVSLP_DITO_SHIFT 15 +#define AHCI_P_DEVSLP_DM 0x0e000000 +#define AHCI_P_DEVSLP_DM_SHIFT 25 + +/* Just to be sure, if building as module. */ +#if MAXPHYS < 512 * 1024 +#undef MAXPHYS +#define MAXPHYS 512 * 1024 +#endif +/* Pessimistic prognosis on number of required S/G entries */ +#define AHCI_SG_ENTRIES (roundup(btoc(MAXPHYS) + 1, 8)) +/* Command list. 32 commands. First, 1Kbyte aligned. */ +#define AHCI_CL_OFFSET 0 +#define AHCI_CL_SIZE 32 +/* Command tables. Up to 32 commands, Each, 128byte aligned. */ +#define AHCI_CT_OFFSET (AHCI_CL_OFFSET + AHCI_CL_SIZE * AHCI_MAX_SLOTS) +#define AHCI_CT_SIZE (128 + AHCI_SG_ENTRIES * 16) +/* Total main work area. */ +#define AHCI_WORK_SIZE (AHCI_CT_OFFSET + AHCI_CT_SIZE * ch->numslots) + +#endif /* _AHCI_H_ */ diff --git a/usr/src/cmd/bhyve/atkbdc.c b/usr/src/cmd/bhyve/atkbdc.c new file mode 100644 index 0000000000..1c1838c2e8 --- /dev/null +++ b/usr/src/cmd/bhyve/atkbdc.c @@ -0,0 +1,586 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * Copyright (c) 2015 Nahanni Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> + +#include <machine/vmm.h> + +#include <vmmapi.h> + +#include <assert.h> +#include <errno.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <pthread.h> +#include <pthread_np.h> + +#include "acpi.h" +#include "atkbdc.h" +#include "inout.h" +#include "pci_emul.h" +#include "pci_irq.h" +#include "pci_lpc.h" +#include "ps2kbd.h" +#include "ps2mouse.h" + +#define KBD_DATA_PORT 0x60 + +#define KBD_STS_CTL_PORT 0x64 + +#define KBDC_RESET 0xfe + +#define KBD_DEV_IRQ 1 +#define AUX_DEV_IRQ 12 + +/* controller commands */ +#define KBDC_SET_COMMAND_BYTE 0x60 +#define KBDC_GET_COMMAND_BYTE 0x20 +#define KBDC_DISABLE_AUX_PORT 0xa7 +#define KBDC_ENABLE_AUX_PORT 0xa8 +#define KBDC_TEST_AUX_PORT 0xa9 +#define KBDC_TEST_CTRL 0xaa +#define KBDC_TEST_KBD_PORT 0xab +#define KBDC_DISABLE_KBD_PORT 0xad +#define KBDC_ENABLE_KBD_PORT 0xae +#define KBDC_READ_INPORT 0xc0 +#define KBDC_READ_OUTPORT 0xd0 +#define KBDC_WRITE_OUTPORT 0xd1 +#define KBDC_WRITE_KBD_OUTBUF 0xd2 +#define KBDC_WRITE_AUX_OUTBUF 0xd3 +#define KBDC_WRITE_TO_AUX 0xd4 + +/* controller command byte (set by KBDC_SET_COMMAND_BYTE) */ +#define KBD_TRANSLATION 0x40 +#define KBD_SYS_FLAG_BIT 0x04 +#define KBD_DISABLE_KBD_PORT 0x10 +#define KBD_DISABLE_AUX_PORT 0x20 +#define KBD_ENABLE_AUX_INT 0x02 +#define KBD_ENABLE_KBD_INT 0x01 +#define KBD_KBD_CONTROL_BITS (KBD_DISABLE_KBD_PORT | KBD_ENABLE_KBD_INT) +#define KBD_AUX_CONTROL_BITS (KBD_DISABLE_AUX_PORT | KBD_ENABLE_AUX_INT) + +/* controller status bits */ +#define KBDS_KBD_BUFFER_FULL 0x01 +#define KBDS_SYS_FLAG 0x04 +#define KBDS_CTRL_FLAG 0x08 +#define KBDS_AUX_BUFFER_FULL 0x20 + +/* controller output port */ +#define KBDO_KBD_OUTFULL 0x10 +#define KBDO_AUX_OUTFULL 0x20 + +#define RAMSZ 32 +#define FIFOSZ 15 +#define CTRL_CMD_FLAG 0x8000 + +struct kbd_dev { + bool irq_active; + int irq; + + uint8_t buffer[FIFOSZ]; + int brd, bwr; + int bcnt; +}; + +struct aux_dev { + bool irq_active; + int irq; +}; + +struct atkbdc_softc { + struct vmctx *ctx; + pthread_mutex_t mtx; + + struct ps2kbd_softc *ps2kbd_sc; + struct ps2mouse_softc *ps2mouse_sc; + + uint8_t status; /* status register */ + uint8_t outport; /* controller output port */ + uint8_t ram[RAMSZ]; /* byte0 = controller config */ + + uint32_t curcmd; /* current command for next byte */ + uint32_t ctrlbyte; + + struct kbd_dev kbd; + struct aux_dev aux; +}; + +static void +atkbdc_assert_kbd_intr(struct atkbdc_softc *sc) +{ + if ((sc->ram[0] & KBD_ENABLE_KBD_INT) != 0) { + sc->kbd.irq_active = true; + vm_isa_pulse_irq(sc->ctx, sc->kbd.irq, sc->kbd.irq); + } +} + +static void +atkbdc_assert_aux_intr(struct atkbdc_softc *sc) +{ + if ((sc->ram[0] & KBD_ENABLE_AUX_INT) != 0) { + sc->aux.irq_active = true; + vm_isa_pulse_irq(sc->ctx, sc->aux.irq, sc->aux.irq); + } +} + +static int +atkbdc_kbd_queue_data(struct atkbdc_softc *sc, uint8_t val) +{ + assert(pthread_mutex_isowned_np(&sc->mtx)); + + if (sc->kbd.bcnt < FIFOSZ) { + sc->kbd.buffer[sc->kbd.bwr] = val; + sc->kbd.bwr = (sc->kbd.bwr + 1) % FIFOSZ; + sc->kbd.bcnt++; + sc->status |= KBDS_KBD_BUFFER_FULL; + sc->outport |= KBDO_KBD_OUTFULL; + } else { + printf("atkbd data buffer full\n"); + } + + return (sc->kbd.bcnt < FIFOSZ); +} + +static void +atkbdc_kbd_read(struct atkbdc_softc *sc) +{ + const uint8_t translation[256] = { + 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, + 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59, + 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a, + 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b, + 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c, + 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d, + 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e, + 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f, + 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60, + 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61, + 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e, + 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76, + 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b, + 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f, + 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45, + 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54, + 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff + }; + uint8_t val; + uint8_t release = 0; + + assert(pthread_mutex_isowned_np(&sc->mtx)); + + if (sc->ram[0] & KBD_TRANSLATION) { + while (ps2kbd_read(sc->ps2kbd_sc, &val) != -1) { + if (val == 0xf0) { + release = 0x80; + continue; + } else { + val = translation[val] | release; + } + atkbdc_kbd_queue_data(sc, val); + break; + } + } else { + while (sc->kbd.bcnt < FIFOSZ) { + if (ps2kbd_read(sc->ps2kbd_sc, &val) != -1) + atkbdc_kbd_queue_data(sc, val); + else + break; + } + } + + if (((sc->ram[0] & KBD_DISABLE_AUX_PORT) || + ps2mouse_fifocnt(sc->ps2mouse_sc) == 0) && sc->kbd.bcnt > 0) + atkbdc_assert_kbd_intr(sc); +} + +static void +atkbdc_aux_poll(struct atkbdc_softc *sc) +{ + if (ps2mouse_fifocnt(sc->ps2mouse_sc) > 0) { + sc->status |= KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL; + sc->outport |= KBDO_AUX_OUTFULL; + atkbdc_assert_aux_intr(sc); + } +} + +static void +atkbdc_kbd_poll(struct atkbdc_softc *sc) +{ + assert(pthread_mutex_isowned_np(&sc->mtx)); + + atkbdc_kbd_read(sc); +} + +static void +atkbdc_poll(struct atkbdc_softc *sc) +{ + atkbdc_aux_poll(sc); + atkbdc_kbd_poll(sc); +} + +static void +atkbdc_dequeue_data(struct atkbdc_softc *sc, uint8_t *buf) +{ + assert(pthread_mutex_isowned_np(&sc->mtx)); + + if (ps2mouse_read(sc->ps2mouse_sc, buf) == 0) { + if (ps2mouse_fifocnt(sc->ps2mouse_sc) == 0) { + if (sc->kbd.bcnt == 0) + sc->status &= ~(KBDS_AUX_BUFFER_FULL | + KBDS_KBD_BUFFER_FULL); + else + sc->status &= ~(KBDS_AUX_BUFFER_FULL); + sc->outport &= ~KBDO_AUX_OUTFULL; + } + + atkbdc_poll(sc); + return; + } + + if (sc->kbd.bcnt > 0) { + *buf = sc->kbd.buffer[sc->kbd.brd]; + sc->kbd.brd = (sc->kbd.brd + 1) % FIFOSZ; + sc->kbd.bcnt--; + if (sc->kbd.bcnt == 0) { + sc->status &= ~KBDS_KBD_BUFFER_FULL; + sc->outport &= ~KBDO_KBD_OUTFULL; + } + + atkbdc_poll(sc); + } + + if (ps2mouse_fifocnt(sc->ps2mouse_sc) == 0 && sc->kbd.bcnt == 0) { + sc->status &= ~(KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL); + } +} + +static int +atkbdc_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + struct atkbdc_softc *sc; + uint8_t buf; + int retval; + + if (bytes != 1) + return (-1); + sc = arg; + retval = 0; + + pthread_mutex_lock(&sc->mtx); + if (in) { + sc->curcmd = 0; + if (sc->ctrlbyte != 0) { + *eax = sc->ctrlbyte & 0xff; + sc->ctrlbyte = 0; + } else { + /* read device buffer; includes kbd cmd responses */ + atkbdc_dequeue_data(sc, &buf); + *eax = buf; + } + + sc->status &= ~KBDS_CTRL_FLAG; + pthread_mutex_unlock(&sc->mtx); + return (retval); + } + + if (sc->status & KBDS_CTRL_FLAG) { + /* + * Command byte for the controller. + */ + switch (sc->curcmd) { + case KBDC_SET_COMMAND_BYTE: + sc->ram[0] = *eax; + if (sc->ram[0] & KBD_SYS_FLAG_BIT) + sc->status |= KBDS_SYS_FLAG; + else + sc->status &= ~KBDS_SYS_FLAG; + break; + case KBDC_WRITE_OUTPORT: + sc->outport = *eax; + break; + case KBDC_WRITE_TO_AUX: + ps2mouse_write(sc->ps2mouse_sc, *eax, 0); + atkbdc_poll(sc); + break; + case KBDC_WRITE_KBD_OUTBUF: + atkbdc_kbd_queue_data(sc, *eax); + break; + case KBDC_WRITE_AUX_OUTBUF: + ps2mouse_write(sc->ps2mouse_sc, *eax, 1); + sc->status |= (KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL); + atkbdc_aux_poll(sc); + break; + default: + /* write to particular RAM byte */ + if (sc->curcmd >= 0x61 && sc->curcmd <= 0x7f) { + int byten; + + byten = (sc->curcmd - 0x60) & 0x1f; + sc->ram[byten] = *eax & 0xff; + } + break; + } + + sc->curcmd = 0; + sc->status &= ~KBDS_CTRL_FLAG; + + pthread_mutex_unlock(&sc->mtx); + return (retval); + } + + /* + * Data byte for the device. + */ + ps2kbd_write(sc->ps2kbd_sc, *eax); + atkbdc_poll(sc); + + pthread_mutex_unlock(&sc->mtx); + + return (retval); +} + +static int +atkbdc_sts_ctl_handler(struct vmctx *ctx, int vcpu, int in, int port, + int bytes, uint32_t *eax, void *arg) +{ + struct atkbdc_softc *sc; + int error, retval; + + if (bytes != 1) + return (-1); + + sc = arg; + retval = 0; + + pthread_mutex_lock(&sc->mtx); + + if (in) { + /* read status register */ + *eax = sc->status; + pthread_mutex_unlock(&sc->mtx); + return (retval); + } + + + sc->curcmd = 0; + sc->status |= KBDS_CTRL_FLAG; + sc->ctrlbyte = 0; + + switch (*eax) { + case KBDC_GET_COMMAND_BYTE: + sc->ctrlbyte = CTRL_CMD_FLAG | sc->ram[0]; + break; + case KBDC_TEST_CTRL: + sc->ctrlbyte = CTRL_CMD_FLAG | 0x55; + break; + case KBDC_TEST_AUX_PORT: + case KBDC_TEST_KBD_PORT: + sc->ctrlbyte = CTRL_CMD_FLAG | 0; + break; + case KBDC_READ_INPORT: + sc->ctrlbyte = CTRL_CMD_FLAG | 0; + break; + case KBDC_READ_OUTPORT: + sc->ctrlbyte = CTRL_CMD_FLAG | sc->outport; + break; + case KBDC_SET_COMMAND_BYTE: + case KBDC_WRITE_OUTPORT: + case KBDC_WRITE_KBD_OUTBUF: + case KBDC_WRITE_AUX_OUTBUF: + sc->curcmd = *eax; + break; + case KBDC_DISABLE_KBD_PORT: + sc->ram[0] |= KBD_DISABLE_KBD_PORT; + break; + case KBDC_ENABLE_KBD_PORT: + sc->ram[0] &= ~KBD_DISABLE_KBD_PORT; + if (sc->kbd.bcnt > 0) + sc->status |= KBDS_KBD_BUFFER_FULL; + atkbdc_poll(sc); + break; + case KBDC_WRITE_TO_AUX: + sc->curcmd = *eax; + break; + case KBDC_DISABLE_AUX_PORT: + sc->ram[0] |= KBD_DISABLE_AUX_PORT; + ps2mouse_toggle(sc->ps2mouse_sc, 0); + sc->status &= ~(KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL); + sc->outport &= ~KBDS_AUX_BUFFER_FULL; + break; + case KBDC_ENABLE_AUX_PORT: + sc->ram[0] &= ~KBD_DISABLE_AUX_PORT; + ps2mouse_toggle(sc->ps2mouse_sc, 1); + if (ps2mouse_fifocnt(sc->ps2mouse_sc) > 0) + sc->status |= KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL; + break; + case KBDC_RESET: /* Pulse "reset" line */ + error = vm_suspend(ctx, VM_SUSPEND_RESET); + assert(error == 0 || errno == EALREADY); + break; + default: + if (*eax >= 0x21 && *eax <= 0x3f) { + /* read "byte N" from RAM */ + int byten; + + byten = (*eax - 0x20) & 0x1f; + sc->ctrlbyte = CTRL_CMD_FLAG | sc->ram[byten]; + } + break; + } + + pthread_mutex_unlock(&sc->mtx); + + if (sc->ctrlbyte != 0) { + sc->status |= KBDS_KBD_BUFFER_FULL; + sc->status &= ~KBDS_AUX_BUFFER_FULL; + atkbdc_assert_kbd_intr(sc); + } else if (ps2mouse_fifocnt(sc->ps2mouse_sc) > 0 && + (sc->ram[0] & KBD_DISABLE_AUX_PORT) == 0) { + sc->status |= KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL; + atkbdc_assert_aux_intr(sc); + } else if (sc->kbd.bcnt > 0 && (sc->ram[0] & KBD_DISABLE_KBD_PORT) == 0) { + sc->status |= KBDS_KBD_BUFFER_FULL; + atkbdc_assert_kbd_intr(sc); + } + + return (retval); +} + +void +atkbdc_event(struct atkbdc_softc *sc, int iskbd) +{ + pthread_mutex_lock(&sc->mtx); + + if (iskbd) + atkbdc_kbd_poll(sc); + else + atkbdc_aux_poll(sc); + pthread_mutex_unlock(&sc->mtx); +} + +void +atkbdc_init(struct vmctx *ctx) +{ + struct inout_port iop; + struct atkbdc_softc *sc; + int error; + + sc = calloc(1, sizeof(struct atkbdc_softc)); + sc->ctx = ctx; + + pthread_mutex_init(&sc->mtx, NULL); + + bzero(&iop, sizeof(struct inout_port)); + iop.name = "atkdbc"; + iop.port = KBD_STS_CTL_PORT; + iop.size = 1; + iop.flags = IOPORT_F_INOUT; + iop.handler = atkbdc_sts_ctl_handler; + iop.arg = sc; + + error = register_inout(&iop); + assert(error == 0); + + bzero(&iop, sizeof(struct inout_port)); + iop.name = "atkdbc"; + iop.port = KBD_DATA_PORT; + iop.size = 1; + iop.flags = IOPORT_F_INOUT; + iop.handler = atkbdc_data_handler; + iop.arg = sc; + + error = register_inout(&iop); + assert(error == 0); + + pci_irq_reserve(KBD_DEV_IRQ); + sc->kbd.irq = KBD_DEV_IRQ; + + pci_irq_reserve(AUX_DEV_IRQ); + sc->aux.irq = AUX_DEV_IRQ; + + sc->ps2kbd_sc = ps2kbd_init(sc); + sc->ps2mouse_sc = ps2mouse_init(sc); +} + +static void +atkbdc_dsdt(void) +{ + + dsdt_line(""); + dsdt_line("Device (KBD)"); + dsdt_line("{"); + dsdt_line(" Name (_HID, EisaId (\"PNP0303\"))"); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_indent(2); + dsdt_fixed_ioport(KBD_DATA_PORT, 1); + dsdt_fixed_ioport(KBD_STS_CTL_PORT, 1); + dsdt_fixed_irq(1); + dsdt_unindent(2); + dsdt_line(" })"); + dsdt_line("}"); + + dsdt_line(""); + dsdt_line("Device (MOU)"); + dsdt_line("{"); + dsdt_line(" Name (_HID, EisaId (\"PNP0F13\"))"); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_indent(2); + dsdt_fixed_ioport(KBD_DATA_PORT, 1); + dsdt_fixed_ioport(KBD_STS_CTL_PORT, 1); + dsdt_fixed_irq(12); + dsdt_unindent(2); + dsdt_line(" })"); + dsdt_line("}"); +} +LPC_DSDT(atkbdc_dsdt); + diff --git a/usr/src/cmd/bhyve/atkbdc.h b/usr/src/cmd/bhyve/atkbdc.h new file mode 100644 index 0000000000..85c8a7141e --- /dev/null +++ b/usr/src/cmd/bhyve/atkbdc.h @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _ATKBDC_H_ +#define _ATKBDC_H_ + +struct atkbdc_softc; +struct vmctx; + +void atkbdc_init(struct vmctx *ctx); +void atkbdc_event(struct atkbdc_softc *sc, int iskbd); + +#endif /* _ATKBDC_H_ */ diff --git a/usr/src/cmd/bhyve/bhyve_sol_glue.c b/usr/src/cmd/bhyve/bhyve_sol_glue.c new file mode 100644 index 0000000000..7b24ea7f5d --- /dev/null +++ b/usr/src/cmd/bhyve/bhyve_sol_glue.c @@ -0,0 +1,39 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2013 Pluribus Networks Inc. + * Copyright 2017 Joyent, Inc. + */ + +#include <sys/uio.h> + +#include <termios.h> +#include <unistd.h> + +/* + * Make a pre-existing termios structure into "raw" mode: character-at-a-time + * mode with no characters interpreted, 8-bit data path. + */ +void +cfmakeraw(struct termios *t) +{ + t->c_iflag &= ~(IMAXBEL|IXOFF|INPCK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR| + ICRNL|IXON|IGNPAR); + t->c_iflag |= IGNBRK; + t->c_oflag &= ~OPOST; + t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH| + TOSTOP|PENDIN); + t->c_cflag &= ~(CSIZE|PARENB); + t->c_cflag |= CS8|CREAD; + t->c_cc[VMIN] = 1; + t->c_cc[VTIME] = 0; +} diff --git a/usr/src/cmd/bhyve/bhyvegc.c b/usr/src/cmd/bhyve/bhyvegc.c new file mode 100644 index 0000000000..4bd49ded79 --- /dev/null +++ b/usr/src/cmd/bhyve/bhyvegc.c @@ -0,0 +1,103 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "bhyvegc.h" + +struct bhyvegc { + struct bhyvegc_image *gc_image; + int raw; +}; + +struct bhyvegc * +bhyvegc_init(int width, int height, void *fbaddr) +{ + struct bhyvegc *gc; + struct bhyvegc_image *gc_image; + + gc = calloc(1, sizeof (struct bhyvegc)); + + gc_image = calloc(1, sizeof(struct bhyvegc_image)); + gc_image->width = width; + gc_image->height = height; + if (fbaddr) { + gc_image->data = fbaddr; + gc->raw = 1; + } else { + gc_image->data = calloc(width * height, sizeof (uint32_t)); + gc->raw = 0; + } + + gc->gc_image = gc_image; + + return (gc); +} + +void +bhyvegc_set_fbaddr(struct bhyvegc *gc, void *fbaddr) +{ + gc->raw = 1; + if (gc->gc_image->data && gc->gc_image->data != fbaddr) + free(gc->gc_image->data); + gc->gc_image->data = fbaddr; +} + +void +bhyvegc_resize(struct bhyvegc *gc, int width, int height) +{ + struct bhyvegc_image *gc_image; + + gc_image = gc->gc_image; + + gc_image->width = width; + gc_image->height = height; + if (!gc->raw) { + gc_image->data = reallocarray(gc_image->data, width * height, + sizeof (uint32_t)); + if (gc_image->data != NULL) + memset(gc_image->data, 0, width * height * + sizeof (uint32_t)); + } +} + +struct bhyvegc_image * +bhyvegc_get_image(struct bhyvegc *gc) +{ + if (gc == NULL) + return (NULL); + + return (gc->gc_image); +} diff --git a/usr/src/cmd/bhyve/bhyvegc.h b/usr/src/cmd/bhyve/bhyvegc.h new file mode 100644 index 0000000000..11323586df --- /dev/null +++ b/usr/src/cmd/bhyve/bhyvegc.h @@ -0,0 +1,48 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _BHYVEGC_H_ +#define _BHYVEGC_H_ + +struct bhyvegc; + +struct bhyvegc_image { + int vgamode; + int width; + int height; + uint32_t *data; +}; + +struct bhyvegc *bhyvegc_init(int width, int height, void *fbaddr); +void bhyvegc_set_fbaddr(struct bhyvegc *gc, void *fbaddr); +void bhyvegc_resize(struct bhyvegc *gc, int width, int height); +struct bhyvegc_image *bhyvegc_get_image(struct bhyvegc *gc); + +#endif /* _BHYVEGC_H_ */ diff --git a/usr/src/cmd/bhyve/bhyverun.c b/usr/src/cmd/bhyve/bhyverun.c new file mode 100644 index 0000000000..ccf89b4613 --- /dev/null +++ b/usr/src/cmd/bhyve/bhyverun.c @@ -0,0 +1,1395 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2015 Pluribus Networks Inc. + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/mman.h> +#include <sys/time.h> +#include <sys/cpuset.h> + +#ifdef __FreeBSD__ +#include <amd64/vmm/intel/vmcs.h> +#else +#include <intel/vmcs.h> +#endif + +#include <machine/atomic.h> +#include <machine/segments.h> + +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <err.h> +#include <errno.h> +#include <libgen.h> +#include <unistd.h> +#include <assert.h> +#include <pthread.h> +#include <pthread_np.h> +#include <sysexits.h> +#include <stdbool.h> +#include <stdint.h> + +#include <machine/vmm.h> +#ifndef WITHOUT_CAPSICUM +#include <machine/vmm_dev.h> +#endif +#include <vmmapi.h> + +#ifndef __FreeBSD__ +#include <sys/stat.h> +#endif + +#include "bhyverun.h" +#include "acpi.h" +#include "atkbdc.h" +#include "console.h" +#include "inout.h" +#include "dbgport.h" +#include "fwctl.h" +#include "gdb.h" +#include "ioapic.h" +#include "mem.h" +#include "mevent.h" +#include "mptbl.h" +#include "pci_emul.h" +#include "pci_irq.h" +#include "pci_lpc.h" +#include "smbiostbl.h" +#include "xmsr.h" +#include "spinup_ap.h" +#include "rfb.h" +#include "rtc.h" +#include "vga.h" + +#define GUEST_NIO_PORT 0x488 /* guest upcalls via i/o port */ + +#define MB (1024UL * 1024) +#define GB (1024UL * MB) + +static const char * const vmx_exit_reason_desc[] = { + [EXIT_REASON_EXCEPTION] = "Exception or non-maskable interrupt (NMI)", + [EXIT_REASON_EXT_INTR] = "External interrupt", + [EXIT_REASON_TRIPLE_FAULT] = "Triple fault", + [EXIT_REASON_INIT] = "INIT signal", + [EXIT_REASON_SIPI] = "Start-up IPI (SIPI)", + [EXIT_REASON_IO_SMI] = "I/O system-management interrupt (SMI)", + [EXIT_REASON_SMI] = "Other SMI", + [EXIT_REASON_INTR_WINDOW] = "Interrupt window", + [EXIT_REASON_NMI_WINDOW] = "NMI window", + [EXIT_REASON_TASK_SWITCH] = "Task switch", + [EXIT_REASON_CPUID] = "CPUID", + [EXIT_REASON_GETSEC] = "GETSEC", + [EXIT_REASON_HLT] = "HLT", + [EXIT_REASON_INVD] = "INVD", + [EXIT_REASON_INVLPG] = "INVLPG", + [EXIT_REASON_RDPMC] = "RDPMC", + [EXIT_REASON_RDTSC] = "RDTSC", + [EXIT_REASON_RSM] = "RSM", + [EXIT_REASON_VMCALL] = "VMCALL", + [EXIT_REASON_VMCLEAR] = "VMCLEAR", + [EXIT_REASON_VMLAUNCH] = "VMLAUNCH", + [EXIT_REASON_VMPTRLD] = "VMPTRLD", + [EXIT_REASON_VMPTRST] = "VMPTRST", + [EXIT_REASON_VMREAD] = "VMREAD", + [EXIT_REASON_VMRESUME] = "VMRESUME", + [EXIT_REASON_VMWRITE] = "VMWRITE", + [EXIT_REASON_VMXOFF] = "VMXOFF", + [EXIT_REASON_VMXON] = "VMXON", + [EXIT_REASON_CR_ACCESS] = "Control-register accesses", + [EXIT_REASON_DR_ACCESS] = "MOV DR", + [EXIT_REASON_INOUT] = "I/O instruction", + [EXIT_REASON_RDMSR] = "RDMSR", + [EXIT_REASON_WRMSR] = "WRMSR", + [EXIT_REASON_INVAL_VMCS] = + "VM-entry failure due to invalid guest state", + [EXIT_REASON_INVAL_MSR] = "VM-entry failure due to MSR loading", + [EXIT_REASON_MWAIT] = "MWAIT", + [EXIT_REASON_MTF] = "Monitor trap flag", + [EXIT_REASON_MONITOR] = "MONITOR", + [EXIT_REASON_PAUSE] = "PAUSE", + [EXIT_REASON_MCE_DURING_ENTRY] = + "VM-entry failure due to machine-check event", + [EXIT_REASON_TPR] = "TPR below threshold", + [EXIT_REASON_APIC_ACCESS] = "APIC access", + [EXIT_REASON_VIRTUALIZED_EOI] = "Virtualized EOI", + [EXIT_REASON_GDTR_IDTR] = "Access to GDTR or IDTR", + [EXIT_REASON_LDTR_TR] = "Access to LDTR or TR", + [EXIT_REASON_EPT_FAULT] = "EPT violation", + [EXIT_REASON_EPT_MISCONFIG] = "EPT misconfiguration", + [EXIT_REASON_INVEPT] = "INVEPT", + [EXIT_REASON_RDTSCP] = "RDTSCP", + [EXIT_REASON_VMX_PREEMPT] = "VMX-preemption timer expired", + [EXIT_REASON_INVVPID] = "INVVPID", + [EXIT_REASON_WBINVD] = "WBINVD", + [EXIT_REASON_XSETBV] = "XSETBV", + [EXIT_REASON_APIC_WRITE] = "APIC write", + [EXIT_REASON_RDRAND] = "RDRAND", + [EXIT_REASON_INVPCID] = "INVPCID", + [EXIT_REASON_VMFUNC] = "VMFUNC", + [EXIT_REASON_ENCLS] = "ENCLS", + [EXIT_REASON_RDSEED] = "RDSEED", + [EXIT_REASON_PM_LOG_FULL] = "Page-modification log full", + [EXIT_REASON_XSAVES] = "XSAVES", + [EXIT_REASON_XRSTORS] = "XRSTORS" +}; + +typedef int (*vmexit_handler_t)(struct vmctx *, struct vm_exit *, int *vcpu); +extern int vmexit_task_switch(struct vmctx *, struct vm_exit *, int *vcpu); + +char *vmname; + +int guest_ncpus; +uint16_t cores, maxcpus, sockets, threads; + +char *guest_uuid_str; + +static int guest_vmexit_on_hlt, guest_vmexit_on_pause; +static int virtio_msix = 1; +static int x2apic_mode = 0; /* default is xAPIC */ + +static int strictio; +static int strictmsr = 1; + +static int acpi; + +static char *progname; +static const int BSP = 0; + +#ifndef __FreeBSD__ +int bcons_wait = 0; +int bcons_connected = 0; +pthread_mutex_t bcons_wait_lock = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t bcons_wait_done = PTHREAD_COND_INITIALIZER; +#endif + +static cpuset_t cpumask; + +static void vm_loop(struct vmctx *ctx, int vcpu, uint64_t rip); + +static struct vm_exit vmexit[VM_MAXCPU]; + +struct bhyvestats { + uint64_t vmexit_bogus; + uint64_t vmexit_reqidle; + uint64_t vmexit_hlt; + uint64_t vmexit_pause; + uint64_t vmexit_mtrap; + uint64_t vmexit_inst_emul; + uint64_t cpu_switch_rotate; + uint64_t cpu_switch_direct; +} stats; + +struct mt_vmm_info { + pthread_t mt_thr; + struct vmctx *mt_ctx; + int mt_vcpu; +} mt_vmm_info[VM_MAXCPU]; + +#ifdef __FreeBSD__ +static cpuset_t *vcpumap[VM_MAXCPU] = { NULL }; +#endif + +static void +usage(int code) +{ + + fprintf(stderr, + "Usage: %s [-abehuwxACHPSWY]\n" + " %*s [-c [[cpus=]numcpus][,sockets=n][,cores=n][,threads=n]]\n" + " %*s [-g <gdb port>] [-l <lpc>]\n" +#ifdef __FreeBSD__ + " %*s [-m mem] [-p vcpu:hostcpu] [-s <pci>] [-U uuid] <vm>\n" +#else + " %*s [-m mem] [-s <pci>] [-U uuid] <vm>\n" +#endif + " -a: local apic is in xAPIC mode (deprecated)\n" + " -A: create ACPI tables\n" + " -c: number of cpus and/or topology specification\n" + " -C: include guest memory in core file\n" +#ifndef __FreeBSD__ + " -d: suspend cpu at boot\n" +#endif + " -e: exit on unhandled I/O access\n" + " -g: gdb port\n" + " -h: help\n" + " -H: vmexit from the guest on hlt\n" + " -l: LPC device configuration\n" + " -m: memory size\n" +#ifdef __FreeBSD__ + " -p: pin 'vcpu' to 'hostcpu'\n" +#endif + " -P: vmexit from the guest on pause\n" + " -s: <slot,driver,configinfo> PCI slot config\n" + " -S: guest memory cannot be swapped\n" + " -u: RTC keeps UTC time\n" + " -U: uuid\n" + " -w: ignore unimplemented MSRs\n" + " -W: force virtio to use single-vector MSI\n" + " -x: local apic is in x2APIC mode\n" + " -Y: disable MPtable generation\n", + progname, (int)strlen(progname), "", (int)strlen(progname), "", + (int)strlen(progname), ""); + + exit(code); +} + +/* + * XXX This parser is known to have the following issues: + * 1. It accepts null key=value tokens ",,". + * 2. It accepts whitespace after = and before value. + * 3. Values out of range of INT are silently wrapped. + * 4. It doesn't check non-final values. + * 5. The apparently bogus limits of UINT16_MAX are for future expansion. + * + * The acceptance of a null specification ('-c ""') is by design to match the + * manual page syntax specification, this results in a topology of 1 vCPU. + */ +static int +topology_parse(const char *opt) +{ + uint64_t ncpus; + int c, chk, n, s, t, tmp; + char *cp, *str; + bool ns, scts; + + c = 1, n = 1, s = 1, t = 1; + ns = false, scts = false; + str = strdup(opt); + if (str == NULL) + goto out; + + while ((cp = strsep(&str, ",")) != NULL) { + if (sscanf(cp, "%i%n", &tmp, &chk) == 1) { + n = tmp; + ns = true; + } else if (sscanf(cp, "cpus=%i%n", &tmp, &chk) == 1) { + n = tmp; + ns = true; + } else if (sscanf(cp, "sockets=%i%n", &tmp, &chk) == 1) { + s = tmp; + scts = true; + } else if (sscanf(cp, "cores=%i%n", &tmp, &chk) == 1) { + c = tmp; + scts = true; + } else if (sscanf(cp, "threads=%i%n", &tmp, &chk) == 1) { + t = tmp; + scts = true; +#ifdef notyet /* Do not expose this until vmm.ko implements it */ + } else if (sscanf(cp, "maxcpus=%i%n", &tmp, &chk) == 1) { + m = tmp; +#endif + /* Skip the empty argument case from -c "" */ + } else if (cp[0] == '\0') + continue; + else + goto out; + /* Any trailing garbage causes an error */ + if (cp[chk] != '\0') + goto out; + } + free(str); + str = NULL; + + /* + * Range check 1 <= n <= UINT16_MAX all values + */ + if (n < 1 || s < 1 || c < 1 || t < 1 || + n > UINT16_MAX || s > UINT16_MAX || c > UINT16_MAX || + t > UINT16_MAX) + return (-1); + + /* If only the cpus was specified, use that as sockets */ + if (!scts) + s = n; + /* + * Compute sockets * cores * threads avoiding overflow + * The range check above insures these are 16 bit values + * If n was specified check it against computed ncpus + */ + ncpus = (uint64_t)s * c * t; + if (ncpus > UINT16_MAX || (ns && n != ncpus)) + return (-1); + + guest_ncpus = ncpus; + sockets = s; + cores = c; + threads = t; + return(0); + +out: + free(str); + return (-1); +} + +#ifndef WITHOUT_CAPSICUM +/* + * 11-stable capsicum helpers + */ +static void +bhyve_caph_cache_catpages(void) +{ + + (void)catopen("libc", NL_CAT_LOCALE); +} + +static int +bhyve_caph_limit_stdoe(void) +{ + cap_rights_t rights; + unsigned long cmds[] = { TIOCGETA, TIOCGWINSZ }; + int i, fds[] = { STDOUT_FILENO, STDERR_FILENO }; + + cap_rights_init(&rights, CAP_FCNTL, CAP_FSTAT, CAP_IOCTL); + cap_rights_set(&rights, CAP_WRITE); + + for (i = 0; i < nitems(fds); i++) { + if (cap_rights_limit(fds[i], &rights) < 0 && errno != ENOSYS) + return (-1); + + if (cap_ioctls_limit(fds[i], cmds, nitems(cmds)) < 0 && errno != ENOSYS) + return (-1); + + if (cap_fcntls_limit(fds[i], CAP_FCNTL_GETFL) < 0 && errno != ENOSYS) + return (-1); + } + + return (0); +} + +#endif + +#ifdef __FreeBSD__ +static int +pincpu_parse(const char *opt) +{ + int vcpu, pcpu; + + if (sscanf(opt, "%d:%d", &vcpu, &pcpu) != 2) { + fprintf(stderr, "invalid format: %s\n", opt); + return (-1); + } + + if (vcpu < 0 || vcpu >= VM_MAXCPU) { + fprintf(stderr, "vcpu '%d' outside valid range from 0 to %d\n", + vcpu, VM_MAXCPU - 1); + return (-1); + } + + if (pcpu < 0 || pcpu >= CPU_SETSIZE) { + fprintf(stderr, "hostcpu '%d' outside valid range from " + "0 to %d\n", pcpu, CPU_SETSIZE - 1); + return (-1); + } + + if (vcpumap[vcpu] == NULL) { + if ((vcpumap[vcpu] = malloc(sizeof(cpuset_t))) == NULL) { + perror("malloc"); + return (-1); + } + CPU_ZERO(vcpumap[vcpu]); + } + CPU_SET(pcpu, vcpumap[vcpu]); + return (0); +} +#endif + +void +vm_inject_fault(void *arg, int vcpu, int vector, int errcode_valid, + int errcode) +{ + struct vmctx *ctx; + int error, restart_instruction; + + ctx = arg; + restart_instruction = 1; + + error = vm_inject_exception(ctx, vcpu, vector, errcode_valid, errcode, + restart_instruction); + assert(error == 0); +} + +void * +paddr_guest2host(struct vmctx *ctx, uintptr_t gaddr, size_t len) +{ + + return (vm_map_gpa(ctx, gaddr, len)); +} + +int +fbsdrun_vmexit_on_pause(void) +{ + + return (guest_vmexit_on_pause); +} + +int +fbsdrun_vmexit_on_hlt(void) +{ + + return (guest_vmexit_on_hlt); +} + +int +fbsdrun_virtio_msix(void) +{ + + return (virtio_msix); +} + +static void * +fbsdrun_start_thread(void *param) +{ + char tname[MAXCOMLEN + 1]; + struct mt_vmm_info *mtp; + int vcpu; + + mtp = param; + vcpu = mtp->mt_vcpu; + + snprintf(tname, sizeof(tname), "vcpu %d", vcpu); + pthread_set_name_np(mtp->mt_thr, tname); + + gdb_cpu_add(vcpu); + + vm_loop(mtp->mt_ctx, vcpu, vmexit[vcpu].rip); + + /* not reached */ + exit(1); + return (NULL); +} + +#ifdef __FreeBSD__ +void +fbsdrun_addcpu(struct vmctx *ctx, int fromcpu, int newcpu, uint64_t rip) +#else +void +fbsdrun_addcpu(struct vmctx *ctx, int fromcpu, int newcpu, uint64_t rip, + bool suspend) +#endif +{ + int error; + + assert(fromcpu == BSP); + + /* + * The 'newcpu' must be activated in the context of 'fromcpu'. If + * vm_activate_cpu() is delayed until newcpu's pthread starts running + * then vmm.ko is out-of-sync with bhyve and this can create a race + * with vm_suspend(). + */ + error = vm_activate_cpu(ctx, newcpu); + if (error != 0) + err(EX_OSERR, "could not activate CPU %d", newcpu); + + CPU_SET_ATOMIC(newcpu, &cpumask); + +#ifndef __FreeBSD__ + if (suspend) + (void) vm_suspend_cpu(ctx, newcpu); +#endif + + /* + * Set up the vmexit struct to allow execution to start + * at the given RIP + */ + vmexit[newcpu].rip = rip; + vmexit[newcpu].inst_length = 0; + + mt_vmm_info[newcpu].mt_ctx = ctx; + mt_vmm_info[newcpu].mt_vcpu = newcpu; + + error = pthread_create(&mt_vmm_info[newcpu].mt_thr, NULL, + fbsdrun_start_thread, &mt_vmm_info[newcpu]); + assert(error == 0); +} + +static int +fbsdrun_deletecpu(struct vmctx *ctx, int vcpu) +{ + + if (!CPU_ISSET(vcpu, &cpumask)) { + fprintf(stderr, "Attempting to delete unknown cpu %d\n", vcpu); + exit(4); + } + + CPU_CLR_ATOMIC(vcpu, &cpumask); + return (CPU_EMPTY(&cpumask)); +} + +static int +vmexit_handle_notify(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu, + uint32_t eax) +{ +#if BHYVE_DEBUG + /* + * put guest-driven debug here + */ +#endif + return (VMEXIT_CONTINUE); +} + +static int +vmexit_inout(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) +{ + int error; + int bytes, port, in, out; + int vcpu; + + vcpu = *pvcpu; + + port = vme->u.inout.port; + bytes = vme->u.inout.bytes; + in = vme->u.inout.in; + out = !in; + + /* Extra-special case of host notifications */ + if (out && port == GUEST_NIO_PORT) { + error = vmexit_handle_notify(ctx, vme, pvcpu, vme->u.inout.eax); + return (error); + } + + error = emulate_inout(ctx, vcpu, vme, strictio); + if (error) { + fprintf(stderr, "Unhandled %s%c 0x%04x at 0x%lx\n", + in ? "in" : "out", + bytes == 1 ? 'b' : (bytes == 2 ? 'w' : 'l'), + port, vmexit->rip); + return (VMEXIT_ABORT); + } else { + return (VMEXIT_CONTINUE); + } +} + +static int +vmexit_rdmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) +{ + uint64_t val; + uint32_t eax, edx; + int error; + + val = 0; + error = emulate_rdmsr(ctx, *pvcpu, vme->u.msr.code, &val); + if (error != 0) { + fprintf(stderr, "rdmsr to register %#x on vcpu %d\n", + vme->u.msr.code, *pvcpu); + if (strictmsr) { + vm_inject_gp(ctx, *pvcpu); + return (VMEXIT_CONTINUE); + } + } + + eax = val; + error = vm_set_register(ctx, *pvcpu, VM_REG_GUEST_RAX, eax); + assert(error == 0); + + edx = val >> 32; + error = vm_set_register(ctx, *pvcpu, VM_REG_GUEST_RDX, edx); + assert(error == 0); + + return (VMEXIT_CONTINUE); +} + +static int +vmexit_wrmsr(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) +{ + int error; + + error = emulate_wrmsr(ctx, *pvcpu, vme->u.msr.code, vme->u.msr.wval); + if (error != 0) { + fprintf(stderr, "wrmsr to register %#x(%#lx) on vcpu %d\n", + vme->u.msr.code, vme->u.msr.wval, *pvcpu); + if (strictmsr) { + vm_inject_gp(ctx, *pvcpu); + return (VMEXIT_CONTINUE); + } + } + return (VMEXIT_CONTINUE); +} + +static int +vmexit_spinup_ap(struct vmctx *ctx, struct vm_exit *vme, int *pvcpu) +{ + + (void)spinup_ap(ctx, *pvcpu, + vme->u.spinup_ap.vcpu, vme->u.spinup_ap.rip); + + return (VMEXIT_CONTINUE); +} + +#define DEBUG_EPT_MISCONFIG +#ifdef DEBUG_EPT_MISCONFIG +#define VMCS_GUEST_PHYSICAL_ADDRESS 0x00002400 + +static uint64_t ept_misconfig_gpa, ept_misconfig_pte[4]; +static int ept_misconfig_ptenum; +#endif + +static const char * +vmexit_vmx_desc(uint32_t exit_reason) +{ + + if (exit_reason >= nitems(vmx_exit_reason_desc) || + vmx_exit_reason_desc[exit_reason] == NULL) + return ("Unknown"); + return (vmx_exit_reason_desc[exit_reason]); +} + +static int +vmexit_vmx(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + + fprintf(stderr, "vm exit[%d]\n", *pvcpu); + fprintf(stderr, "\treason\t\tVMX\n"); + fprintf(stderr, "\trip\t\t0x%016lx\n", vmexit->rip); + fprintf(stderr, "\tinst_length\t%d\n", vmexit->inst_length); + fprintf(stderr, "\tstatus\t\t%d\n", vmexit->u.vmx.status); + fprintf(stderr, "\texit_reason\t%u (%s)\n", vmexit->u.vmx.exit_reason, + vmexit_vmx_desc(vmexit->u.vmx.exit_reason)); + fprintf(stderr, "\tqualification\t0x%016lx\n", + vmexit->u.vmx.exit_qualification); + fprintf(stderr, "\tinst_type\t\t%d\n", vmexit->u.vmx.inst_type); + fprintf(stderr, "\tinst_error\t\t%d\n", vmexit->u.vmx.inst_error); +#ifdef DEBUG_EPT_MISCONFIG + if (vmexit->u.vmx.exit_reason == EXIT_REASON_EPT_MISCONFIG) { + vm_get_register(ctx, *pvcpu, + VMCS_IDENT(VMCS_GUEST_PHYSICAL_ADDRESS), + &ept_misconfig_gpa); + vm_get_gpa_pmap(ctx, ept_misconfig_gpa, ept_misconfig_pte, + &ept_misconfig_ptenum); + fprintf(stderr, "\tEPT misconfiguration:\n"); + fprintf(stderr, "\t\tGPA: %#lx\n", ept_misconfig_gpa); + fprintf(stderr, "\t\tPTE(%d): %#lx %#lx %#lx %#lx\n", + ept_misconfig_ptenum, ept_misconfig_pte[0], + ept_misconfig_pte[1], ept_misconfig_pte[2], + ept_misconfig_pte[3]); + } +#endif /* DEBUG_EPT_MISCONFIG */ + return (VMEXIT_ABORT); +} + +static int +vmexit_svm(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + + fprintf(stderr, "vm exit[%d]\n", *pvcpu); + fprintf(stderr, "\treason\t\tSVM\n"); + fprintf(stderr, "\trip\t\t0x%016lx\n", vmexit->rip); + fprintf(stderr, "\tinst_length\t%d\n", vmexit->inst_length); + fprintf(stderr, "\texitcode\t%#lx\n", vmexit->u.svm.exitcode); + fprintf(stderr, "\texitinfo1\t%#lx\n", vmexit->u.svm.exitinfo1); + fprintf(stderr, "\texitinfo2\t%#lx\n", vmexit->u.svm.exitinfo2); + return (VMEXIT_ABORT); +} + +static int +vmexit_bogus(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + + assert(vmexit->inst_length == 0); + + stats.vmexit_bogus++; + + return (VMEXIT_CONTINUE); +} + +static int +vmexit_reqidle(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + + assert(vmexit->inst_length == 0); + + stats.vmexit_reqidle++; + + return (VMEXIT_CONTINUE); +} + +static int +vmexit_hlt(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + + stats.vmexit_hlt++; + + /* + * Just continue execution with the next instruction. We use + * the HLT VM exit as a way to be friendly with the host + * scheduler. + */ + return (VMEXIT_CONTINUE); +} + +static int +vmexit_pause(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + + stats.vmexit_pause++; + + return (VMEXIT_CONTINUE); +} + +static int +vmexit_mtrap(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + + assert(vmexit->inst_length == 0); + + stats.vmexit_mtrap++; + + gdb_cpu_mtrap(*pvcpu); + + return (VMEXIT_CONTINUE); +} + +static int +vmexit_inst_emul(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + int err, i; + struct vie *vie; + + stats.vmexit_inst_emul++; + + vie = &vmexit->u.inst_emul.vie; + err = emulate_mem(ctx, *pvcpu, vmexit->u.inst_emul.gpa, + vie, &vmexit->u.inst_emul.paging); + + if (err) { + if (err == ESRCH) { + fprintf(stderr, "Unhandled memory access to 0x%lx\n", + vmexit->u.inst_emul.gpa); + } + + fprintf(stderr, "Failed to emulate instruction ["); + for (i = 0; i < vie->num_valid; i++) { + fprintf(stderr, "0x%02x%s", vie->inst[i], + i != (vie->num_valid - 1) ? " " : ""); + } + fprintf(stderr, "] at 0x%lx\n", vmexit->rip); + return (VMEXIT_ABORT); + } + + return (VMEXIT_CONTINUE); +} + +static pthread_mutex_t resetcpu_mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t resetcpu_cond = PTHREAD_COND_INITIALIZER; + +static int +vmexit_suspend(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + enum vm_suspend_how how; + + how = vmexit->u.suspended.how; + + fbsdrun_deletecpu(ctx, *pvcpu); + + if (*pvcpu != BSP) { + pthread_mutex_lock(&resetcpu_mtx); + pthread_cond_signal(&resetcpu_cond); + pthread_mutex_unlock(&resetcpu_mtx); + pthread_exit(NULL); + } + + pthread_mutex_lock(&resetcpu_mtx); + while (!CPU_EMPTY(&cpumask)) { + pthread_cond_wait(&resetcpu_cond, &resetcpu_mtx); + } + pthread_mutex_unlock(&resetcpu_mtx); + + switch (how) { + case VM_SUSPEND_RESET: + exit(0); + case VM_SUSPEND_POWEROFF: + exit(1); + case VM_SUSPEND_HALT: + exit(2); + case VM_SUSPEND_TRIPLEFAULT: + exit(3); + default: + fprintf(stderr, "vmexit_suspend: invalid reason %d\n", how); + exit(100); + } + return (0); /* NOTREACHED */ +} + +static int +vmexit_debug(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + + gdb_cpu_suspend(*pvcpu); + return (VMEXIT_CONTINUE); +} + +static vmexit_handler_t handler[VM_EXITCODE_MAX] = { + [VM_EXITCODE_INOUT] = vmexit_inout, + [VM_EXITCODE_INOUT_STR] = vmexit_inout, + [VM_EXITCODE_VMX] = vmexit_vmx, + [VM_EXITCODE_SVM] = vmexit_svm, + [VM_EXITCODE_BOGUS] = vmexit_bogus, + [VM_EXITCODE_REQIDLE] = vmexit_reqidle, + [VM_EXITCODE_RDMSR] = vmexit_rdmsr, + [VM_EXITCODE_WRMSR] = vmexit_wrmsr, + [VM_EXITCODE_MTRAP] = vmexit_mtrap, + [VM_EXITCODE_INST_EMUL] = vmexit_inst_emul, + [VM_EXITCODE_SPINUP_AP] = vmexit_spinup_ap, + [VM_EXITCODE_SUSPENDED] = vmexit_suspend, + [VM_EXITCODE_TASK_SWITCH] = vmexit_task_switch, + [VM_EXITCODE_DEBUG] = vmexit_debug, +}; + +static void +vm_loop(struct vmctx *ctx, int vcpu, uint64_t startrip) +{ + int error, rc; + enum vm_exitcode exitcode; + cpuset_t active_cpus; + +#ifdef __FreeBSD__ + if (vcpumap[vcpu] != NULL) { + error = pthread_setaffinity_np(pthread_self(), + sizeof(cpuset_t), vcpumap[vcpu]); + assert(error == 0); + } +#endif + error = vm_active_cpus(ctx, &active_cpus); + assert(CPU_ISSET(vcpu, &active_cpus)); + + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, startrip); + assert(error == 0); + + while (1) { + error = vm_run(ctx, vcpu, &vmexit[vcpu]); + if (error != 0) + break; + + exitcode = vmexit[vcpu].exitcode; + if (exitcode >= VM_EXITCODE_MAX || handler[exitcode] == NULL) { + fprintf(stderr, "vm_loop: unexpected exitcode 0x%x\n", + exitcode); + exit(4); + } + + rc = (*handler[exitcode])(ctx, &vmexit[vcpu], &vcpu); + + switch (rc) { + case VMEXIT_CONTINUE: + break; + case VMEXIT_ABORT: + abort(); + default: + exit(4); + } + } + fprintf(stderr, "vm_run error %d, errno %d\n", error, errno); +} + +static int +num_vcpus_allowed(struct vmctx *ctx) +{ + int tmp, error; + + error = vm_get_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, &tmp); + + /* + * The guest is allowed to spinup more than one processor only if the + * UNRESTRICTED_GUEST capability is available. + */ + if (error == 0) + return (VM_MAXCPU); + else + return (1); +} + +void +fbsdrun_set_capabilities(struct vmctx *ctx, int cpu) +{ + int err, tmp; + + if (fbsdrun_vmexit_on_hlt()) { + err = vm_get_capability(ctx, cpu, VM_CAP_HALT_EXIT, &tmp); + if (err < 0) { + fprintf(stderr, "VM exit on HLT not supported\n"); + exit(4); + } + vm_set_capability(ctx, cpu, VM_CAP_HALT_EXIT, 1); + if (cpu == BSP) + handler[VM_EXITCODE_HLT] = vmexit_hlt; + } + + if (fbsdrun_vmexit_on_pause()) { + /* + * pause exit support required for this mode + */ + err = vm_get_capability(ctx, cpu, VM_CAP_PAUSE_EXIT, &tmp); + if (err < 0) { + fprintf(stderr, + "SMP mux requested, no pause support\n"); + exit(4); + } + vm_set_capability(ctx, cpu, VM_CAP_PAUSE_EXIT, 1); + if (cpu == BSP) + handler[VM_EXITCODE_PAUSE] = vmexit_pause; + } + + if (x2apic_mode) + err = vm_set_x2apic_state(ctx, cpu, X2APIC_ENABLED); + else + err = vm_set_x2apic_state(ctx, cpu, X2APIC_DISABLED); + + if (err) { + fprintf(stderr, "Unable to set x2apic state (%d)\n", err); + exit(4); + } + +#ifdef __FreeBSD__ + vm_set_capability(ctx, cpu, VM_CAP_ENABLE_INVPCID, 1); +#endif +} + +static struct vmctx * +do_open(const char *vmname) +{ + struct vmctx *ctx; + int error; + bool reinit, romboot; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; + const cap_ioctl_t *cmds; + size_t ncmds; +#endif + + reinit = romboot = false; + + if (lpc_bootrom()) + romboot = true; + + error = vm_create(vmname); + if (error) { + if (errno == EEXIST) { + if (romboot) { + reinit = true; + } else { + /* + * The virtual machine has been setup by the + * userspace bootloader. + */ + } + } else { + perror("vm_create"); + exit(4); + } + } else { + if (!romboot) { + /* + * If the virtual machine was just created then a + * bootrom must be configured to boot it. + */ + fprintf(stderr, "virtual machine cannot be booted\n"); + exit(4); + } + } + + ctx = vm_open(vmname); + if (ctx == NULL) { + perror("vm_open"); + exit(4); + } + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_IOCTL, CAP_MMAP_RW); + if (caph_rights_limit(vm_get_device_fd(ctx), &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + vm_get_ioctls(&ncmds); + cmds = vm_get_ioctls(NULL); + if (cmds == NULL) + errx(EX_OSERR, "out of memory"); + if (caph_ioctls_limit(vm_get_device_fd(ctx), cmds, ncmds) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + free((cap_ioctl_t *)cmds); +#endif + + if (reinit) { + error = vm_reinit(ctx); + if (error) { + perror("vm_reinit"); + exit(4); + } + } + error = vm_set_topology(ctx, sockets, cores, threads, maxcpus); + if (error) + errx(EX_OSERR, "vm_set_topology"); + return (ctx); +} + +#ifndef __FreeBSD__ + +#define FILE_PROVISIONING "/var/svc/provisioning" +#define FILE_PROVISION_SUCCESS "/var/svc/provision_success" + +static void +mark_provisioned(void) +{ + struct stat stbuf; + + if (lstat(FILE_PROVISIONING, &stbuf) != 0) + return; + + if (rename(FILE_PROVISIONING, FILE_PROVISION_SUCCESS) != 0) { + (void) fprintf(stderr, "Cannot rename %s to %s: %s\n", + FILE_PROVISIONING, FILE_PROVISION_SUCCESS, + strerror(errno)); + } +} + +#endif + +int +main(int argc, char *argv[]) +{ + int c, error, dbg_port, gdb_port, err, bvmcons; + int max_vcpus, mptgen, memflags; + int rtc_localtime; + bool gdb_stop; +#ifndef __FreeBSD__ + bool suspend = false; +#endif + struct vmctx *ctx; + uint64_t rip; + size_t memsize; + char *optstr; + + bvmcons = 0; + progname = basename(argv[0]); + dbg_port = 0; + gdb_port = 0; + gdb_stop = false; + guest_ncpus = 1; + sockets = cores = threads = 1; + maxcpus = 0; + memsize = 256 * MB; + mptgen = 1; + rtc_localtime = 1; + memflags = 0; + +#ifdef __FreeBSD__ + optstr = "abehuwxACHIPSWYp:g:G:c:s:m:l:B:U:"; +#else + optstr = "abdehuwxACHIPSWYg:G:c:s:m:l:B:U:"; +#endif + while ((c = getopt(argc, argv, optstr)) != -1) { + switch (c) { + case 'a': + x2apic_mode = 0; + break; + case 'A': + acpi = 1; + break; + case 'b': + bvmcons = 1; + break; + case 'B': + if (smbios_parse(optarg) != 0) { + errx(EX_USAGE, "invalid SMBIOS " + "configuration '%s'", optarg); + } + break; +#ifndef __FreeBSD__ + case 'd': + suspend = true; + break; +#else + case 'p': + if (pincpu_parse(optarg) != 0) { + errx(EX_USAGE, "invalid vcpu pinning " + "configuration '%s'", optarg); + } + break; +#endif + case 'c': + if (topology_parse(optarg) != 0) { + errx(EX_USAGE, "invalid cpu topology " + "'%s'", optarg); + } + break; + case 'C': + memflags |= VM_MEM_F_INCORE; + break; + case 'g': + dbg_port = atoi(optarg); + break; + case 'G': + if (optarg[0] == 'w') { + gdb_stop = true; + optarg++; + } + gdb_port = atoi(optarg); + break; + case 'l': + if (strncmp(optarg, "help", strlen(optarg)) == 0) { + lpc_print_supported_devices(); + exit(0); + } else if (lpc_device_parse(optarg) != 0) { + errx(EX_USAGE, "invalid lpc device " + "configuration '%s'", optarg); + } + break; + case 's': + if (strncmp(optarg, "help", strlen(optarg)) == 0) { + pci_print_supported_devices(); + exit(0); + } else if (pci_parse_slot(optarg) != 0) + exit(4); + else + break; + case 'S': + memflags |= VM_MEM_F_WIRED; + break; + case 'm': + error = vm_parse_memsize(optarg, &memsize); + if (error) + errx(EX_USAGE, "invalid memsize '%s'", optarg); + break; + case 'H': + guest_vmexit_on_hlt = 1; + break; + case 'I': + /* + * The "-I" option was used to add an ioapic to the + * virtual machine. + * + * An ioapic is now provided unconditionally for each + * virtual machine and this option is now deprecated. + */ + break; + case 'P': + guest_vmexit_on_pause = 1; + break; + case 'e': + strictio = 1; + break; + case 'u': + rtc_localtime = 0; + break; + case 'U': + guest_uuid_str = optarg; + break; + case 'w': + strictmsr = 0; + break; + case 'W': + virtio_msix = 0; + break; + case 'x': + x2apic_mode = 1; + break; + case 'Y': + mptgen = 0; + break; + case 'h': + usage(0); + default: + usage(1); + } + } + argc -= optind; + argv += optind; + + if (argc != 1) + usage(1); + + vmname = argv[0]; + ctx = do_open(vmname); + + max_vcpus = num_vcpus_allowed(ctx); + if (guest_ncpus > max_vcpus) { + fprintf(stderr, "%d vCPUs requested but only %d available\n", + guest_ncpus, max_vcpus); + exit(4); + } + + fbsdrun_set_capabilities(ctx, BSP); + + vm_set_memflags(ctx, memflags); +#ifdef __FreeBSD__ + err = vm_setup_memory(ctx, memsize, VM_MMAP_ALL); +#else + do { + errno = 0; + err = vm_setup_memory(ctx, memsize, VM_MMAP_ALL); + error = errno; + if (err != 0 && error == ENOMEM) { + (void) fprintf(stderr, "Unable to allocate memory " + "(%llu), retrying in 1 second\n", memsize); + sleep(1); + } + } while (error == ENOMEM); +#endif + if (err) { + fprintf(stderr, "Unable to setup memory (%d)\n", errno); + exit(4); + } + + error = init_msr(); + if (error) { + fprintf(stderr, "init_msr error %d", error); + exit(4); + } + + init_mem(); + init_inout(); + atkbdc_init(ctx); + pci_irq_init(ctx); + ioapic_init(ctx); + + rtc_init(ctx, rtc_localtime); + sci_init(ctx); + + /* + * Exit if a device emulation finds an error in its initilization + */ + if (init_pci(ctx) != 0) { + perror("device emulation initialization error"); + exit(4); + } + + if (dbg_port != 0) + init_dbgport(dbg_port); + + if (gdb_port != 0) + init_gdb(ctx, gdb_port, gdb_stop); + + if (bvmcons) + init_bvmcons(); + + vga_init(1); + + if (lpc_bootrom()) { + if (vm_set_capability(ctx, BSP, VM_CAP_UNRESTRICTED_GUEST, 1)) { + fprintf(stderr, "ROM boot failed: unrestricted guest " + "capability not available\n"); + exit(4); + } + error = vcpu_reset(ctx, BSP); + assert(error == 0); + } + + error = vm_get_register(ctx, BSP, VM_REG_GUEST_RIP, &rip); + assert(error == 0); + + /* + * build the guest tables, MP etc. + */ + if (mptgen) { + error = mptable_build(ctx, guest_ncpus); + if (error) { + perror("error to build the guest tables"); + exit(4); + } + } + + error = smbios_build(ctx); + assert(error == 0); + + if (acpi) { + error = acpi_build(ctx, guest_ncpus); + assert(error == 0); + } + + if (lpc_bootrom()) + fwctl_init(); + + /* + * Change the proc title to include the VM name. + */ + setproctitle("%s", vmname); + +#ifndef WITHOUT_CAPSICUM + caph_cache_catpages(); + + if (caph_limit_stdout() == -1 || caph_limit_stderr() == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + + if (caph_enter() == -1) + errx(EX_OSERR, "cap_enter() failed"); +#endif + +#ifndef __FreeBSD__ + /* + * If applicable, wait for bhyveconsole + */ + if (bcons_wait) { + printf("Waiting for bhyveconsole connection...\n"); + (void) pthread_mutex_lock(&bcons_wait_lock); + while (!bcons_connected) { + (void) pthread_cond_wait(&bcons_wait_done, + &bcons_wait_lock); + } + (void) pthread_mutex_unlock(&bcons_wait_lock); + } +#endif + + /* + * Add CPU 0 + */ +#ifdef __FreeBSD__ + fbsdrun_addcpu(ctx, BSP, BSP, rip); +#else + fbsdrun_addcpu(ctx, BSP, BSP, rip, suspend); + + mark_provisioned(); +#endif + + /* + * Head off to the main event dispatch loop + */ + mevent_dispatch(); + + exit(4); +} diff --git a/usr/src/cmd/bhyve/bhyverun.h b/usr/src/cmd/bhyve/bhyverun.h new file mode 100644 index 0000000000..cdde04862c --- /dev/null +++ b/usr/src/cmd/bhyve/bhyverun.h @@ -0,0 +1,74 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2015 Pluribus Networks Inc. + */ + +#ifndef _FBSDRUN_H_ +#define _FBSDRUN_H_ + +#define VMEXIT_CONTINUE (0) +#define VMEXIT_ABORT (-1) + +struct vmctx; +extern int guest_ncpus; +extern char *guest_uuid_str; +extern char *vmname; +#ifndef __FreeBSD__ +extern int bcons_wait; +extern int bcons_connected; +extern pthread_mutex_t bcons_wait_lock; +extern pthread_cond_t bcons_wait_done; +#endif + +void *paddr_guest2host(struct vmctx *ctx, uintptr_t addr, size_t len); + +void fbsdrun_set_capabilities(struct vmctx *ctx, int cpu); +#ifdef __FreeBSD__ +void fbsdrun_addcpu(struct vmctx *ctx, int fromcpu, int newcpu, uint64_t rip); +#else +void fbsdrun_addcpu(struct vmctx *ctx, int fromcpu, int newcpu, uint64_t rip, + bool suspend); +#endif +int fbsdrun_muxed(void); +int fbsdrun_vmexit_on_hlt(void); +int fbsdrun_vmexit_on_pause(void); +int fbsdrun_disable_x2apic(void); +int fbsdrun_virtio_msix(void); +#endif diff --git a/usr/src/cmd/bhyve/block_if.c b/usr/src/cmd/bhyve/block_if.c new file mode 100644 index 0000000000..fcb4149b62 --- /dev/null +++ b/usr/src/cmd/bhyve/block_if.c @@ -0,0 +1,1028 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Peter Grehan <grehan@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/queue.h> +#include <sys/errno.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/disk.h> +#include <sys/limits.h> +#include <sys/uio.h> +#ifndef __FreeBSD__ +#include <sys/dkio.h> +#endif + +#include <assert.h> +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pthread.h> +#include <pthread_np.h> +#include <signal.h> +#include <sysexits.h> +#include <unistd.h> + +#include <machine/atomic.h> + +#include "bhyverun.h" +#ifdef __FreeBSD__ +#include "mevent.h" +#endif +#include "block_if.h" + +#define BLOCKIF_SIG 0xb109b109 + +#ifdef __FreeBSD__ +#define BLOCKIF_NUMTHR 8 +#define BLOCKIF_MAXREQ (64 + BLOCKIF_NUMTHR) +#else +/* Enlarge to keep pace with the virtio-block ring size */ +#define BLOCKIF_NUMTHR 16 +#define BLOCKIF_MAXREQ (128 + BLOCKIF_NUMTHR) +#endif + +enum blockop { + BOP_READ, + BOP_WRITE, +#ifndef __FreeBSD__ + BOP_WRITE_SYNC, +#endif + BOP_FLUSH, + BOP_DELETE +}; + +enum blockstat { + BST_FREE, + BST_BLOCK, + BST_PEND, + BST_BUSY, + BST_DONE +}; + +struct blockif_elem { + TAILQ_ENTRY(blockif_elem) be_link; + struct blockif_req *be_req; + enum blockop be_op; + enum blockstat be_status; + pthread_t be_tid; + off_t be_block; +}; + +#ifndef __FreeBSD__ +enum blockif_wce { + WCE_NONE = 0, + WCE_IOCTL, + WCE_FCNTL +}; +#endif + +struct blockif_ctxt { + int bc_magic; + int bc_fd; + int bc_ischr; + int bc_isgeom; + int bc_candelete; +#ifndef __FreeBSD__ + enum blockif_wce bc_wce; +#endif + int bc_rdonly; + off_t bc_size; + int bc_sectsz; + int bc_psectsz; + int bc_psectoff; + int bc_closing; + pthread_t bc_btid[BLOCKIF_NUMTHR]; + pthread_mutex_t bc_mtx; + pthread_cond_t bc_cond; + + /* Request elements and free/pending/busy queues */ + TAILQ_HEAD(, blockif_elem) bc_freeq; + TAILQ_HEAD(, blockif_elem) bc_pendq; + TAILQ_HEAD(, blockif_elem) bc_busyq; + struct blockif_elem bc_reqs[BLOCKIF_MAXREQ]; +}; + +static pthread_once_t blockif_once = PTHREAD_ONCE_INIT; + +struct blockif_sig_elem { + pthread_mutex_t bse_mtx; + pthread_cond_t bse_cond; + int bse_pending; + struct blockif_sig_elem *bse_next; +}; + +static struct blockif_sig_elem *blockif_bse_head; + +static int +blockif_enqueue(struct blockif_ctxt *bc, struct blockif_req *breq, + enum blockop op) +{ + struct blockif_elem *be, *tbe; + off_t off; + int i; + + be = TAILQ_FIRST(&bc->bc_freeq); + assert(be != NULL); + assert(be->be_status == BST_FREE); + TAILQ_REMOVE(&bc->bc_freeq, be, be_link); + be->be_req = breq; + be->be_op = op; + switch (op) { + case BOP_READ: + case BOP_WRITE: +#ifndef __FreeBSD__ + case BOP_WRITE_SYNC: +#endif + case BOP_DELETE: + off = breq->br_offset; + for (i = 0; i < breq->br_iovcnt; i++) + off += breq->br_iov[i].iov_len; + break; + default: + off = OFF_MAX; + } + be->be_block = off; + TAILQ_FOREACH(tbe, &bc->bc_pendq, be_link) { + if (tbe->be_block == breq->br_offset) + break; + } + if (tbe == NULL) { + TAILQ_FOREACH(tbe, &bc->bc_busyq, be_link) { + if (tbe->be_block == breq->br_offset) + break; + } + } + if (tbe == NULL) + be->be_status = BST_PEND; + else + be->be_status = BST_BLOCK; + TAILQ_INSERT_TAIL(&bc->bc_pendq, be, be_link); + return (be->be_status == BST_PEND); +} + +static int +blockif_dequeue(struct blockif_ctxt *bc, pthread_t t, struct blockif_elem **bep) +{ + struct blockif_elem *be; + + TAILQ_FOREACH(be, &bc->bc_pendq, be_link) { + if (be->be_status == BST_PEND) + break; + assert(be->be_status == BST_BLOCK); + } + if (be == NULL) + return (0); + TAILQ_REMOVE(&bc->bc_pendq, be, be_link); + be->be_status = BST_BUSY; + be->be_tid = t; + TAILQ_INSERT_TAIL(&bc->bc_busyq, be, be_link); + *bep = be; + return (1); +} + +static void +blockif_complete(struct blockif_ctxt *bc, struct blockif_elem *be) +{ + struct blockif_elem *tbe; + + if (be->be_status == BST_DONE || be->be_status == BST_BUSY) + TAILQ_REMOVE(&bc->bc_busyq, be, be_link); + else + TAILQ_REMOVE(&bc->bc_pendq, be, be_link); + TAILQ_FOREACH(tbe, &bc->bc_pendq, be_link) { + if (tbe->be_req->br_offset == be->be_block) + tbe->be_status = BST_PEND; + } + be->be_tid = 0; + be->be_status = BST_FREE; + be->be_req = NULL; + TAILQ_INSERT_TAIL(&bc->bc_freeq, be, be_link); +} + +static void +blockif_proc(struct blockif_ctxt *bc, struct blockif_elem *be, uint8_t *buf) +{ + struct blockif_req *br; +#ifdef __FreeBSD__ + off_t arg[2]; +#endif + ssize_t clen, len, off, boff, voff; + int i, err; + + br = be->be_req; + if (br->br_iovcnt <= 1) + buf = NULL; + err = 0; + switch (be->be_op) { + case BOP_READ: + if (buf == NULL) { + if ((len = preadv(bc->bc_fd, br->br_iov, br->br_iovcnt, + br->br_offset)) < 0) + err = errno; + else + br->br_resid -= len; + break; + } + i = 0; + off = voff = 0; + while (br->br_resid > 0) { + len = MIN(br->br_resid, MAXPHYS); + if (pread(bc->bc_fd, buf, len, br->br_offset + + off) < 0) { + err = errno; + break; + } + boff = 0; + do { + clen = MIN(len - boff, br->br_iov[i].iov_len - + voff); + memcpy(br->br_iov[i].iov_base + voff, + buf + boff, clen); + if (clen < br->br_iov[i].iov_len - voff) + voff += clen; + else { + i++; + voff = 0; + } + boff += clen; + } while (boff < len); + off += len; + br->br_resid -= len; + } + break; + case BOP_WRITE: + if (bc->bc_rdonly) { + err = EROFS; + break; + } + if (buf == NULL) { + if ((len = pwritev(bc->bc_fd, br->br_iov, br->br_iovcnt, + br->br_offset)) < 0) + err = errno; + else + br->br_resid -= len; + break; + } + i = 0; + off = voff = 0; + while (br->br_resid > 0) { + len = MIN(br->br_resid, MAXPHYS); + boff = 0; + do { + clen = MIN(len - boff, br->br_iov[i].iov_len - + voff); + memcpy(buf + boff, + br->br_iov[i].iov_base + voff, clen); + if (clen < br->br_iov[i].iov_len - voff) + voff += clen; + else { + i++; + voff = 0; + } + boff += clen; + } while (boff < len); + if (pwrite(bc->bc_fd, buf, len, br->br_offset + + off) < 0) { + err = errno; + break; + } + off += len; + br->br_resid -= len; + } + break; + case BOP_FLUSH: +#ifdef __FreeBSD__ + if (bc->bc_ischr) { + if (ioctl(bc->bc_fd, DIOCGFLUSH)) + err = errno; + } else if (fsync(bc->bc_fd)) + err = errno; +#else + /* + * This fsync() should be adequate to flush the cache of a file + * or device. In VFS, the VOP_SYNC operation is converted to + * the appropriate ioctl in both sdev (for real devices) and + * zfs (for zvols). + */ + if (fsync(bc->bc_fd)) + err = errno; +#endif + break; + case BOP_DELETE: + if (!bc->bc_candelete) + err = EOPNOTSUPP; + else if (bc->bc_rdonly) + err = EROFS; +#ifdef __FreeBSD__ + else if (bc->bc_ischr) { + arg[0] = br->br_offset; + arg[1] = br->br_resid; + if (ioctl(bc->bc_fd, DIOCGDELETE, arg)) + err = errno; + else + br->br_resid = 0; + } +#endif + else + err = EOPNOTSUPP; + break; + default: + err = EINVAL; + break; + } + + be->be_status = BST_DONE; + + (*br->br_callback)(br, err); +} + +static void * +blockif_thr(void *arg) +{ + struct blockif_ctxt *bc; + struct blockif_elem *be; + pthread_t t; + uint8_t *buf; + + bc = arg; + if (bc->bc_isgeom) + buf = malloc(MAXPHYS); + else + buf = NULL; + t = pthread_self(); + + pthread_mutex_lock(&bc->bc_mtx); + for (;;) { + while (blockif_dequeue(bc, t, &be)) { + pthread_mutex_unlock(&bc->bc_mtx); + blockif_proc(bc, be, buf); + pthread_mutex_lock(&bc->bc_mtx); + blockif_complete(bc, be); + } + /* Check ctxt status here to see if exit requested */ + if (bc->bc_closing) + break; + pthread_cond_wait(&bc->bc_cond, &bc->bc_mtx); + } + pthread_mutex_unlock(&bc->bc_mtx); + + if (buf) + free(buf); + pthread_exit(NULL); + return (NULL); +} + +#ifdef __FreeBSD__ +static void +blockif_sigcont_handler(int signal, enum ev_type type, void *arg) +#else +static void +blockif_sigcont_handler(int signal) +#endif +{ + struct blockif_sig_elem *bse; + + for (;;) { + /* + * Process the entire list even if not intended for + * this thread. + */ + do { + bse = blockif_bse_head; + if (bse == NULL) + return; + } while (!atomic_cmpset_ptr((uintptr_t *)&blockif_bse_head, + (uintptr_t)bse, + (uintptr_t)bse->bse_next)); + + pthread_mutex_lock(&bse->bse_mtx); + bse->bse_pending = 0; + pthread_cond_signal(&bse->bse_cond); + pthread_mutex_unlock(&bse->bse_mtx); + } +} + +static void +blockif_init(void) +{ +#ifdef __FreeBSD__ + mevent_add(SIGCONT, EVF_SIGNAL, blockif_sigcont_handler, NULL); + (void) signal(SIGCONT, SIG_IGN); +#else + (void) sigset(SIGCONT, blockif_sigcont_handler); +#endif +} + +struct blockif_ctxt * +blockif_open(const char *optstr, const char *ident) +{ + char tname[MAXCOMLEN + 1]; +#ifdef __FreeBSD__ + char name[MAXPATHLEN]; + char *nopt, *xopts, *cp; +#else + char *nopt, *xopts, *cp = NULL; +#endif + struct blockif_ctxt *bc; + struct stat sbuf; +#ifdef __FreeBSD__ + struct diocgattr_arg arg; +#else + enum blockif_wce wce = WCE_NONE; +#endif + off_t size, psectsz, psectoff; + int extra, fd, i, sectsz; + int nocache, sync, ro, candelete, geom, ssopt, pssopt; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; + cap_ioctl_t cmds[] = { DIOCGFLUSH, DIOCGDELETE }; +#endif + + pthread_once(&blockif_once, blockif_init); + + fd = -1; + ssopt = 0; + nocache = 0; + sync = 0; + ro = 0; + + /* + * The first element in the optstring is always a pathname. + * Optional elements follow + */ + nopt = xopts = strdup(optstr); + while (xopts != NULL) { + cp = strsep(&xopts, ","); + if (cp == nopt) /* file or device pathname */ + continue; + else if (!strcmp(cp, "nocache")) + nocache = 1; + else if (!strcmp(cp, "sync") || !strcmp(cp, "direct")) + sync = 1; + else if (!strcmp(cp, "ro")) + ro = 1; + else if (sscanf(cp, "sectorsize=%d/%d", &ssopt, &pssopt) == 2) + ; + else if (sscanf(cp, "sectorsize=%d", &ssopt) == 1) + pssopt = ssopt; + else { + fprintf(stderr, "Invalid device option \"%s\"\n", cp); + goto err; + } + } + + extra = 0; + if (nocache) + extra |= O_DIRECT; + if (sync) + extra |= O_SYNC; + + fd = open(nopt, (ro ? O_RDONLY : O_RDWR) | extra); + if (fd < 0 && !ro) { + /* Attempt a r/w fail with a r/o open */ + fd = open(nopt, O_RDONLY | extra); + ro = 1; + } + + if (fd < 0) { + warn("Could not open backing file: %s", nopt); + goto err; + } + + if (fstat(fd, &sbuf) < 0) { + warn("Could not stat backing file %s", nopt); + goto err; + } + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_FSYNC, CAP_IOCTL, CAP_READ, CAP_SEEK, + CAP_WRITE); + if (ro) + cap_rights_clear(&rights, CAP_FSYNC, CAP_WRITE); + + if (caph_rights_limit(fd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + /* + * Deal with raw devices + */ + size = sbuf.st_size; + sectsz = DEV_BSIZE; + psectsz = psectoff = 0; + candelete = geom = 0; +#ifdef __FreeBSD__ + if (S_ISCHR(sbuf.st_mode)) { + if (ioctl(fd, DIOCGMEDIASIZE, &size) < 0 || + ioctl(fd, DIOCGSECTORSIZE, §sz)) { + perror("Could not fetch dev blk/sector size"); + goto err; + } + assert(size != 0); + assert(sectsz != 0); + if (ioctl(fd, DIOCGSTRIPESIZE, &psectsz) == 0 && psectsz > 0) + ioctl(fd, DIOCGSTRIPEOFFSET, &psectoff); + strlcpy(arg.name, "GEOM::candelete", sizeof(arg.name)); + arg.len = sizeof(arg.value.i); + if (ioctl(fd, DIOCGATTR, &arg) == 0) + candelete = arg.value.i; + if (ioctl(fd, DIOCGPROVIDERNAME, name) == 0) + geom = 1; + } else { + psectsz = sbuf.st_blksize; + } +#else + psectsz = sbuf.st_blksize; + if (S_ISCHR(sbuf.st_mode)) { + struct dk_minfo_ext dkmext; + int wce_val; + + /* Look for a more accurate physical blocksize */ + if (ioctl(fd, DKIOCGMEDIAINFOEXT, &dkmext) == 0) { + psectsz = dkmext.dki_pbsize; + } + /* See if a configurable write cache is present and working */ + if (ioctl(fd, DKIOCGETWCE, &wce_val) == 0) { + /* + * If WCE is already active, disable it until the + * specific device driver calls for its return. If it + * is not active, toggle it on and off to verify that + * such actions are possible. + */ + if (wce_val != 0) { + wce_val = 0; + /* + * Inability to disable the cache is a threat + * to data durability. + */ + assert(ioctl(fd, DKIOCSETWCE, &wce_val) == 0); + wce = WCE_IOCTL; + } else { + int r1, r2; + + wce_val = 1; + r1 = ioctl(fd, DKIOCSETWCE, &wce_val); + wce_val = 0; + r2 = ioctl(fd, DKIOCSETWCE, &wce_val); + + if (r1 == 0 && r2 == 0) { + wce = WCE_IOCTL; + } else { + /* + * If the cache cache toggle was not + * successful, ensure that the cache + * was not left enabled. + */ + assert(r1 != 0); + } + } + } + } else { + int flags; + + if ((flags = fcntl(fd, F_GETFL)) >= 0) { + flags |= O_DSYNC; + if (fcntl(fd, F_SETFL, flags) != -1) { + wce = WCE_FCNTL; + } + } + } +#endif + +#ifndef WITHOUT_CAPSICUM + if (caph_ioctls_limit(fd, cmds, nitems(cmds)) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + if (ssopt != 0) { + if (!powerof2(ssopt) || !powerof2(pssopt) || ssopt < 512 || + ssopt > pssopt) { + fprintf(stderr, "Invalid sector size %d/%d\n", + ssopt, pssopt); + goto err; + } + + /* + * Some backend drivers (e.g. cd0, ada0) require that the I/O + * size be a multiple of the device's sector size. + * + * Validate that the emulated sector size complies with this + * requirement. + */ + if (S_ISCHR(sbuf.st_mode)) { + if (ssopt < sectsz || (ssopt % sectsz) != 0) { + fprintf(stderr, "Sector size %d incompatible " + "with underlying device sector size %d\n", + ssopt, sectsz); + goto err; + } + } + + sectsz = ssopt; + psectsz = pssopt; + psectoff = 0; + } + + bc = calloc(1, sizeof(struct blockif_ctxt)); + if (bc == NULL) { + perror("calloc"); + goto err; + } + + bc->bc_magic = BLOCKIF_SIG; + bc->bc_fd = fd; + bc->bc_ischr = S_ISCHR(sbuf.st_mode); + bc->bc_isgeom = geom; + bc->bc_candelete = candelete; +#ifndef __FreeBSD__ + bc->bc_wce = wce; +#endif + bc->bc_rdonly = ro; + bc->bc_size = size; + bc->bc_sectsz = sectsz; + bc->bc_psectsz = psectsz; + bc->bc_psectoff = psectoff; + pthread_mutex_init(&bc->bc_mtx, NULL); + pthread_cond_init(&bc->bc_cond, NULL); + TAILQ_INIT(&bc->bc_freeq); + TAILQ_INIT(&bc->bc_pendq); + TAILQ_INIT(&bc->bc_busyq); + for (i = 0; i < BLOCKIF_MAXREQ; i++) { + bc->bc_reqs[i].be_status = BST_FREE; + TAILQ_INSERT_HEAD(&bc->bc_freeq, &bc->bc_reqs[i], be_link); + } + + for (i = 0; i < BLOCKIF_NUMTHR; i++) { + pthread_create(&bc->bc_btid[i], NULL, blockif_thr, bc); + snprintf(tname, sizeof(tname), "blk-%s-%d", ident, i); + pthread_set_name_np(bc->bc_btid[i], tname); + } + + return (bc); +err: + if (fd >= 0) + close(fd); +#ifdef __FreeBSD__ + free(cp); + free(xopts); + free(nopt); +#else + free(nopt); +#endif + return (NULL); +} + +static int +blockif_request(struct blockif_ctxt *bc, struct blockif_req *breq, + enum blockop op) +{ + int err; + + err = 0; + + pthread_mutex_lock(&bc->bc_mtx); + if (!TAILQ_EMPTY(&bc->bc_freeq)) { + /* + * Enqueue and inform the block i/o thread + * that there is work available + */ + if (blockif_enqueue(bc, breq, op)) + pthread_cond_signal(&bc->bc_cond); + } else { + /* + * Callers are not allowed to enqueue more than + * the specified blockif queue limit. Return an + * error to indicate that the queue length has been + * exceeded. + */ + err = E2BIG; + } + pthread_mutex_unlock(&bc->bc_mtx); + + return (err); +} + +int +blockif_read(struct blockif_ctxt *bc, struct blockif_req *breq) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (blockif_request(bc, breq, BOP_READ)); +} + +int +blockif_write(struct blockif_ctxt *bc, struct blockif_req *breq) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (blockif_request(bc, breq, BOP_WRITE)); +} + +int +blockif_flush(struct blockif_ctxt *bc, struct blockif_req *breq) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (blockif_request(bc, breq, BOP_FLUSH)); +} + +int +blockif_delete(struct blockif_ctxt *bc, struct blockif_req *breq) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (blockif_request(bc, breq, BOP_DELETE)); +} + +int +blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq) +{ + struct blockif_elem *be; + + assert(bc->bc_magic == BLOCKIF_SIG); + + pthread_mutex_lock(&bc->bc_mtx); + /* + * Check pending requests. + */ + TAILQ_FOREACH(be, &bc->bc_pendq, be_link) { + if (be->be_req == breq) + break; + } + if (be != NULL) { + /* + * Found it. + */ + blockif_complete(bc, be); + pthread_mutex_unlock(&bc->bc_mtx); + + return (0); + } + + /* + * Check in-flight requests. + */ + TAILQ_FOREACH(be, &bc->bc_busyq, be_link) { + if (be->be_req == breq) + break; + } + if (be == NULL) { + /* + * Didn't find it. + */ + pthread_mutex_unlock(&bc->bc_mtx); + return (EINVAL); + } + + /* + * Interrupt the processing thread to force it return + * prematurely via it's normal callback path. + */ + while (be->be_status == BST_BUSY) { + struct blockif_sig_elem bse, *old_head; + + pthread_mutex_init(&bse.bse_mtx, NULL); + pthread_cond_init(&bse.bse_cond, NULL); + + bse.bse_pending = 1; + + do { + old_head = blockif_bse_head; + bse.bse_next = old_head; + } while (!atomic_cmpset_ptr((uintptr_t *)&blockif_bse_head, + (uintptr_t)old_head, + (uintptr_t)&bse)); + + pthread_kill(be->be_tid, SIGCONT); + + pthread_mutex_lock(&bse.bse_mtx); + while (bse.bse_pending) + pthread_cond_wait(&bse.bse_cond, &bse.bse_mtx); + pthread_mutex_unlock(&bse.bse_mtx); + } + + pthread_mutex_unlock(&bc->bc_mtx); + + /* + * The processing thread has been interrupted. Since it's not + * clear if the callback has been invoked yet, return EBUSY. + */ + return (EBUSY); +} + +int +blockif_close(struct blockif_ctxt *bc) +{ + void *jval; + int i; + + assert(bc->bc_magic == BLOCKIF_SIG); + + /* + * Stop the block i/o thread + */ + pthread_mutex_lock(&bc->bc_mtx); + bc->bc_closing = 1; + pthread_mutex_unlock(&bc->bc_mtx); + pthread_cond_broadcast(&bc->bc_cond); + for (i = 0; i < BLOCKIF_NUMTHR; i++) + pthread_join(bc->bc_btid[i], &jval); + + /* XXX Cancel queued i/o's ??? */ + + /* + * Release resources + */ + bc->bc_magic = 0; + close(bc->bc_fd); + free(bc); + + return (0); +} + +/* + * Return virtual C/H/S values for a given block. Use the algorithm + * outlined in the VHD specification to calculate values. + */ +void +blockif_chs(struct blockif_ctxt *bc, uint16_t *c, uint8_t *h, uint8_t *s) +{ + off_t sectors; /* total sectors of the block dev */ + off_t hcyl; /* cylinders times heads */ + uint16_t secpt; /* sectors per track */ + uint8_t heads; + + assert(bc->bc_magic == BLOCKIF_SIG); + + sectors = bc->bc_size / bc->bc_sectsz; + + /* Clamp the size to the largest possible with CHS */ + if (sectors > 65535UL*16*255) + sectors = 65535UL*16*255; + + if (sectors >= 65536UL*16*63) { + secpt = 255; + heads = 16; + hcyl = sectors / secpt; + } else { + secpt = 17; + hcyl = sectors / secpt; + heads = (hcyl + 1023) / 1024; + + if (heads < 4) + heads = 4; + + if (hcyl >= (heads * 1024) || heads > 16) { + secpt = 31; + heads = 16; + hcyl = sectors / secpt; + } + if (hcyl >= (heads * 1024)) { + secpt = 63; + heads = 16; + hcyl = sectors / secpt; + } + } + + *c = hcyl / heads; + *h = heads; + *s = secpt; +} + +/* + * Accessors + */ +off_t +blockif_size(struct blockif_ctxt *bc) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (bc->bc_size); +} + +int +blockif_sectsz(struct blockif_ctxt *bc) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (bc->bc_sectsz); +} + +void +blockif_psectsz(struct blockif_ctxt *bc, int *size, int *off) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + *size = bc->bc_psectsz; + *off = bc->bc_psectoff; +} + +int +blockif_queuesz(struct blockif_ctxt *bc) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (BLOCKIF_MAXREQ - 1); +} + +int +blockif_is_ro(struct blockif_ctxt *bc) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (bc->bc_rdonly); +} + +int +blockif_candelete(struct blockif_ctxt *bc) +{ + + assert(bc->bc_magic == BLOCKIF_SIG); + return (bc->bc_candelete); +} + +#ifndef __FreeBSD__ +int +blockif_set_wce(struct blockif_ctxt *bc, int wc_enable) +{ + int res = 0, flags; + int clean_val = (wc_enable != 0) ? 1 : 0; + + (void) pthread_mutex_lock(&bc->bc_mtx); + switch (bc->bc_wce) { + case WCE_IOCTL: + res = ioctl(bc->bc_fd, DKIOCSETWCE, &clean_val); + break; + case WCE_FCNTL: + if ((flags = fcntl(bc->bc_fd, F_GETFL)) >= 0) { + if (wc_enable == 0) { + flags |= O_DSYNC; + } else { + flags &= ~O_DSYNC; + } + if (fcntl(bc->bc_fd, F_SETFL, flags) == -1) { + res = -1; + } + } else { + res = -1; + } + break; + default: + break; + } + + /* + * After a successful disable of the write cache, ensure that any + * lingering data in the cache is synced out. + */ + if (res == 0 && wc_enable == 0) { + res = fsync(bc->bc_fd); + } + (void) pthread_mutex_unlock(&bc->bc_mtx); + + return (res); +} +#endif /* __FreeBSD__ */ diff --git a/usr/src/cmd/bhyve/block_if.h b/usr/src/cmd/bhyve/block_if.h new file mode 100644 index 0000000000..8401cd9529 --- /dev/null +++ b/usr/src/cmd/bhyve/block_if.h @@ -0,0 +1,84 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Peter Grehan <grehan@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +/* + * The block API to be used by bhyve block-device emulations. The routines + * are thread safe, with no assumptions about the context of the completion + * callback - it may occur in the caller's context, or asynchronously in + * another thread. + */ + +#ifndef _BLOCK_IF_H_ +#define _BLOCK_IF_H_ + +#include <sys/uio.h> +#include <sys/unistd.h> + +#ifdef __FreeBSD__ +#define BLOCKIF_IOV_MAX 33 /* not practical to be IOV_MAX */ +#else +/* + * Upstream is in the process of bumping this up to 128 for several reasons, + * including Windows compatibility. For the sake of our Windows support, we + * will use the higher value now. + */ +#define BLOCKIF_IOV_MAX 128 +#endif + +struct blockif_req { + int br_iovcnt; + off_t br_offset; + ssize_t br_resid; + void (*br_callback)(struct blockif_req *req, int err); + void *br_param; + struct iovec br_iov[BLOCKIF_IOV_MAX]; +}; + +struct blockif_ctxt; +struct blockif_ctxt *blockif_open(const char *optstr, const char *ident); +off_t blockif_size(struct blockif_ctxt *bc); +void blockif_chs(struct blockif_ctxt *bc, uint16_t *c, uint8_t *h, + uint8_t *s); +int blockif_sectsz(struct blockif_ctxt *bc); +void blockif_psectsz(struct blockif_ctxt *bc, int *size, int *off); +int blockif_queuesz(struct blockif_ctxt *bc); +int blockif_is_ro(struct blockif_ctxt *bc); +int blockif_candelete(struct blockif_ctxt *bc); +#ifndef __FreeBSD__ +int blockif_set_wce(struct blockif_ctxt *bc, int enable); +#endif +int blockif_read(struct blockif_ctxt *bc, struct blockif_req *breq); +int blockif_write(struct blockif_ctxt *bc, struct blockif_req *breq); +int blockif_flush(struct blockif_ctxt *bc, struct blockif_req *breq); +int blockif_delete(struct blockif_ctxt *bc, struct blockif_req *breq); +int blockif_cancel(struct blockif_ctxt *bc, struct blockif_req *breq); +int blockif_close(struct blockif_ctxt *bc); + +#endif /* _BLOCK_IF_H_ */ diff --git a/usr/src/cmd/bhyve/bootrom.c b/usr/src/cmd/bhyve/bootrom.c new file mode 100644 index 0000000000..b8c63828c8 --- /dev/null +++ b/usr/src/cmd/bhyve/bootrom.c @@ -0,0 +1,113 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Neel Natu <neel@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/param.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> + +#include <machine/vmm.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <stdbool.h> + +#include <vmmapi.h> +#include "bhyverun.h" +#include "bootrom.h" + +#define MAX_BOOTROM_SIZE (16 * 1024 * 1024) /* 16 MB */ + +int +bootrom_init(struct vmctx *ctx, const char *romfile) +{ + struct stat sbuf; + vm_paddr_t gpa; + ssize_t rlen; + char *ptr; + int fd, i, rv, prot; + + rv = -1; + fd = open(romfile, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Error opening bootrom \"%s\": %s\n", + romfile, strerror(errno)); + goto done; + } + + if (fstat(fd, &sbuf) < 0) { + fprintf(stderr, "Could not fstat bootrom file \"%s\": %s\n", + romfile, strerror(errno)); + goto done; + } + + /* + * Limit bootrom size to 16MB so it doesn't encroach into reserved + * MMIO space (e.g. APIC, HPET, MSI). + */ + if (sbuf.st_size > MAX_BOOTROM_SIZE || sbuf.st_size < PAGE_SIZE) { + fprintf(stderr, "Invalid bootrom size %ld\n", sbuf.st_size); + goto done; + } + + if (sbuf.st_size & PAGE_MASK) { + fprintf(stderr, "Bootrom size %ld is not a multiple of the " + "page size\n", sbuf.st_size); + goto done; + } + + ptr = vm_create_devmem(ctx, VM_BOOTROM, "bootrom", sbuf.st_size); + if (ptr == MAP_FAILED) + goto done; + + /* Map the bootrom into the guest address space */ + prot = PROT_READ | PROT_EXEC; + gpa = (1ULL << 32) - sbuf.st_size; + if (vm_mmap_memseg(ctx, gpa, VM_BOOTROM, 0, sbuf.st_size, prot) != 0) + goto done; + + /* Read 'romfile' into the guest address space */ + for (i = 0; i < sbuf.st_size / PAGE_SIZE; i++) { + rlen = read(fd, ptr + i * PAGE_SIZE, PAGE_SIZE); + if (rlen != PAGE_SIZE) { + fprintf(stderr, "Incomplete read of page %d of bootrom " + "file %s: %ld bytes\n", i, romfile, rlen); + goto done; + } + } + rv = 0; +done: + if (fd >= 0) + close(fd); + return (rv); +} diff --git a/usr/src/cmd/bhyve/bootrom.h b/usr/src/cmd/bhyve/bootrom.h new file mode 100644 index 0000000000..7fb12181dd --- /dev/null +++ b/usr/src/cmd/bhyve/bootrom.h @@ -0,0 +1,40 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Neel Natu <neel@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _BOOTROM_H_ +#define _BOOTROM_H_ + +#include <stdbool.h> + +struct vmctx; + +int bootrom_init(struct vmctx *ctx, const char *romfile); + +#endif diff --git a/usr/src/cmd/bhyve/console.c b/usr/src/cmd/bhyve/console.c new file mode 100644 index 0000000000..2567f69959 --- /dev/null +++ b/usr/src/cmd/bhyve/console.c @@ -0,0 +1,120 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> + +#include "bhyvegc.h" +#include "console.h" + +static struct { + struct bhyvegc *gc; + + fb_render_func_t fb_render_cb; + void *fb_arg; + + kbd_event_func_t kbd_event_cb; + void *kbd_arg; + int kbd_priority; + + ptr_event_func_t ptr_event_cb; + void *ptr_arg; + int ptr_priority; +} console; + +void +console_init(int w, int h, void *fbaddr) +{ + console.gc = bhyvegc_init(w, h, fbaddr); +} + +void +console_set_fbaddr(void *fbaddr) +{ + bhyvegc_set_fbaddr(console.gc, fbaddr); +} + +struct bhyvegc_image * +console_get_image(void) +{ + struct bhyvegc_image *bhyvegc_image; + + bhyvegc_image = bhyvegc_get_image(console.gc); + + return (bhyvegc_image); +} + +void +console_fb_register(fb_render_func_t render_cb, void *arg) +{ + console.fb_render_cb = render_cb; + console.fb_arg = arg; +} + +void +console_refresh(void) +{ + if (console.fb_render_cb) + (*console.fb_render_cb)(console.gc, console.fb_arg); +} + +void +console_kbd_register(kbd_event_func_t event_cb, void *arg, int pri) +{ + if (pri > console.kbd_priority) { + console.kbd_event_cb = event_cb; + console.kbd_arg = arg; + console.kbd_priority = pri; + } +} + +void +console_ptr_register(ptr_event_func_t event_cb, void *arg, int pri) +{ + if (pri > console.ptr_priority) { + console.ptr_event_cb = event_cb; + console.ptr_arg = arg; + console.ptr_priority = pri; + } +} + +void +console_key_event(int down, uint32_t keysym) +{ + if (console.kbd_event_cb) + (*console.kbd_event_cb)(down, keysym, console.kbd_arg); +} + +void +console_ptr_event(uint8_t button, int x, int y) +{ + if (console.ptr_event_cb) + (*console.ptr_event_cb)(button, x, y, console.ptr_arg); +} diff --git a/usr/src/cmd/bhyve/console.h b/usr/src/cmd/bhyve/console.h new file mode 100644 index 0000000000..0d0a854866 --- /dev/null +++ b/usr/src/cmd/bhyve/console.h @@ -0,0 +1,55 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _CONSOLE_H_ +#define _CONSOLE_H_ + +struct bhyvegc; + +typedef void (*fb_render_func_t)(struct bhyvegc *gc, void *arg); +typedef void (*kbd_event_func_t)(int down, uint32_t keysym, void *arg); +typedef void (*ptr_event_func_t)(uint8_t mask, int x, int y, void *arg); + +void console_init(int w, int h, void *fbaddr); + +void console_set_fbaddr(void *fbaddr); + +struct bhyvegc_image *console_get_image(void); + +void console_fb_register(fb_render_func_t render_cb, void *arg); +void console_refresh(void); + +void console_kbd_register(kbd_event_func_t event_cb, void *arg, int pri); +void console_key_event(int down, uint32_t keysym); + +void console_ptr_register(ptr_event_func_t event_cb, void *arg, int pri); +void console_ptr_event(uint8_t button, int x, int y); + +#endif /* _CONSOLE_H_ */ diff --git a/usr/src/cmd/bhyve/consport.c b/usr/src/cmd/bhyve/consport.c new file mode 100644 index 0000000000..cda2df2414 --- /dev/null +++ b/usr/src/cmd/bhyve/consport.c @@ -0,0 +1,180 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/select.h> + +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <termios.h> +#include <unistd.h> +#include <stdbool.h> +#include <sysexits.h> + +#include "inout.h" +#include "pci_lpc.h" + +#define BVM_CONSOLE_PORT 0x220 +#define BVM_CONS_SIG ('b' << 8 | 'v') + +#ifdef __FreeBSD__ +static struct termios tio_orig, tio_new; + +static void +ttyclose(void) +{ + tcsetattr(STDIN_FILENO, TCSANOW, &tio_orig); +} +#endif + +static void +ttyopen(void) +{ +#ifdef __FreeBSD__ + tcgetattr(STDIN_FILENO, &tio_orig); + + cfmakeraw(&tio_new); + tcsetattr(STDIN_FILENO, TCSANOW, &tio_new); + + atexit(ttyclose); +#endif +} + +static bool +tty_char_available(void) +{ + fd_set rfds; + struct timeval tv; + + FD_ZERO(&rfds); + FD_SET(STDIN_FILENO, &rfds); + tv.tv_sec = 0; + tv.tv_usec = 0; + if (select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv) > 0) { + return (true); + } else { + return (false); + } +} + +static int +ttyread(void) +{ + char rb; + + if (tty_char_available()) { + read(STDIN_FILENO, &rb, 1); + return (rb & 0xff); + } else { + return (-1); + } +} + +static void +ttywrite(unsigned char wb) +{ + (void) write(STDOUT_FILENO, &wb, 1); +} + +static int +console_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + static int opened; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; + cap_ioctl_t cmds[] = { TIOCGETA, TIOCSETA, TIOCGWINSZ }; +#endif + + if (bytes == 2 && in) { + *eax = BVM_CONS_SIG; + return (0); + } + + /* + * Guests might probe this port to look for old ISA devices + * using single-byte reads. Return 0xff for those. + */ + if (bytes == 1 && in) { + *eax = 0xff; + return (0); + } + + if (bytes != 4) + return (-1); + + if (!opened) { +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, + CAP_WRITE); + if (caph_rights_limit(STDIN_FILENO, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (caph_ioctls_limit(STDIN_FILENO, cmds, nitems(cmds)) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + ttyopen(); + opened = 1; + } + + if (in) + *eax = ttyread(); + else + ttywrite(*eax); + + return (0); +} + +SYSRES_IO(BVM_CONSOLE_PORT, 4); + +static struct inout_port consport = { + "bvmcons", + BVM_CONSOLE_PORT, + 1, + IOPORT_F_INOUT, + console_handler +}; + +void +init_bvmcons(void) +{ + + register_inout(&consport); +} diff --git a/usr/src/cmd/bhyve/dbgport.c b/usr/src/cmd/bhyve/dbgport.c new file mode 100644 index 0000000000..88a616b50d --- /dev/null +++ b/usr/src/cmd/bhyve/dbgport.c @@ -0,0 +1,180 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <sys/uio.h> + +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <sysexits.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> + +#include "inout.h" +#include "dbgport.h" +#include "pci_lpc.h" + +#define BVM_DBG_PORT 0x224 +#define BVM_DBG_SIG ('B' << 8 | 'V') + +static int listen_fd, conn_fd; + +static struct sockaddr_in sin; + +static int +dbg_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + int nwritten, nread, printonce; + int on = 1; + char ch; + + if (bytes == 2 && in) { + *eax = BVM_DBG_SIG; + return (0); + } + + if (bytes != 4) + return (-1); + +again: + printonce = 0; + while (conn_fd < 0) { + if (!printonce) { + printf("Waiting for connection from gdb\r\n"); + printonce = 1; + } + conn_fd = accept4(listen_fd, NULL, NULL, SOCK_NONBLOCK); + if (conn_fd >= 0) { + /* Avoid EPIPE after the client drops off. */ + (void)setsockopt(conn_fd, SOL_SOCKET, SO_NOSIGPIPE, + &on, sizeof(on)); + /* Improve latency for one byte at a time tranfers. */ + (void)setsockopt(conn_fd, IPPROTO_TCP, TCP_NODELAY, + &on, sizeof(on)); + } else if (errno != EINTR) { + perror("accept"); + } + } + + if (in) { + nread = read(conn_fd, &ch, 1); + if (nread == -1 && errno == EAGAIN) + *eax = -1; + else if (nread == 1) + *eax = ch; + else { + close(conn_fd); + conn_fd = -1; + goto again; + } + } else { + ch = *eax; + nwritten = write(conn_fd, &ch, 1); + if (nwritten != 1) { + close(conn_fd); + conn_fd = -1; + goto again; + } + } + return (0); +} + +static struct inout_port dbgport = { + "bvmdbg", + BVM_DBG_PORT, + 1, + IOPORT_F_INOUT, + dbg_handler +}; + +SYSRES_IO(BVM_DBG_PORT, 4); + +void +init_dbgport(int sport) +{ + int reuse; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; +#endif + + conn_fd = -1; + + if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("cannot create socket"); + exit(4); + } + +#ifdef __FreeBSD__ + sin.sin_len = sizeof(sin); +#endif + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(sport); + + reuse = 1; + if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, + sizeof(reuse)) < 0) { + perror("cannot set socket options"); + exit(4); + } + + if (bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + perror("cannot bind socket"); + exit(4); + } + + if (listen(listen_fd, 1) < 0) { + perror("cannot listen socket"); + exit(4); + } + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_ACCEPT, CAP_READ, CAP_WRITE); + if (caph_rights_limit(listen_fd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + register_inout(&dbgport); +} diff --git a/usr/src/cmd/bhyve/dbgport.h b/usr/src/cmd/bhyve/dbgport.h new file mode 100644 index 0000000000..407ff3ffbf --- /dev/null +++ b/usr/src/cmd/bhyve/dbgport.h @@ -0,0 +1,36 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _DBGPORT_H_ +#define _DBGPORT_H_ + +void init_dbgport(int port); + +#endif diff --git a/usr/src/cmd/bhyve/fwctl.c b/usr/src/cmd/bhyve/fwctl.c new file mode 100644 index 0000000000..0640bc28ba --- /dev/null +++ b/usr/src/cmd/bhyve/fwctl.c @@ -0,0 +1,552 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Peter Grehan <grehan@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +/* + * Guest firmware interface. Uses i/o ports x510/x511 as Qemu does, + * but with a request/response messaging protocol. + */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/uio.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "bhyverun.h" +#include "inout.h" +#include "fwctl.h" + +/* + * Messaging protocol base operations + */ +#define OP_NULL 1 +#define OP_ECHO 2 +#define OP_GET 3 +#define OP_GET_LEN 4 +#define OP_SET 5 +#define OP_MAX OP_SET + +/* I/O ports */ +#define FWCTL_OUT 0x510 +#define FWCTL_IN 0x511 + +/* + * Back-end state-machine + */ +enum state { + DORMANT, + IDENT_WAIT, + IDENT_SEND, + REQ, + RESP +} be_state = DORMANT; + +static uint8_t sig[] = { 'B', 'H', 'Y', 'V' }; +static u_int ident_idx; + +struct op_info { + int op; + int (*op_start)(uint32_t len); + void (*op_data)(uint32_t data, uint32_t len); + int (*op_result)(struct iovec **data); + void (*op_done)(struct iovec *data); +}; +static struct op_info *ops[OP_MAX+1]; + +/* Return 0-padded uint32_t */ +static uint32_t +fwctl_send_rest(uint32_t *data, size_t len) +{ + union { + uint8_t c[4]; + uint32_t w; + } u; + uint8_t *cdata; + int i; + + cdata = (uint8_t *) data; + u.w = 0; + + for (i = 0, u.w = 0; i < len; i++) + u.c[i] = *cdata++; + + return (u.w); +} + +/* + * error op dummy proto - drop all data sent and return an error +*/ +static int errop_code; + +static void +errop_set(int err) +{ + + errop_code = err; +} + +static int +errop_start(uint32_t len) +{ + errop_code = ENOENT; + + /* accept any length */ + return (errop_code); +} + +static void +errop_data(uint32_t data, uint32_t len) +{ + + /* ignore */ +} + +static int +errop_result(struct iovec **data) +{ + + /* no data to send back; always successful */ + *data = NULL; + return (errop_code); +} + +static void +errop_done(struct iovec *data) +{ + + /* assert data is NULL */ +} + +static struct op_info errop_info = { + .op_start = errop_start, + .op_data = errop_data, + .op_result = errop_result, + .op_done = errop_done +}; + +/* OID search */ +SET_DECLARE(ctl_set, struct ctl); + +CTL_NODE("hw.ncpu", &guest_ncpus, sizeof(guest_ncpus)); + +static struct ctl * +ctl_locate(const char *str, int maxlen) +{ + struct ctl *cp, **cpp; + + SET_FOREACH(cpp, ctl_set) { + cp = *cpp; + if (!strncmp(str, cp->c_oid, maxlen)) + return (cp); + } + + return (NULL); +} + +/* uefi-sysctl get-len */ +#define FGET_STRSZ 80 +static struct iovec fget_biov[2]; +static char fget_str[FGET_STRSZ]; +static struct { + size_t f_sz; + uint32_t f_data[1024]; +} fget_buf; +static int fget_cnt; +static size_t fget_size; + +static int +fget_start(uint32_t len) +{ + + if (len > FGET_STRSZ) + return(E2BIG); + + fget_cnt = 0; + + return (0); +} + +static void +fget_data(uint32_t data, uint32_t len) +{ + + *((uint32_t *) &fget_str[fget_cnt]) = data; + fget_cnt += sizeof(uint32_t); +} + +static int +fget_result(struct iovec **data, int val) +{ + struct ctl *cp; + int err; + + err = 0; + + /* Locate the OID */ + cp = ctl_locate(fget_str, fget_cnt); + if (cp == NULL) { + *data = NULL; + err = ENOENT; + } else { + if (val) { + /* For now, copy the len/data into a buffer */ + memset(&fget_buf, 0, sizeof(fget_buf)); + fget_buf.f_sz = cp->c_len; + memcpy(fget_buf.f_data, cp->c_data, cp->c_len); + fget_biov[0].iov_base = (char *)&fget_buf; + fget_biov[0].iov_len = sizeof(fget_buf.f_sz) + + cp->c_len; + } else { + fget_size = cp->c_len; + fget_biov[0].iov_base = (char *)&fget_size; + fget_biov[0].iov_len = sizeof(fget_size); + } + + fget_biov[1].iov_base = NULL; + fget_biov[1].iov_len = 0; + *data = fget_biov; + } + + return (err); +} + +static void +fget_done(struct iovec *data) +{ + + /* nothing needs to be freed */ +} + +static int +fget_len_result(struct iovec **data) +{ + return (fget_result(data, 0)); +} + +static int +fget_val_result(struct iovec **data) +{ + return (fget_result(data, 1)); +} + +static struct op_info fgetlen_info = { + .op_start = fget_start, + .op_data = fget_data, + .op_result = fget_len_result, + .op_done = fget_done +}; + +static struct op_info fgetval_info = { + .op_start = fget_start, + .op_data = fget_data, + .op_result = fget_val_result, + .op_done = fget_done +}; + +static struct req_info { + int req_error; + u_int req_count; + uint32_t req_size; + uint32_t req_type; + uint32_t req_txid; + struct op_info *req_op; + int resp_error; + int resp_count; + size_t resp_size; + size_t resp_off; + struct iovec *resp_biov; +} rinfo; + +static void +fwctl_response_done(void) +{ + + (*rinfo.req_op->op_done)(rinfo.resp_biov); + + /* reinit the req data struct */ + memset(&rinfo, 0, sizeof(rinfo)); +} + +static void +fwctl_request_done(void) +{ + + rinfo.resp_error = (*rinfo.req_op->op_result)(&rinfo.resp_biov); + + /* XXX only a single vector supported at the moment */ + rinfo.resp_off = 0; + if (rinfo.resp_biov == NULL) { + rinfo.resp_size = 0; + } else { + rinfo.resp_size = rinfo.resp_biov[0].iov_len; + } +} + +static int +fwctl_request_start(void) +{ + int err; + + /* Data size doesn't include header */ + rinfo.req_size -= 12; + + rinfo.req_op = &errop_info; + if (rinfo.req_type <= OP_MAX && ops[rinfo.req_type] != NULL) + rinfo.req_op = ops[rinfo.req_type]; + + err = (*rinfo.req_op->op_start)(rinfo.req_size); + + if (err) { + errop_set(err); + rinfo.req_op = &errop_info; + } + + /* Catch case of zero-length message here */ + if (rinfo.req_size == 0) { + fwctl_request_done(); + return (1); + } + + return (0); +} + +static int +fwctl_request_data(uint32_t value) +{ + + /* Make sure remaining size is >= 0 */ + if (rinfo.req_size <= sizeof(uint32_t)) + rinfo.req_size = 0; + else + rinfo.req_size -= sizeof(uint32_t); + + (*rinfo.req_op->op_data)(value, rinfo.req_size); + + if (rinfo.req_size < sizeof(uint32_t)) { + fwctl_request_done(); + return (1); + } + + return (0); +} + +static int +fwctl_request(uint32_t value) +{ + + int ret; + + ret = 0; + + switch (rinfo.req_count) { + case 0: + /* Verify size */ + if (value < 12) { + printf("msg size error"); + exit(4); + } + rinfo.req_size = value; + rinfo.req_count = 1; + break; + case 1: + rinfo.req_type = value; + rinfo.req_count++; + break; + case 2: + rinfo.req_txid = value; + rinfo.req_count++; + ret = fwctl_request_start(); + break; + default: + ret = fwctl_request_data(value); + break; + } + + return (ret); +} + +static int +fwctl_response(uint32_t *retval) +{ + uint32_t *dp; + ssize_t remlen; + + switch(rinfo.resp_count) { + case 0: + /* 4 x u32 header len + data */ + *retval = 4*sizeof(uint32_t) + + roundup(rinfo.resp_size, sizeof(uint32_t)); + rinfo.resp_count++; + break; + case 1: + *retval = rinfo.req_type; + rinfo.resp_count++; + break; + case 2: + *retval = rinfo.req_txid; + rinfo.resp_count++; + break; + case 3: + *retval = rinfo.resp_error; + rinfo.resp_count++; + break; + default: + remlen = rinfo.resp_size - rinfo.resp_off; + dp = (uint32_t *) + ((uint8_t *)rinfo.resp_biov->iov_base + rinfo.resp_off); + if (remlen >= sizeof(uint32_t)) { + *retval = *dp; + } else if (remlen > 0) { + *retval = fwctl_send_rest(dp, remlen); + } + rinfo.resp_off += sizeof(uint32_t); + break; + } + + if (rinfo.resp_count > 3 && + rinfo.resp_off >= rinfo.resp_size) { + fwctl_response_done(); + return (1); + } + + return (0); +} + + +/* + * i/o port handling. + */ +static uint8_t +fwctl_inb(void) +{ + uint8_t retval; + + retval = 0xff; + + switch (be_state) { + case IDENT_SEND: + retval = sig[ident_idx++]; + if (ident_idx >= sizeof(sig)) + be_state = REQ; + break; + default: + break; + } + + return (retval); +} + +static void +fwctl_outw(uint16_t val) +{ + switch (be_state) { + case IDENT_WAIT: + if (val == 0) { + be_state = IDENT_SEND; + ident_idx = 0; + } + break; + default: + /* ignore */ + break; + } +} + +static uint32_t +fwctl_inl(void) +{ + uint32_t retval; + + switch (be_state) { + case RESP: + if (fwctl_response(&retval)) + be_state = REQ; + break; + default: + retval = 0xffffffff; + break; + } + + return (retval); +} + +static void +fwctl_outl(uint32_t val) +{ + + switch (be_state) { + case REQ: + if (fwctl_request(val)) + be_state = RESP; + default: + break; + } + +} + +static int +fwctl_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + + if (in) { + if (bytes == 1) + *eax = fwctl_inb(); + else if (bytes == 4) + *eax = fwctl_inl(); + else + *eax = 0xffff; + } else { + if (bytes == 2) + fwctl_outw(*eax); + else if (bytes == 4) + fwctl_outl(*eax); + } + + return (0); +} +INOUT_PORT(fwctl_wreg, FWCTL_OUT, IOPORT_F_INOUT, fwctl_handler); +INOUT_PORT(fwctl_rreg, FWCTL_IN, IOPORT_F_IN, fwctl_handler); + +void +fwctl_init(void) +{ + + ops[OP_GET_LEN] = &fgetlen_info; + ops[OP_GET] = &fgetval_info; + + be_state = IDENT_WAIT; +} diff --git a/usr/src/cmd/bhyve/fwctl.h b/usr/src/cmd/bhyve/fwctl.h new file mode 100644 index 0000000000..6dad244811 --- /dev/null +++ b/usr/src/cmd/bhyve/fwctl.h @@ -0,0 +1,56 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Peter Grehan <grehan@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _FWCTL_H_ +#define _FWCTL_H_ + +#include <sys/linker_set.h> + +/* + * Linker set api for export of information to guest firmware via + * a sysctl-like OID interface + */ +struct ctl { + const char *c_oid; + const void *c_data; + const int c_len; +}; + +#define CTL_NODE(oid, data, len) \ + static struct ctl __CONCAT(__ctl, __LINE__) = { \ + oid, \ + (data), \ + (len), \ + }; \ + DATA_SET(ctl_set, __CONCAT(__ctl, __LINE__)) + +void fwctl_init(void); + +#endif /* _FWCTL_H_ */ diff --git a/usr/src/cmd/bhyve/gdb.c b/usr/src/cmd/bhyve/gdb.c new file mode 100644 index 0000000000..69bcf53c31 --- /dev/null +++ b/usr/src/cmd/bhyve/gdb.c @@ -0,0 +1,1332 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2017-2018 John H. Baldwin <jhb@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <sys/socket.h> +#include <machine/atomic.h> +#include <machine/specialreg.h> +#include <machine/vmm.h> +#include <netinet/in.h> +#include <assert.h> +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <pthread_np.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <unistd.h> +#include <vmmapi.h> + +#include "bhyverun.h" +#include "mem.h" +#include "mevent.h" + +/* + * GDB_SIGNAL_* numbers are part of the GDB remote protocol. Most stops + * use SIGTRAP. + */ +#define GDB_SIGNAL_TRAP 5 + +static void gdb_resume_vcpus(void); +static void check_command(int fd); + +static struct mevent *read_event, *write_event; + +static cpuset_t vcpus_active, vcpus_suspended, vcpus_waiting; +static pthread_mutex_t gdb_lock; +static pthread_cond_t idle_vcpus; +static bool stop_pending, first_stop; +#ifdef __FreeBSD__ +static int stepping_vcpu, stopped_vcpu; +#else +static int stepping_vcpu = -1, stopped_vcpu = -1; +#endif + +/* + * An I/O buffer contains 'capacity' bytes of room at 'data'. For a + * read buffer, 'start' is unused and 'len' contains the number of + * valid bytes in the buffer. For a write buffer, 'start' is set to + * the index of the next byte in 'data' to send, and 'len' contains + * the remaining number of valid bytes to send. + */ +struct io_buffer { + uint8_t *data; + size_t capacity; + size_t start; + size_t len; +}; + +static struct io_buffer cur_comm, cur_resp; +static uint8_t cur_csum; +static int cur_vcpu; +static struct vmctx *ctx; +static int cur_fd = -1; + +const int gdb_regset[] = { + VM_REG_GUEST_RAX, + VM_REG_GUEST_RBX, + VM_REG_GUEST_RCX, + VM_REG_GUEST_RDX, + VM_REG_GUEST_RSI, + VM_REG_GUEST_RDI, + VM_REG_GUEST_RBP, + VM_REG_GUEST_RSP, + VM_REG_GUEST_R8, + VM_REG_GUEST_R9, + VM_REG_GUEST_R10, + VM_REG_GUEST_R11, + VM_REG_GUEST_R12, + VM_REG_GUEST_R13, + VM_REG_GUEST_R14, + VM_REG_GUEST_R15, + VM_REG_GUEST_RIP, + VM_REG_GUEST_RFLAGS, + VM_REG_GUEST_CS, + VM_REG_GUEST_SS, + VM_REG_GUEST_DS, + VM_REG_GUEST_ES, + VM_REG_GUEST_FS, + VM_REG_GUEST_GS +}; + +const int gdb_regsize[] = { + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 8, + 4, + 4, + 4, + 4, + 4, + 4, + 4 +}; + +#ifdef GDB_LOG +#include <stdarg.h> +#include <stdio.h> + +static void __printflike(1, 2) +debug(const char *fmt, ...) +{ + static FILE *logfile; + va_list ap; + + if (logfile == NULL) { + logfile = fopen("/tmp/bhyve_gdb.log", "w"); + if (logfile == NULL) + return; +#ifndef WITHOUT_CAPSICUM + if (caph_limit_stream(fileno(logfile), CAPH_WRITE) == -1) { + fclose(logfile); + logfile = NULL; + return; + } +#endif + setlinebuf(logfile); + } + va_start(ap, fmt); + vfprintf(logfile, fmt, ap); + va_end(ap); +} +#else +#define debug(...) +#endif + +static int +guest_paging_info(int vcpu, struct vm_guest_paging *paging) +{ + uint64_t regs[4]; + const int regset[4] = { + VM_REG_GUEST_CR0, + VM_REG_GUEST_CR3, + VM_REG_GUEST_CR4, + VM_REG_GUEST_EFER + }; + + if (vm_get_register_set(ctx, vcpu, nitems(regset), regset, regs) == -1) + return (-1); + + /* + * For the debugger, always pretend to be the kernel (CPL 0), + * and if long-mode is enabled, always parse addresses as if + * in 64-bit mode. + */ + paging->cr3 = regs[1]; + paging->cpl = 0; + if (regs[3] & EFER_LMA) + paging->cpu_mode = CPU_MODE_64BIT; + else if (regs[0] & CR0_PE) + paging->cpu_mode = CPU_MODE_PROTECTED; + else + paging->cpu_mode = CPU_MODE_REAL; + if (!(regs[0] & CR0_PG)) + paging->paging_mode = PAGING_MODE_FLAT; + else if (!(regs[2] & CR4_PAE)) + paging->paging_mode = PAGING_MODE_32; + else if (regs[3] & EFER_LME) + paging->paging_mode = PAGING_MODE_64; + else + paging->paging_mode = PAGING_MODE_PAE; + return (0); +} + +/* + * Map a guest virtual address to a physical address (for a given vcpu). + * If a guest virtual address is valid, return 1. If the address is + * not valid, return 0. If an error occurs obtaining the mapping, + * return -1. + */ +static int +guest_vaddr2paddr(int vcpu, uint64_t vaddr, uint64_t *paddr) +{ + struct vm_guest_paging paging; + int fault; + + if (guest_paging_info(vcpu, &paging) == -1) + return (-1); + + /* + * Always use PROT_READ. We really care if the VA is + * accessible, not if the current vCPU can write. + */ + if (vm_gla2gpa_nofault(ctx, vcpu, &paging, vaddr, PROT_READ, paddr, + &fault) == -1) + return (-1); + if (fault) + return (0); + return (1); +} + +static void +io_buffer_reset(struct io_buffer *io) +{ + + io->start = 0; + io->len = 0; +} + +/* Available room for adding data. */ +static size_t +io_buffer_avail(struct io_buffer *io) +{ + + return (io->capacity - (io->start + io->len)); +} + +static uint8_t * +io_buffer_head(struct io_buffer *io) +{ + + return (io->data + io->start); +} + +static uint8_t * +io_buffer_tail(struct io_buffer *io) +{ + + return (io->data + io->start + io->len); +} + +static void +io_buffer_advance(struct io_buffer *io, size_t amount) +{ + + assert(amount <= io->len); + io->start += amount; + io->len -= amount; +} + +static void +io_buffer_consume(struct io_buffer *io, size_t amount) +{ + + io_buffer_advance(io, amount); + if (io->len == 0) { + io->start = 0; + return; + } + + /* + * XXX: Consider making this move optional and compacting on a + * future read() before realloc(). + */ + memmove(io->data, io_buffer_head(io), io->len); + io->start = 0; +} + +static void +io_buffer_grow(struct io_buffer *io, size_t newsize) +{ + uint8_t *new_data; + size_t avail, new_cap; + + avail = io_buffer_avail(io); + if (newsize <= avail) + return; + + new_cap = io->capacity + (newsize - avail); + new_data = realloc(io->data, new_cap); + if (new_data == NULL) + err(1, "Failed to grow GDB I/O buffer"); + io->data = new_data; + io->capacity = new_cap; +} + +static bool +response_pending(void) +{ + + if (cur_resp.start == 0 && cur_resp.len == 0) + return (false); + if (cur_resp.start + cur_resp.len == 1 && cur_resp.data[0] == '+') + return (false); + return (true); +} + +static void +close_connection(void) +{ + + /* + * XXX: This triggers a warning because mevent does the close + * before the EV_DELETE. + */ + pthread_mutex_lock(&gdb_lock); + mevent_delete(write_event); + mevent_delete_close(read_event); + write_event = NULL; + read_event = NULL; + io_buffer_reset(&cur_comm); + io_buffer_reset(&cur_resp); + cur_fd = -1; + + /* Resume any stopped vCPUs. */ + gdb_resume_vcpus(); + pthread_mutex_unlock(&gdb_lock); +} + +static uint8_t +hex_digit(uint8_t nibble) +{ + + if (nibble <= 9) + return (nibble + '0'); + else + return (nibble + 'a' - 10); +} + +static uint8_t +parse_digit(uint8_t v) +{ + + if (v >= '0' && v <= '9') + return (v - '0'); + if (v >= 'a' && v <= 'f') + return (v - 'a' + 10); + if (v >= 'A' && v <= 'F') + return (v - 'A' + 10); + return (0xF); +} + +/* Parses big-endian hexadecimal. */ +static uintmax_t +parse_integer(const uint8_t *p, size_t len) +{ + uintmax_t v; + + v = 0; + while (len > 0) { + v <<= 4; + v |= parse_digit(*p); + p++; + len--; + } + return (v); +} + +static uint8_t +parse_byte(const uint8_t *p) +{ + + return (parse_digit(p[0]) << 4 | parse_digit(p[1])); +} + +static void +send_pending_data(int fd) +{ + ssize_t nwritten; + + if (cur_resp.len == 0) { + mevent_disable(write_event); + return; + } + nwritten = write(fd, io_buffer_head(&cur_resp), cur_resp.len); + if (nwritten == -1) { + warn("Write to GDB socket failed"); + close_connection(); + } else { + io_buffer_advance(&cur_resp, nwritten); + if (cur_resp.len == 0) + mevent_disable(write_event); + else + mevent_enable(write_event); + } +} + +/* Append a single character to the output buffer. */ +static void +send_char(uint8_t data) +{ + io_buffer_grow(&cur_resp, 1); + *io_buffer_tail(&cur_resp) = data; + cur_resp.len++; +} + +/* Append an array of bytes to the output buffer. */ +static void +send_data(const uint8_t *data, size_t len) +{ + + io_buffer_grow(&cur_resp, len); + memcpy(io_buffer_tail(&cur_resp), data, len); + cur_resp.len += len; +} + +static void +format_byte(uint8_t v, uint8_t *buf) +{ + + buf[0] = hex_digit(v >> 4); + buf[1] = hex_digit(v & 0xf); +} + +/* + * Append a single byte (formatted as two hex characters) to the + * output buffer. + */ +static void +send_byte(uint8_t v) +{ + uint8_t buf[2]; + + format_byte(v, buf); + send_data(buf, sizeof(buf)); +} + +static void +start_packet(void) +{ + + send_char('$'); + cur_csum = 0; +} + +static void +finish_packet(void) +{ + + send_char('#'); + send_byte(cur_csum); + debug("-> %.*s\n", (int)cur_resp.len, io_buffer_head(&cur_resp)); +} + +/* + * Append a single character (for the packet payload) and update the + * checksum. + */ +static void +append_char(uint8_t v) +{ + + send_char(v); + cur_csum += v; +} + +/* + * Append an array of bytes (for the packet payload) and update the + * checksum. + */ +static void +append_packet_data(const uint8_t *data, size_t len) +{ + + send_data(data, len); + while (len > 0) { + cur_csum += *data; + data++; + len--; + } +} + +static void +append_string(const char *str) +{ + +#ifdef __FreeBSD__ + append_packet_data(str, strlen(str)); +#else + append_packet_data((const uint8_t *)str, strlen(str)); +#endif +} + +static void +append_byte(uint8_t v) +{ + uint8_t buf[2]; + + format_byte(v, buf); + append_packet_data(buf, sizeof(buf)); +} + +static void +append_unsigned_native(uintmax_t value, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) { + append_byte(value); + value >>= 8; + } +} + +static void +append_unsigned_be(uintmax_t value, size_t len) +{ + char buf[len * 2]; + size_t i; + + for (i = 0; i < len; i++) { +#ifdef __FreeBSD__ + format_byte(value, buf + (len - i - 1) * 2); +#else + format_byte(value, (uint8_t *)(buf + (len - i - 1) * 2)); +#endif + value >>= 8; + } +#ifdef __FreeBSD__ + append_packet_data(buf, sizeof(buf)); +#else + append_packet_data((const uint8_t *)buf, sizeof(buf)); +#endif +} + +static void +append_integer(unsigned int value) +{ + + if (value == 0) + append_char('0'); + else + append_unsigned_be(value, fls(value) + 7 / 8); +} + +static void +append_asciihex(const char *str) +{ + + while (*str != '\0') { + append_byte(*str); + str++; + } +} + +static void +send_empty_response(void) +{ + + start_packet(); + finish_packet(); +} + +static void +send_error(int error) +{ + + start_packet(); + append_char('E'); + append_byte(error); + finish_packet(); +} + +static void +send_ok(void) +{ + + start_packet(); + append_string("OK"); + finish_packet(); +} + +static int +parse_threadid(const uint8_t *data, size_t len) +{ + + if (len == 1 && *data == '0') + return (0); + if (len == 2 && memcmp(data, "-1", 2) == 0) + return (-1); + if (len == 0) + return (-2); + return (parse_integer(data, len)); +} + +static void +report_stop(void) +{ + + start_packet(); + if (stopped_vcpu == -1) + append_char('S'); + else + append_char('T'); + append_byte(GDB_SIGNAL_TRAP); + if (stopped_vcpu != -1) { + append_string("thread:"); + append_integer(stopped_vcpu + 1); + append_char(';'); + } + stopped_vcpu = -1; + finish_packet(); +} + +static void +gdb_finish_suspend_vcpus(void) +{ + + if (first_stop) { + first_stop = false; + stopped_vcpu = -1; + } else if (response_pending()) + stop_pending = true; + else { + report_stop(); + send_pending_data(cur_fd); + } +} + +static void +_gdb_cpu_suspend(int vcpu, bool report_stop) +{ + + debug("$vCPU %d suspending\n", vcpu); + CPU_SET(vcpu, &vcpus_waiting); + if (report_stop && CPU_CMP(&vcpus_waiting, &vcpus_suspended) == 0) + gdb_finish_suspend_vcpus(); + while (CPU_ISSET(vcpu, &vcpus_suspended) && vcpu != stepping_vcpu) + pthread_cond_wait(&idle_vcpus, &gdb_lock); + CPU_CLR(vcpu, &vcpus_waiting); + debug("$vCPU %d resuming\n", vcpu); +} + +void +gdb_cpu_add(int vcpu) +{ + + debug("$vCPU %d starting\n", vcpu); + pthread_mutex_lock(&gdb_lock); + CPU_SET(vcpu, &vcpus_active); + + /* + * If a vcpu is added while vcpus are stopped, suspend the new + * vcpu so that it will pop back out with a debug exit before + * executing the first instruction. + */ + if (!CPU_EMPTY(&vcpus_suspended)) { + CPU_SET(vcpu, &vcpus_suspended); + _gdb_cpu_suspend(vcpu, false); + } + pthread_mutex_unlock(&gdb_lock); +} + +void +gdb_cpu_suspend(int vcpu) +{ + + pthread_mutex_lock(&gdb_lock); + _gdb_cpu_suspend(vcpu, true); + pthread_mutex_unlock(&gdb_lock); +} + +void +gdb_cpu_mtrap(int vcpu) +{ + + debug("$vCPU %d MTRAP\n", vcpu); + pthread_mutex_lock(&gdb_lock); + if (vcpu == stepping_vcpu) { + stepping_vcpu = -1; + vm_set_capability(ctx, vcpu, VM_CAP_MTRAP_EXIT, 0); + vm_suspend_cpu(ctx, vcpu); + assert(stopped_vcpu == -1); + stopped_vcpu = vcpu; + _gdb_cpu_suspend(vcpu, true); + } + pthread_mutex_unlock(&gdb_lock); +} + +static void +gdb_suspend_vcpus(void) +{ + + assert(pthread_mutex_isowned_np(&gdb_lock)); + debug("suspending all CPUs\n"); + vcpus_suspended = vcpus_active; + vm_suspend_cpu(ctx, -1); + if (CPU_CMP(&vcpus_waiting, &vcpus_suspended) == 0) + gdb_finish_suspend_vcpus(); +} + +static bool +gdb_step_vcpu(int vcpu) +{ + int error, val; + + debug("$vCPU %d step\n", vcpu); + error = vm_get_capability(ctx, vcpu, VM_CAP_MTRAP_EXIT, &val); + if (error < 0) + return (false); + error = vm_set_capability(ctx, vcpu, VM_CAP_MTRAP_EXIT, 1); + vm_resume_cpu(ctx, vcpu); + stepping_vcpu = vcpu; + pthread_cond_broadcast(&idle_vcpus); + return (true); +} + +static void +gdb_resume_vcpus(void) +{ + + assert(pthread_mutex_isowned_np(&gdb_lock)); + vm_resume_cpu(ctx, -1); + debug("resuming all CPUs\n"); + CPU_ZERO(&vcpus_suspended); + pthread_cond_broadcast(&idle_vcpus); +} + +static void +gdb_read_regs(void) +{ + uint64_t regvals[nitems(gdb_regset)]; + int i; + + if (vm_get_register_set(ctx, cur_vcpu, nitems(gdb_regset), + gdb_regset, regvals) == -1) { + send_error(errno); + return; + } + start_packet(); + for (i = 0; i < nitems(regvals); i++) + append_unsigned_native(regvals[i], gdb_regsize[i]); + finish_packet(); +} + +static void +gdb_read_mem(const uint8_t *data, size_t len) +{ + uint64_t gpa, gva, val; + uint8_t *cp; + size_t resid, todo, bytes; + bool started; + int error; + + cp = memchr(data, ',', len); + if (cp == NULL) { + send_error(EINVAL); + return; + } + gva = parse_integer(data + 1, cp - (data + 1)); + resid = parse_integer(cp + 1, len - (cp + 1 - data)); + started = false; + + while (resid > 0) { + error = guest_vaddr2paddr(cur_vcpu, gva, &gpa); + if (error == -1) { + if (started) + finish_packet(); + else + send_error(errno); + return; + } + if (error == 0) { + if (started) + finish_packet(); + else + send_error(EFAULT); + return; + } + + /* Read bytes from current page. */ + todo = getpagesize() - gpa % getpagesize(); + if (todo > resid) + todo = resid; + + cp = paddr_guest2host(ctx, gpa, todo); + if (cp != NULL) { + /* + * If this page is guest RAM, read it a byte + * at a time. + */ + if (!started) { + start_packet(); + started = true; + } + while (todo > 0) { + append_byte(*cp); + cp++; + gpa++; + gva++; + resid--; + todo--; + } + } else { + /* + * If this page isn't guest RAM, try to handle + * it via MMIO. For MMIO requests, use + * aligned reads of words when possible. + */ + while (todo > 0) { + if (gpa & 1 || todo == 1) + bytes = 1; + else if (gpa & 2 || todo == 2) + bytes = 2; + else + bytes = 4; + error = read_mem(ctx, cur_vcpu, gpa, &val, + bytes); + if (error == 0) { + if (!started) { + start_packet(); + started = true; + } + gpa += bytes; + gva += bytes; + resid -= bytes; + todo -= bytes; + while (bytes > 0) { + append_byte(val); + val >>= 8; + bytes--; + } + } else { + if (started) + finish_packet(); + else + send_error(EFAULT); + return; + } + } + } + assert(resid == 0 || gpa % getpagesize() == 0); + } + if (!started) + start_packet(); + finish_packet(); +} + +static bool +command_equals(const uint8_t *data, size_t len, const char *cmd) +{ + + if (strlen(cmd) > len) + return (false); + return (memcmp(data, cmd, strlen(cmd)) == 0); +} + +static void +gdb_query(const uint8_t *data, size_t len) +{ + + /* + * TODO: + * - qSearch + * - qSupported + */ + if (command_equals(data, len, "qAttached")) { + start_packet(); + append_char('1'); + finish_packet(); + } else if (command_equals(data, len, "qC")) { + start_packet(); + append_string("QC"); + append_integer(cur_vcpu + 1); + finish_packet(); + } else if (command_equals(data, len, "qfThreadInfo")) { + cpuset_t mask; + bool first; + int vcpu; + + if (CPU_EMPTY(&vcpus_active)) { + send_error(EINVAL); + return; + } + mask = vcpus_active; + start_packet(); + append_char('m'); + first = true; + while (!CPU_EMPTY(&mask)) { + vcpu = CPU_FFS(&mask) - 1; + CPU_CLR(vcpu, &mask); + if (first) + first = false; + else + append_char(','); + append_integer(vcpu + 1); + } + finish_packet(); + } else if (command_equals(data, len, "qsThreadInfo")) { + start_packet(); + append_char('l'); + finish_packet(); + } else if (command_equals(data, len, "qThreadExtraInfo")) { + char buf[16]; + int tid; + + data += strlen("qThreadExtraInfo"); + len -= strlen("qThreadExtraInfo"); + if (*data != ',') { + send_error(EINVAL); + return; + } + tid = parse_threadid(data + 1, len - 1); + if (tid <= 0 || !CPU_ISSET(tid - 1, &vcpus_active)) { + send_error(EINVAL); + return; + } + + snprintf(buf, sizeof(buf), "vCPU %d", tid - 1); + start_packet(); + append_asciihex(buf); + finish_packet(); + } else + send_empty_response(); +} + +static void +handle_command(const uint8_t *data, size_t len) +{ + + /* Reject packets with a sequence-id. */ + if (len >= 3 && data[0] >= '0' && data[0] <= '9' && + data[0] >= '0' && data[0] <= '9' && data[2] == ':') { + send_empty_response(); + return; + } + + switch (*data) { + case 'c': + if (len != 1) { + send_error(EINVAL); + break; + } + + /* Don't send a reply until a stop occurs. */ + gdb_resume_vcpus(); + break; + case 'D': + send_ok(); + + /* TODO: Resume any stopped CPUs. */ + break; + case 'g': { + gdb_read_regs(); + break; + } + case 'H': { + int tid; + + if (data[1] != 'g' && data[1] != 'c') { + send_error(EINVAL); + break; + } + tid = parse_threadid(data + 2, len - 2); + if (tid == -2) { + send_error(EINVAL); + break; + } + + if (CPU_EMPTY(&vcpus_active)) { + send_error(EINVAL); + break; + } + if (tid == -1 || tid == 0) + cur_vcpu = CPU_FFS(&vcpus_active) - 1; + else if (CPU_ISSET(tid - 1, &vcpus_active)) + cur_vcpu = tid - 1; + else { + send_error(EINVAL); + break; + } + send_ok(); + break; + } + case 'm': + gdb_read_mem(data, len); + break; + case 'T': { + int tid; + + tid = parse_threadid(data + 1, len - 1); + if (tid <= 0 || !CPU_ISSET(tid - 1, &vcpus_active)) { + send_error(EINVAL); + return; + } + send_ok(); + break; + } + case 'q': + gdb_query(data, len); + break; + case 's': + if (len != 1) { + send_error(EINVAL); + break; + } + + /* Don't send a reply until a stop occurs. */ + if (!gdb_step_vcpu(cur_vcpu)) { + send_error(EOPNOTSUPP); + break; + } + break; + case '?': + /* XXX: Only if stopped? */ + /* For now, just report that we are always stopped. */ + start_packet(); + append_char('S'); + append_byte(GDB_SIGNAL_TRAP); + finish_packet(); + break; + case 'G': /* TODO */ + case 'M': /* TODO */ + case 'v': + /* Handle 'vCont' */ + /* 'vCtrlC' */ + case 'p': /* TODO */ + case 'P': /* TODO */ + case 'Q': /* TODO */ + case 't': /* TODO */ + case 'X': /* TODO */ + case 'z': /* TODO */ + case 'Z': /* TODO */ + default: + send_empty_response(); + } +} + +/* Check for a valid packet in the command buffer. */ +static void +check_command(int fd) +{ + uint8_t *head, *hash, *p, sum; + size_t avail, plen; + + for (;;) { + avail = cur_comm.len; + if (avail == 0) + return; + head = io_buffer_head(&cur_comm); + switch (*head) { + case 0x03: + debug("<- Ctrl-C\n"); + io_buffer_consume(&cur_comm, 1); + + gdb_suspend_vcpus(); + break; + case '+': + /* ACK of previous response. */ + debug("<- +\n"); + if (response_pending()) + io_buffer_reset(&cur_resp); + io_buffer_consume(&cur_comm, 1); + if (stop_pending) { + stop_pending = false; + report_stop(); + send_pending_data(fd); + } + break; + case '-': + /* NACK of previous response. */ + debug("<- -\n"); + if (response_pending()) { + cur_resp.len += cur_resp.start; + cur_resp.start = 0; + if (cur_resp.data[0] == '+') + io_buffer_advance(&cur_resp, 1); + debug("-> %.*s\n", (int)cur_resp.len, + io_buffer_head(&cur_resp)); + } + io_buffer_consume(&cur_comm, 1); + send_pending_data(fd); + break; + case '$': + /* Packet. */ + + if (response_pending()) { + warnx("New GDB command while response in " + "progress"); + io_buffer_reset(&cur_resp); + } + + /* Is packet complete? */ + hash = memchr(head, '#', avail); + if (hash == NULL) + return; + plen = (hash - head + 1) + 2; + if (avail < plen) + return; + debug("<- %.*s\n", (int)plen, head); + + /* Verify checksum. */ + for (sum = 0, p = head + 1; p < hash; p++) + sum += *p; + if (sum != parse_byte(hash + 1)) { + io_buffer_consume(&cur_comm, plen); + debug("-> -\n"); + send_char('-'); + send_pending_data(fd); + break; + } + send_char('+'); + + handle_command(head + 1, hash - (head + 1)); + io_buffer_consume(&cur_comm, plen); + if (!response_pending()) { + debug("-> +\n"); + } + send_pending_data(fd); + break; + default: + /* XXX: Possibly drop connection instead. */ + debug("-> %02x\n", *head); + io_buffer_consume(&cur_comm, 1); + break; + } + } +} + +static void +gdb_readable(int fd, enum ev_type event, void *arg) +{ + ssize_t nread; + int pending; + + if (ioctl(fd, FIONREAD, &pending) == -1) { + warn("FIONREAD on GDB socket"); + return; + } + + /* + * 'pending' might be zero due to EOF. We need to call read + * with a non-zero length to detect EOF. + */ + if (pending == 0) + pending = 1; + + /* Ensure there is room in the command buffer. */ + io_buffer_grow(&cur_comm, pending); + assert(io_buffer_avail(&cur_comm) >= pending); + + nread = read(fd, io_buffer_tail(&cur_comm), io_buffer_avail(&cur_comm)); + if (nread == 0) { + close_connection(); + } else if (nread == -1) { + if (errno == EAGAIN) + return; + + warn("Read from GDB socket"); + close_connection(); + } else { + cur_comm.len += nread; + pthread_mutex_lock(&gdb_lock); + check_command(fd); + pthread_mutex_unlock(&gdb_lock); + } +} + +static void +gdb_writable(int fd, enum ev_type event, void *arg) +{ + + send_pending_data(fd); +} + +static void +new_connection(int fd, enum ev_type event, void *arg) +{ + int optval, s; + + s = accept4(fd, NULL, NULL, SOCK_NONBLOCK); + if (s == -1) { + if (arg != NULL) + err(1, "Failed accepting initial GDB connection"); + + /* Silently ignore errors post-startup. */ + return; + } + + optval = 1; + if (setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)) == + -1) { + warn("Failed to disable SIGPIPE for GDB connection"); + close(s); + return; + } + + pthread_mutex_lock(&gdb_lock); + if (cur_fd != -1) { + close(s); + warnx("Ignoring additional GDB connection."); + } + + read_event = mevent_add(s, EVF_READ, gdb_readable, NULL); + if (read_event == NULL) { + if (arg != NULL) + err(1, "Failed to setup initial GDB connection"); + pthread_mutex_unlock(&gdb_lock); + return; + } + write_event = mevent_add(s, EVF_WRITE, gdb_writable, NULL); + if (write_event == NULL) { + if (arg != NULL) + err(1, "Failed to setup initial GDB connection"); + mevent_delete_close(read_event); + read_event = NULL; + } + + cur_fd = s; + cur_vcpu = 0; + stepping_vcpu = -1; + stopped_vcpu = -1; + stop_pending = false; + + /* Break on attach. */ + first_stop = true; + gdb_suspend_vcpus(); + pthread_mutex_unlock(&gdb_lock); +} + +#ifndef WITHOUT_CAPSICUM +void +limit_gdb_socket(int s) +{ + cap_rights_t rights; + unsigned long ioctls[] = { FIONREAD }; + + cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE, + CAP_SETSOCKOPT, CAP_IOCTL); + if (caph_rights_limit(s, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (caph_ioctls_limit(s, ioctls, nitems(ioctls)) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +} +#endif + +void +init_gdb(struct vmctx *_ctx, int sport, bool wait) +{ + struct sockaddr_in sin; + int error, flags, s; + + debug("==> starting on %d, %swaiting\n", sport, wait ? "" : "not "); + + error = pthread_mutex_init(&gdb_lock, NULL); + if (error != 0) + errc(1, error, "gdb mutex init"); + error = pthread_cond_init(&idle_vcpus, NULL); + if (error != 0) + errc(1, error, "gdb cv init"); + + ctx = _ctx; + s = socket(PF_INET, SOCK_STREAM, 0); + if (s < 0) + err(1, "gdb socket create"); + +#ifdef __FreeBSD__ + sin.sin_len = sizeof(sin); +#endif + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(sport); + + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) + err(1, "gdb socket bind"); + + if (listen(s, 1) < 0) + err(1, "gdb socket listen"); + + if (wait) { + /* + * Set vcpu 0 in vcpus_suspended. This will trigger the + * logic in gdb_cpu_add() to suspend the first vcpu before + * it starts execution. The vcpu will remain suspended + * until a debugger connects. + */ + stepping_vcpu = -1; + stopped_vcpu = -1; + CPU_SET(0, &vcpus_suspended); + } + + flags = fcntl(s, F_GETFL); + if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) + err(1, "Failed to mark gdb socket non-blocking"); + +#ifndef WITHOUT_CAPSICUM + limit_gdb_socket(s); +#endif + mevent_add(s, EVF_READ, new_connection, NULL); +} diff --git a/usr/src/cmd/bhyve/gdb.h b/usr/src/cmd/bhyve/gdb.h new file mode 100644 index 0000000000..fa2184df16 --- /dev/null +++ b/usr/src/cmd/bhyve/gdb.h @@ -0,0 +1,39 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2017 John H. Baldwin <jhb@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef __GDB_H__ +#define __GDB_H__ + +void gdb_cpu_add(int vcpu); +void gdb_cpu_mtrap(int vcpu); +void gdb_cpu_suspend(int vcpu); +void init_gdb(struct vmctx *ctx, int sport, bool wait); + +#endif /* !__GDB_H__ */ diff --git a/usr/src/cmd/bhyve/inout.c b/usr/src/cmd/bhyve/inout.c new file mode 100644 index 0000000000..b460ee2988 --- /dev/null +++ b/usr/src/cmd/bhyve/inout.c @@ -0,0 +1,299 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/linker_set.h> +#include <sys/_iovec.h> +#include <sys/mman.h> + +#include <x86/psl.h> +#include <x86/segments.h> + +#include <machine/vmm.h> +#include <machine/vmm_instruction_emul.h> +#include <vmmapi.h> + +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "bhyverun.h" +#include "inout.h" + +SET_DECLARE(inout_port_set, struct inout_port); + +#define MAX_IOPORTS (1 << 16) + +#define VERIFY_IOPORT(port, size) \ + assert((port) >= 0 && (size) > 0 && ((port) + (size)) <= MAX_IOPORTS) + +static struct { + const char *name; + int flags; + inout_func_t handler; + void *arg; +} inout_handlers[MAX_IOPORTS]; + +static int +default_inout(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + if (in) { + switch (bytes) { + case 4: + *eax = 0xffffffff; + break; + case 2: + *eax = 0xffff; + break; + case 1: + *eax = 0xff; + break; + } + } + + return (0); +} + +static void +register_default_iohandler(int start, int size) +{ + struct inout_port iop; + + VERIFY_IOPORT(start, size); + + bzero(&iop, sizeof(iop)); + iop.name = "default"; + iop.port = start; + iop.size = size; + iop.flags = IOPORT_F_INOUT | IOPORT_F_DEFAULT; + iop.handler = default_inout; + + register_inout(&iop); +} + +int +emulate_inout(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit, int strict) +{ + int addrsize, bytes, flags, in, port, prot, rep; + uint32_t eax, val; + inout_func_t handler; + void *arg; + int error, fault, retval; + enum vm_reg_name idxreg; + uint64_t gla, index, iterations, count; + struct vm_inout_str *vis; + struct iovec iov[2]; + + bytes = vmexit->u.inout.bytes; + in = vmexit->u.inout.in; + port = vmexit->u.inout.port; + + assert(port < MAX_IOPORTS); + assert(bytes == 1 || bytes == 2 || bytes == 4); + + handler = inout_handlers[port].handler; + + if (strict && handler == default_inout) + return (-1); + + flags = inout_handlers[port].flags; + arg = inout_handlers[port].arg; + + if (in) { + if (!(flags & IOPORT_F_IN)) + return (-1); + } else { + if (!(flags & IOPORT_F_OUT)) + return (-1); + } + + retval = 0; + if (vmexit->u.inout.string) { + vis = &vmexit->u.inout_str; + rep = vis->inout.rep; + addrsize = vis->addrsize; + prot = in ? PROT_WRITE : PROT_READ; + assert(addrsize == 2 || addrsize == 4 || addrsize == 8); + + /* Index register */ + idxreg = in ? VM_REG_GUEST_RDI : VM_REG_GUEST_RSI; + index = vis->index & vie_size2mask(addrsize); + + /* Count register */ + count = vis->count & vie_size2mask(addrsize); + + /* Limit number of back-to-back in/out emulations to 16 */ + iterations = MIN(count, 16); + while (iterations > 0) { + assert(retval == 0); + if (vie_calculate_gla(vis->paging.cpu_mode, + vis->seg_name, &vis->seg_desc, index, bytes, + addrsize, prot, &gla)) { + vm_inject_gp(ctx, vcpu); + break; + } + + error = vm_copy_setup(ctx, vcpu, &vis->paging, gla, + bytes, prot, iov, nitems(iov), &fault); + if (error) { + retval = -1; /* Unrecoverable error */ + break; + } else if (fault) { + retval = 0; /* Resume guest to handle fault */ + break; + } + + if (vie_alignment_check(vis->paging.cpl, bytes, + vis->cr0, vis->rflags, gla)) { + vm_inject_ac(ctx, vcpu, 0); + break; + } + + val = 0; + if (!in) + vm_copyin(ctx, vcpu, iov, &val, bytes); + + retval = handler(ctx, vcpu, in, port, bytes, &val, arg); + if (retval != 0) + break; + + if (in) + vm_copyout(ctx, vcpu, &val, iov, bytes); + + /* Update index */ + if (vis->rflags & PSL_D) + index -= bytes; + else + index += bytes; + + count--; + iterations--; + } + + /* Update index register */ + error = vie_update_register(ctx, vcpu, idxreg, index, addrsize); + assert(error == 0); + + /* + * Update count register only if the instruction had a repeat + * prefix. + */ + if (rep) { + error = vie_update_register(ctx, vcpu, VM_REG_GUEST_RCX, + count, addrsize); + assert(error == 0); + } + + /* Restart the instruction if more iterations remain */ + if (retval == 0 && count != 0) { + error = vm_restart_instruction(ctx, vcpu); + assert(error == 0); + } + } else { + eax = vmexit->u.inout.eax; + val = eax & vie_size2mask(bytes); + retval = handler(ctx, vcpu, in, port, bytes, &val, arg); + if (retval == 0 && in) { + eax &= ~vie_size2mask(bytes); + eax |= val & vie_size2mask(bytes); + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, + eax); + assert(error == 0); + } + } + return (retval); +} + +void +init_inout(void) +{ + struct inout_port **iopp, *iop; + + /* + * Set up the default handler for all ports + */ + register_default_iohandler(0, MAX_IOPORTS); + + /* + * Overwrite with specified handlers + */ + SET_FOREACH(iopp, inout_port_set) { + iop = *iopp; + assert(iop->port < MAX_IOPORTS); + inout_handlers[iop->port].name = iop->name; + inout_handlers[iop->port].flags = iop->flags; + inout_handlers[iop->port].handler = iop->handler; + inout_handlers[iop->port].arg = NULL; + } +} + +int +register_inout(struct inout_port *iop) +{ + int i; + + VERIFY_IOPORT(iop->port, iop->size); + + /* + * Verify that the new registration is not overwriting an already + * allocated i/o range. + */ + if ((iop->flags & IOPORT_F_DEFAULT) == 0) { + for (i = iop->port; i < iop->port + iop->size; i++) { + if ((inout_handlers[i].flags & IOPORT_F_DEFAULT) == 0) + return (-1); + } + } + + for (i = iop->port; i < iop->port + iop->size; i++) { + inout_handlers[i].name = iop->name; + inout_handlers[i].flags = iop->flags; + inout_handlers[i].handler = iop->handler; + inout_handlers[i].arg = iop->arg; + } + + return (0); +} + +int +unregister_inout(struct inout_port *iop) +{ + + VERIFY_IOPORT(iop->port, iop->size); + assert(inout_handlers[iop->port].name == iop->name); + + register_default_iohandler(iop->port, iop->size); + + return (0); +} diff --git a/usr/src/cmd/bhyve/inout.h b/usr/src/cmd/bhyve/inout.h new file mode 100644 index 0000000000..b72ee5d93e --- /dev/null +++ b/usr/src/cmd/bhyve/inout.h @@ -0,0 +1,93 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2014 Pluribus Networks Inc. + */ + +#ifndef _INOUT_H_ +#define _INOUT_H_ + +#include <sys/linker_set.h> + +struct vmctx; +struct vm_exit; + +/* + * inout emulation handlers return 0 on success and -1 on failure. + */ +typedef int (*inout_func_t)(struct vmctx *ctx, int vcpu, int in, int port, + int bytes, uint32_t *eax, void *arg); + +struct inout_port { + const char *name; + int port; + int size; + int flags; + inout_func_t handler; + void *arg; +}; +#define IOPORT_F_IN 0x1 +#define IOPORT_F_OUT 0x2 +#define IOPORT_F_INOUT (IOPORT_F_IN | IOPORT_F_OUT) + +/* + * The following flags are used internally and must not be used by + * device models. + */ +#define IOPORT_F_DEFAULT 0x80000000 /* claimed by default handler */ + +#define INOUT_PORT(name, port, flags, handler) \ + static struct inout_port __CONCAT(__inout_port, __LINE__) = { \ + #name, \ + (port), \ + 1, \ + (flags), \ + (handler), \ + 0 \ + }; \ + DATA_SET(inout_port_set, __CONCAT(__inout_port, __LINE__)) + +void init_inout(void); +int emulate_inout(struct vmctx *, int vcpu, struct vm_exit *vmexit, + int strict); +int register_inout(struct inout_port *iop); +int unregister_inout(struct inout_port *iop); +void init_bvmcons(void); + +#endif /* _INOUT_H_ */ diff --git a/usr/src/cmd/bhyve/ioapic.c b/usr/src/cmd/bhyve/ioapic.c new file mode 100644 index 0000000000..acdbb5111b --- /dev/null +++ b/usr/src/cmd/bhyve/ioapic.c @@ -0,0 +1,83 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Hudson River Trading LLC + * Written by: John H. Baldwin <jhb@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <stdio.h> + +#include <machine/vmm.h> +#include <vmmapi.h> + +#include "ioapic.h" +#include "pci_emul.h" +#include "pci_lpc.h" + +/* + * Assign PCI INTx interrupts to I/O APIC pins in a round-robin + * fashion. Note that we have no idea what the HPET is using, but the + * HPET is also programmable whereas this is intended for hardwired + * PCI interrupts. + * + * This assumes a single I/O APIC where pins >= 16 are permitted for + * PCI devices. + */ +static int pci_pins; + +void +ioapic_init(struct vmctx *ctx) +{ + + if (vm_ioapic_pincount(ctx, &pci_pins) < 0) { + pci_pins = 0; + return; + } + + /* Ignore the first 16 pins. */ + if (pci_pins <= 16) { + pci_pins = 0; + return; + } + pci_pins -= 16; +} + +int +ioapic_pci_alloc_irq(struct pci_devinst *pi) +{ + static int last_pin; + + if (pci_pins == 0) + return (-1); + if (lpc_bootrom()) { + /* For external bootrom use fixed mapping. */ + return (16 + (4 + pi->pi_slot + pi->pi_lintr.pin) % 8); + } + return (16 + (last_pin++ % pci_pins)); +} diff --git a/usr/src/cmd/bhyve/ioapic.h b/usr/src/cmd/bhyve/ioapic.h new file mode 100644 index 0000000000..3a7fa76192 --- /dev/null +++ b/usr/src/cmd/bhyve/ioapic.h @@ -0,0 +1,43 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Hudson River Trading LLC + * Written by: John H. Baldwin <jhb@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _IOAPIC_H_ +#define _IOAPIC_H_ + +struct pci_devinst; + +/* + * Allocate a PCI IRQ from the I/O APIC. + */ +void ioapic_init(struct vmctx *ctx); +int ioapic_pci_alloc_irq(struct pci_devinst *pi); + +#endif diff --git a/usr/src/cmd/bhyve/iov.c b/usr/src/cmd/bhyve/iov.c new file mode 100644 index 0000000000..54ea22aa94 --- /dev/null +++ b/usr/src/cmd/bhyve/iov.c @@ -0,0 +1,148 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2016 Jakub Klama <jceel@FreeBSD.org>. + * Copyright (c) 2018 Alexander Motin <mav@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/uio.h> + +#include <stdlib.h> +#include <string.h> +#include "iov.h" + +void +seek_iov(const struct iovec *iov1, int niov1, struct iovec *iov2, int *niov2, + size_t seek) +{ + size_t remainder = 0; + size_t left = seek; + int i, j; + + for (i = 0; i < niov1; i++) { + size_t toseek = MIN(left, iov1[i].iov_len); + left -= toseek; + + if (toseek == iov1[i].iov_len) + continue; + + if (left == 0) { + remainder = toseek; + break; + } + } + + for (j = i; j < niov1; j++) { + iov2[j - i].iov_base = (char *)iov1[j].iov_base + remainder; + iov2[j - i].iov_len = iov1[j].iov_len - remainder; + remainder = 0; + } + + *niov2 = j - i; +} + +size_t +count_iov(const struct iovec *iov, int niov) +{ + size_t total = 0; + int i; + + for (i = 0; i < niov; i++) + total += iov[i].iov_len; + + return (total); +} + +void +truncate_iov(struct iovec *iov, int *niov, size_t length) +{ + size_t done = 0; + int i; + + for (i = 0; i < *niov; i++) { + size_t toseek = MIN(length - done, iov[i].iov_len); + done += toseek; + + if (toseek <= iov[i].iov_len) { + iov[i].iov_len = toseek; + *niov = i + 1; + return; + } + } +} + +ssize_t +iov_to_buf(const struct iovec *iov, int niov, void **buf) +{ + size_t ptr, total; + int i; + + total = count_iov(iov, niov); + *buf = realloc(*buf, total); + if (*buf == NULL) + return (-1); + + for (i = 0, ptr = 0; i < niov; i++) { + memcpy(*buf + ptr, iov[i].iov_base, iov[i].iov_len); + ptr += iov[i].iov_len; + } + + return (total); +} + +ssize_t +buf_to_iov(const void *buf, size_t buflen, struct iovec *iov, int niov, + size_t seek) +{ + struct iovec *diov; + int ndiov, i; + size_t off = 0, len; + + if (seek > 0) { + diov = malloc(sizeof(struct iovec) * niov); + seek_iov(iov, niov, diov, &ndiov, seek); + } else { + diov = iov; + ndiov = niov; + } + + for (i = 0; i < ndiov && off < buflen; i++) { + len = MIN(diov[i].iov_len, buflen - off); + memcpy(diov[i].iov_base, buf + off, len); + off += len; + } + + if (seek > 0) + free(diov); + + return ((ssize_t)off); +} + diff --git a/usr/src/cmd/bhyve/iov.h b/usr/src/cmd/bhyve/iov.h new file mode 100644 index 0000000000..e3b5916edb --- /dev/null +++ b/usr/src/cmd/bhyve/iov.h @@ -0,0 +1,44 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2016 Jakub Klama <jceel@FreeBSD.org>. + * Copyright (c) 2018 Alexander Motin <mav@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _IOV_H_ +#define _IOV_H_ + +void seek_iov(const struct iovec *iov1, int niov1, struct iovec *iov2, + int *niov2, size_t seek); +void truncate_iov(struct iovec *iov, int *niov, size_t length); +size_t count_iov(const struct iovec *iov, int niov); +ssize_t iov_to_buf(const struct iovec *iov, int niov, void **buf); +ssize_t buf_to_iov(const void *buf, size_t buflen, struct iovec *iov, int niov, + size_t seek); + +#endif /* _IOV_H_ */ diff --git a/usr/src/cmd/bhyve/mem.c b/usr/src/cmd/bhyve/mem.c new file mode 100644 index 0000000000..85e56af10b --- /dev/null +++ b/usr/src/cmd/bhyve/mem.c @@ -0,0 +1,361 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +/* + * Memory ranges are represented with an RB tree. On insertion, the range + * is checked for overlaps. On lookup, the key has the same base and limit + * so it can be searched within the range. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/tree.h> +#include <machine/vmm.h> +#include <machine/vmm_instruction_emul.h> + +#include <assert.h> +#include <err.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +#include "mem.h" + +struct mmio_rb_range { + RB_ENTRY(mmio_rb_range) mr_link; /* RB tree links */ + struct mem_range mr_param; + uint64_t mr_base; + uint64_t mr_end; +}; + +struct mmio_rb_tree; +RB_PROTOTYPE(mmio_rb_tree, mmio_rb_range, mr_link, mmio_rb_range_compare); + +RB_HEAD(mmio_rb_tree, mmio_rb_range) mmio_rb_root, mmio_rb_fallback; + +/* + * Per-vCPU cache. Since most accesses from a vCPU will be to + * consecutive addresses in a range, it makes sense to cache the + * result of a lookup. + */ +static struct mmio_rb_range *mmio_hint[VM_MAXCPU]; + +static pthread_rwlock_t mmio_rwlock; + +static int +mmio_rb_range_compare(struct mmio_rb_range *a, struct mmio_rb_range *b) +{ + if (a->mr_end < b->mr_base) + return (-1); + else if (a->mr_base > b->mr_end) + return (1); + return (0); +} + +static int +mmio_rb_lookup(struct mmio_rb_tree *rbt, uint64_t addr, + struct mmio_rb_range **entry) +{ + struct mmio_rb_range find, *res; + + find.mr_base = find.mr_end = addr; + + res = RB_FIND(mmio_rb_tree, rbt, &find); + + if (res != NULL) { + *entry = res; + return (0); + } + + return (ENOENT); +} + +static int +mmio_rb_add(struct mmio_rb_tree *rbt, struct mmio_rb_range *new) +{ + struct mmio_rb_range *overlap; + + overlap = RB_INSERT(mmio_rb_tree, rbt, new); + + if (overlap != NULL) { +#ifdef RB_DEBUG + printf("overlap detected: new %lx:%lx, tree %lx:%lx\n", + new->mr_base, new->mr_end, + overlap->mr_base, overlap->mr_end); +#endif + + return (EEXIST); + } + + return (0); +} + +#if 0 +static void +mmio_rb_dump(struct mmio_rb_tree *rbt) +{ + int perror; + struct mmio_rb_range *np; + + pthread_rwlock_rdlock(&mmio_rwlock); + RB_FOREACH(np, mmio_rb_tree, rbt) { + printf(" %lx:%lx, %s\n", np->mr_base, np->mr_end, + np->mr_param.name); + } + perror = pthread_rwlock_unlock(&mmio_rwlock); + assert(perror == 0); +} +#endif + +RB_GENERATE(mmio_rb_tree, mmio_rb_range, mr_link, mmio_rb_range_compare); + +typedef int (mem_cb_t)(struct vmctx *ctx, int vcpu, uint64_t gpa, + struct mem_range *mr, void *arg); + +static int +mem_read(void *ctx, int vcpu, uint64_t gpa, uint64_t *rval, int size, void *arg) +{ + int error; + struct mem_range *mr = arg; + + error = (*mr->handler)(ctx, vcpu, MEM_F_READ, gpa, size, + rval, mr->arg1, mr->arg2); + return (error); +} + +static int +mem_write(void *ctx, int vcpu, uint64_t gpa, uint64_t wval, int size, void *arg) +{ + int error; + struct mem_range *mr = arg; + + error = (*mr->handler)(ctx, vcpu, MEM_F_WRITE, gpa, size, + &wval, mr->arg1, mr->arg2); + return (error); +} + +static int +access_memory(struct vmctx *ctx, int vcpu, uint64_t paddr, mem_cb_t *cb, + void *arg) +{ + struct mmio_rb_range *entry; + int err, perror, immutable; + + pthread_rwlock_rdlock(&mmio_rwlock); + /* + * First check the per-vCPU cache + */ + if (mmio_hint[vcpu] && + paddr >= mmio_hint[vcpu]->mr_base && + paddr <= mmio_hint[vcpu]->mr_end) { + entry = mmio_hint[vcpu]; + } else + entry = NULL; + + if (entry == NULL) { + if (mmio_rb_lookup(&mmio_rb_root, paddr, &entry) == 0) { + /* Update the per-vCPU cache */ + mmio_hint[vcpu] = entry; + } else if (mmio_rb_lookup(&mmio_rb_fallback, paddr, &entry)) { + perror = pthread_rwlock_unlock(&mmio_rwlock); + assert(perror == 0); + return (ESRCH); + } + } + + assert(entry != NULL); + + /* + * An 'immutable' memory range is guaranteed to be never removed + * so there is no need to hold 'mmio_rwlock' while calling the + * handler. + * + * XXX writes to the PCIR_COMMAND register can cause register_mem() + * to be called. If the guest is using PCI extended config space + * to modify the PCIR_COMMAND register then register_mem() can + * deadlock on 'mmio_rwlock'. However by registering the extended + * config space window as 'immutable' the deadlock can be avoided. + */ + immutable = (entry->mr_param.flags & MEM_F_IMMUTABLE); + if (immutable) { + perror = pthread_rwlock_unlock(&mmio_rwlock); + assert(perror == 0); + } + + err = cb(ctx, vcpu, paddr, &entry->mr_param, arg); + + if (!immutable) { + perror = pthread_rwlock_unlock(&mmio_rwlock); + assert(perror == 0); + } + + + return (err); +} + +struct emulate_mem_args { + struct vie *vie; + struct vm_guest_paging *paging; +}; + +static int +emulate_mem_cb(struct vmctx *ctx, int vcpu, uint64_t paddr, struct mem_range *mr, + void *arg) +{ + struct emulate_mem_args *ema; + + ema = arg; + return (vmm_emulate_instruction(ctx, vcpu, paddr, ema->vie, ema->paging, + mem_read, mem_write, mr)); +} + +int +emulate_mem(struct vmctx *ctx, int vcpu, uint64_t paddr, struct vie *vie, + struct vm_guest_paging *paging) + +{ + struct emulate_mem_args ema; + + ema.vie = vie; + ema.paging = paging; + return (access_memory(ctx, vcpu, paddr, emulate_mem_cb, &ema)); +} + +struct read_mem_args { + uint64_t *rval; + int size; +}; + +static int +read_mem_cb(struct vmctx *ctx, int vcpu, uint64_t paddr, struct mem_range *mr, + void *arg) +{ + struct read_mem_args *rma; + + rma = arg; + return (mr->handler(ctx, vcpu, MEM_F_READ, paddr, rma->size, + rma->rval, mr->arg1, mr->arg2)); +} + +int +read_mem(struct vmctx *ctx, int vcpu, uint64_t gpa, uint64_t *rval, int size) +{ + struct read_mem_args rma; + + rma.rval = rval; + rma.size = size; + return (access_memory(ctx, vcpu, gpa, read_mem_cb, &rma)); +} + +static int +register_mem_int(struct mmio_rb_tree *rbt, struct mem_range *memp) +{ + struct mmio_rb_range *entry, *mrp; + int err, perror; + + err = 0; + + mrp = malloc(sizeof(struct mmio_rb_range)); + if (mrp == NULL) { + warn("%s: couldn't allocate memory for mrp\n", + __func__); + err = ENOMEM; + } else { + mrp->mr_param = *memp; + mrp->mr_base = memp->base; + mrp->mr_end = memp->base + memp->size - 1; + pthread_rwlock_wrlock(&mmio_rwlock); + if (mmio_rb_lookup(rbt, memp->base, &entry) != 0) + err = mmio_rb_add(rbt, mrp); + perror = pthread_rwlock_unlock(&mmio_rwlock); + assert(perror == 0); + if (err) + free(mrp); + } + + return (err); +} + +int +register_mem(struct mem_range *memp) +{ + + return (register_mem_int(&mmio_rb_root, memp)); +} + +int +register_mem_fallback(struct mem_range *memp) +{ + + return (register_mem_int(&mmio_rb_fallback, memp)); +} + +int +unregister_mem(struct mem_range *memp) +{ + struct mem_range *mr; + struct mmio_rb_range *entry = NULL; + int err, perror, i; + + pthread_rwlock_wrlock(&mmio_rwlock); + err = mmio_rb_lookup(&mmio_rb_root, memp->base, &entry); + if (err == 0) { + mr = &entry->mr_param; + assert(mr->name == memp->name); + assert(mr->base == memp->base && mr->size == memp->size); + assert((mr->flags & MEM_F_IMMUTABLE) == 0); + RB_REMOVE(mmio_rb_tree, &mmio_rb_root, entry); + + /* flush Per-vCPU cache */ + for (i=0; i < VM_MAXCPU; i++) { + if (mmio_hint[i] == entry) + mmio_hint[i] = NULL; + } + } + perror = pthread_rwlock_unlock(&mmio_rwlock); + assert(perror == 0); + + if (entry) + free(entry); + + return (err); +} + +void +init_mem(void) +{ + + RB_INIT(&mmio_rb_root); + RB_INIT(&mmio_rb_fallback); + pthread_rwlock_init(&mmio_rwlock, NULL); +} diff --git a/usr/src/cmd/bhyve/mem.h b/usr/src/cmd/bhyve/mem.h new file mode 100644 index 0000000000..596c0b0cf3 --- /dev/null +++ b/usr/src/cmd/bhyve/mem.h @@ -0,0 +1,65 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _MEM_H_ +#define _MEM_H_ + +#include <sys/linker_set.h> + +struct vmctx; + +typedef int (*mem_func_t)(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, + int size, uint64_t *val, void *arg1, long arg2); + +struct mem_range { + const char *name; + int flags; + mem_func_t handler; + void *arg1; + long arg2; + uint64_t base; + uint64_t size; +}; +#define MEM_F_READ 0x1 +#define MEM_F_WRITE 0x2 +#define MEM_F_RW 0x3 +#define MEM_F_IMMUTABLE 0x4 /* mem_range cannot be unregistered */ + +void init_mem(void); +int emulate_mem(struct vmctx *, int vcpu, uint64_t paddr, struct vie *vie, + struct vm_guest_paging *paging); + +int read_mem(struct vmctx *ctx, int vcpu, uint64_t gpa, uint64_t *rval, + int size); +int register_mem(struct mem_range *memp); +int register_mem_fallback(struct mem_range *memp); +int unregister_mem(struct mem_range *memp); + +#endif /* _MEM_H_ */ diff --git a/usr/src/cmd/bhyve/mevent.c b/usr/src/cmd/bhyve/mevent.c new file mode 100644 index 0000000000..a258fd3047 --- /dev/null +++ b/usr/src/cmd/bhyve/mevent.c @@ -0,0 +1,680 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +/* + * Micro event library for FreeBSD, designed for a single i/o thread + * using kqueue, and having events be persistent by default. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <assert.h> +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <err.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sysexits.h> +#include <unistd.h> + +#include <sys/types.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#ifdef __FreeBSD__ +#include <sys/event.h> +#else +#include <port.h> +#include <sys/poll.h> +#include <sys/siginfo.h> +#include <sys/queue.h> +#endif +#include <sys/time.h> + +#include <pthread.h> +#include <pthread_np.h> + +#include "mevent.h" + +#define MEVENT_MAX 64 + +#define MEV_ADD 1 +#define MEV_ENABLE 2 +#define MEV_DISABLE 3 +#define MEV_DEL_PENDING 4 + +extern char *vmname; + +static pthread_t mevent_tid; +static int mevent_timid = 43; +static int mevent_pipefd[2]; +static pthread_mutex_t mevent_lmutex = PTHREAD_MUTEX_INITIALIZER; + +struct mevent { + void (*me_func)(int, enum ev_type, void *); +#define me_msecs me_fd + int me_fd; +#ifdef __FreeBSD__ + int me_timid; +#else + timer_t me_timid; +#endif + enum ev_type me_type; + void *me_param; + int me_cq; + int me_state; + int me_closefd; +#ifndef __FreeBSD__ + port_notify_t me_notify; + struct sigevent me_sigev; + boolean_t me_auto_requeue; +#endif + LIST_ENTRY(mevent) me_list; +}; + +static LIST_HEAD(listhead, mevent) global_head, change_head; + +static void +mevent_qlock(void) +{ + pthread_mutex_lock(&mevent_lmutex); +} + +static void +mevent_qunlock(void) +{ + pthread_mutex_unlock(&mevent_lmutex); +} + +static void +mevent_pipe_read(int fd, enum ev_type type, void *param) +{ + char buf[MEVENT_MAX]; + int status; + + /* + * Drain the pipe read side. The fd is non-blocking so this is + * safe to do. + */ + do { + status = read(fd, buf, sizeof(buf)); + } while (status == MEVENT_MAX); +} + +static void +mevent_notify(void) +{ + char c; + + /* + * If calling from outside the i/o thread, write a byte on the + * pipe to force the i/o thread to exit the blocking kevent call. + */ + if (mevent_pipefd[1] != 0 && pthread_self() != mevent_tid) { + write(mevent_pipefd[1], &c, 1); + } +} +#ifdef __FreeBSD__ +static int +mevent_kq_filter(struct mevent *mevp) +{ + int retval; + + retval = 0; + + if (mevp->me_type == EVF_READ) + retval = EVFILT_READ; + + if (mevp->me_type == EVF_WRITE) + retval = EVFILT_WRITE; + + if (mevp->me_type == EVF_TIMER) + retval = EVFILT_TIMER; + + if (mevp->me_type == EVF_SIGNAL) + retval = EVFILT_SIGNAL; + + return (retval); +} + +static int +mevent_kq_flags(struct mevent *mevp) +{ + int ret; + + switch (mevp->me_state) { + case MEV_ADD: + ret = EV_ADD; /* implicitly enabled */ + break; + case MEV_ENABLE: + ret = EV_ENABLE; + break; + case MEV_DISABLE: + ret = EV_DISABLE; + break; + case MEV_DEL_PENDING: + ret = EV_DELETE; + break; + default: + assert(0); + break; + } + + return (ret); +} + +static int +mevent_kq_fflags(struct mevent *mevp) +{ + /* XXX nothing yet, perhaps EV_EOF for reads ? */ + return (0); +} + +static int +mevent_build(int mfd, struct kevent *kev) +{ + struct mevent *mevp, *tmpp; + int i; + + i = 0; + + mevent_qlock(); + + LIST_FOREACH_SAFE(mevp, &change_head, me_list, tmpp) { + if (mevp->me_closefd) { + /* + * A close of the file descriptor will remove the + * event + */ + close(mevp->me_fd); + } else { + if (mevp->me_type == EVF_TIMER) { + kev[i].ident = mevp->me_timid; + kev[i].data = mevp->me_msecs; + } else { + kev[i].ident = mevp->me_fd; + kev[i].data = 0; + } + kev[i].filter = mevent_kq_filter(mevp); + kev[i].flags = mevent_kq_flags(mevp); + kev[i].fflags = mevent_kq_fflags(mevp); + kev[i].udata = mevp; + i++; + } + + mevp->me_cq = 0; + LIST_REMOVE(mevp, me_list); + + if (mevp->me_state == MEV_DEL_PENDING) { + free(mevp); + } else { + LIST_INSERT_HEAD(&global_head, mevp, me_list); + } + + assert(i < MEVENT_MAX); + } + + mevent_qunlock(); + + return (i); +} + +static void +mevent_handle(struct kevent *kev, int numev) +{ + struct mevent *mevp; + int i; + + for (i = 0; i < numev; i++) { + mevp = kev[i].udata; + + /* XXX check for EV_ERROR ? */ + + (*mevp->me_func)(mevp->me_fd, mevp->me_type, mevp->me_param); + } +} + +#else /* __FreeBSD__ */ + +static void +mevent_update_one(struct mevent *mevp) +{ + int portfd = mevp->me_notify.portnfy_port; + + switch (mevp->me_type) { + case EVF_READ: + case EVF_WRITE: + mevp->me_auto_requeue = B_FALSE; + + switch (mevp->me_state) { + case MEV_ADD: + case MEV_ENABLE: + { + int events; + + events = (mevp->me_type == EVF_READ) ? POLLIN : POLLOUT; + + if (port_associate(portfd, PORT_SOURCE_FD, mevp->me_fd, + events, mevp) != 0) { + (void) fprintf(stderr, + "port_associate fd %d %p failed: %s\n", + mevp->me_fd, mevp, strerror(errno)); + } + return; + } + case MEV_DISABLE: + case MEV_DEL_PENDING: + /* + * A disable that comes in while an event is being + * handled will result in an ENOENT. + */ + if (port_dissociate(portfd, PORT_SOURCE_FD, + mevp->me_fd) != 0 && errno != ENOENT) { + (void) fprintf(stderr, "port_dissociate " + "portfd %d fd %d mevp %p failed: %s\n", + portfd, mevp->me_fd, mevp, strerror(errno)); + } + return; + default: + goto abort; + } + + case EVF_TIMER: + mevp->me_auto_requeue = B_TRUE; + + switch (mevp->me_state) { + case MEV_ADD: + case MEV_ENABLE: + { + struct itimerspec it = { 0 }; + + mevp->me_sigev.sigev_notify = SIGEV_PORT; + mevp->me_sigev.sigev_value.sival_ptr = &mevp->me_notify; + + if (timer_create(CLOCK_REALTIME, &mevp->me_sigev, + &mevp->me_timid) != 0) { + (void) fprintf(stderr, + "timer_create failed: %s", strerror(errno)); + return; + } + + /* The first timeout */ + it.it_value.tv_sec = mevp->me_msecs / MILLISEC; + it.it_value.tv_nsec = + MSEC2NSEC(mevp->me_msecs % MILLISEC); + /* Repeat at the same interval */ + it.it_interval = it.it_value; + + if (timer_settime(mevp->me_timid, 0, &it, NULL) != 0) { + (void) fprintf(stderr, "timer_settime failed: " + "%s", strerror(errno)); + } + return; + } + case MEV_DISABLE: + case MEV_DEL_PENDING: + if (timer_delete(mevp->me_timid) != 0) { + (void) fprintf(stderr, "timer_delete failed: " + "%s", strerror(errno)); + } + return; + default: + goto abort; + } + default: + /* EVF_SIGNAL not yet implemented. */ + goto abort; + } + +abort: + (void) fprintf(stderr, "%s: unhandled type %d state %d\n", __func__, + mevp->me_type, mevp->me_state); + abort(); +} + +static void +mevent_update_pending(int portfd) +{ + struct mevent *mevp, *tmpp; + + mevent_qlock(); + + LIST_FOREACH_SAFE(mevp, &change_head, me_list, tmpp) { + mevp->me_notify.portnfy_port = portfd; + mevp->me_notify.portnfy_user = mevp; + if (mevp->me_closefd) { + /* + * A close of the file descriptor will remove the + * event + */ + (void) close(mevp->me_fd); + mevp->me_fd = -1; + } else { + mevent_update_one(mevp); + } + + mevp->me_cq = 0; + LIST_REMOVE(mevp, me_list); + + if (mevp->me_state == MEV_DEL_PENDING) { + free(mevp); + } else { + LIST_INSERT_HEAD(&global_head, mevp, me_list); + } + } + + mevent_qunlock(); +} + +static void +mevent_handle_pe(port_event_t *pe) +{ + struct mevent *mevp = pe->portev_user; + + mevent_qunlock(); + + (*mevp->me_func)(mevp->me_fd, mevp->me_type, mevp->me_param); + + mevent_qlock(); + if (!mevp->me_cq && !mevp->me_auto_requeue) { + mevent_update_one(mevp); + } + mevent_qunlock(); +} +#endif + +struct mevent * +mevent_add(int tfd, enum ev_type type, + void (*func)(int, enum ev_type, void *), void *param) +{ + struct mevent *lp, *mevp; + + if (tfd < 0 || func == NULL) { + return (NULL); + } + + mevp = NULL; + + mevent_qlock(); + + /* + * Verify that the fd/type tuple is not present in any list + */ + LIST_FOREACH(lp, &global_head, me_list) { + if (type != EVF_TIMER && lp->me_fd == tfd && + lp->me_type == type) { + goto exit; + } + } + + LIST_FOREACH(lp, &change_head, me_list) { + if (type != EVF_TIMER && lp->me_fd == tfd && + lp->me_type == type) { + goto exit; + } + } + + /* + * Allocate an entry, populate it, and add it to the change list. + */ + mevp = calloc(1, sizeof(struct mevent)); + if (mevp == NULL) { + goto exit; + } + + if (type == EVF_TIMER) { + mevp->me_msecs = tfd; + mevp->me_timid = mevent_timid++; + } else + mevp->me_fd = tfd; + mevp->me_type = type; + mevp->me_func = func; + mevp->me_param = param; + + LIST_INSERT_HEAD(&change_head, mevp, me_list); + mevp->me_cq = 1; + mevp->me_state = MEV_ADD; + mevent_notify(); + +exit: + mevent_qunlock(); + + return (mevp); +} + +static int +mevent_update(struct mevent *evp, int newstate) +{ + /* + * It's not possible to enable/disable a deleted event + */ + if (evp->me_state == MEV_DEL_PENDING) + return (EINVAL); + + /* + * No update needed if state isn't changing + */ + if (evp->me_state == newstate) + return (0); + + mevent_qlock(); + + evp->me_state = newstate; + + /* + * Place the entry onto the changed list if not already there. + */ + if (evp->me_cq == 0) { + evp->me_cq = 1; + LIST_REMOVE(evp, me_list); + LIST_INSERT_HEAD(&change_head, evp, me_list); + mevent_notify(); + } + + mevent_qunlock(); + + return (0); +} + +int +mevent_enable(struct mevent *evp) +{ + + return (mevent_update(evp, MEV_ENABLE)); +} + +int +mevent_disable(struct mevent *evp) +{ + + return (mevent_update(evp, MEV_DISABLE)); +} + +static int +mevent_delete_event(struct mevent *evp, int closefd) +{ + mevent_qlock(); + + /* + * Place the entry onto the changed list if not already there, and + * mark as to be deleted. + */ + if (evp->me_cq == 0) { + evp->me_cq = 1; + LIST_REMOVE(evp, me_list); + LIST_INSERT_HEAD(&change_head, evp, me_list); + mevent_notify(); + } + evp->me_state = MEV_DEL_PENDING; + + if (closefd) + evp->me_closefd = 1; + + mevent_qunlock(); + + return (0); +} + +int +mevent_delete(struct mevent *evp) +{ + + return (mevent_delete_event(evp, 0)); +} + +int +mevent_delete_close(struct mevent *evp) +{ + + return (mevent_delete_event(evp, 1)); +} + +static void +mevent_set_name(void) +{ + + pthread_set_name_np(mevent_tid, "mevent"); +} + +void +mevent_dispatch(void) +{ +#ifdef __FreeBSD__ + struct kevent changelist[MEVENT_MAX]; + struct kevent eventlist[MEVENT_MAX]; + struct mevent *pipev; + int mfd; + int numev; +#else + struct mevent *pipev; + int portfd; +#endif + int ret; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; +#endif + + mevent_tid = pthread_self(); + mevent_set_name(); + +#ifdef __FreeBSD__ + mfd = kqueue(); + assert(mfd > 0); +#else + portfd = port_create(); + assert(portfd >= 0); +#endif + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_KQUEUE); + if (caph_rights_limit(mfd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + /* + * Open the pipe that will be used for other threads to force + * the blocking kqueue call to exit by writing to it. Set the + * descriptor to non-blocking. + */ + ret = pipe(mevent_pipefd); + if (ret < 0) { + perror("pipe"); + exit(0); + } + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE); + if (caph_rights_limit(mevent_pipefd[0], &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (caph_rights_limit(mevent_pipefd[1], &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + /* + * Add internal event handler for the pipe write fd + */ + pipev = mevent_add(mevent_pipefd[0], EVF_READ, mevent_pipe_read, NULL); + assert(pipev != NULL); + + for (;;) { +#ifdef __FreeBSD__ + /* + * Build changelist if required. + * XXX the changelist can be put into the blocking call + * to eliminate the extra syscall. Currently better for + * debug. + */ + numev = mevent_build(mfd, changelist); + if (numev) { + ret = kevent(mfd, changelist, numev, NULL, 0, NULL); + if (ret == -1) { + perror("Error return from kevent change"); + } + } + + /* + * Block awaiting events + */ + ret = kevent(mfd, NULL, 0, eventlist, MEVENT_MAX, NULL); + if (ret == -1 && errno != EINTR) { + perror("Error return from kevent monitor"); + } + + /* + * Handle reported events + */ + mevent_handle(eventlist, ret); + +#else /* __FreeBSD__ */ + port_event_t pev; + + /* Handle any pending updates */ + mevent_update_pending(portfd); + + /* Block awaiting events */ + ret = port_get(portfd, &pev, NULL); + if (ret != 0 && errno != EINTR) { + perror("Error return from port_get"); + continue; + } + + /* Handle reported event */ + mevent_handle_pe(&pev); +#endif /* __FreeBSD__ */ + } +} diff --git a/usr/src/cmd/bhyve/mevent.h b/usr/src/cmd/bhyve/mevent.h new file mode 100644 index 0000000000..e6b96f0a7c --- /dev/null +++ b/usr/src/cmd/bhyve/mevent.h @@ -0,0 +1,53 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _MEVENT_H_ +#define _MEVENT_H_ + +enum ev_type { + EVF_READ, + EVF_WRITE, + EVF_TIMER, + EVF_SIGNAL +}; + +struct mevent; + +struct mevent *mevent_add(int fd, enum ev_type type, + void (*func)(int, enum ev_type, void *), + void *param); +int mevent_enable(struct mevent *evp); +int mevent_disable(struct mevent *evp); +int mevent_delete(struct mevent *evp); +int mevent_delete_close(struct mevent *evp); + +void mevent_dispatch(void); + +#endif /* _MEVENT_H_ */ diff --git a/usr/src/cmd/bhyve/mevent_test.c b/usr/src/cmd/bhyve/mevent_test.c new file mode 100644 index 0000000000..4da3adb5ae --- /dev/null +++ b/usr/src/cmd/bhyve/mevent_test.c @@ -0,0 +1,282 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +/* + * Test program for the micro event library. Set up a simple TCP echo + * service. + * + * cc mevent_test.c mevent.c -lpthread + */ + +#include <sys/types.h> +#include <sys/stdint.h> +#ifdef __FreeBSD__ +#include <sys/sysctl.h> +#endif +#include <sys/socket.h> +#include <netinet/in.h> +#ifdef __FreeBSD__ +#include <machine/cpufunc.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <unistd.h> + +#include "mevent.h" + +#define TEST_PORT 4321 + +static pthread_mutex_t accept_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t accept_condvar = PTHREAD_COND_INITIALIZER; + +static struct mevent *tevp; + +char *vmname = "test vm"; + + +#define MEVENT_ECHO + +/* Number of timer events to capture */ +#define TEVSZ 4096 +uint64_t tevbuf[TEVSZ]; + +static void +timer_print(void) +{ + uint64_t min, max, diff, sum; +#ifdef __FreeBSD__ + uint64_t tsc_freq; + size_t len; +#endif + int j; + + min = UINT64_MAX; + max = 0; + sum = 0; + +#ifdef __FreeBSD__ + len = sizeof(tsc_freq); + sysctlbyname("machdep.tsc_freq", &tsc_freq, &len, NULL, 0); +#endif + + for (j = 1; j < TEVSZ; j++) { +#ifdef __FreeBSD__ + /* Convert a tsc diff into microseconds */ + diff = (tevbuf[j] - tevbuf[j-1]) * 1000000 / tsc_freq; +#else + diff = (tevbuf[j] - tevbuf[j-1]) / 1000; +#endif + sum += diff; + if (min > diff) + min = diff; + if (max < diff) + max = diff; + } + + printf("timers done: usecs, min %ld, max %ld, mean %ld\n", min, max, + sum/(TEVSZ - 1)); +} + +static void +timer_callback(int fd, enum ev_type type, void *param) +{ + static int i; + + if (i >= TEVSZ) + abort(); + +#ifdef __FreeBSD__ + tevbuf[i++] = rdtsc(); +#else + tevbuf[i++] = gethrtime(); +#endif + + if (i == TEVSZ) { + mevent_delete(tevp); + timer_print(); + } +} + + +#ifdef MEVENT_ECHO +struct esync { + pthread_mutex_t e_mt; + pthread_cond_t e_cond; +}; + +static void +echoer_callback(int fd, enum ev_type type, void *param) +{ + struct esync *sync = param; + + pthread_mutex_lock(&sync->e_mt); + pthread_cond_signal(&sync->e_cond); + pthread_mutex_unlock(&sync->e_mt); +} + +static void * +echoer(void *param) +{ + struct esync sync; + struct mevent *mev; + char buf[128]; + int fd = (int)(uintptr_t) param; + int len; + + pthread_mutex_init(&sync.e_mt, NULL); + pthread_cond_init(&sync.e_cond, NULL); + + pthread_mutex_lock(&sync.e_mt); + + mev = mevent_add(fd, EVF_READ, echoer_callback, &sync); + if (mev == NULL) { + printf("Could not allocate echoer event\n"); + exit(4); + } + + while (!pthread_cond_wait(&sync.e_cond, &sync.e_mt)) { + len = read(fd, buf, sizeof(buf)); + if (len > 0) { + write(fd, buf, len); + write(0, buf, len); + } else { + break; + } + } + + mevent_delete_close(mev); + + pthread_mutex_unlock(&sync.e_mt); + pthread_mutex_destroy(&sync.e_mt); + pthread_cond_destroy(&sync.e_cond); + + return (NULL); +} + +#else + +static void * +echoer(void *param) +{ + char buf[128]; + int fd = (int)(uintptr_t) param; + int len; + + while ((len = read(fd, buf, sizeof(buf))) > 0) { + write(1, buf, len); + } + + return (NULL); +} +#endif /* MEVENT_ECHO */ + +static void +acceptor_callback(int fd, enum ev_type type, void *param) +{ + pthread_mutex_lock(&accept_mutex); + pthread_cond_signal(&accept_condvar); + pthread_mutex_unlock(&accept_mutex); +} + +static void * +acceptor(void *param) +{ + struct sockaddr_in sin; + pthread_t tid; + int news; + int s; + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + perror("cannot create socket"); + exit(4); + } + +#ifdef __FreeBSD__ + sin.sin_len = sizeof(sin); +#endif + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = htons(TEST_PORT); + + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { + perror("cannot bind socket"); + exit(4); + } + + if (listen(s, 1) < 0) { + perror("cannot listen socket"); + exit(4); + } + + (void) mevent_add(s, EVF_READ, acceptor_callback, NULL); + + pthread_mutex_lock(&accept_mutex); + + while (!pthread_cond_wait(&accept_condvar, &accept_mutex)) { + news = accept(s, NULL, NULL); + if (news < 0) { + perror("accept error"); + } else { + static int first = 1; + + if (first) { + /* + * Start a timer + */ + first = 0; + tevp = mevent_add(1, EVF_TIMER, timer_callback, + NULL); + } + + printf("incoming connection, spawning thread\n"); + pthread_create(&tid, NULL, echoer, + (void *)(uintptr_t)news); + } + } + + return (NULL); +} + +int +main() +{ + pthread_t tid; + + pthread_create(&tid, NULL, acceptor, NULL); + + mevent_dispatch(); + return (0); +} diff --git a/usr/src/cmd/bhyve/mptbl.c b/usr/src/cmd/bhyve/mptbl.c new file mode 100644 index 0000000000..e78f88f074 --- /dev/null +++ b/usr/src/cmd/bhyve/mptbl.c @@ -0,0 +1,379 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/errno.h> +#include <x86/mptable.h> + +#include <stdio.h> +#include <string.h> + +#include "acpi.h" +#include "bhyverun.h" +#include "mptbl.h" +#include "pci_emul.h" + +#define MPTABLE_BASE 0xE0000 + +/* floating pointer length + maximum length of configuration table */ +#define MPTABLE_MAX_LENGTH (65536 + 16) + +#define LAPIC_PADDR 0xFEE00000 +#define LAPIC_VERSION 16 + +#define IOAPIC_PADDR 0xFEC00000 +#define IOAPIC_VERSION 0x11 + +#define MP_SPECREV 4 +#define MPFP_SIG "_MP_" + +/* Configuration header defines */ +#define MPCH_SIG "PCMP" +#define MPCH_OEMID "BHyVe " +#define MPCH_OEMID_LEN 8 +#define MPCH_PRODID "Hypervisor " +#define MPCH_PRODID_LEN 12 + +/* Processor entry defines */ +#define MPEP_SIG_FAMILY 6 /* XXX bhyve should supply this */ +#define MPEP_SIG_MODEL 26 +#define MPEP_SIG_STEPPING 5 +#define MPEP_SIG \ + ((MPEP_SIG_FAMILY << 8) | \ + (MPEP_SIG_MODEL << 4) | \ + (MPEP_SIG_STEPPING)) + +#define MPEP_FEATURES (0xBFEBFBFF) /* XXX Intel i7 */ + +/* Number of local intr entries */ +#define MPEII_NUM_LOCAL_IRQ 2 + +/* Bus entry defines */ +#define MPE_NUM_BUSES 2 +#define MPE_BUSNAME_LEN 6 +#define MPE_BUSNAME_ISA "ISA " +#define MPE_BUSNAME_PCI "PCI " + +static void *oem_tbl_start; +static int oem_tbl_size; + +static uint8_t +mpt_compute_checksum(void *base, size_t len) +{ + uint8_t *bytes; + uint8_t sum; + + for(bytes = base, sum = 0; len > 0; len--) { + sum += *bytes++; + } + + return (256 - sum); +} + +static void +mpt_build_mpfp(mpfps_t mpfp, vm_paddr_t gpa) +{ + + memset(mpfp, 0, sizeof(*mpfp)); + memcpy(mpfp->signature, MPFP_SIG, 4); + mpfp->pap = gpa + sizeof(*mpfp); + mpfp->length = 1; + mpfp->spec_rev = MP_SPECREV; + mpfp->checksum = mpt_compute_checksum(mpfp, sizeof(*mpfp)); +} + +static void +mpt_build_mpch(mpcth_t mpch) +{ + + memset(mpch, 0, sizeof(*mpch)); + memcpy(mpch->signature, MPCH_SIG, 4); + mpch->spec_rev = MP_SPECREV; + memcpy(mpch->oem_id, MPCH_OEMID, MPCH_OEMID_LEN); + memcpy(mpch->product_id, MPCH_PRODID, MPCH_PRODID_LEN); + mpch->apic_address = LAPIC_PADDR; +} + +static void +mpt_build_proc_entries(proc_entry_ptr mpep, int ncpu) +{ + int i; + + for (i = 0; i < ncpu; i++) { + memset(mpep, 0, sizeof(*mpep)); + mpep->type = MPCT_ENTRY_PROCESSOR; + mpep->apic_id = i; // XXX + mpep->apic_version = LAPIC_VERSION; + mpep->cpu_flags = PROCENTRY_FLAG_EN; + if (i == 0) + mpep->cpu_flags |= PROCENTRY_FLAG_BP; + mpep->cpu_signature = MPEP_SIG; + mpep->feature_flags = MPEP_FEATURES; + mpep++; + } +} + +static void +mpt_build_localint_entries(int_entry_ptr mpie) +{ + + /* Hardcode LINT0 as ExtINT on all CPUs. */ + memset(mpie, 0, sizeof(*mpie)); + mpie->type = MPCT_ENTRY_LOCAL_INT; + mpie->int_type = INTENTRY_TYPE_EXTINT; + mpie->int_flags = INTENTRY_FLAGS_POLARITY_CONFORM | + INTENTRY_FLAGS_TRIGGER_CONFORM; + mpie->dst_apic_id = 0xff; + mpie->dst_apic_int = 0; + mpie++; + + /* Hardcode LINT1 as NMI on all CPUs. */ + memset(mpie, 0, sizeof(*mpie)); + mpie->type = MPCT_ENTRY_LOCAL_INT; + mpie->int_type = INTENTRY_TYPE_NMI; + mpie->int_flags = INTENTRY_FLAGS_POLARITY_CONFORM | + INTENTRY_FLAGS_TRIGGER_CONFORM; + mpie->dst_apic_id = 0xff; + mpie->dst_apic_int = 1; +} + +static void +mpt_build_bus_entries(bus_entry_ptr mpeb) +{ + + memset(mpeb, 0, sizeof(*mpeb)); + mpeb->type = MPCT_ENTRY_BUS; + mpeb->bus_id = 0; + memcpy(mpeb->bus_type, MPE_BUSNAME_PCI, MPE_BUSNAME_LEN); + mpeb++; + + memset(mpeb, 0, sizeof(*mpeb)); + mpeb->type = MPCT_ENTRY_BUS; + mpeb->bus_id = 1; + memcpy(mpeb->bus_type, MPE_BUSNAME_ISA, MPE_BUSNAME_LEN); +} + +static void +mpt_build_ioapic_entries(io_apic_entry_ptr mpei, int id) +{ + + memset(mpei, 0, sizeof(*mpei)); + mpei->type = MPCT_ENTRY_IOAPIC; + mpei->apic_id = id; + mpei->apic_version = IOAPIC_VERSION; + mpei->apic_flags = IOAPICENTRY_FLAG_EN; + mpei->apic_address = IOAPIC_PADDR; +} + +static int +mpt_count_ioint_entries(void) +{ + int bus, count; + + count = 0; + for (bus = 0; bus <= PCI_BUSMAX; bus++) + count += pci_count_lintr(bus); + + /* + * Always include entries for the first 16 pins along with a entry + * for each active PCI INTx pin. + */ + return (16 + count); +} + +static void +mpt_generate_pci_int(int bus, int slot, int pin, int pirq_pin, int ioapic_irq, + void *arg) +{ + int_entry_ptr *mpiep, mpie; + + mpiep = arg; + mpie = *mpiep; + memset(mpie, 0, sizeof(*mpie)); + + /* + * This is always after another I/O interrupt entry, so cheat + * and fetch the I/O APIC ID from the prior entry. + */ + mpie->type = MPCT_ENTRY_INT; + mpie->int_type = INTENTRY_TYPE_INT; + mpie->src_bus_id = bus; + mpie->src_bus_irq = slot << 2 | (pin - 1); + mpie->dst_apic_id = mpie[-1].dst_apic_id; + mpie->dst_apic_int = ioapic_irq; + + *mpiep = mpie + 1; +} + +static void +mpt_build_ioint_entries(int_entry_ptr mpie, int id) +{ + int pin, bus; + + /* + * The following config is taken from kernel mptable.c + * mptable_parse_default_config_ints(...), for now + * just use the default config, tweek later if needed. + */ + + /* First, generate the first 16 pins. */ + for (pin = 0; pin < 16; pin++) { + memset(mpie, 0, sizeof(*mpie)); + mpie->type = MPCT_ENTRY_INT; + mpie->src_bus_id = 1; + mpie->dst_apic_id = id; + + /* + * All default configs route IRQs from bus 0 to the first 16 + * pins of the first I/O APIC with an APIC ID of 2. + */ + mpie->dst_apic_int = pin; + switch (pin) { + case 0: + /* Pin 0 is an ExtINT pin. */ + mpie->int_type = INTENTRY_TYPE_EXTINT; + break; + case 2: + /* IRQ 0 is routed to pin 2. */ + mpie->int_type = INTENTRY_TYPE_INT; + mpie->src_bus_irq = 0; + break; + case SCI_INT: + /* ACPI SCI is level triggered and active-lo. */ + mpie->int_flags = INTENTRY_FLAGS_POLARITY_ACTIVELO | + INTENTRY_FLAGS_TRIGGER_LEVEL; + mpie->int_type = INTENTRY_TYPE_INT; + mpie->src_bus_irq = SCI_INT; + break; + default: + /* All other pins are identity mapped. */ + mpie->int_type = INTENTRY_TYPE_INT; + mpie->src_bus_irq = pin; + break; + } + mpie++; + } + + /* Next, generate entries for any PCI INTx interrupts. */ + for (bus = 0; bus <= PCI_BUSMAX; bus++) + pci_walk_lintr(bus, mpt_generate_pci_int, &mpie); +} + +void +mptable_add_oemtbl(void *tbl, int tblsz) +{ + + oem_tbl_start = tbl; + oem_tbl_size = tblsz; +} + +int +mptable_build(struct vmctx *ctx, int ncpu) +{ + mpcth_t mpch; + bus_entry_ptr mpeb; + io_apic_entry_ptr mpei; + proc_entry_ptr mpep; + mpfps_t mpfp; + int_entry_ptr mpie; + int ioints, bus; + char *curraddr; + char *startaddr; + + startaddr = paddr_guest2host(ctx, MPTABLE_BASE, MPTABLE_MAX_LENGTH); + if (startaddr == NULL) { + fprintf(stderr, "mptable requires mapped mem\n"); + return (ENOMEM); + } + + /* + * There is no way to advertise multiple PCI hierarchies via MPtable + * so require that there is no PCI hierarchy with a non-zero bus + * number. + */ + for (bus = 1; bus <= PCI_BUSMAX; bus++) { + if (pci_bus_configured(bus)) { + fprintf(stderr, "MPtable is incompatible with " + "multiple PCI hierarchies.\r\n"); + fprintf(stderr, "MPtable generation can be disabled " + "by passing the -Y option to bhyve(8).\r\n"); + return (EINVAL); + } + } + + curraddr = startaddr; + mpfp = (mpfps_t)curraddr; + mpt_build_mpfp(mpfp, MPTABLE_BASE); + curraddr += sizeof(*mpfp); + + mpch = (mpcth_t)curraddr; + mpt_build_mpch(mpch); + curraddr += sizeof(*mpch); + + mpep = (proc_entry_ptr)curraddr; + mpt_build_proc_entries(mpep, ncpu); + curraddr += sizeof(*mpep) * ncpu; + mpch->entry_count += ncpu; + + mpeb = (bus_entry_ptr) curraddr; + mpt_build_bus_entries(mpeb); + curraddr += sizeof(*mpeb) * MPE_NUM_BUSES; + mpch->entry_count += MPE_NUM_BUSES; + + mpei = (io_apic_entry_ptr)curraddr; + mpt_build_ioapic_entries(mpei, 0); + curraddr += sizeof(*mpei); + mpch->entry_count++; + + mpie = (int_entry_ptr) curraddr; + ioints = mpt_count_ioint_entries(); + mpt_build_ioint_entries(mpie, 0); + curraddr += sizeof(*mpie) * ioints; + mpch->entry_count += ioints; + + mpie = (int_entry_ptr)curraddr; + mpt_build_localint_entries(mpie); + curraddr += sizeof(*mpie) * MPEII_NUM_LOCAL_IRQ; + mpch->entry_count += MPEII_NUM_LOCAL_IRQ; + + if (oem_tbl_start) { + mpch->oem_table_pointer = curraddr - startaddr + MPTABLE_BASE; + mpch->oem_table_size = oem_tbl_size; + memcpy(curraddr, oem_tbl_start, oem_tbl_size); + } + + mpch->base_table_length = curraddr - (char *)mpch; + mpch->checksum = mpt_compute_checksum(mpch, mpch->base_table_length); + + return (0); +} diff --git a/usr/src/cmd/bhyve/mptbl.h b/usr/src/cmd/bhyve/mptbl.h new file mode 100644 index 0000000000..ebc8d85ea8 --- /dev/null +++ b/usr/src/cmd/bhyve/mptbl.h @@ -0,0 +1,37 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _MPTBL_H_ +#define _MPTBL_H_ + +int mptable_build(struct vmctx *ctx, int ncpu); +void mptable_add_oemtbl(void *tbl, int tblsz); + +#endif /* _MPTBL_H_ */ diff --git a/usr/src/cmd/bhyve/pci_ahci.c b/usr/src/cmd/bhyve/pci_ahci.c new file mode 100644 index 0000000000..1e3feffcc2 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_ahci.c @@ -0,0 +1,2485 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Zhixiang Yu <zcore@freebsd.org> + * Copyright (c) 2015-2016 Alexander Motin <mav@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/linker_set.h> +#include <sys/stat.h> +#include <sys/uio.h> +#include <sys/ioctl.h> +#include <sys/disk.h> +#include <sys/ata.h> +#include <sys/endian.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include <assert.h> +#include <pthread.h> +#include <pthread_np.h> +#include <inttypes.h> +#include <md5.h> + +#include "bhyverun.h" +#include "pci_emul.h" +#include "ahci.h" +#include "block_if.h" + +#define DEF_PORTS 6 /* Intel ICH8 AHCI supports 6 ports */ +#define MAX_PORTS 32 /* AHCI supports 32 ports */ + +#define PxSIG_ATA 0x00000101 /* ATA drive */ +#define PxSIG_ATAPI 0xeb140101 /* ATAPI drive */ + +enum sata_fis_type { + FIS_TYPE_REGH2D = 0x27, /* Register FIS - host to device */ + FIS_TYPE_REGD2H = 0x34, /* Register FIS - device to host */ + FIS_TYPE_DMAACT = 0x39, /* DMA activate FIS - device to host */ + FIS_TYPE_DMASETUP = 0x41, /* DMA setup FIS - bidirectional */ + FIS_TYPE_DATA = 0x46, /* Data FIS - bidirectional */ + FIS_TYPE_BIST = 0x58, /* BIST activate FIS - bidirectional */ + FIS_TYPE_PIOSETUP = 0x5F, /* PIO setup FIS - device to host */ + FIS_TYPE_SETDEVBITS = 0xA1, /* Set dev bits FIS - device to host */ +}; + +/* + * SCSI opcodes + */ +#define TEST_UNIT_READY 0x00 +#define REQUEST_SENSE 0x03 +#define INQUIRY 0x12 +#define START_STOP_UNIT 0x1B +#define PREVENT_ALLOW 0x1E +#define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define POSITION_TO_ELEMENT 0x2B +#define READ_TOC 0x43 +#define GET_EVENT_STATUS_NOTIFICATION 0x4A +#define MODE_SENSE_10 0x5A +#define REPORT_LUNS 0xA0 +#define READ_12 0xA8 +#define READ_CD 0xBE + +/* + * SCSI mode page codes + */ +#define MODEPAGE_RW_ERROR_RECOVERY 0x01 +#define MODEPAGE_CD_CAPABILITIES 0x2A + +/* + * ATA commands + */ +#define ATA_SF_ENAB_SATA_SF 0x10 +#define ATA_SATA_SF_AN 0x05 +#define ATA_SF_DIS_SATA_SF 0x90 + +/* + * Debug printf + */ +#ifdef AHCI_DEBUG +static FILE *dbg; +#define DPRINTF(format, arg...) do{fprintf(dbg, format, ##arg);fflush(dbg);}while(0) +#else +#define DPRINTF(format, arg...) +#endif +#define WPRINTF(format, arg...) printf(format, ##arg) + +#define AHCI_PORT_IDENT 20 + 1 + +struct ahci_ioreq { + struct blockif_req io_req; + struct ahci_port *io_pr; + STAILQ_ENTRY(ahci_ioreq) io_flist; + TAILQ_ENTRY(ahci_ioreq) io_blist; + uint8_t *cfis; + uint32_t len; + uint32_t done; + int slot; + int more; +}; + +struct ahci_port { + struct blockif_ctxt *bctx; + struct pci_ahci_softc *pr_sc; + uint8_t *cmd_lst; + uint8_t *rfis; + char ident[AHCI_PORT_IDENT]; + int port; + int atapi; + int reset; + int waitforclear; + int mult_sectors; + uint8_t xfermode; + uint8_t err_cfis[20]; + uint8_t sense_key; + uint8_t asc; + u_int ccs; + uint32_t pending; + + uint32_t clb; + uint32_t clbu; + uint32_t fb; + uint32_t fbu; + uint32_t is; + uint32_t ie; + uint32_t cmd; + uint32_t unused0; + uint32_t tfd; + uint32_t sig; + uint32_t ssts; + uint32_t sctl; + uint32_t serr; + uint32_t sact; + uint32_t ci; + uint32_t sntf; + uint32_t fbs; + + /* + * i/o request info + */ + struct ahci_ioreq *ioreq; + int ioqsz; + STAILQ_HEAD(ahci_fhead, ahci_ioreq) iofhd; + TAILQ_HEAD(ahci_bhead, ahci_ioreq) iobhd; +}; + +struct ahci_cmd_hdr { + uint16_t flags; + uint16_t prdtl; + uint32_t prdbc; + uint64_t ctba; + uint32_t reserved[4]; +}; + +struct ahci_prdt_entry { + uint64_t dba; + uint32_t reserved; +#define DBCMASK 0x3fffff + uint32_t dbc; +}; + +struct pci_ahci_softc { + struct pci_devinst *asc_pi; + pthread_mutex_t mtx; + int ports; + uint32_t cap; + uint32_t ghc; + uint32_t is; + uint32_t pi; + uint32_t vs; + uint32_t ccc_ctl; + uint32_t ccc_pts; + uint32_t em_loc; + uint32_t em_ctl; + uint32_t cap2; + uint32_t bohc; + uint32_t lintr; + struct ahci_port port[MAX_PORTS]; +}; +#define ahci_ctx(sc) ((sc)->asc_pi->pi_vmctx) + +static void ahci_handle_port(struct ahci_port *p); + +static inline void lba_to_msf(uint8_t *buf, int lba) +{ + lba += 150; + buf[0] = (lba / 75) / 60; + buf[1] = (lba / 75) % 60; + buf[2] = lba % 75; +} + +/* + * Generate HBA interrupts on global IS register write. + */ +static void +ahci_generate_intr(struct pci_ahci_softc *sc, uint32_t mask) +{ + struct pci_devinst *pi = sc->asc_pi; + struct ahci_port *p; + int i, nmsg; + uint32_t mmask; + + /* Update global IS from PxIS/PxIE. */ + for (i = 0; i < sc->ports; i++) { + p = &sc->port[i]; + if (p->is & p->ie) + sc->is |= (1 << i); + } + DPRINTF("%s(%08x) %08x\n", __func__, mask, sc->is); + + /* If there is nothing enabled -- clear legacy interrupt and exit. */ + if (sc->is == 0 || (sc->ghc & AHCI_GHC_IE) == 0) { + if (sc->lintr) { + pci_lintr_deassert(pi); + sc->lintr = 0; + } + return; + } + + /* If there is anything and no MSI -- assert legacy interrupt. */ + nmsg = pci_msi_maxmsgnum(pi); + if (nmsg == 0) { + if (!sc->lintr) { + sc->lintr = 1; + pci_lintr_assert(pi); + } + return; + } + + /* Assert respective MSIs for ports that were touched. */ + for (i = 0; i < nmsg; i++) { + if (sc->ports <= nmsg || i < nmsg - 1) + mmask = 1 << i; + else + mmask = 0xffffffff << i; + if (sc->is & mask && mmask & mask) + pci_generate_msi(pi, i); + } +} + +/* + * Generate HBA interrupt on specific port event. + */ +static void +ahci_port_intr(struct ahci_port *p) +{ + struct pci_ahci_softc *sc = p->pr_sc; + struct pci_devinst *pi = sc->asc_pi; + int nmsg; + + DPRINTF("%s(%d) %08x/%08x %08x\n", __func__, + p->port, p->is, p->ie, sc->is); + + /* If there is nothing enabled -- we are done. */ + if ((p->is & p->ie) == 0) + return; + + /* In case of non-shared MSI always generate interrupt. */ + nmsg = pci_msi_maxmsgnum(pi); + if (sc->ports <= nmsg || p->port < nmsg - 1) { + sc->is |= (1 << p->port); + if ((sc->ghc & AHCI_GHC_IE) == 0) + return; + pci_generate_msi(pi, p->port); + return; + } + + /* If IS for this port is already set -- do nothing. */ + if (sc->is & (1 << p->port)) + return; + + sc->is |= (1 << p->port); + + /* If interrupts are enabled -- generate one. */ + if ((sc->ghc & AHCI_GHC_IE) == 0) + return; + if (nmsg > 0) { + pci_generate_msi(pi, nmsg - 1); + } else if (!sc->lintr) { + sc->lintr = 1; + pci_lintr_assert(pi); + } +} + +static void +ahci_write_fis(struct ahci_port *p, enum sata_fis_type ft, uint8_t *fis) +{ + int offset, len, irq; + + if (p->rfis == NULL || !(p->cmd & AHCI_P_CMD_FRE)) + return; + + switch (ft) { + case FIS_TYPE_REGD2H: + offset = 0x40; + len = 20; + irq = (fis[1] & (1 << 6)) ? AHCI_P_IX_DHR : 0; + break; + case FIS_TYPE_SETDEVBITS: + offset = 0x58; + len = 8; + irq = (fis[1] & (1 << 6)) ? AHCI_P_IX_SDB : 0; + break; + case FIS_TYPE_PIOSETUP: + offset = 0x20; + len = 20; + irq = (fis[1] & (1 << 6)) ? AHCI_P_IX_PS : 0; + break; + default: + WPRINTF("unsupported fis type %d\n", ft); + return; + } + if (fis[2] & ATA_S_ERROR) { + p->waitforclear = 1; + irq |= AHCI_P_IX_TFE; + } + memcpy(p->rfis + offset, fis, len); + if (irq) { + if (~p->is & irq) { + p->is |= irq; + ahci_port_intr(p); + } + } +} + +static void +ahci_write_fis_piosetup(struct ahci_port *p) +{ + uint8_t fis[20]; + + memset(fis, 0, sizeof(fis)); + fis[0] = FIS_TYPE_PIOSETUP; + ahci_write_fis(p, FIS_TYPE_PIOSETUP, fis); +} + +static void +ahci_write_fis_sdb(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t tfd) +{ + uint8_t fis[8]; + uint8_t error; + + error = (tfd >> 8) & 0xff; + tfd &= 0x77; + memset(fis, 0, sizeof(fis)); + fis[0] = FIS_TYPE_SETDEVBITS; + fis[1] = (1 << 6); + fis[2] = tfd; + fis[3] = error; + if (fis[2] & ATA_S_ERROR) { + p->err_cfis[0] = slot; + p->err_cfis[2] = tfd; + p->err_cfis[3] = error; + memcpy(&p->err_cfis[4], cfis + 4, 16); + } else { + *(uint32_t *)(fis + 4) = (1 << slot); + p->sact &= ~(1 << slot); + } + p->tfd &= ~0x77; + p->tfd |= tfd; + ahci_write_fis(p, FIS_TYPE_SETDEVBITS, fis); +} + +static void +ahci_write_fis_d2h(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t tfd) +{ + uint8_t fis[20]; + uint8_t error; + + error = (tfd >> 8) & 0xff; + memset(fis, 0, sizeof(fis)); + fis[0] = FIS_TYPE_REGD2H; + fis[1] = (1 << 6); + fis[2] = tfd & 0xff; + fis[3] = error; + fis[4] = cfis[4]; + fis[5] = cfis[5]; + fis[6] = cfis[6]; + fis[7] = cfis[7]; + fis[8] = cfis[8]; + fis[9] = cfis[9]; + fis[10] = cfis[10]; + fis[11] = cfis[11]; + fis[12] = cfis[12]; + fis[13] = cfis[13]; + if (fis[2] & ATA_S_ERROR) { + p->err_cfis[0] = 0x80; + p->err_cfis[2] = tfd & 0xff; + p->err_cfis[3] = error; + memcpy(&p->err_cfis[4], cfis + 4, 16); + } else + p->ci &= ~(1 << slot); + p->tfd = tfd; + ahci_write_fis(p, FIS_TYPE_REGD2H, fis); +} + +static void +ahci_write_fis_d2h_ncq(struct ahci_port *p, int slot) +{ + uint8_t fis[20]; + + p->tfd = ATA_S_READY | ATA_S_DSC; + memset(fis, 0, sizeof(fis)); + fis[0] = FIS_TYPE_REGD2H; + fis[1] = 0; /* No interrupt */ + fis[2] = p->tfd; /* Status */ + fis[3] = 0; /* No error */ + p->ci &= ~(1 << slot); + ahci_write_fis(p, FIS_TYPE_REGD2H, fis); +} + +static void +ahci_write_reset_fis_d2h(struct ahci_port *p) +{ + uint8_t fis[20]; + + memset(fis, 0, sizeof(fis)); + fis[0] = FIS_TYPE_REGD2H; + fis[3] = 1; + fis[4] = 1; + if (p->atapi) { + fis[5] = 0x14; + fis[6] = 0xeb; + } + fis[12] = 1; + ahci_write_fis(p, FIS_TYPE_REGD2H, fis); +} + +static void +ahci_check_stopped(struct ahci_port *p) +{ + /* + * If we are no longer processing the command list and nothing + * is in-flight, clear the running bit, the current command + * slot, the command issue and active bits. + */ + if (!(p->cmd & AHCI_P_CMD_ST)) { + if (p->pending == 0) { + p->ccs = 0; + p->cmd &= ~(AHCI_P_CMD_CR | AHCI_P_CMD_CCS_MASK); + p->ci = 0; + p->sact = 0; + p->waitforclear = 0; + } + } +} + +static void +ahci_port_stop(struct ahci_port *p) +{ + struct ahci_ioreq *aior; + uint8_t *cfis; + int slot; + int error; + + assert(pthread_mutex_isowned_np(&p->pr_sc->mtx)); + + TAILQ_FOREACH(aior, &p->iobhd, io_blist) { + /* + * Try to cancel the outstanding blockif request. + */ + error = blockif_cancel(p->bctx, &aior->io_req); + if (error != 0) + continue; + + slot = aior->slot; + cfis = aior->cfis; + if (cfis[2] == ATA_WRITE_FPDMA_QUEUED || + cfis[2] == ATA_READ_FPDMA_QUEUED || + cfis[2] == ATA_SEND_FPDMA_QUEUED) + p->sact &= ~(1 << slot); /* NCQ */ + else + p->ci &= ~(1 << slot); + + /* + * This command is now done. + */ + p->pending &= ~(1 << slot); + + /* + * Delete the blockif request from the busy list + */ + TAILQ_REMOVE(&p->iobhd, aior, io_blist); + + /* + * Move the blockif request back to the free list + */ + STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist); + } + + ahci_check_stopped(p); +} + +static void +ahci_port_reset(struct ahci_port *pr) +{ + pr->serr = 0; + pr->sact = 0; + pr->xfermode = ATA_UDMA6; + pr->mult_sectors = 128; + + if (!pr->bctx) { + pr->ssts = ATA_SS_DET_NO_DEVICE; + pr->sig = 0xFFFFFFFF; + pr->tfd = 0x7F; + return; + } + pr->ssts = ATA_SS_DET_PHY_ONLINE | ATA_SS_IPM_ACTIVE; + if (pr->sctl & ATA_SC_SPD_MASK) + pr->ssts |= (pr->sctl & ATA_SC_SPD_MASK); + else + pr->ssts |= ATA_SS_SPD_GEN3; + pr->tfd = (1 << 8) | ATA_S_DSC | ATA_S_DMA; + if (!pr->atapi) { + pr->sig = PxSIG_ATA; + pr->tfd |= ATA_S_READY; + } else + pr->sig = PxSIG_ATAPI; + ahci_write_reset_fis_d2h(pr); +} + +static void +ahci_reset(struct pci_ahci_softc *sc) +{ + int i; + + sc->ghc = AHCI_GHC_AE; + sc->is = 0; + + if (sc->lintr) { + pci_lintr_deassert(sc->asc_pi); + sc->lintr = 0; + } + + for (i = 0; i < sc->ports; i++) { + sc->port[i].ie = 0; + sc->port[i].is = 0; + sc->port[i].cmd = (AHCI_P_CMD_SUD | AHCI_P_CMD_POD); + if (sc->port[i].bctx) + sc->port[i].cmd |= AHCI_P_CMD_CPS; + sc->port[i].sctl = 0; + ahci_port_reset(&sc->port[i]); + } +} + +static void +ata_string(uint8_t *dest, const char *src, int len) +{ + int i; + + for (i = 0; i < len; i++) { + if (*src) + dest[i ^ 1] = *src++; + else + dest[i ^ 1] = ' '; + } +} + +static void +atapi_string(uint8_t *dest, const char *src, int len) +{ + int i; + + for (i = 0; i < len; i++) { + if (*src) + dest[i] = *src++; + else + dest[i] = ' '; + } +} + +/* + * Build up the iovec based on the PRDT, 'done' and 'len'. + */ +static void +ahci_build_iov(struct ahci_port *p, struct ahci_ioreq *aior, + struct ahci_prdt_entry *prdt, uint16_t prdtl) +{ + struct blockif_req *breq = &aior->io_req; + int i, j, skip, todo, left, extra; + uint32_t dbcsz; + + /* Copy part of PRDT between 'done' and 'len' bytes into the iov. */ + skip = aior->done; + left = aior->len - aior->done; + todo = 0; + for (i = 0, j = 0; i < prdtl && j < BLOCKIF_IOV_MAX && left > 0; + i++, prdt++) { + dbcsz = (prdt->dbc & DBCMASK) + 1; + /* Skip already done part of the PRDT */ + if (dbcsz <= skip) { + skip -= dbcsz; + continue; + } + dbcsz -= skip; + if (dbcsz > left) + dbcsz = left; + breq->br_iov[j].iov_base = paddr_guest2host(ahci_ctx(p->pr_sc), + prdt->dba + skip, dbcsz); + breq->br_iov[j].iov_len = dbcsz; + todo += dbcsz; + left -= dbcsz; + skip = 0; + j++; + } + + /* If we got limited by IOV length, round I/O down to sector size. */ + if (j == BLOCKIF_IOV_MAX) { + extra = todo % blockif_sectsz(p->bctx); + todo -= extra; + assert(todo > 0); + while (extra > 0) { + if (breq->br_iov[j - 1].iov_len > extra) { + breq->br_iov[j - 1].iov_len -= extra; + break; + } + extra -= breq->br_iov[j - 1].iov_len; + j--; + } + } + + breq->br_iovcnt = j; + breq->br_resid = todo; + aior->done += todo; + aior->more = (aior->done < aior->len && i < prdtl); +} + +static void +ahci_handle_rw(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done) +{ + struct ahci_ioreq *aior; + struct blockif_req *breq; + struct ahci_prdt_entry *prdt; + struct ahci_cmd_hdr *hdr; + uint64_t lba; + uint32_t len; + int err, first, ncq, readop; + + prdt = (struct ahci_prdt_entry *)(cfis + 0x80); + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); + ncq = 0; + readop = 1; + first = (done == 0); + + if (cfis[2] == ATA_WRITE || cfis[2] == ATA_WRITE48 || + cfis[2] == ATA_WRITE_MUL || cfis[2] == ATA_WRITE_MUL48 || + cfis[2] == ATA_WRITE_DMA || cfis[2] == ATA_WRITE_DMA48 || + cfis[2] == ATA_WRITE_FPDMA_QUEUED) + readop = 0; + + if (cfis[2] == ATA_WRITE_FPDMA_QUEUED || + cfis[2] == ATA_READ_FPDMA_QUEUED) { + lba = ((uint64_t)cfis[10] << 40) | + ((uint64_t)cfis[9] << 32) | + ((uint64_t)cfis[8] << 24) | + ((uint64_t)cfis[6] << 16) | + ((uint64_t)cfis[5] << 8) | + cfis[4]; + len = cfis[11] << 8 | cfis[3]; + if (!len) + len = 65536; + ncq = 1; + } else if (cfis[2] == ATA_READ48 || cfis[2] == ATA_WRITE48 || + cfis[2] == ATA_READ_MUL48 || cfis[2] == ATA_WRITE_MUL48 || + cfis[2] == ATA_READ_DMA48 || cfis[2] == ATA_WRITE_DMA48) { + lba = ((uint64_t)cfis[10] << 40) | + ((uint64_t)cfis[9] << 32) | + ((uint64_t)cfis[8] << 24) | + ((uint64_t)cfis[6] << 16) | + ((uint64_t)cfis[5] << 8) | + cfis[4]; + len = cfis[13] << 8 | cfis[12]; + if (!len) + len = 65536; + } else { + lba = ((cfis[7] & 0xf) << 24) | (cfis[6] << 16) | + (cfis[5] << 8) | cfis[4]; + len = cfis[12]; + if (!len) + len = 256; + } + lba *= blockif_sectsz(p->bctx); + len *= blockif_sectsz(p->bctx); + + /* Pull request off free list */ + aior = STAILQ_FIRST(&p->iofhd); + assert(aior != NULL); + STAILQ_REMOVE_HEAD(&p->iofhd, io_flist); + + aior->cfis = cfis; + aior->slot = slot; + aior->len = len; + aior->done = done; + breq = &aior->io_req; + breq->br_offset = lba + done; + ahci_build_iov(p, aior, prdt, hdr->prdtl); + + /* Mark this command in-flight. */ + p->pending |= 1 << slot; + + /* Stuff request onto busy list. */ + TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist); + + if (ncq && first) + ahci_write_fis_d2h_ncq(p, slot); + + if (readop) + err = blockif_read(p->bctx, breq); + else + err = blockif_write(p->bctx, breq); + assert(err == 0); +} + +static void +ahci_handle_flush(struct ahci_port *p, int slot, uint8_t *cfis) +{ + struct ahci_ioreq *aior; + struct blockif_req *breq; + int err; + + /* + * Pull request off free list + */ + aior = STAILQ_FIRST(&p->iofhd); + assert(aior != NULL); + STAILQ_REMOVE_HEAD(&p->iofhd, io_flist); + aior->cfis = cfis; + aior->slot = slot; + aior->len = 0; + aior->done = 0; + aior->more = 0; + breq = &aior->io_req; + + /* + * Mark this command in-flight. + */ + p->pending |= 1 << slot; + + /* + * Stuff request onto busy list + */ + TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist); + + err = blockif_flush(p->bctx, breq); + assert(err == 0); +} + +static inline void +read_prdt(struct ahci_port *p, int slot, uint8_t *cfis, + void *buf, int size) +{ + struct ahci_cmd_hdr *hdr; + struct ahci_prdt_entry *prdt; + void *to; + int i, len; + + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); + len = size; + to = buf; + prdt = (struct ahci_prdt_entry *)(cfis + 0x80); + for (i = 0; i < hdr->prdtl && len; i++) { + uint8_t *ptr; + uint32_t dbcsz; + int sublen; + + dbcsz = (prdt->dbc & DBCMASK) + 1; + ptr = paddr_guest2host(ahci_ctx(p->pr_sc), prdt->dba, dbcsz); + sublen = MIN(len, dbcsz); + memcpy(to, ptr, sublen); + len -= sublen; + to += sublen; + prdt++; + } +} + +static void +ahci_handle_dsm_trim(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done) +{ + struct ahci_ioreq *aior; + struct blockif_req *breq; + uint8_t *entry; + uint64_t elba; + uint32_t len, elen; + int err, first, ncq; + uint8_t buf[512]; + + first = (done == 0); + if (cfis[2] == ATA_DATA_SET_MANAGEMENT) { + len = (uint16_t)cfis[13] << 8 | cfis[12]; + len *= 512; + ncq = 0; + } else { /* ATA_SEND_FPDMA_QUEUED */ + len = (uint16_t)cfis[11] << 8 | cfis[3]; + len *= 512; + ncq = 1; + } + read_prdt(p, slot, cfis, buf, sizeof(buf)); + +next: + entry = &buf[done]; + elba = ((uint64_t)entry[5] << 40) | + ((uint64_t)entry[4] << 32) | + ((uint64_t)entry[3] << 24) | + ((uint64_t)entry[2] << 16) | + ((uint64_t)entry[1] << 8) | + entry[0]; + elen = (uint16_t)entry[7] << 8 | entry[6]; + done += 8; + if (elen == 0) { + if (done >= len) { + if (ncq) { + if (first) + ahci_write_fis_d2h_ncq(p, slot); + ahci_write_fis_sdb(p, slot, cfis, + ATA_S_READY | ATA_S_DSC); + } else { + ahci_write_fis_d2h(p, slot, cfis, + ATA_S_READY | ATA_S_DSC); + } + p->pending &= ~(1 << slot); + ahci_check_stopped(p); + if (!first) + ahci_handle_port(p); + return; + } + goto next; + } + + /* + * Pull request off free list + */ + aior = STAILQ_FIRST(&p->iofhd); + assert(aior != NULL); + STAILQ_REMOVE_HEAD(&p->iofhd, io_flist); + aior->cfis = cfis; + aior->slot = slot; + aior->len = len; + aior->done = done; + aior->more = (len != done); + + breq = &aior->io_req; + breq->br_offset = elba * blockif_sectsz(p->bctx); + breq->br_resid = elen * blockif_sectsz(p->bctx); + + /* + * Mark this command in-flight. + */ + p->pending |= 1 << slot; + + /* + * Stuff request onto busy list + */ + TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist); + + if (ncq && first) + ahci_write_fis_d2h_ncq(p, slot); + + err = blockif_delete(p->bctx, breq); + assert(err == 0); +} + +static inline void +write_prdt(struct ahci_port *p, int slot, uint8_t *cfis, + void *buf, int size) +{ + struct ahci_cmd_hdr *hdr; + struct ahci_prdt_entry *prdt; + void *from; + int i, len; + + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); + len = size; + from = buf; + prdt = (struct ahci_prdt_entry *)(cfis + 0x80); + for (i = 0; i < hdr->prdtl && len; i++) { + uint8_t *ptr; + uint32_t dbcsz; + int sublen; + + dbcsz = (prdt->dbc & DBCMASK) + 1; + ptr = paddr_guest2host(ahci_ctx(p->pr_sc), prdt->dba, dbcsz); + sublen = MIN(len, dbcsz); + memcpy(ptr, from, sublen); + len -= sublen; + from += sublen; + prdt++; + } + hdr->prdbc = size - len; +} + +static void +ahci_checksum(uint8_t *buf, int size) +{ + int i; + uint8_t sum = 0; + + for (i = 0; i < size - 1; i++) + sum += buf[i]; + buf[size - 1] = 0x100 - sum; +} + +static void +ahci_handle_read_log(struct ahci_port *p, int slot, uint8_t *cfis) +{ + struct ahci_cmd_hdr *hdr; + uint32_t buf[128]; + uint8_t *buf8 = (uint8_t *)buf; + uint16_t *buf16 = (uint16_t *)buf; + + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); + if (p->atapi || hdr->prdtl == 0 || cfis[5] != 0 || + cfis[9] != 0 || cfis[12] != 1 || cfis[13] != 0) { + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + return; + } + + memset(buf, 0, sizeof(buf)); + if (cfis[4] == 0x00) { /* Log directory */ + buf16[0x00] = 1; /* Version -- 1 */ + buf16[0x10] = 1; /* NCQ Command Error Log -- 1 page */ + buf16[0x13] = 1; /* SATA NCQ Send and Receive Log -- 1 page */ + } else if (cfis[4] == 0x10) { /* NCQ Command Error Log */ + memcpy(buf8, p->err_cfis, sizeof(p->err_cfis)); + ahci_checksum(buf8, sizeof(buf)); + } else if (cfis[4] == 0x13) { /* SATA NCQ Send and Receive Log */ + if (blockif_candelete(p->bctx) && !blockif_is_ro(p->bctx)) { + buf[0x00] = 1; /* SFQ DSM supported */ + buf[0x01] = 1; /* SFQ DSM TRIM supported */ + } + } else { + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + return; + } + + if (cfis[2] == ATA_READ_LOG_EXT) + ahci_write_fis_piosetup(p); + write_prdt(p, slot, cfis, (void *)buf, sizeof(buf)); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); +} + +static void +handle_identify(struct ahci_port *p, int slot, uint8_t *cfis) +{ + struct ahci_cmd_hdr *hdr; + + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); + if (p->atapi || hdr->prdtl == 0) { + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + } else { + uint16_t buf[256]; + uint64_t sectors; + int sectsz, psectsz, psectoff, candelete, ro; + uint16_t cyl; + uint8_t sech, heads; + + ro = blockif_is_ro(p->bctx); + candelete = blockif_candelete(p->bctx); + sectsz = blockif_sectsz(p->bctx); + sectors = blockif_size(p->bctx) / sectsz; + blockif_chs(p->bctx, &cyl, &heads, &sech); + blockif_psectsz(p->bctx, &psectsz, &psectoff); + memset(buf, 0, sizeof(buf)); + buf[0] = 0x0040; + buf[1] = cyl; + buf[3] = heads; + buf[6] = sech; + ata_string((uint8_t *)(buf+10), p->ident, 20); + ata_string((uint8_t *)(buf+23), "001", 8); + ata_string((uint8_t *)(buf+27), "BHYVE SATA DISK", 40); + buf[47] = (0x8000 | 128); + buf[48] = 0; + buf[49] = (1 << 8 | 1 << 9 | 1 << 11); + buf[50] = (1 << 14); + buf[53] = (1 << 1 | 1 << 2); + if (p->mult_sectors) + buf[59] = (0x100 | p->mult_sectors); + if (sectors <= 0x0fffffff) { + buf[60] = sectors; + buf[61] = (sectors >> 16); + } else { + buf[60] = 0xffff; + buf[61] = 0x0fff; + } + buf[63] = 0x7; + if (p->xfermode & ATA_WDMA0) + buf[63] |= (1 << ((p->xfermode & 7) + 8)); + buf[64] = 0x3; + buf[65] = 120; + buf[66] = 120; + buf[67] = 120; + buf[68] = 120; + buf[69] = 0; + buf[75] = 31; + buf[76] = (ATA_SATA_GEN1 | ATA_SATA_GEN2 | ATA_SATA_GEN3 | + ATA_SUPPORT_NCQ); + buf[77] = (ATA_SUPPORT_RCVSND_FPDMA_QUEUED | + (p->ssts & ATA_SS_SPD_MASK) >> 3); + buf[80] = 0x3f0; + buf[81] = 0x28; + buf[82] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_WRITECACHE| + ATA_SUPPORT_LOOKAHEAD | ATA_SUPPORT_NOP); + buf[83] = (ATA_SUPPORT_ADDRESS48 | ATA_SUPPORT_FLUSHCACHE | + ATA_SUPPORT_FLUSHCACHE48 | 1 << 14); + buf[84] = (1 << 14); + buf[85] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_WRITECACHE| + ATA_SUPPORT_LOOKAHEAD | ATA_SUPPORT_NOP); + buf[86] = (ATA_SUPPORT_ADDRESS48 | ATA_SUPPORT_FLUSHCACHE | + ATA_SUPPORT_FLUSHCACHE48 | 1 << 15); + buf[87] = (1 << 14); + buf[88] = 0x7f; + if (p->xfermode & ATA_UDMA0) + buf[88] |= (1 << ((p->xfermode & 7) + 8)); + buf[100] = sectors; + buf[101] = (sectors >> 16); + buf[102] = (sectors >> 32); + buf[103] = (sectors >> 48); + if (candelete && !ro) { + buf[69] |= ATA_SUPPORT_RZAT | ATA_SUPPORT_DRAT; + buf[105] = 1; + buf[169] = ATA_SUPPORT_DSM_TRIM; + } + buf[106] = 0x4000; + buf[209] = 0x4000; + if (psectsz > sectsz) { + buf[106] |= 0x2000; + buf[106] |= ffsl(psectsz / sectsz) - 1; + buf[209] |= (psectoff / sectsz); + } + if (sectsz > 512) { + buf[106] |= 0x1000; + buf[117] = sectsz / 2; + buf[118] = ((sectsz / 2) >> 16); + } + buf[119] = (ATA_SUPPORT_RWLOGDMAEXT | 1 << 14); + buf[120] = (ATA_SUPPORT_RWLOGDMAEXT | 1 << 14); + buf[222] = 0x1020; + buf[255] = 0x00a5; + ahci_checksum((uint8_t *)buf, sizeof(buf)); + ahci_write_fis_piosetup(p); + write_prdt(p, slot, cfis, (void *)buf, sizeof(buf)); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); + } +} + +static void +handle_atapi_identify(struct ahci_port *p, int slot, uint8_t *cfis) +{ + if (!p->atapi) { + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + } else { + uint16_t buf[256]; + + memset(buf, 0, sizeof(buf)); + buf[0] = (2 << 14 | 5 << 8 | 1 << 7 | 2 << 5); + ata_string((uint8_t *)(buf+10), p->ident, 20); + ata_string((uint8_t *)(buf+23), "001", 8); + ata_string((uint8_t *)(buf+27), "BHYVE SATA DVD ROM", 40); + buf[49] = (1 << 9 | 1 << 8); + buf[50] = (1 << 14 | 1); + buf[53] = (1 << 2 | 1 << 1); + buf[62] = 0x3f; + buf[63] = 7; + if (p->xfermode & ATA_WDMA0) + buf[63] |= (1 << ((p->xfermode & 7) + 8)); + buf[64] = 3; + buf[65] = 120; + buf[66] = 120; + buf[67] = 120; + buf[68] = 120; + buf[76] = (ATA_SATA_GEN1 | ATA_SATA_GEN2 | ATA_SATA_GEN3); + buf[77] = ((p->ssts & ATA_SS_SPD_MASK) >> 3); + buf[78] = (1 << 5); + buf[80] = 0x3f0; + buf[82] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_PACKET | + ATA_SUPPORT_RESET | ATA_SUPPORT_NOP); + buf[83] = (1 << 14); + buf[84] = (1 << 14); + buf[85] = (ATA_SUPPORT_POWERMGT | ATA_SUPPORT_PACKET | + ATA_SUPPORT_RESET | ATA_SUPPORT_NOP); + buf[87] = (1 << 14); + buf[88] = 0x7f; + if (p->xfermode & ATA_UDMA0) + buf[88] |= (1 << ((p->xfermode & 7) + 8)); + buf[222] = 0x1020; + buf[255] = 0x00a5; + ahci_checksum((uint8_t *)buf, sizeof(buf)); + ahci_write_fis_piosetup(p); + write_prdt(p, slot, cfis, (void *)buf, sizeof(buf)); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_DSC | ATA_S_READY); + } +} + +static void +atapi_inquiry(struct ahci_port *p, int slot, uint8_t *cfis) +{ + uint8_t buf[36]; + uint8_t *acmd; + int len; + uint32_t tfd; + + acmd = cfis + 0x40; + + if (acmd[1] & 1) { /* VPD */ + if (acmd[2] == 0) { /* Supported VPD pages */ + buf[0] = 0x05; + buf[1] = 0; + buf[2] = 0; + buf[3] = 1; + buf[4] = 0; + len = 4 + buf[3]; + } else { + p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; + p->asc = 0x24; + tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, tfd); + return; + } + } else { + buf[0] = 0x05; + buf[1] = 0x80; + buf[2] = 0x00; + buf[3] = 0x21; + buf[4] = 31; + buf[5] = 0; + buf[6] = 0; + buf[7] = 0; + atapi_string(buf + 8, "BHYVE", 8); + atapi_string(buf + 16, "BHYVE DVD-ROM", 16); + atapi_string(buf + 32, "001", 4); + len = sizeof(buf); + } + + if (len > acmd[4]) + len = acmd[4]; + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + write_prdt(p, slot, cfis, buf, len); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); +} + +static void +atapi_read_capacity(struct ahci_port *p, int slot, uint8_t *cfis) +{ + uint8_t buf[8]; + uint64_t sectors; + + sectors = blockif_size(p->bctx) / 2048; + be32enc(buf, sectors - 1); + be32enc(buf + 4, 2048); + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + write_prdt(p, slot, cfis, buf, sizeof(buf)); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); +} + +static void +atapi_read_toc(struct ahci_port *p, int slot, uint8_t *cfis) +{ + uint8_t *acmd; + uint8_t format; + int len; + + acmd = cfis + 0x40; + + len = be16dec(acmd + 7); + format = acmd[9] >> 6; + switch (format) { + case 0: + { + int msf, size; + uint64_t sectors; + uint8_t start_track, buf[20], *bp; + + msf = (acmd[1] >> 1) & 1; + start_track = acmd[6]; + if (start_track > 1 && start_track != 0xaa) { + uint32_t tfd; + p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; + p->asc = 0x24; + tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, tfd); + return; + } + bp = buf + 2; + *bp++ = 1; + *bp++ = 1; + if (start_track <= 1) { + *bp++ = 0; + *bp++ = 0x14; + *bp++ = 1; + *bp++ = 0; + if (msf) { + *bp++ = 0; + lba_to_msf(bp, 0); + bp += 3; + } else { + *bp++ = 0; + *bp++ = 0; + *bp++ = 0; + *bp++ = 0; + } + } + *bp++ = 0; + *bp++ = 0x14; + *bp++ = 0xaa; + *bp++ = 0; + sectors = blockif_size(p->bctx) / blockif_sectsz(p->bctx); + sectors >>= 2; + if (msf) { + *bp++ = 0; + lba_to_msf(bp, sectors); + bp += 3; + } else { + be32enc(bp, sectors); + bp += 4; + } + size = bp - buf; + be16enc(buf, size - 2); + if (len > size) + len = size; + write_prdt(p, slot, cfis, buf, len); + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); + break; + } + case 1: + { + uint8_t buf[12]; + + memset(buf, 0, sizeof(buf)); + buf[1] = 0xa; + buf[2] = 0x1; + buf[3] = 0x1; + if (len > sizeof(buf)) + len = sizeof(buf); + write_prdt(p, slot, cfis, buf, len); + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); + break; + } + case 2: + { + int msf, size; + uint64_t sectors; + uint8_t *bp, buf[50]; + + msf = (acmd[1] >> 1) & 1; + bp = buf + 2; + *bp++ = 1; + *bp++ = 1; + + *bp++ = 1; + *bp++ = 0x14; + *bp++ = 0; + *bp++ = 0xa0; + *bp++ = 0; + *bp++ = 0; + *bp++ = 0; + *bp++ = 0; + *bp++ = 1; + *bp++ = 0; + *bp++ = 0; + + *bp++ = 1; + *bp++ = 0x14; + *bp++ = 0; + *bp++ = 0xa1; + *bp++ = 0; + *bp++ = 0; + *bp++ = 0; + *bp++ = 0; + *bp++ = 1; + *bp++ = 0; + *bp++ = 0; + + *bp++ = 1; + *bp++ = 0x14; + *bp++ = 0; + *bp++ = 0xa2; + *bp++ = 0; + *bp++ = 0; + *bp++ = 0; + sectors = blockif_size(p->bctx) / blockif_sectsz(p->bctx); + sectors >>= 2; + if (msf) { + *bp++ = 0; + lba_to_msf(bp, sectors); + bp += 3; + } else { + be32enc(bp, sectors); + bp += 4; + } + + *bp++ = 1; + *bp++ = 0x14; + *bp++ = 0; + *bp++ = 1; + *bp++ = 0; + *bp++ = 0; + *bp++ = 0; + if (msf) { + *bp++ = 0; + lba_to_msf(bp, 0); + bp += 3; + } else { + *bp++ = 0; + *bp++ = 0; + *bp++ = 0; + *bp++ = 0; + } + + size = bp - buf; + be16enc(buf, size - 2); + if (len > size) + len = size; + write_prdt(p, slot, cfis, buf, len); + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); + break; + } + default: + { + uint32_t tfd; + + p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; + p->asc = 0x24; + tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, tfd); + break; + } + } +} + +static void +atapi_report_luns(struct ahci_port *p, int slot, uint8_t *cfis) +{ + uint8_t buf[16]; + + memset(buf, 0, sizeof(buf)); + buf[3] = 8; + + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + write_prdt(p, slot, cfis, buf, sizeof(buf)); + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); +} + +static void +atapi_read(struct ahci_port *p, int slot, uint8_t *cfis, uint32_t done) +{ + struct ahci_ioreq *aior; + struct ahci_cmd_hdr *hdr; + struct ahci_prdt_entry *prdt; + struct blockif_req *breq; + uint8_t *acmd; + uint64_t lba; + uint32_t len; + int err; + + acmd = cfis + 0x40; + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); + prdt = (struct ahci_prdt_entry *)(cfis + 0x80); + + lba = be32dec(acmd + 2); + if (acmd[0] == READ_10) + len = be16dec(acmd + 7); + else + len = be32dec(acmd + 6); + if (len == 0) { + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); + } + lba *= 2048; + len *= 2048; + + /* + * Pull request off free list + */ + aior = STAILQ_FIRST(&p->iofhd); + assert(aior != NULL); + STAILQ_REMOVE_HEAD(&p->iofhd, io_flist); + aior->cfis = cfis; + aior->slot = slot; + aior->len = len; + aior->done = done; + breq = &aior->io_req; + breq->br_offset = lba + done; + ahci_build_iov(p, aior, prdt, hdr->prdtl); + + /* Mark this command in-flight. */ + p->pending |= 1 << slot; + + /* Stuff request onto busy list. */ + TAILQ_INSERT_HEAD(&p->iobhd, aior, io_blist); + + err = blockif_read(p->bctx, breq); + assert(err == 0); +} + +static void +atapi_request_sense(struct ahci_port *p, int slot, uint8_t *cfis) +{ + uint8_t buf[64]; + uint8_t *acmd; + int len; + + acmd = cfis + 0x40; + len = acmd[4]; + if (len > sizeof(buf)) + len = sizeof(buf); + memset(buf, 0, len); + buf[0] = 0x70 | (1 << 7); + buf[2] = p->sense_key; + buf[7] = 10; + buf[12] = p->asc; + write_prdt(p, slot, cfis, buf, len); + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); +} + +static void +atapi_start_stop_unit(struct ahci_port *p, int slot, uint8_t *cfis) +{ + uint8_t *acmd = cfis + 0x40; + uint32_t tfd; + + switch (acmd[4] & 3) { + case 0: + case 1: + case 3: + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + tfd = ATA_S_READY | ATA_S_DSC; + break; + case 2: + /* TODO eject media */ + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; + p->asc = 0x53; + tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; + break; + } + ahci_write_fis_d2h(p, slot, cfis, tfd); +} + +static void +atapi_mode_sense(struct ahci_port *p, int slot, uint8_t *cfis) +{ + uint8_t *acmd; + uint32_t tfd = 0; + uint8_t pc, code; + int len; + + acmd = cfis + 0x40; + len = be16dec(acmd + 7); + pc = acmd[2] >> 6; + code = acmd[2] & 0x3f; + + switch (pc) { + case 0: + switch (code) { + case MODEPAGE_RW_ERROR_RECOVERY: + { + uint8_t buf[16]; + + if (len > sizeof(buf)) + len = sizeof(buf); + + memset(buf, 0, sizeof(buf)); + be16enc(buf, 16 - 2); + buf[2] = 0x70; + buf[8] = 0x01; + buf[9] = 16 - 10; + buf[11] = 0x05; + write_prdt(p, slot, cfis, buf, len); + tfd = ATA_S_READY | ATA_S_DSC; + break; + } + case MODEPAGE_CD_CAPABILITIES: + { + uint8_t buf[30]; + + if (len > sizeof(buf)) + len = sizeof(buf); + + memset(buf, 0, sizeof(buf)); + be16enc(buf, 30 - 2); + buf[2] = 0x70; + buf[8] = 0x2A; + buf[9] = 30 - 10; + buf[10] = 0x08; + buf[12] = 0x71; + be16enc(&buf[18], 2); + be16enc(&buf[20], 512); + write_prdt(p, slot, cfis, buf, len); + tfd = ATA_S_READY | ATA_S_DSC; + break; + } + default: + goto error; + break; + } + break; + case 3: + p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; + p->asc = 0x39; + tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; + break; +error: + case 1: + case 2: + p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; + p->asc = 0x24; + tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; + break; + } + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, tfd); +} + +static void +atapi_get_event_status_notification(struct ahci_port *p, int slot, + uint8_t *cfis) +{ + uint8_t *acmd; + uint32_t tfd; + + acmd = cfis + 0x40; + + /* we don't support asynchronous operation */ + if (!(acmd[1] & 1)) { + p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; + p->asc = 0x24; + tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; + } else { + uint8_t buf[8]; + int len; + + len = be16dec(acmd + 7); + if (len > sizeof(buf)) + len = sizeof(buf); + + memset(buf, 0, sizeof(buf)); + be16enc(buf, 8 - 2); + buf[2] = 0x04; + buf[3] = 0x10; + buf[5] = 0x02; + write_prdt(p, slot, cfis, buf, len); + tfd = ATA_S_READY | ATA_S_DSC; + } + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, tfd); +} + +static void +handle_packet_cmd(struct ahci_port *p, int slot, uint8_t *cfis) +{ + uint8_t *acmd; + + acmd = cfis + 0x40; + +#ifdef AHCI_DEBUG + { + int i; + DPRINTF("ACMD:"); + for (i = 0; i < 16; i++) + DPRINTF("%02x ", acmd[i]); + DPRINTF("\n"); + } +#endif + + switch (acmd[0]) { + case TEST_UNIT_READY: + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); + break; + case INQUIRY: + atapi_inquiry(p, slot, cfis); + break; + case READ_CAPACITY: + atapi_read_capacity(p, slot, cfis); + break; + case PREVENT_ALLOW: + /* TODO */ + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); + break; + case READ_TOC: + atapi_read_toc(p, slot, cfis); + break; + case REPORT_LUNS: + atapi_report_luns(p, slot, cfis); + break; + case READ_10: + case READ_12: + atapi_read(p, slot, cfis, 0); + break; + case REQUEST_SENSE: + atapi_request_sense(p, slot, cfis); + break; + case START_STOP_UNIT: + atapi_start_stop_unit(p, slot, cfis); + break; + case MODE_SENSE_10: + atapi_mode_sense(p, slot, cfis); + break; + case GET_EVENT_STATUS_NOTIFICATION: + atapi_get_event_status_notification(p, slot, cfis); + break; + default: + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; + p->asc = 0x20; + ahci_write_fis_d2h(p, slot, cfis, (p->sense_key << 12) | + ATA_S_READY | ATA_S_ERROR); + break; + } +} + +static void +ahci_handle_cmd(struct ahci_port *p, int slot, uint8_t *cfis) +{ + + p->tfd |= ATA_S_BUSY; + switch (cfis[2]) { + case ATA_ATA_IDENTIFY: + handle_identify(p, slot, cfis); + break; + case ATA_SETFEATURES: + { + switch (cfis[3]) { + case ATA_SF_ENAB_SATA_SF: + switch (cfis[12]) { + case ATA_SATA_SF_AN: + p->tfd = ATA_S_DSC | ATA_S_READY; + break; + default: + p->tfd = ATA_S_ERROR | ATA_S_READY; + p->tfd |= (ATA_ERROR_ABORT << 8); + break; + } + break; + case ATA_SF_ENAB_WCACHE: + case ATA_SF_DIS_WCACHE: + case ATA_SF_ENAB_RCACHE: + case ATA_SF_DIS_RCACHE: + p->tfd = ATA_S_DSC | ATA_S_READY; + break; + case ATA_SF_SETXFER: + { + switch (cfis[12] & 0xf8) { + case ATA_PIO: + case ATA_PIO0: + break; + case ATA_WDMA0: + case ATA_UDMA0: + p->xfermode = (cfis[12] & 0x7); + break; + } + p->tfd = ATA_S_DSC | ATA_S_READY; + break; + } + default: + p->tfd = ATA_S_ERROR | ATA_S_READY; + p->tfd |= (ATA_ERROR_ABORT << 8); + break; + } + ahci_write_fis_d2h(p, slot, cfis, p->tfd); + break; + } + case ATA_SET_MULTI: + if (cfis[12] != 0 && + (cfis[12] > 128 || (cfis[12] & (cfis[12] - 1)))) { + p->tfd = ATA_S_ERROR | ATA_S_READY; + p->tfd |= (ATA_ERROR_ABORT << 8); + } else { + p->mult_sectors = cfis[12]; + p->tfd = ATA_S_DSC | ATA_S_READY; + } + ahci_write_fis_d2h(p, slot, cfis, p->tfd); + break; + case ATA_READ: + case ATA_WRITE: + case ATA_READ48: + case ATA_WRITE48: + case ATA_READ_MUL: + case ATA_WRITE_MUL: + case ATA_READ_MUL48: + case ATA_WRITE_MUL48: + case ATA_READ_DMA: + case ATA_WRITE_DMA: + case ATA_READ_DMA48: + case ATA_WRITE_DMA48: + case ATA_READ_FPDMA_QUEUED: + case ATA_WRITE_FPDMA_QUEUED: + ahci_handle_rw(p, slot, cfis, 0); + break; + case ATA_FLUSHCACHE: + case ATA_FLUSHCACHE48: + ahci_handle_flush(p, slot, cfis); + break; + case ATA_DATA_SET_MANAGEMENT: + if (cfis[11] == 0 && cfis[3] == ATA_DSM_TRIM && + cfis[13] == 0 && cfis[12] == 1) { + ahci_handle_dsm_trim(p, slot, cfis, 0); + break; + } + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + break; + case ATA_SEND_FPDMA_QUEUED: + if ((cfis[13] & 0x1f) == ATA_SFPDMA_DSM && + cfis[17] == 0 && cfis[16] == ATA_DSM_TRIM && + cfis[11] == 0 && cfis[3] == 1) { + ahci_handle_dsm_trim(p, slot, cfis, 0); + break; + } + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + break; + case ATA_READ_LOG_EXT: + case ATA_READ_LOG_DMA_EXT: + ahci_handle_read_log(p, slot, cfis); + break; + case ATA_SECURITY_FREEZE_LOCK: + case ATA_SMART_CMD: + case ATA_NOP: + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + break; + case ATA_CHECK_POWER_MODE: + cfis[12] = 0xff; /* always on */ + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); + break; + case ATA_STANDBY_CMD: + case ATA_STANDBY_IMMEDIATE: + case ATA_IDLE_CMD: + case ATA_IDLE_IMMEDIATE: + case ATA_SLEEP: + case ATA_READ_VERIFY: + case ATA_READ_VERIFY48: + ahci_write_fis_d2h(p, slot, cfis, ATA_S_READY | ATA_S_DSC); + break; + case ATA_ATAPI_IDENTIFY: + handle_atapi_identify(p, slot, cfis); + break; + case ATA_PACKET_CMD: + if (!p->atapi) { + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + } else + handle_packet_cmd(p, slot, cfis); + break; + default: + WPRINTF("Unsupported cmd:%02x\n", cfis[2]); + ahci_write_fis_d2h(p, slot, cfis, + (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR); + break; + } +} + +static void +ahci_handle_slot(struct ahci_port *p, int slot) +{ + struct ahci_cmd_hdr *hdr; +#ifdef AHCI_DEBUG + struct ahci_prdt_entry *prdt; +#endif + struct pci_ahci_softc *sc; + uint8_t *cfis; +#ifdef AHCI_DEBUG + int cfl, i; +#endif + + sc = p->pr_sc; + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); +#ifdef AHCI_DEBUG + cfl = (hdr->flags & 0x1f) * 4; +#endif + cfis = paddr_guest2host(ahci_ctx(sc), hdr->ctba, + 0x80 + hdr->prdtl * sizeof(struct ahci_prdt_entry)); +#ifdef AHCI_DEBUG + prdt = (struct ahci_prdt_entry *)(cfis + 0x80); + + DPRINTF("\ncfis:"); + for (i = 0; i < cfl; i++) { + if (i % 10 == 0) + DPRINTF("\n"); + DPRINTF("%02x ", cfis[i]); + } + DPRINTF("\n"); + + for (i = 0; i < hdr->prdtl; i++) { + DPRINTF("%d@%08"PRIx64"\n", prdt->dbc & 0x3fffff, prdt->dba); + prdt++; + } +#endif + + if (cfis[0] != FIS_TYPE_REGH2D) { + WPRINTF("Not a H2D FIS:%02x\n", cfis[0]); + return; + } + + if (cfis[1] & 0x80) { + ahci_handle_cmd(p, slot, cfis); + } else { + if (cfis[15] & (1 << 2)) + p->reset = 1; + else if (p->reset) { + p->reset = 0; + ahci_port_reset(p); + } + p->ci &= ~(1 << slot); + } +} + +static void +ahci_handle_port(struct ahci_port *p) +{ + + if (!(p->cmd & AHCI_P_CMD_ST)) + return; + + /* + * Search for any new commands to issue ignoring those that + * are already in-flight. Stop if device is busy or in error. + */ + for (; (p->ci & ~p->pending) != 0; p->ccs = ((p->ccs + 1) & 31)) { + if ((p->tfd & (ATA_S_BUSY | ATA_S_DRQ)) != 0) + break; + if (p->waitforclear) + break; + if ((p->ci & ~p->pending & (1 << p->ccs)) != 0) { + p->cmd &= ~AHCI_P_CMD_CCS_MASK; + p->cmd |= p->ccs << AHCI_P_CMD_CCS_SHIFT; + ahci_handle_slot(p, p->ccs); + } + } +} + +/* + * blockif callback routine - this runs in the context of the blockif + * i/o thread, so the mutex needs to be acquired. + */ +static void +ata_ioreq_cb(struct blockif_req *br, int err) +{ + struct ahci_cmd_hdr *hdr; + struct ahci_ioreq *aior; + struct ahci_port *p; + struct pci_ahci_softc *sc; + uint32_t tfd; + uint8_t *cfis; + int slot, ncq, dsm; + + DPRINTF("%s %d\n", __func__, err); + + ncq = dsm = 0; + aior = br->br_param; + p = aior->io_pr; + cfis = aior->cfis; + slot = aior->slot; + sc = p->pr_sc; + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + slot * AHCI_CL_SIZE); + + if (cfis[2] == ATA_WRITE_FPDMA_QUEUED || + cfis[2] == ATA_READ_FPDMA_QUEUED || + cfis[2] == ATA_SEND_FPDMA_QUEUED) + ncq = 1; + if (cfis[2] == ATA_DATA_SET_MANAGEMENT || + (cfis[2] == ATA_SEND_FPDMA_QUEUED && + (cfis[13] & 0x1f) == ATA_SFPDMA_DSM)) + dsm = 1; + + pthread_mutex_lock(&sc->mtx); + + /* + * Delete the blockif request from the busy list + */ + TAILQ_REMOVE(&p->iobhd, aior, io_blist); + + /* + * Move the blockif request back to the free list + */ + STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist); + + if (!err) + hdr->prdbc = aior->done; + + if (!err && aior->more) { + if (dsm) + ahci_handle_dsm_trim(p, slot, cfis, aior->done); + else + ahci_handle_rw(p, slot, cfis, aior->done); + goto out; + } + + if (!err) + tfd = ATA_S_READY | ATA_S_DSC; + else + tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR; + if (ncq) + ahci_write_fis_sdb(p, slot, cfis, tfd); + else + ahci_write_fis_d2h(p, slot, cfis, tfd); + + /* + * This command is now complete. + */ + p->pending &= ~(1 << slot); + + ahci_check_stopped(p); + ahci_handle_port(p); +out: + pthread_mutex_unlock(&sc->mtx); + DPRINTF("%s exit\n", __func__); +} + +static void +atapi_ioreq_cb(struct blockif_req *br, int err) +{ + struct ahci_cmd_hdr *hdr; + struct ahci_ioreq *aior; + struct ahci_port *p; + struct pci_ahci_softc *sc; + uint8_t *cfis; + uint32_t tfd; + int slot; + + DPRINTF("%s %d\n", __func__, err); + + aior = br->br_param; + p = aior->io_pr; + cfis = aior->cfis; + slot = aior->slot; + sc = p->pr_sc; + hdr = (struct ahci_cmd_hdr *)(p->cmd_lst + aior->slot * AHCI_CL_SIZE); + + pthread_mutex_lock(&sc->mtx); + + /* + * Delete the blockif request from the busy list + */ + TAILQ_REMOVE(&p->iobhd, aior, io_blist); + + /* + * Move the blockif request back to the free list + */ + STAILQ_INSERT_TAIL(&p->iofhd, aior, io_flist); + + if (!err) + hdr->prdbc = aior->done; + + if (!err && aior->more) { + atapi_read(p, slot, cfis, aior->done); + goto out; + } + + if (!err) { + tfd = ATA_S_READY | ATA_S_DSC; + } else { + p->sense_key = ATA_SENSE_ILLEGAL_REQUEST; + p->asc = 0x21; + tfd = (p->sense_key << 12) | ATA_S_READY | ATA_S_ERROR; + } + cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN; + ahci_write_fis_d2h(p, slot, cfis, tfd); + + /* + * This command is now complete. + */ + p->pending &= ~(1 << slot); + + ahci_check_stopped(p); + ahci_handle_port(p); +out: + pthread_mutex_unlock(&sc->mtx); + DPRINTF("%s exit\n", __func__); +} + +static void +pci_ahci_ioreq_init(struct ahci_port *pr) +{ + struct ahci_ioreq *vr; + int i; + + pr->ioqsz = blockif_queuesz(pr->bctx); + pr->ioreq = calloc(pr->ioqsz, sizeof(struct ahci_ioreq)); + STAILQ_INIT(&pr->iofhd); + + /* + * Add all i/o request entries to the free queue + */ + for (i = 0; i < pr->ioqsz; i++) { + vr = &pr->ioreq[i]; + vr->io_pr = pr; + if (!pr->atapi) + vr->io_req.br_callback = ata_ioreq_cb; + else + vr->io_req.br_callback = atapi_ioreq_cb; + vr->io_req.br_param = vr; + STAILQ_INSERT_TAIL(&pr->iofhd, vr, io_flist); + } + + TAILQ_INIT(&pr->iobhd); +} + +static void +pci_ahci_port_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value) +{ + int port = (offset - AHCI_OFFSET) / AHCI_STEP; + offset = (offset - AHCI_OFFSET) % AHCI_STEP; + struct ahci_port *p = &sc->port[port]; + + DPRINTF("pci_ahci_port %d: write offset 0x%"PRIx64" value 0x%"PRIx64"\n", + port, offset, value); + + switch (offset) { + case AHCI_P_CLB: + p->clb = value; + break; + case AHCI_P_CLBU: + p->clbu = value; + break; + case AHCI_P_FB: + p->fb = value; + break; + case AHCI_P_FBU: + p->fbu = value; + break; + case AHCI_P_IS: + p->is &= ~value; + ahci_port_intr(p); + break; + case AHCI_P_IE: + p->ie = value & 0xFDC000FF; + ahci_port_intr(p); + break; + case AHCI_P_CMD: + { + p->cmd &= ~(AHCI_P_CMD_ST | AHCI_P_CMD_SUD | AHCI_P_CMD_POD | + AHCI_P_CMD_CLO | AHCI_P_CMD_FRE | AHCI_P_CMD_APSTE | + AHCI_P_CMD_ATAPI | AHCI_P_CMD_DLAE | AHCI_P_CMD_ALPE | + AHCI_P_CMD_ASP | AHCI_P_CMD_ICC_MASK); + p->cmd |= (AHCI_P_CMD_ST | AHCI_P_CMD_SUD | AHCI_P_CMD_POD | + AHCI_P_CMD_CLO | AHCI_P_CMD_FRE | AHCI_P_CMD_APSTE | + AHCI_P_CMD_ATAPI | AHCI_P_CMD_DLAE | AHCI_P_CMD_ALPE | + AHCI_P_CMD_ASP | AHCI_P_CMD_ICC_MASK) & value; + + if (!(value & AHCI_P_CMD_ST)) { + ahci_port_stop(p); + } else { + uint64_t clb; + + p->cmd |= AHCI_P_CMD_CR; + clb = (uint64_t)p->clbu << 32 | p->clb; + p->cmd_lst = paddr_guest2host(ahci_ctx(sc), clb, + AHCI_CL_SIZE * AHCI_MAX_SLOTS); + } + + if (value & AHCI_P_CMD_FRE) { + uint64_t fb; + + p->cmd |= AHCI_P_CMD_FR; + fb = (uint64_t)p->fbu << 32 | p->fb; + /* we don't support FBSCP, so rfis size is 256Bytes */ + p->rfis = paddr_guest2host(ahci_ctx(sc), fb, 256); + } else { + p->cmd &= ~AHCI_P_CMD_FR; + } + + if (value & AHCI_P_CMD_CLO) { + p->tfd &= ~(ATA_S_BUSY | ATA_S_DRQ); + p->cmd &= ~AHCI_P_CMD_CLO; + } + + if (value & AHCI_P_CMD_ICC_MASK) { + p->cmd &= ~AHCI_P_CMD_ICC_MASK; + } + + ahci_handle_port(p); + break; + } + case AHCI_P_TFD: + case AHCI_P_SIG: + case AHCI_P_SSTS: + WPRINTF("pci_ahci_port: read only registers 0x%"PRIx64"\n", offset); + break; + case AHCI_P_SCTL: + p->sctl = value; + if (!(p->cmd & AHCI_P_CMD_ST)) { + if (value & ATA_SC_DET_RESET) + ahci_port_reset(p); + } + break; + case AHCI_P_SERR: + p->serr &= ~value; + break; + case AHCI_P_SACT: + p->sact |= value; + break; + case AHCI_P_CI: + p->ci |= value; + ahci_handle_port(p); + break; + case AHCI_P_SNTF: + case AHCI_P_FBS: + default: + break; + } +} + +static void +pci_ahci_host_write(struct pci_ahci_softc *sc, uint64_t offset, uint64_t value) +{ + DPRINTF("pci_ahci_host: write offset 0x%"PRIx64" value 0x%"PRIx64"\n", + offset, value); + + switch (offset) { + case AHCI_CAP: + case AHCI_PI: + case AHCI_VS: + case AHCI_CAP2: + DPRINTF("pci_ahci_host: read only registers 0x%"PRIx64"\n", offset); + break; + case AHCI_GHC: + if (value & AHCI_GHC_HR) { + ahci_reset(sc); + break; + } + if (value & AHCI_GHC_IE) + sc->ghc |= AHCI_GHC_IE; + else + sc->ghc &= ~AHCI_GHC_IE; + ahci_generate_intr(sc, 0xffffffff); + break; + case AHCI_IS: + sc->is &= ~value; + ahci_generate_intr(sc, value); + break; + default: + break; + } +} + +static void +pci_ahci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value) +{ + struct pci_ahci_softc *sc = pi->pi_arg; + + assert(baridx == 5); + assert((offset % 4) == 0 && size == 4); + + pthread_mutex_lock(&sc->mtx); + + if (offset < AHCI_OFFSET) + pci_ahci_host_write(sc, offset, value); + else if (offset < AHCI_OFFSET + sc->ports * AHCI_STEP) + pci_ahci_port_write(sc, offset, value); + else + WPRINTF("pci_ahci: unknown i/o write offset 0x%"PRIx64"\n", offset); + + pthread_mutex_unlock(&sc->mtx); +} + +static uint64_t +pci_ahci_host_read(struct pci_ahci_softc *sc, uint64_t offset) +{ + uint32_t value; + + switch (offset) { + case AHCI_CAP: + case AHCI_GHC: + case AHCI_IS: + case AHCI_PI: + case AHCI_VS: + case AHCI_CCCC: + case AHCI_CCCP: + case AHCI_EM_LOC: + case AHCI_EM_CTL: + case AHCI_CAP2: + { + uint32_t *p = &sc->cap; + p += (offset - AHCI_CAP) / sizeof(uint32_t); + value = *p; + break; + } + default: + value = 0; + break; + } + DPRINTF("pci_ahci_host: read offset 0x%"PRIx64" value 0x%x\n", + offset, value); + + return (value); +} + +static uint64_t +pci_ahci_port_read(struct pci_ahci_softc *sc, uint64_t offset) +{ + uint32_t value; + int port = (offset - AHCI_OFFSET) / AHCI_STEP; + offset = (offset - AHCI_OFFSET) % AHCI_STEP; + + switch (offset) { + case AHCI_P_CLB: + case AHCI_P_CLBU: + case AHCI_P_FB: + case AHCI_P_FBU: + case AHCI_P_IS: + case AHCI_P_IE: + case AHCI_P_CMD: + case AHCI_P_TFD: + case AHCI_P_SIG: + case AHCI_P_SSTS: + case AHCI_P_SCTL: + case AHCI_P_SERR: + case AHCI_P_SACT: + case AHCI_P_CI: + case AHCI_P_SNTF: + case AHCI_P_FBS: + { + uint32_t *p= &sc->port[port].clb; + p += (offset - AHCI_P_CLB) / sizeof(uint32_t); + value = *p; + break; + } + default: + value = 0; + break; + } + + DPRINTF("pci_ahci_port %d: read offset 0x%"PRIx64" value 0x%x\n", + port, offset, value); + + return value; +} + +static uint64_t +pci_ahci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, + uint64_t regoff, int size) +{ + struct pci_ahci_softc *sc = pi->pi_arg; + uint64_t offset; + uint32_t value; + + assert(baridx == 5); + assert(size == 1 || size == 2 || size == 4); + assert((regoff & (size - 1)) == 0); + + pthread_mutex_lock(&sc->mtx); + + offset = regoff & ~0x3; /* round down to a multiple of 4 bytes */ + if (offset < AHCI_OFFSET) + value = pci_ahci_host_read(sc, offset); + else if (offset < AHCI_OFFSET + sc->ports * AHCI_STEP) + value = pci_ahci_port_read(sc, offset); + else { + value = 0; + WPRINTF("pci_ahci: unknown i/o read offset 0x%"PRIx64"\n", + regoff); + } + value >>= 8 * (regoff & 0x3); + + pthread_mutex_unlock(&sc->mtx); + + return (value); +} + +static int +pci_ahci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts, int atapi) +{ + char bident[sizeof("XX:XX:XX")]; + struct blockif_ctxt *bctxt; + struct pci_ahci_softc *sc; + int ret, slots, p; + MD5_CTX mdctx; + u_char digest[16]; + char *next, *next2; + + ret = 0; + +#ifdef AHCI_DEBUG + dbg = fopen("/tmp/log", "w+"); +#endif + + sc = calloc(1, sizeof(struct pci_ahci_softc)); + pi->pi_arg = sc; + sc->asc_pi = pi; + pthread_mutex_init(&sc->mtx, NULL); + sc->ports = 0; + sc->pi = 0; + slots = 32; + + for (p = 0; p < MAX_PORTS && opts != NULL; p++, opts = next) { + /* Identify and cut off type of present port. */ + if (strncmp(opts, "hd:", 3) == 0) { + atapi = 0; + opts += 3; + } else if (strncmp(opts, "cd:", 3) == 0) { + atapi = 1; + opts += 3; + } + + /* Find and cut off the next port options. */ + next = strstr(opts, ",hd:"); + next2 = strstr(opts, ",cd:"); + if (next == NULL || (next2 != NULL && next2 < next)) + next = next2; + if (next != NULL) { + next[0] = 0; + next++; + } + + if (opts[0] == 0) + continue; + + /* + * Attempt to open the backing image. Use the PCI slot/func + * and the port number for the identifier string. + */ + snprintf(bident, sizeof(bident), "%d:%d:%d", pi->pi_slot, + pi->pi_func, p); + bctxt = blockif_open(opts, bident); + if (bctxt == NULL) { + sc->ports = p; + ret = 1; + goto open_fail; + } + sc->port[p].bctx = bctxt; + sc->port[p].pr_sc = sc; + sc->port[p].port = p; + sc->port[p].atapi = atapi; + +#ifndef __FreeBSD__ + /* + * Attempt to enable the write cache for this device, as the + * guest will issue FLUSH commands when it requires durability. + * + * Failure here is fine, since an always-sync device will not + * have an impact on correctness. + */ + (void) blockif_set_wce(bctxt, 1); +#endif + + /* + * Create an identifier for the backing file. + * Use parts of the md5 sum of the filename + */ + MD5Init(&mdctx); + MD5Update(&mdctx, opts, strlen(opts)); + MD5Final(digest, &mdctx); + snprintf(sc->port[p].ident, AHCI_PORT_IDENT, + "BHYVE-%02X%02X-%02X%02X-%02X%02X", + digest[0], digest[1], digest[2], digest[3], digest[4], + digest[5]); + + /* + * Allocate blockif request structures and add them + * to the free list + */ + pci_ahci_ioreq_init(&sc->port[p]); + + sc->pi |= (1 << p); + if (sc->port[p].ioqsz < slots) + slots = sc->port[p].ioqsz; + } + sc->ports = p; + + /* Intel ICH8 AHCI */ + --slots; + if (sc->ports < DEF_PORTS) + sc->ports = DEF_PORTS; + sc->cap = AHCI_CAP_64BIT | AHCI_CAP_SNCQ | AHCI_CAP_SSNTF | + AHCI_CAP_SMPS | AHCI_CAP_SSS | AHCI_CAP_SALP | + AHCI_CAP_SAL | AHCI_CAP_SCLO | (0x3 << AHCI_CAP_ISS_SHIFT)| + AHCI_CAP_PMD | AHCI_CAP_SSC | AHCI_CAP_PSC | + (slots << AHCI_CAP_NCS_SHIFT) | AHCI_CAP_SXS | (sc->ports - 1); + + sc->vs = 0x10300; + sc->cap2 = AHCI_CAP2_APST; + ahci_reset(sc); + + pci_set_cfgdata16(pi, PCIR_DEVICE, 0x2821); + pci_set_cfgdata16(pi, PCIR_VENDOR, 0x8086); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE); + pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_STORAGE_SATA); + pci_set_cfgdata8(pi, PCIR_PROGIF, PCIP_STORAGE_SATA_AHCI_1_0); + p = MIN(sc->ports, 16); + p = flsl(p) - ((p & (p - 1)) ? 0 : 1); + pci_emul_add_msicap(pi, 1 << p); + pci_emul_alloc_bar(pi, 5, PCIBAR_MEM32, + AHCI_OFFSET + sc->ports * AHCI_STEP); + + pci_lintr_request(pi); + +open_fail: + if (ret) { + for (p = 0; p < sc->ports; p++) { + if (sc->port[p].bctx != NULL) + blockif_close(sc->port[p].bctx); + } + free(sc); + } + + return (ret); +} + +static int +pci_ahci_hd_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + + return (pci_ahci_init(ctx, pi, opts, 0)); +} + +static int +pci_ahci_atapi_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + + return (pci_ahci_init(ctx, pi, opts, 1)); +} + +/* + * Use separate emulation names to distinguish drive and atapi devices + */ +struct pci_devemu pci_de_ahci = { + .pe_emu = "ahci", + .pe_init = pci_ahci_hd_init, + .pe_barwrite = pci_ahci_write, + .pe_barread = pci_ahci_read +}; +PCI_EMUL_SET(pci_de_ahci); + +struct pci_devemu pci_de_ahci_hd = { + .pe_emu = "ahci-hd", + .pe_init = pci_ahci_hd_init, + .pe_barwrite = pci_ahci_write, + .pe_barread = pci_ahci_read +}; +PCI_EMUL_SET(pci_de_ahci_hd); + +struct pci_devemu pci_de_ahci_cd = { + .pe_emu = "ahci-cd", + .pe_init = pci_ahci_atapi_init, + .pe_barwrite = pci_ahci_write, + .pe_barread = pci_ahci_read +}; +PCI_EMUL_SET(pci_de_ahci_cd); diff --git a/usr/src/cmd/bhyve/pci_e82545.c b/usr/src/cmd/bhyve/pci_e82545.c new file mode 100644 index 0000000000..e211b5cf9c --- /dev/null +++ b/usr/src/cmd/bhyve/pci_e82545.c @@ -0,0 +1,2418 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2016 Alexander Motin <mav@FreeBSD.org> + * Copyright (c) 2015 Peter Grehan <grehan@freebsd.org> + * Copyright (c) 2013 Jeremiah Lott, Avere Systems + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/limits.h> +#include <sys/ioctl.h> +#include <sys/uio.h> +#include <net/ethernet.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#ifndef __FreeBSD__ +#include <sys/filio.h> +#endif + +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <md5.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sysexits.h> +#include <unistd.h> +#include <pthread.h> +#include <pthread_np.h> + +#include "e1000_regs.h" +#include "e1000_defines.h" +#include "mii.h" + +#include "bhyverun.h" +#include "pci_emul.h" +#include "mevent.h" + +/* Hardware/register definitions XXX: move some to common code. */ +#define E82545_VENDOR_ID_INTEL 0x8086 +#define E82545_DEV_ID_82545EM_COPPER 0x100F +#define E82545_SUBDEV_ID 0x1008 + +#define E82545_REVISION_4 4 + +#define E82545_MDIC_DATA_MASK 0x0000FFFF +#define E82545_MDIC_OP_MASK 0x0c000000 +#define E82545_MDIC_IE 0x20000000 + +#define E82545_EECD_FWE_DIS 0x00000010 /* Flash writes disabled */ +#define E82545_EECD_FWE_EN 0x00000020 /* Flash writes enabled */ +#define E82545_EECD_FWE_MASK 0x00000030 /* Flash writes mask */ + +#define E82545_BAR_REGISTER 0 +#define E82545_BAR_REGISTER_LEN (128*1024) +#define E82545_BAR_FLASH 1 +#define E82545_BAR_FLASH_LEN (64*1024) +#define E82545_BAR_IO 2 +#define E82545_BAR_IO_LEN 8 + +#define E82545_IOADDR 0x00000000 +#define E82545_IODATA 0x00000004 +#define E82545_IO_REGISTER_MAX 0x0001FFFF +#define E82545_IO_FLASH_BASE 0x00080000 +#define E82545_IO_FLASH_MAX 0x000FFFFF + +#define E82545_ARRAY_ENTRY(reg, offset) (reg + (offset<<2)) +#define E82545_RAR_MAX 15 +#define E82545_MTA_MAX 127 +#define E82545_VFTA_MAX 127 + +/* Slightly modified from the driver versions, hardcoded for 3 opcode bits, + * followed by 6 address bits. + * TODO: make opcode bits and addr bits configurable? + * NVM Commands - Microwire */ +#define E82545_NVM_OPCODE_BITS 3 +#define E82545_NVM_ADDR_BITS 6 +#define E82545_NVM_DATA_BITS 16 +#define E82545_NVM_OPADDR_BITS (E82545_NVM_OPCODE_BITS + E82545_NVM_ADDR_BITS) +#define E82545_NVM_ADDR_MASK ((1 << E82545_NVM_ADDR_BITS)-1) +#define E82545_NVM_OPCODE_MASK \ + (((1 << E82545_NVM_OPCODE_BITS) - 1) << E82545_NVM_ADDR_BITS) +#define E82545_NVM_OPCODE_READ (0x6 << E82545_NVM_ADDR_BITS) /* read */ +#define E82545_NVM_OPCODE_WRITE (0x5 << E82545_NVM_ADDR_BITS) /* write */ +#define E82545_NVM_OPCODE_ERASE (0x7 << E82545_NVM_ADDR_BITS) /* erase */ +#define E82545_NVM_OPCODE_EWEN (0x4 << E82545_NVM_ADDR_BITS) /* wr-enable */ + +#define E82545_NVM_EEPROM_SIZE 64 /* 64 * 16-bit values == 128K */ + +#define E1000_ICR_SRPD 0x00010000 + +/* This is an arbitrary number. There is no hard limit on the chip. */ +#define I82545_MAX_TXSEGS 64 + +/* Legacy receive descriptor */ +struct e1000_rx_desc { + uint64_t buffer_addr; /* Address of the descriptor's data buffer */ + uint16_t length; /* Length of data DMAed into data buffer */ + uint16_t csum; /* Packet checksum */ + uint8_t status; /* Descriptor status */ + uint8_t errors; /* Descriptor Errors */ + uint16_t special; +}; + +/* Transmit descriptor types */ +#define E1000_TXD_MASK (E1000_TXD_CMD_DEXT | 0x00F00000) +#define E1000_TXD_TYP_L (0) +#define E1000_TXD_TYP_C (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_C) +#define E1000_TXD_TYP_D (E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D) + +/* Legacy transmit descriptor */ +struct e1000_tx_desc { + uint64_t buffer_addr; /* Address of the descriptor's data buffer */ + union { + uint32_t data; + struct { + uint16_t length; /* Data buffer length */ + uint8_t cso; /* Checksum offset */ + uint8_t cmd; /* Descriptor control */ + } flags; + } lower; + union { + uint32_t data; + struct { + uint8_t status; /* Descriptor status */ + uint8_t css; /* Checksum start */ + uint16_t special; + } fields; + } upper; +}; + +/* Context descriptor */ +struct e1000_context_desc { + union { + uint32_t ip_config; + struct { + uint8_t ipcss; /* IP checksum start */ + uint8_t ipcso; /* IP checksum offset */ + uint16_t ipcse; /* IP checksum end */ + } ip_fields; + } lower_setup; + union { + uint32_t tcp_config; + struct { + uint8_t tucss; /* TCP checksum start */ + uint8_t tucso; /* TCP checksum offset */ + uint16_t tucse; /* TCP checksum end */ + } tcp_fields; + } upper_setup; + uint32_t cmd_and_length; + union { + uint32_t data; + struct { + uint8_t status; /* Descriptor status */ + uint8_t hdr_len; /* Header length */ + uint16_t mss; /* Maximum segment size */ + } fields; + } tcp_seg_setup; +}; + +/* Data descriptor */ +struct e1000_data_desc { + uint64_t buffer_addr; /* Address of the descriptor's buffer address */ + union { + uint32_t data; + struct { + uint16_t length; /* Data buffer length */ + uint8_t typ_len_ext; + uint8_t cmd; + } flags; + } lower; + union { + uint32_t data; + struct { + uint8_t status; /* Descriptor status */ + uint8_t popts; /* Packet Options */ + uint16_t special; + } fields; + } upper; +}; + +union e1000_tx_udesc { + struct e1000_tx_desc td; + struct e1000_context_desc cd; + struct e1000_data_desc dd; +}; + +/* Tx checksum info for a packet. */ +struct ck_info { + int ck_valid; /* ck_info is valid */ + uint8_t ck_start; /* start byte of cksum calcuation */ + uint8_t ck_off; /* offset of cksum insertion */ + uint16_t ck_len; /* length of cksum calc: 0 is to packet-end */ +}; + +/* + * Debug printf + */ +static int e82545_debug = 0; +#define DPRINTF(msg,params...) if (e82545_debug) fprintf(stderr, "e82545: " msg, params) +#define WPRINTF(msg,params...) fprintf(stderr, "e82545: " msg, params) + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +/* s/w representation of the RAL/RAH regs */ +struct eth_uni { + int eu_valid; + int eu_addrsel; + struct ether_addr eu_eth; +}; + + +struct e82545_softc { + struct pci_devinst *esc_pi; + struct vmctx *esc_ctx; + struct mevent *esc_mevp; + struct mevent *esc_mevpitr; + pthread_mutex_t esc_mtx; + struct ether_addr esc_mac; + int esc_tapfd; + + /* General */ + uint32_t esc_CTRL; /* x0000 device ctl */ + uint32_t esc_FCAL; /* x0028 flow ctl addr lo */ + uint32_t esc_FCAH; /* x002C flow ctl addr hi */ + uint32_t esc_FCT; /* x0030 flow ctl type */ + uint32_t esc_VET; /* x0038 VLAN eth type */ + uint32_t esc_FCTTV; /* x0170 flow ctl tx timer */ + uint32_t esc_LEDCTL; /* x0E00 LED control */ + uint32_t esc_PBA; /* x1000 pkt buffer allocation */ + + /* Interrupt control */ + int esc_irq_asserted; + uint32_t esc_ICR; /* x00C0 cause read/clear */ + uint32_t esc_ITR; /* x00C4 intr throttling */ + uint32_t esc_ICS; /* x00C8 cause set */ + uint32_t esc_IMS; /* x00D0 mask set/read */ + uint32_t esc_IMC; /* x00D8 mask clear */ + + /* Transmit */ + union e1000_tx_udesc *esc_txdesc; + struct e1000_context_desc esc_txctx; + pthread_t esc_tx_tid; + pthread_cond_t esc_tx_cond; + int esc_tx_enabled; + int esc_tx_active; + uint32_t esc_TXCW; /* x0178 transmit config */ + uint32_t esc_TCTL; /* x0400 transmit ctl */ + uint32_t esc_TIPG; /* x0410 inter-packet gap */ + uint16_t esc_AIT; /* x0458 Adaptive Interframe Throttle */ + uint64_t esc_tdba; /* verified 64-bit desc table addr */ + uint32_t esc_TDBAL; /* x3800 desc table addr, low bits */ + uint32_t esc_TDBAH; /* x3804 desc table addr, hi 32-bits */ + uint32_t esc_TDLEN; /* x3808 # descriptors in bytes */ + uint16_t esc_TDH; /* x3810 desc table head idx */ + uint16_t esc_TDHr; /* internal read version of TDH */ + uint16_t esc_TDT; /* x3818 desc table tail idx */ + uint32_t esc_TIDV; /* x3820 intr delay */ + uint32_t esc_TXDCTL; /* x3828 desc control */ + uint32_t esc_TADV; /* x382C intr absolute delay */ + + /* L2 frame acceptance */ + struct eth_uni esc_uni[16]; /* 16 x unicast MAC addresses */ + uint32_t esc_fmcast[128]; /* Multicast filter bit-match */ + uint32_t esc_fvlan[128]; /* VLAN 4096-bit filter */ + + /* Receive */ + struct e1000_rx_desc *esc_rxdesc; + pthread_cond_t esc_rx_cond; + int esc_rx_enabled; + int esc_rx_active; + int esc_rx_loopback; + uint32_t esc_RCTL; /* x0100 receive ctl */ + uint32_t esc_FCRTL; /* x2160 flow cntl thresh, low */ + uint32_t esc_FCRTH; /* x2168 flow cntl thresh, hi */ + uint64_t esc_rdba; /* verified 64-bit desc table addr */ + uint32_t esc_RDBAL; /* x2800 desc table addr, low bits */ + uint32_t esc_RDBAH; /* x2804 desc table addr, hi 32-bits*/ + uint32_t esc_RDLEN; /* x2808 #descriptors */ + uint16_t esc_RDH; /* x2810 desc table head idx */ + uint16_t esc_RDT; /* x2818 desc table tail idx */ + uint32_t esc_RDTR; /* x2820 intr delay */ + uint32_t esc_RXDCTL; /* x2828 desc control */ + uint32_t esc_RADV; /* x282C intr absolute delay */ + uint32_t esc_RSRPD; /* x2C00 recv small packet detect */ + uint32_t esc_RXCSUM; /* x5000 receive cksum ctl */ + + /* IO Port register access */ + uint32_t io_addr; + + /* Shadow copy of MDIC */ + uint32_t mdi_control; + /* Shadow copy of EECD */ + uint32_t eeprom_control; + /* Latest NVM in/out */ + uint16_t nvm_data; + uint16_t nvm_opaddr; + /* stats */ + uint32_t missed_pkt_count; /* dropped for no room in rx queue */ + uint32_t pkt_rx_by_size[6]; + uint32_t pkt_tx_by_size[6]; + uint32_t good_pkt_rx_count; + uint32_t bcast_pkt_rx_count; + uint32_t mcast_pkt_rx_count; + uint32_t good_pkt_tx_count; + uint32_t bcast_pkt_tx_count; + uint32_t mcast_pkt_tx_count; + uint32_t oversize_rx_count; + uint32_t tso_tx_count; + uint64_t good_octets_rx; + uint64_t good_octets_tx; + uint64_t missed_octets; /* counts missed and oversized */ + + uint8_t nvm_bits:6; /* number of bits remaining in/out */ + uint8_t nvm_mode:2; +#define E82545_NVM_MODE_OPADDR 0x0 +#define E82545_NVM_MODE_DATAIN 0x1 +#define E82545_NVM_MODE_DATAOUT 0x2 + /* EEPROM data */ + uint16_t eeprom_data[E82545_NVM_EEPROM_SIZE]; +}; + +static void e82545_reset(struct e82545_softc *sc, int dev); +static void e82545_rx_enable(struct e82545_softc *sc); +static void e82545_rx_disable(struct e82545_softc *sc); +#ifdef __FreeBSD__ +static void e82545_tap_callback(int fd, enum ev_type type, void *param); +#endif +static void e82545_tx_start(struct e82545_softc *sc); +static void e82545_tx_enable(struct e82545_softc *sc); +static void e82545_tx_disable(struct e82545_softc *sc); + +static inline int +e82545_size_stat_index(uint32_t size) +{ + if (size <= 64) { + return 0; + } else if (size >= 1024) { + return 5; + } else { + /* should be 1-4 */ + return (ffs(size) - 6); + } +} + +static void +e82545_init_eeprom(struct e82545_softc *sc) +{ + uint16_t checksum, i; + + /* mac addr */ + sc->eeprom_data[NVM_MAC_ADDR] = ((uint16_t)sc->esc_mac.octet[0]) | + (((uint16_t)sc->esc_mac.octet[1]) << 8); + sc->eeprom_data[NVM_MAC_ADDR+1] = ((uint16_t)sc->esc_mac.octet[2]) | + (((uint16_t)sc->esc_mac.octet[3]) << 8); + sc->eeprom_data[NVM_MAC_ADDR+2] = ((uint16_t)sc->esc_mac.octet[4]) | + (((uint16_t)sc->esc_mac.octet[5]) << 8); + + /* pci ids */ + sc->eeprom_data[NVM_SUB_DEV_ID] = E82545_SUBDEV_ID; + sc->eeprom_data[NVM_SUB_VEN_ID] = E82545_VENDOR_ID_INTEL; + sc->eeprom_data[NVM_DEV_ID] = E82545_DEV_ID_82545EM_COPPER; + sc->eeprom_data[NVM_VEN_ID] = E82545_VENDOR_ID_INTEL; + + /* fill in the checksum */ + checksum = 0; + for (i = 0; i < NVM_CHECKSUM_REG; i++) { + checksum += sc->eeprom_data[i]; + } + checksum = NVM_SUM - checksum; + sc->eeprom_data[NVM_CHECKSUM_REG] = checksum; + DPRINTF("eeprom checksum: 0x%x\r\n", checksum); +} + +static void +e82545_write_mdi(struct e82545_softc *sc, uint8_t reg_addr, + uint8_t phy_addr, uint32_t data) +{ + DPRINTF("Write mdi reg:0x%x phy:0x%x data: 0x%x\r\n", reg_addr, phy_addr, data); +} + +static uint32_t +e82545_read_mdi(struct e82545_softc *sc, uint8_t reg_addr, + uint8_t phy_addr) +{ + //DPRINTF("Read mdi reg:0x%x phy:0x%x\r\n", reg_addr, phy_addr); + switch (reg_addr) { + case PHY_STATUS: + return (MII_SR_LINK_STATUS | MII_SR_AUTONEG_CAPS | + MII_SR_AUTONEG_COMPLETE); + case PHY_AUTONEG_ADV: + return NWAY_AR_SELECTOR_FIELD; + case PHY_LP_ABILITY: + return 0; + case PHY_1000T_STATUS: + return (SR_1000T_LP_FD_CAPS | SR_1000T_REMOTE_RX_STATUS | + SR_1000T_LOCAL_RX_STATUS); + case PHY_ID1: + return (M88E1011_I_PHY_ID >> 16) & 0xFFFF; + case PHY_ID2: + return (M88E1011_I_PHY_ID | E82545_REVISION_4) & 0xFFFF; + default: + DPRINTF("Unknown mdi read reg:0x%x phy:0x%x\r\n", reg_addr, phy_addr); + return 0; + } + /* not reached */ +} + +static void +e82545_eecd_strobe(struct e82545_softc *sc) +{ + /* Microwire state machine */ + /* + DPRINTF("eeprom state machine srtobe " + "0x%x 0x%x 0x%x 0x%x\r\n", + sc->nvm_mode, sc->nvm_bits, + sc->nvm_opaddr, sc->nvm_data);*/ + + if (sc->nvm_bits == 0) { + DPRINTF("eeprom state machine not expecting data! " + "0x%x 0x%x 0x%x 0x%x\r\n", + sc->nvm_mode, sc->nvm_bits, + sc->nvm_opaddr, sc->nvm_data); + return; + } + sc->nvm_bits--; + if (sc->nvm_mode == E82545_NVM_MODE_DATAOUT) { + /* shifting out */ + if (sc->nvm_data & 0x8000) { + sc->eeprom_control |= E1000_EECD_DO; + } else { + sc->eeprom_control &= ~E1000_EECD_DO; + } + sc->nvm_data <<= 1; + if (sc->nvm_bits == 0) { + /* read done, back to opcode mode. */ + sc->nvm_opaddr = 0; + sc->nvm_mode = E82545_NVM_MODE_OPADDR; + sc->nvm_bits = E82545_NVM_OPADDR_BITS; + } + } else if (sc->nvm_mode == E82545_NVM_MODE_DATAIN) { + /* shifting in */ + sc->nvm_data <<= 1; + if (sc->eeprom_control & E1000_EECD_DI) { + sc->nvm_data |= 1; + } + if (sc->nvm_bits == 0) { + /* eeprom write */ + uint16_t op = sc->nvm_opaddr & E82545_NVM_OPCODE_MASK; + uint16_t addr = sc->nvm_opaddr & E82545_NVM_ADDR_MASK; + if (op != E82545_NVM_OPCODE_WRITE) { + DPRINTF("Illegal eeprom write op 0x%x\r\n", + sc->nvm_opaddr); + } else if (addr >= E82545_NVM_EEPROM_SIZE) { + DPRINTF("Illegal eeprom write addr 0x%x\r\n", + sc->nvm_opaddr); + } else { + DPRINTF("eeprom write eeprom[0x%x] = 0x%x\r\n", + addr, sc->nvm_data); + sc->eeprom_data[addr] = sc->nvm_data; + } + /* back to opcode mode */ + sc->nvm_opaddr = 0; + sc->nvm_mode = E82545_NVM_MODE_OPADDR; + sc->nvm_bits = E82545_NVM_OPADDR_BITS; + } + } else if (sc->nvm_mode == E82545_NVM_MODE_OPADDR) { + sc->nvm_opaddr <<= 1; + if (sc->eeprom_control & E1000_EECD_DI) { + sc->nvm_opaddr |= 1; + } + if (sc->nvm_bits == 0) { + uint16_t op = sc->nvm_opaddr & E82545_NVM_OPCODE_MASK; + switch (op) { + case E82545_NVM_OPCODE_EWEN: + DPRINTF("eeprom write enable: 0x%x\r\n", + sc->nvm_opaddr); + /* back to opcode mode */ + sc->nvm_opaddr = 0; + sc->nvm_mode = E82545_NVM_MODE_OPADDR; + sc->nvm_bits = E82545_NVM_OPADDR_BITS; + break; + case E82545_NVM_OPCODE_READ: + { + uint16_t addr = sc->nvm_opaddr & + E82545_NVM_ADDR_MASK; + sc->nvm_mode = E82545_NVM_MODE_DATAOUT; + sc->nvm_bits = E82545_NVM_DATA_BITS; + if (addr < E82545_NVM_EEPROM_SIZE) { + sc->nvm_data = sc->eeprom_data[addr]; + DPRINTF("eeprom read: eeprom[0x%x] = 0x%x\r\n", + addr, sc->nvm_data); + } else { + DPRINTF("eeprom illegal read: 0x%x\r\n", + sc->nvm_opaddr); + sc->nvm_data = 0; + } + break; + } + case E82545_NVM_OPCODE_WRITE: + sc->nvm_mode = E82545_NVM_MODE_DATAIN; + sc->nvm_bits = E82545_NVM_DATA_BITS; + sc->nvm_data = 0; + break; + default: + DPRINTF("eeprom unknown op: 0x%x\r\r", + sc->nvm_opaddr); + /* back to opcode mode */ + sc->nvm_opaddr = 0; + sc->nvm_mode = E82545_NVM_MODE_OPADDR; + sc->nvm_bits = E82545_NVM_OPADDR_BITS; + } + } + } else { + DPRINTF("eeprom state machine wrong state! " + "0x%x 0x%x 0x%x 0x%x\r\n", + sc->nvm_mode, sc->nvm_bits, + sc->nvm_opaddr, sc->nvm_data); + } +} + +#ifdef __FreeBSD__ +static void +e82545_itr_callback(int fd, enum ev_type type, void *param) +{ + uint32_t new; + struct e82545_softc *sc = param; + + pthread_mutex_lock(&sc->esc_mtx); + new = sc->esc_ICR & sc->esc_IMS; + if (new && !sc->esc_irq_asserted) { + DPRINTF("itr callback: lintr assert %x\r\n", new); + sc->esc_irq_asserted = 1; + pci_lintr_assert(sc->esc_pi); + } else { + mevent_delete(sc->esc_mevpitr); + sc->esc_mevpitr = NULL; + } + pthread_mutex_unlock(&sc->esc_mtx); +} +#endif + +static void +e82545_icr_assert(struct e82545_softc *sc, uint32_t bits) +{ + uint32_t new; + + DPRINTF("icr assert: 0x%x\r\n", bits); + + /* + * An interrupt is only generated if bits are set that + * aren't already in the ICR, these bits are unmasked, + * and there isn't an interrupt already pending. + */ + new = bits & ~sc->esc_ICR & sc->esc_IMS; + sc->esc_ICR |= bits; + + if (new == 0) { + DPRINTF("icr assert: masked %x, ims %x\r\n", new, sc->esc_IMS); + } else if (sc->esc_mevpitr != NULL) { + DPRINTF("icr assert: throttled %x, ims %x\r\n", new, sc->esc_IMS); + } else if (!sc->esc_irq_asserted) { + DPRINTF("icr assert: lintr assert %x\r\n", new); + sc->esc_irq_asserted = 1; + pci_lintr_assert(sc->esc_pi); + if (sc->esc_ITR != 0) { +#ifdef __FreeBSD__ + sc->esc_mevpitr = mevent_add( + (sc->esc_ITR + 3905) / 3906, /* 256ns -> 1ms */ + EVF_TIMER, e82545_itr_callback, sc); +#endif + } + } +} + +static void +e82545_ims_change(struct e82545_softc *sc, uint32_t bits) +{ + uint32_t new; + + /* + * Changing the mask may allow previously asserted + * but masked interrupt requests to generate an interrupt. + */ + new = bits & sc->esc_ICR & ~sc->esc_IMS; + sc->esc_IMS |= bits; + + if (new == 0) { + DPRINTF("ims change: masked %x, ims %x\r\n", new, sc->esc_IMS); + } else if (sc->esc_mevpitr != NULL) { + DPRINTF("ims change: throttled %x, ims %x\r\n", new, sc->esc_IMS); + } else if (!sc->esc_irq_asserted) { + DPRINTF("ims change: lintr assert %x\n\r", new); + sc->esc_irq_asserted = 1; + pci_lintr_assert(sc->esc_pi); + if (sc->esc_ITR != 0) { +#ifdef __FreeBSD__ + sc->esc_mevpitr = mevent_add( + (sc->esc_ITR + 3905) / 3906, /* 256ns -> 1ms */ + EVF_TIMER, e82545_itr_callback, sc); +#endif + } + } +} + +static void +e82545_icr_deassert(struct e82545_softc *sc, uint32_t bits) +{ + + DPRINTF("icr deassert: 0x%x\r\n", bits); + sc->esc_ICR &= ~bits; + + /* + * If there are no longer any interrupt sources and there + * was an asserted interrupt, clear it + */ + if (sc->esc_irq_asserted && !(sc->esc_ICR & sc->esc_IMS)) { + DPRINTF("icr deassert: lintr deassert %x\r\n", bits); + pci_lintr_deassert(sc->esc_pi); + sc->esc_irq_asserted = 0; + } +} + +static void +e82545_intr_write(struct e82545_softc *sc, uint32_t offset, uint32_t value) +{ + + DPRINTF("intr_write: off %x, val %x\n\r", offset, value); + + switch (offset) { + case E1000_ICR: + e82545_icr_deassert(sc, value); + break; + case E1000_ITR: + sc->esc_ITR = value; + break; + case E1000_ICS: + sc->esc_ICS = value; /* not used: store for debug */ + e82545_icr_assert(sc, value); + break; + case E1000_IMS: + e82545_ims_change(sc, value); + break; + case E1000_IMC: + sc->esc_IMC = value; /* for debug */ + sc->esc_IMS &= ~value; + // XXX clear interrupts if all ICR bits now masked + // and interrupt was pending ? + break; + default: + break; + } +} + +static uint32_t +e82545_intr_read(struct e82545_softc *sc, uint32_t offset) +{ + uint32_t retval; + + retval = 0; + + DPRINTF("intr_read: off %x\n\r", offset); + + switch (offset) { + case E1000_ICR: + retval = sc->esc_ICR; + sc->esc_ICR = 0; + e82545_icr_deassert(sc, ~0); + break; + case E1000_ITR: + retval = sc->esc_ITR; + break; + case E1000_ICS: + /* write-only register */ + break; + case E1000_IMS: + retval = sc->esc_IMS; + break; + case E1000_IMC: + /* write-only register */ + break; + default: + break; + } + + return (retval); +} + +static void +e82545_devctl(struct e82545_softc *sc, uint32_t val) +{ + + sc->esc_CTRL = val & ~E1000_CTRL_RST; + + if (val & E1000_CTRL_RST) { + DPRINTF("e1k: s/w reset, ctl %x\n", val); + e82545_reset(sc, 1); + } + /* XXX check for phy reset ? */ +} + +static void +e82545_rx_update_rdba(struct e82545_softc *sc) +{ + + /* XXX verify desc base/len within phys mem range */ + sc->esc_rdba = (uint64_t)sc->esc_RDBAH << 32 | + sc->esc_RDBAL; + + /* Cache host mapping of guest descriptor array */ + sc->esc_rxdesc = paddr_guest2host(sc->esc_ctx, + sc->esc_rdba, sc->esc_RDLEN); +} + +static void +e82545_rx_ctl(struct e82545_softc *sc, uint32_t val) +{ + int on; + + on = ((val & E1000_RCTL_EN) == E1000_RCTL_EN); + + /* Save RCTL after stripping reserved bits 31:27,24,21,14,11:10,0 */ + sc->esc_RCTL = val & ~0xF9204c01; + + DPRINTF("rx_ctl - %s RCTL %x, val %x\n", + on ? "on" : "off", sc->esc_RCTL, val); + + /* state change requested */ + if (on != sc->esc_rx_enabled) { + if (on) { + /* Catch disallowed/unimplemented settings */ + //assert(!(val & E1000_RCTL_LBM_TCVR)); + + if (sc->esc_RCTL & E1000_RCTL_LBM_TCVR) { + sc->esc_rx_loopback = 1; + } else { + sc->esc_rx_loopback = 0; + } + + e82545_rx_update_rdba(sc); + e82545_rx_enable(sc); + } else { + e82545_rx_disable(sc); + sc->esc_rx_loopback = 0; + sc->esc_rdba = 0; + sc->esc_rxdesc = NULL; + } + } +} + +static void +e82545_tx_update_tdba(struct e82545_softc *sc) +{ + + /* XXX verify desc base/len within phys mem range */ + sc->esc_tdba = (uint64_t)sc->esc_TDBAH << 32 | sc->esc_TDBAL; + + /* Cache host mapping of guest descriptor array */ + sc->esc_txdesc = paddr_guest2host(sc->esc_ctx, sc->esc_tdba, + sc->esc_TDLEN); +} + +static void +e82545_tx_ctl(struct e82545_softc *sc, uint32_t val) +{ + int on; + + on = ((val & E1000_TCTL_EN) == E1000_TCTL_EN); + + /* ignore TCTL_EN settings that don't change state */ + if (on == sc->esc_tx_enabled) + return; + + if (on) { + e82545_tx_update_tdba(sc); + e82545_tx_enable(sc); + } else { + e82545_tx_disable(sc); + sc->esc_tdba = 0; + sc->esc_txdesc = NULL; + } + + /* Save TCTL value after stripping reserved bits 31:25,23,2,0 */ + sc->esc_TCTL = val & ~0xFE800005; +} + +int +e82545_bufsz(uint32_t rctl) +{ + + switch (rctl & (E1000_RCTL_BSEX | E1000_RCTL_SZ_256)) { + case (E1000_RCTL_SZ_2048): return (2048); + case (E1000_RCTL_SZ_1024): return (1024); + case (E1000_RCTL_SZ_512): return (512); + case (E1000_RCTL_SZ_256): return (256); + case (E1000_RCTL_BSEX|E1000_RCTL_SZ_16384): return (16384); + case (E1000_RCTL_BSEX|E1000_RCTL_SZ_8192): return (8192); + case (E1000_RCTL_BSEX|E1000_RCTL_SZ_4096): return (4096); + } + return (256); /* Forbidden value. */ +} + +#ifdef __FreeBSD__ +static uint8_t dummybuf[2048]; + +/* XXX one packet at a time until this is debugged */ +static void +e82545_tap_callback(int fd, enum ev_type type, void *param) +{ + struct e82545_softc *sc = param; + struct e1000_rx_desc *rxd; + struct iovec vec[64]; + int left, len, lim, maxpktsz, maxpktdesc, bufsz, i, n, size; + uint32_t cause = 0; + uint16_t *tp, tag, head; + + pthread_mutex_lock(&sc->esc_mtx); + DPRINTF("rx_run: head %x, tail %x\r\n", sc->esc_RDH, sc->esc_RDT); + + if (!sc->esc_rx_enabled || sc->esc_rx_loopback) { + DPRINTF("rx disabled (!%d || %d) -- packet(s) dropped\r\n", + sc->esc_rx_enabled, sc->esc_rx_loopback); + while (read(sc->esc_tapfd, dummybuf, sizeof(dummybuf)) > 0) { + } + goto done1; + } + bufsz = e82545_bufsz(sc->esc_RCTL); + maxpktsz = (sc->esc_RCTL & E1000_RCTL_LPE) ? 16384 : 1522; + maxpktdesc = (maxpktsz + bufsz - 1) / bufsz; + size = sc->esc_RDLEN / 16; + head = sc->esc_RDH; + left = (size + sc->esc_RDT - head) % size; + if (left < maxpktdesc) { + DPRINTF("rx overflow (%d < %d) -- packet(s) dropped\r\n", + left, maxpktdesc); + while (read(sc->esc_tapfd, dummybuf, sizeof(dummybuf)) > 0) { + } + goto done1; + } + + sc->esc_rx_active = 1; + pthread_mutex_unlock(&sc->esc_mtx); + + for (lim = size / 4; lim > 0 && left >= maxpktdesc; lim -= n) { + + /* Grab rx descriptor pointed to by the head pointer */ + for (i = 0; i < maxpktdesc; i++) { + rxd = &sc->esc_rxdesc[(head + i) % size]; + vec[i].iov_base = paddr_guest2host(sc->esc_ctx, + rxd->buffer_addr, bufsz); + vec[i].iov_len = bufsz; + } + len = readv(sc->esc_tapfd, vec, maxpktdesc); + if (len <= 0) { + DPRINTF("tap: readv() returned %d\n", len); + goto done; + } + + /* + * Adjust the packet length based on whether the CRC needs + * to be stripped or if the packet is less than the minimum + * eth packet size. + */ + if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) + len = ETHER_MIN_LEN - ETHER_CRC_LEN; + if (!(sc->esc_RCTL & E1000_RCTL_SECRC)) + len += ETHER_CRC_LEN; + n = (len + bufsz - 1) / bufsz; + + DPRINTF("packet read %d bytes, %d segs, head %d\r\n", + len, n, head); + + /* Apply VLAN filter. */ + tp = (uint16_t *)vec[0].iov_base + 6; + if ((sc->esc_RCTL & E1000_RCTL_VFE) && + (ntohs(tp[0]) == sc->esc_VET)) { + tag = ntohs(tp[1]) & 0x0fff; + if ((sc->esc_fvlan[tag >> 5] & + (1 << (tag & 0x1f))) != 0) { + DPRINTF("known VLAN %d\r\n", tag); + } else { + DPRINTF("unknown VLAN %d\r\n", tag); + n = 0; + continue; + } + } + + /* Update all consumed descriptors. */ + for (i = 0; i < n - 1; i++) { + rxd = &sc->esc_rxdesc[(head + i) % size]; + rxd->length = bufsz; + rxd->csum = 0; + rxd->errors = 0; + rxd->special = 0; + rxd->status = E1000_RXD_STAT_DD; + } + rxd = &sc->esc_rxdesc[(head + i) % size]; + rxd->length = len % bufsz; + rxd->csum = 0; + rxd->errors = 0; + rxd->special = 0; + /* XXX signal no checksum for now */ + rxd->status = E1000_RXD_STAT_PIF | E1000_RXD_STAT_IXSM | + E1000_RXD_STAT_EOP | E1000_RXD_STAT_DD; + + /* Schedule receive interrupts. */ + if (len <= sc->esc_RSRPD) { + cause |= E1000_ICR_SRPD | E1000_ICR_RXT0; + } else { + /* XXX: RDRT and RADV timers should be here. */ + cause |= E1000_ICR_RXT0; + } + + head = (head + n) % size; + left -= n; + } + +done: + pthread_mutex_lock(&sc->esc_mtx); + sc->esc_rx_active = 0; + if (sc->esc_rx_enabled == 0) + pthread_cond_signal(&sc->esc_rx_cond); + + sc->esc_RDH = head; + /* Respect E1000_RCTL_RDMTS */ + left = (size + sc->esc_RDT - head) % size; + if (left < (size >> (((sc->esc_RCTL >> 8) & 3) + 1))) + cause |= E1000_ICR_RXDMT0; + /* Assert all accumulated interrupts. */ + if (cause != 0) + e82545_icr_assert(sc, cause); +done1: + DPRINTF("rx_run done: head %x, tail %x\r\n", sc->esc_RDH, sc->esc_RDT); + pthread_mutex_unlock(&sc->esc_mtx); +} +#endif + +static uint16_t +e82545_carry(uint32_t sum) +{ + + sum = (sum & 0xFFFF) + (sum >> 16); + if (sum > 0xFFFF) + sum -= 0xFFFF; + return (sum); +} + +static uint16_t +#ifdef __FreeBSD__ +e82545_buf_checksum(uint8_t *buf, int len) +#else +e82545_buf_checksum(caddr_t buf, int len) +#endif +{ + int i; + uint32_t sum = 0; + + /* Checksum all the pairs of bytes first... */ + for (i = 0; i < (len & ~1U); i += 2) + sum += *((u_int16_t *)(buf + i)); + + /* + * If there's a single byte left over, checksum it, too. + * Network byte order is big-endian, so the remaining byte is + * the high byte. + */ + if (i < len) + sum += htons(buf[i] << 8); + + return (e82545_carry(sum)); +} + +static uint16_t +e82545_iov_checksum(struct iovec *iov, int iovcnt, int off, int len) +{ + int now, odd; + uint32_t sum = 0, s; + + /* Skip completely unneeded vectors. */ + while (iovcnt > 0 && iov->iov_len <= off && off > 0) { + off -= iov->iov_len; + iov++; + iovcnt--; + } + + /* Calculate checksum of requested range. */ + odd = 0; + while (len > 0 && iovcnt > 0) { + now = MIN(len, iov->iov_len - off); + s = e82545_buf_checksum(iov->iov_base + off, now); + sum += odd ? (s << 8) : s; + odd ^= (now & 1); + len -= now; + off = 0; + iov++; + iovcnt--; + } + + return (e82545_carry(sum)); +} + +/* + * Return the transmit descriptor type. + */ +int +e82545_txdesc_type(uint32_t lower) +{ + int type; + + type = 0; + + if (lower & E1000_TXD_CMD_DEXT) + type = lower & E1000_TXD_MASK; + + return (type); +} + +static void +e82545_transmit_checksum(struct iovec *iov, int iovcnt, struct ck_info *ck) +{ + uint16_t cksum; + int cklen; + + DPRINTF("tx cksum: iovcnt/s/off/len %d/%d/%d/%d\r\n", + iovcnt, ck->ck_start, ck->ck_off, ck->ck_len); + cklen = ck->ck_len ? ck->ck_len - ck->ck_start + 1 : INT_MAX; + cksum = e82545_iov_checksum(iov, iovcnt, ck->ck_start, cklen); + *(uint16_t *)((uint8_t *)iov[0].iov_base + ck->ck_off) = ~cksum; +} + +static void +e82545_transmit_backend(struct e82545_softc *sc, struct iovec *iov, int iovcnt) +{ + + if (sc->esc_tapfd == -1) + return; + + (void) writev(sc->esc_tapfd, iov, iovcnt); +} + +static void +e82545_transmit_done(struct e82545_softc *sc, uint16_t head, uint16_t tail, + uint16_t dsize, int *tdwb) +{ + union e1000_tx_udesc *dsc; + + for ( ; head != tail; head = (head + 1) % dsize) { + dsc = &sc->esc_txdesc[head]; + if (dsc->td.lower.data & E1000_TXD_CMD_RS) { + dsc->td.upper.data |= E1000_TXD_STAT_DD; + *tdwb = 1; + } + } +} + +static int +e82545_transmit(struct e82545_softc *sc, uint16_t head, uint16_t tail, + uint16_t dsize, uint16_t *rhead, int *tdwb) +{ +#ifdef __FreeBSD__ + uint8_t *hdr, *hdrp; +#else + caddr_t hdr, hdrp; +#endif + struct iovec iovb[I82545_MAX_TXSEGS + 2]; + struct iovec tiov[I82545_MAX_TXSEGS + 2]; + struct e1000_context_desc *cd; + struct ck_info ckinfo[2]; + struct iovec *iov; + union e1000_tx_udesc *dsc; + int desc, dtype, len, ntype, iovcnt, tlen, hdrlen, vlen, tcp, tso; + int mss, paylen, seg, tiovcnt, left, now, nleft, nnow, pv, pvoff; + uint32_t tcpsum, tcpseq; + uint16_t ipcs, tcpcs, ipid, ohead; + + ckinfo[0].ck_valid = ckinfo[1].ck_valid = 0; + iovcnt = 0; + tlen = 0; + ntype = 0; + tso = 0; + ohead = head; + hdr = NULL; + + /* iovb[0/1] may be used for writable copy of headers. */ + iov = &iovb[2]; + + for (desc = 0; ; desc++, head = (head + 1) % dsize) { + if (head == tail) { + *rhead = head; + return (0); + } + dsc = &sc->esc_txdesc[head]; + dtype = e82545_txdesc_type(dsc->td.lower.data); + + if (desc == 0) { + switch (dtype) { + case E1000_TXD_TYP_C: + DPRINTF("tx ctxt desc idx %d: %016jx " + "%08x%08x\r\n", + head, dsc->td.buffer_addr, + dsc->td.upper.data, dsc->td.lower.data); + /* Save context and return */ + sc->esc_txctx = dsc->cd; + goto done; + case E1000_TXD_TYP_L: + DPRINTF("tx legacy desc idx %d: %08x%08x\r\n", + head, dsc->td.upper.data, dsc->td.lower.data); + /* + * legacy cksum start valid in first descriptor + */ + ntype = dtype; + ckinfo[0].ck_start = dsc->td.upper.fields.css; + break; + case E1000_TXD_TYP_D: + DPRINTF("tx data desc idx %d: %08x%08x\r\n", + head, dsc->td.upper.data, dsc->td.lower.data); + ntype = dtype; + break; + default: + break; + } + } else { + /* Descriptor type must be consistent */ + assert(dtype == ntype); + DPRINTF("tx next desc idx %d: %08x%08x\r\n", + head, dsc->td.upper.data, dsc->td.lower.data); + } + + len = (dtype == E1000_TXD_TYP_L) ? dsc->td.lower.flags.length : + dsc->dd.lower.data & 0xFFFFF; + + if (len > 0) { + /* Strip checksum supplied by guest. */ + if ((dsc->td.lower.data & E1000_TXD_CMD_EOP) != 0 && + (dsc->td.lower.data & E1000_TXD_CMD_IFCS) == 0) + len -= 2; + tlen += len; + if (iovcnt < I82545_MAX_TXSEGS) { + iov[iovcnt].iov_base = paddr_guest2host( + sc->esc_ctx, dsc->td.buffer_addr, len); + iov[iovcnt].iov_len = len; + } + iovcnt++; + } + + /* + * Pull out info that is valid in the final descriptor + * and exit descriptor loop. + */ + if (dsc->td.lower.data & E1000_TXD_CMD_EOP) { + if (dtype == E1000_TXD_TYP_L) { + if (dsc->td.lower.data & E1000_TXD_CMD_IC) { + ckinfo[0].ck_valid = 1; + ckinfo[0].ck_off = + dsc->td.lower.flags.cso; + ckinfo[0].ck_len = 0; + } + } else { + cd = &sc->esc_txctx; + if (dsc->dd.lower.data & E1000_TXD_CMD_TSE) + tso = 1; + if (dsc->dd.upper.fields.popts & + E1000_TXD_POPTS_IXSM) + ckinfo[0].ck_valid = 1; + if (dsc->dd.upper.fields.popts & + E1000_TXD_POPTS_IXSM || tso) { + ckinfo[0].ck_start = + cd->lower_setup.ip_fields.ipcss; + ckinfo[0].ck_off = + cd->lower_setup.ip_fields.ipcso; + ckinfo[0].ck_len = + cd->lower_setup.ip_fields.ipcse; + } + if (dsc->dd.upper.fields.popts & + E1000_TXD_POPTS_TXSM) + ckinfo[1].ck_valid = 1; + if (dsc->dd.upper.fields.popts & + E1000_TXD_POPTS_TXSM || tso) { + ckinfo[1].ck_start = + cd->upper_setup.tcp_fields.tucss; + ckinfo[1].ck_off = + cd->upper_setup.tcp_fields.tucso; + ckinfo[1].ck_len = + cd->upper_setup.tcp_fields.tucse; + } + } + break; + } + } + + if (iovcnt > I82545_MAX_TXSEGS) { + WPRINTF("tx too many descriptors (%d > %d) -- dropped\r\n", + iovcnt, I82545_MAX_TXSEGS); + goto done; + } + + hdrlen = vlen = 0; + /* Estimate writable space for VLAN header insertion. */ + if ((sc->esc_CTRL & E1000_CTRL_VME) && + (dsc->td.lower.data & E1000_TXD_CMD_VLE)) { + hdrlen = ETHER_ADDR_LEN*2; + vlen = ETHER_VLAN_ENCAP_LEN; + } + if (!tso) { + /* Estimate required writable space for checksums. */ + if (ckinfo[0].ck_valid) + hdrlen = MAX(hdrlen, ckinfo[0].ck_off + 2); + if (ckinfo[1].ck_valid) + hdrlen = MAX(hdrlen, ckinfo[1].ck_off + 2); + /* Round up writable space to the first vector. */ + if (hdrlen != 0 && iov[0].iov_len > hdrlen && + iov[0].iov_len < hdrlen + 100) + hdrlen = iov[0].iov_len; + } else { + /* In case of TSO header length provided by software. */ + hdrlen = sc->esc_txctx.tcp_seg_setup.fields.hdr_len; + } + + /* Allocate, fill and prepend writable header vector. */ + if (hdrlen != 0) { + hdr = __builtin_alloca(hdrlen + vlen); + hdr += vlen; + for (left = hdrlen, hdrp = hdr; left > 0; + left -= now, hdrp += now) { + now = MIN(left, iov->iov_len); + memcpy(hdrp, iov->iov_base, now); + iov->iov_base += now; + iov->iov_len -= now; + if (iov->iov_len == 0) { + iov++; + iovcnt--; + } + } + iov--; + iovcnt++; + iov->iov_base = hdr; + iov->iov_len = hdrlen; + } + + /* Insert VLAN tag. */ + if (vlen != 0) { + hdr -= ETHER_VLAN_ENCAP_LEN; + memmove(hdr, hdr + ETHER_VLAN_ENCAP_LEN, ETHER_ADDR_LEN*2); + hdrlen += ETHER_VLAN_ENCAP_LEN; + hdr[ETHER_ADDR_LEN*2 + 0] = sc->esc_VET >> 8; + hdr[ETHER_ADDR_LEN*2 + 1] = sc->esc_VET & 0xff; + hdr[ETHER_ADDR_LEN*2 + 2] = dsc->td.upper.fields.special >> 8; + hdr[ETHER_ADDR_LEN*2 + 3] = dsc->td.upper.fields.special & 0xff; + iov->iov_base = hdr; + iov->iov_len += ETHER_VLAN_ENCAP_LEN; + /* Correct checksum offsets after VLAN tag insertion. */ + ckinfo[0].ck_start += ETHER_VLAN_ENCAP_LEN; + ckinfo[0].ck_off += ETHER_VLAN_ENCAP_LEN; + if (ckinfo[0].ck_len != 0) + ckinfo[0].ck_len += ETHER_VLAN_ENCAP_LEN; + ckinfo[1].ck_start += ETHER_VLAN_ENCAP_LEN; + ckinfo[1].ck_off += ETHER_VLAN_ENCAP_LEN; + if (ckinfo[1].ck_len != 0) + ckinfo[1].ck_len += ETHER_VLAN_ENCAP_LEN; + } + + /* Simple non-TSO case. */ + if (!tso) { + /* Calculate checksums and transmit. */ + if (ckinfo[0].ck_valid) + e82545_transmit_checksum(iov, iovcnt, &ckinfo[0]); + if (ckinfo[1].ck_valid) + e82545_transmit_checksum(iov, iovcnt, &ckinfo[1]); + e82545_transmit_backend(sc, iov, iovcnt); + goto done; + } + + /* Doing TSO. */ + tcp = (sc->esc_txctx.cmd_and_length & E1000_TXD_CMD_TCP) != 0; + mss = sc->esc_txctx.tcp_seg_setup.fields.mss; + paylen = (sc->esc_txctx.cmd_and_length & 0x000fffff); + DPRINTF("tx %s segmentation offload %d+%d/%d bytes %d iovs\r\n", + tcp ? "TCP" : "UDP", hdrlen, paylen, mss, iovcnt); + ipid = ntohs(*(uint16_t *)&hdr[ckinfo[0].ck_start + 4]); + tcpseq = ntohl(*(uint32_t *)&hdr[ckinfo[1].ck_start + 4]); + ipcs = *(uint16_t *)&hdr[ckinfo[0].ck_off]; + tcpcs = 0; + if (ckinfo[1].ck_valid) /* Save partial pseudo-header checksum. */ + tcpcs = *(uint16_t *)&hdr[ckinfo[1].ck_off]; + pv = 1; + pvoff = 0; + for (seg = 0, left = paylen; left > 0; seg++, left -= now) { + now = MIN(left, mss); + + /* Construct IOVs for the segment. */ + /* Include whole original header. */ + tiov[0].iov_base = hdr; + tiov[0].iov_len = hdrlen; + tiovcnt = 1; + /* Include respective part of payload IOV. */ + for (nleft = now; pv < iovcnt && nleft > 0; nleft -= nnow) { + nnow = MIN(nleft, iov[pv].iov_len - pvoff); + tiov[tiovcnt].iov_base = iov[pv].iov_base + pvoff; + tiov[tiovcnt++].iov_len = nnow; + if (pvoff + nnow == iov[pv].iov_len) { + pv++; + pvoff = 0; + } else + pvoff += nnow; + } + DPRINTF("tx segment %d %d+%d bytes %d iovs\r\n", + seg, hdrlen, now, tiovcnt); + + /* Update IP header. */ + if (sc->esc_txctx.cmd_and_length & E1000_TXD_CMD_IP) { + /* IPv4 -- set length and ID */ + *(uint16_t *)&hdr[ckinfo[0].ck_start + 2] = + htons(hdrlen - ckinfo[0].ck_start + now); + *(uint16_t *)&hdr[ckinfo[0].ck_start + 4] = + htons(ipid + seg); + } else { + /* IPv6 -- set length */ + *(uint16_t *)&hdr[ckinfo[0].ck_start + 4] = + htons(hdrlen - ckinfo[0].ck_start - 40 + + now); + } + + /* Update pseudo-header checksum. */ + tcpsum = tcpcs; + tcpsum += htons(hdrlen - ckinfo[1].ck_start + now); + + /* Update TCP/UDP headers. */ + if (tcp) { + /* Update sequence number and FIN/PUSH flags. */ + *(uint32_t *)&hdr[ckinfo[1].ck_start + 4] = + htonl(tcpseq + paylen - left); + if (now < left) { + hdr[ckinfo[1].ck_start + 13] &= + ~(TH_FIN | TH_PUSH); + } + } else { + /* Update payload length. */ + *(uint32_t *)&hdr[ckinfo[1].ck_start + 4] = + hdrlen - ckinfo[1].ck_start + now; + } + + /* Calculate checksums and transmit. */ + if (ckinfo[0].ck_valid) { + *(uint16_t *)&hdr[ckinfo[0].ck_off] = ipcs; + e82545_transmit_checksum(tiov, tiovcnt, &ckinfo[0]); + } + if (ckinfo[1].ck_valid) { + *(uint16_t *)&hdr[ckinfo[1].ck_off] = + e82545_carry(tcpsum); + e82545_transmit_checksum(tiov, tiovcnt, &ckinfo[1]); + } + e82545_transmit_backend(sc, tiov, tiovcnt); + } + +done: + head = (head + 1) % dsize; + e82545_transmit_done(sc, ohead, head, dsize, tdwb); + + *rhead = head; + return (desc + 1); +} + +static void +e82545_tx_run(struct e82545_softc *sc) +{ + uint32_t cause; + uint16_t head, rhead, tail, size; + int lim, tdwb, sent; + + head = sc->esc_TDH; + tail = sc->esc_TDT; + size = sc->esc_TDLEN / 16; + DPRINTF("tx_run: head %x, rhead %x, tail %x\r\n", + sc->esc_TDH, sc->esc_TDHr, sc->esc_TDT); + + pthread_mutex_unlock(&sc->esc_mtx); + rhead = head; + tdwb = 0; + for (lim = size / 4; sc->esc_tx_enabled && lim > 0; lim -= sent) { + sent = e82545_transmit(sc, head, tail, size, &rhead, &tdwb); + if (sent == 0) + break; + head = rhead; + } + pthread_mutex_lock(&sc->esc_mtx); + + sc->esc_TDH = head; + sc->esc_TDHr = rhead; + cause = 0; + if (tdwb) + cause |= E1000_ICR_TXDW; + if (lim != size / 4 && sc->esc_TDH == sc->esc_TDT) + cause |= E1000_ICR_TXQE; + if (cause) + e82545_icr_assert(sc, cause); + + DPRINTF("tx_run done: head %x, rhead %x, tail %x\r\n", + sc->esc_TDH, sc->esc_TDHr, sc->esc_TDT); +} + +static void * +e82545_tx_thread(void *param) +{ + struct e82545_softc *sc = param; + + pthread_mutex_lock(&sc->esc_mtx); + for (;;) { + while (!sc->esc_tx_enabled || sc->esc_TDHr == sc->esc_TDT) { + if (sc->esc_tx_enabled && sc->esc_TDHr != sc->esc_TDT) + break; + sc->esc_tx_active = 0; + if (sc->esc_tx_enabled == 0) + pthread_cond_signal(&sc->esc_tx_cond); + pthread_cond_wait(&sc->esc_tx_cond, &sc->esc_mtx); + } + sc->esc_tx_active = 1; + + /* Process some tx descriptors. Lock dropped inside. */ + e82545_tx_run(sc); + } +#ifndef __FreeBSD__ + return (NULL); +#endif +} + +static void +e82545_tx_start(struct e82545_softc *sc) +{ + + if (sc->esc_tx_active == 0) + pthread_cond_signal(&sc->esc_tx_cond); +} + +static void +e82545_tx_enable(struct e82545_softc *sc) +{ + + sc->esc_tx_enabled = 1; +} + +static void +e82545_tx_disable(struct e82545_softc *sc) +{ + + sc->esc_tx_enabled = 0; + while (sc->esc_tx_active) + pthread_cond_wait(&sc->esc_tx_cond, &sc->esc_mtx); +} + +static void +e82545_rx_enable(struct e82545_softc *sc) +{ + + sc->esc_rx_enabled = 1; +} + +static void +e82545_rx_disable(struct e82545_softc *sc) +{ + + sc->esc_rx_enabled = 0; + while (sc->esc_rx_active) + pthread_cond_wait(&sc->esc_rx_cond, &sc->esc_mtx); +} + +static void +e82545_write_ra(struct e82545_softc *sc, int reg, uint32_t wval) +{ + struct eth_uni *eu; + int idx; + + idx = reg >> 1; + assert(idx < 15); + + eu = &sc->esc_uni[idx]; + + if (reg & 0x1) { + /* RAH */ + eu->eu_valid = ((wval & E1000_RAH_AV) == E1000_RAH_AV); + eu->eu_addrsel = (wval >> 16) & 0x3; + eu->eu_eth.octet[5] = wval >> 8; + eu->eu_eth.octet[4] = wval; + } else { + /* RAL */ + eu->eu_eth.octet[3] = wval >> 24; + eu->eu_eth.octet[2] = wval >> 16; + eu->eu_eth.octet[1] = wval >> 8; + eu->eu_eth.octet[0] = wval; + } +} + +static uint32_t +e82545_read_ra(struct e82545_softc *sc, int reg) +{ + struct eth_uni *eu; + uint32_t retval; + int idx; + + idx = reg >> 1; + assert(idx < 15); + + eu = &sc->esc_uni[idx]; + + if (reg & 0x1) { + /* RAH */ + retval = (eu->eu_valid << 31) | + (eu->eu_addrsel << 16) | + (eu->eu_eth.octet[5] << 8) | + eu->eu_eth.octet[4]; + } else { + /* RAL */ + retval = (eu->eu_eth.octet[3] << 24) | + (eu->eu_eth.octet[2] << 16) | + (eu->eu_eth.octet[1] << 8) | + eu->eu_eth.octet[0]; + } + + return (retval); +} + +static void +e82545_write_register(struct e82545_softc *sc, uint32_t offset, uint32_t value) +{ + int ridx; + + if (offset & 0x3) { + DPRINTF("Unaligned register write offset:0x%x value:0x%x\r\n", offset, value); + return; + } + DPRINTF("Register write: 0x%x value: 0x%x\r\n", offset, value); + + switch (offset) { + case E1000_CTRL: + case E1000_CTRL_DUP: + e82545_devctl(sc, value); + break; + case E1000_FCAL: + sc->esc_FCAL = value; + break; + case E1000_FCAH: + sc->esc_FCAH = value & ~0xFFFF0000; + break; + case E1000_FCT: + sc->esc_FCT = value & ~0xFFFF0000; + break; + case E1000_VET: + sc->esc_VET = value & ~0xFFFF0000; + break; + case E1000_FCTTV: + sc->esc_FCTTV = value & ~0xFFFF0000; + break; + case E1000_LEDCTL: + sc->esc_LEDCTL = value & ~0x30303000; + break; + case E1000_PBA: + sc->esc_PBA = value & 0x0000FF80; + break; + case E1000_ICR: + case E1000_ITR: + case E1000_ICS: + case E1000_IMS: + case E1000_IMC: + e82545_intr_write(sc, offset, value); + break; + case E1000_RCTL: + e82545_rx_ctl(sc, value); + break; + case E1000_FCRTL: + sc->esc_FCRTL = value & ~0xFFFF0007; + break; + case E1000_FCRTH: + sc->esc_FCRTH = value & ~0xFFFF0007; + break; + case E1000_RDBAL(0): + sc->esc_RDBAL = value & ~0xF; + if (sc->esc_rx_enabled) { + /* Apparently legal: update cached address */ + e82545_rx_update_rdba(sc); + } + break; + case E1000_RDBAH(0): + assert(!sc->esc_rx_enabled); + sc->esc_RDBAH = value; + break; + case E1000_RDLEN(0): + assert(!sc->esc_rx_enabled); + sc->esc_RDLEN = value & ~0xFFF0007F; + break; + case E1000_RDH(0): + /* XXX should only ever be zero ? Range check ? */ + sc->esc_RDH = value; + break; + case E1000_RDT(0): + /* XXX if this opens up the rx ring, do something ? */ + sc->esc_RDT = value; + break; + case E1000_RDTR: + /* ignore FPD bit 31 */ + sc->esc_RDTR = value & ~0xFFFF0000; + break; + case E1000_RXDCTL(0): + sc->esc_RXDCTL = value & ~0xFEC0C0C0; + break; + case E1000_RADV: + sc->esc_RADV = value & ~0xFFFF0000; + break; + case E1000_RSRPD: + sc->esc_RSRPD = value & ~0xFFFFF000; + break; + case E1000_RXCSUM: + sc->esc_RXCSUM = value & ~0xFFFFF800; + break; + case E1000_TXCW: + sc->esc_TXCW = value & ~0x3FFF0000; + break; + case E1000_TCTL: + e82545_tx_ctl(sc, value); + break; + case E1000_TIPG: + sc->esc_TIPG = value; + break; + case E1000_AIT: + sc->esc_AIT = value; + break; + case E1000_TDBAL(0): + sc->esc_TDBAL = value & ~0xF; + if (sc->esc_tx_enabled) { + /* Apparently legal */ + e82545_tx_update_tdba(sc); + } + break; + case E1000_TDBAH(0): + //assert(!sc->esc_tx_enabled); + sc->esc_TDBAH = value; + break; + case E1000_TDLEN(0): + //assert(!sc->esc_tx_enabled); + sc->esc_TDLEN = value & ~0xFFF0007F; + break; + case E1000_TDH(0): + //assert(!sc->esc_tx_enabled); + /* XXX should only ever be zero ? Range check ? */ + sc->esc_TDHr = sc->esc_TDH = value; + break; + case E1000_TDT(0): + /* XXX range check ? */ + sc->esc_TDT = value; + if (sc->esc_tx_enabled) + e82545_tx_start(sc); + break; + case E1000_TIDV: + sc->esc_TIDV = value & ~0xFFFF0000; + break; + case E1000_TXDCTL(0): + //assert(!sc->esc_tx_enabled); + sc->esc_TXDCTL = value & ~0xC0C0C0; + break; + case E1000_TADV: + sc->esc_TADV = value & ~0xFFFF0000; + break; + case E1000_RAL(0) ... E1000_RAH(15): + /* convert to u32 offset */ + ridx = (offset - E1000_RAL(0)) >> 2; + e82545_write_ra(sc, ridx, value); + break; + case E1000_MTA ... (E1000_MTA + (127*4)): + sc->esc_fmcast[(offset - E1000_MTA) >> 2] = value; + break; + case E1000_VFTA ... (E1000_VFTA + (127*4)): + sc->esc_fvlan[(offset - E1000_VFTA) >> 2] = value; + break; + case E1000_EECD: + { + //DPRINTF("EECD write 0x%x -> 0x%x\r\n", sc->eeprom_control, value); + /* edge triggered low->high */ + uint32_t eecd_strobe = ((sc->eeprom_control & E1000_EECD_SK) ? + 0 : (value & E1000_EECD_SK)); + uint32_t eecd_mask = (E1000_EECD_SK|E1000_EECD_CS| + E1000_EECD_DI|E1000_EECD_REQ); + sc->eeprom_control &= ~eecd_mask; + sc->eeprom_control |= (value & eecd_mask); + /* grant/revoke immediately */ + if (value & E1000_EECD_REQ) { + sc->eeprom_control |= E1000_EECD_GNT; + } else { + sc->eeprom_control &= ~E1000_EECD_GNT; + } + if (eecd_strobe && (sc->eeprom_control & E1000_EECD_CS)) { + e82545_eecd_strobe(sc); + } + return; + } + case E1000_MDIC: + { + uint8_t reg_addr = (uint8_t)((value & E1000_MDIC_REG_MASK) >> + E1000_MDIC_REG_SHIFT); + uint8_t phy_addr = (uint8_t)((value & E1000_MDIC_PHY_MASK) >> + E1000_MDIC_PHY_SHIFT); + sc->mdi_control = + (value & ~(E1000_MDIC_ERROR|E1000_MDIC_DEST)); + if ((value & E1000_MDIC_READY) != 0) { + DPRINTF("Incorrect MDIC ready bit: 0x%x\r\n", value); + return; + } + switch (value & E82545_MDIC_OP_MASK) { + case E1000_MDIC_OP_READ: + sc->mdi_control &= ~E82545_MDIC_DATA_MASK; + sc->mdi_control |= e82545_read_mdi(sc, reg_addr, phy_addr); + break; + case E1000_MDIC_OP_WRITE: + e82545_write_mdi(sc, reg_addr, phy_addr, + value & E82545_MDIC_DATA_MASK); + break; + default: + DPRINTF("Unknown MDIC op: 0x%x\r\n", value); + return; + } + /* TODO: barrier? */ + sc->mdi_control |= E1000_MDIC_READY; + if (value & E82545_MDIC_IE) { + // TODO: generate interrupt + } + return; + } + case E1000_MANC: + case E1000_STATUS: + return; + default: + DPRINTF("Unknown write register: 0x%x value:%x\r\n", offset, value); + return; + } +} + +static uint32_t +e82545_read_register(struct e82545_softc *sc, uint32_t offset) +{ + uint32_t retval; + int ridx; + + if (offset & 0x3) { + DPRINTF("Unaligned register read offset:0x%x\r\n", offset); + return 0; + } + + DPRINTF("Register read: 0x%x\r\n", offset); + + switch (offset) { + case E1000_CTRL: + retval = sc->esc_CTRL; + break; + case E1000_STATUS: + retval = E1000_STATUS_FD | E1000_STATUS_LU | + E1000_STATUS_SPEED_1000; + break; + case E1000_FCAL: + retval = sc->esc_FCAL; + break; + case E1000_FCAH: + retval = sc->esc_FCAH; + break; + case E1000_FCT: + retval = sc->esc_FCT; + break; + case E1000_VET: + retval = sc->esc_VET; + break; + case E1000_FCTTV: + retval = sc->esc_FCTTV; + break; + case E1000_LEDCTL: + retval = sc->esc_LEDCTL; + break; + case E1000_PBA: + retval = sc->esc_PBA; + break; + case E1000_ICR: + case E1000_ITR: + case E1000_ICS: + case E1000_IMS: + case E1000_IMC: + retval = e82545_intr_read(sc, offset); + break; + case E1000_RCTL: + retval = sc->esc_RCTL; + break; + case E1000_FCRTL: + retval = sc->esc_FCRTL; + break; + case E1000_FCRTH: + retval = sc->esc_FCRTH; + break; + case E1000_RDBAL(0): + retval = sc->esc_RDBAL; + break; + case E1000_RDBAH(0): + retval = sc->esc_RDBAH; + break; + case E1000_RDLEN(0): + retval = sc->esc_RDLEN; + break; + case E1000_RDH(0): + retval = sc->esc_RDH; + break; + case E1000_RDT(0): + retval = sc->esc_RDT; + break; + case E1000_RDTR: + retval = sc->esc_RDTR; + break; + case E1000_RXDCTL(0): + retval = sc->esc_RXDCTL; + break; + case E1000_RADV: + retval = sc->esc_RADV; + break; + case E1000_RSRPD: + retval = sc->esc_RSRPD; + break; + case E1000_RXCSUM: + retval = sc->esc_RXCSUM; + break; + case E1000_TXCW: + retval = sc->esc_TXCW; + break; + case E1000_TCTL: + retval = sc->esc_TCTL; + break; + case E1000_TIPG: + retval = sc->esc_TIPG; + break; + case E1000_AIT: + retval = sc->esc_AIT; + break; + case E1000_TDBAL(0): + retval = sc->esc_TDBAL; + break; + case E1000_TDBAH(0): + retval = sc->esc_TDBAH; + break; + case E1000_TDLEN(0): + retval = sc->esc_TDLEN; + break; + case E1000_TDH(0): + retval = sc->esc_TDH; + break; + case E1000_TDT(0): + retval = sc->esc_TDT; + break; + case E1000_TIDV: + retval = sc->esc_TIDV; + break; + case E1000_TXDCTL(0): + retval = sc->esc_TXDCTL; + break; + case E1000_TADV: + retval = sc->esc_TADV; + break; + case E1000_RAL(0) ... E1000_RAH(15): + /* convert to u32 offset */ + ridx = (offset - E1000_RAL(0)) >> 2; + retval = e82545_read_ra(sc, ridx); + break; + case E1000_MTA ... (E1000_MTA + (127*4)): + retval = sc->esc_fmcast[(offset - E1000_MTA) >> 2]; + break; + case E1000_VFTA ... (E1000_VFTA + (127*4)): + retval = sc->esc_fvlan[(offset - E1000_VFTA) >> 2]; + break; + case E1000_EECD: + //DPRINTF("EECD read %x\r\n", sc->eeprom_control); + retval = sc->eeprom_control; + break; + case E1000_MDIC: + retval = sc->mdi_control; + break; + case E1000_MANC: + retval = 0; + break; + /* stats that we emulate. */ + case E1000_MPC: + retval = sc->missed_pkt_count; + break; + case E1000_PRC64: + retval = sc->pkt_rx_by_size[0]; + break; + case E1000_PRC127: + retval = sc->pkt_rx_by_size[1]; + break; + case E1000_PRC255: + retval = sc->pkt_rx_by_size[2]; + break; + case E1000_PRC511: + retval = sc->pkt_rx_by_size[3]; + break; + case E1000_PRC1023: + retval = sc->pkt_rx_by_size[4]; + break; + case E1000_PRC1522: + retval = sc->pkt_rx_by_size[5]; + break; + case E1000_GPRC: + retval = sc->good_pkt_rx_count; + break; + case E1000_BPRC: + retval = sc->bcast_pkt_rx_count; + break; + case E1000_MPRC: + retval = sc->mcast_pkt_rx_count; + break; + case E1000_GPTC: + case E1000_TPT: + retval = sc->good_pkt_tx_count; + break; + case E1000_GORCL: + retval = (uint32_t)sc->good_octets_rx; + break; + case E1000_GORCH: + retval = (uint32_t)(sc->good_octets_rx >> 32); + break; + case E1000_TOTL: + case E1000_GOTCL: + retval = (uint32_t)sc->good_octets_tx; + break; + case E1000_TOTH: + case E1000_GOTCH: + retval = (uint32_t)(sc->good_octets_tx >> 32); + break; + case E1000_ROC: + retval = sc->oversize_rx_count; + break; + case E1000_TORL: + retval = (uint32_t)(sc->good_octets_rx + sc->missed_octets); + break; + case E1000_TORH: + retval = (uint32_t)((sc->good_octets_rx + + sc->missed_octets) >> 32); + break; + case E1000_TPR: + retval = sc->good_pkt_rx_count + sc->missed_pkt_count + + sc->oversize_rx_count; + break; + case E1000_PTC64: + retval = sc->pkt_tx_by_size[0]; + break; + case E1000_PTC127: + retval = sc->pkt_tx_by_size[1]; + break; + case E1000_PTC255: + retval = sc->pkt_tx_by_size[2]; + break; + case E1000_PTC511: + retval = sc->pkt_tx_by_size[3]; + break; + case E1000_PTC1023: + retval = sc->pkt_tx_by_size[4]; + break; + case E1000_PTC1522: + retval = sc->pkt_tx_by_size[5]; + break; + case E1000_MPTC: + retval = sc->mcast_pkt_tx_count; + break; + case E1000_BPTC: + retval = sc->bcast_pkt_tx_count; + break; + case E1000_TSCTC: + retval = sc->tso_tx_count; + break; + /* stats that are always 0. */ + case E1000_CRCERRS: + case E1000_ALGNERRC: + case E1000_SYMERRS: + case E1000_RXERRC: + case E1000_SCC: + case E1000_ECOL: + case E1000_MCC: + case E1000_LATECOL: + case E1000_COLC: + case E1000_DC: + case E1000_TNCRS: + case E1000_SEC: + case E1000_CEXTERR: + case E1000_RLEC: + case E1000_XONRXC: + case E1000_XONTXC: + case E1000_XOFFRXC: + case E1000_XOFFTXC: + case E1000_FCRUC: + case E1000_RNBC: + case E1000_RUC: + case E1000_RFC: + case E1000_RJC: + case E1000_MGTPRC: + case E1000_MGTPDC: + case E1000_MGTPTC: + case E1000_TSCTFC: + retval = 0; + break; + default: + DPRINTF("Unknown read register: 0x%x\r\n", offset); + retval = 0; + break; + } + + return (retval); +} + +static void +e82545_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, + uint64_t offset, int size, uint64_t value) +{ + struct e82545_softc *sc; + + //DPRINTF("Write bar:%d offset:0x%lx value:0x%lx size:%d\r\n", baridx, offset, value, size); + + sc = pi->pi_arg; + + pthread_mutex_lock(&sc->esc_mtx); + + switch (baridx) { + case E82545_BAR_IO: + switch (offset) { + case E82545_IOADDR: + if (size != 4) { + DPRINTF("Wrong io addr write sz:%d value:0x%lx\r\n", size, value); + } else + sc->io_addr = (uint32_t)value; + break; + case E82545_IODATA: + if (size != 4) { + DPRINTF("Wrong io data write size:%d value:0x%lx\r\n", size, value); + } else if (sc->io_addr > E82545_IO_REGISTER_MAX) { + DPRINTF("Non-register io write addr:0x%x value:0x%lx\r\n", sc->io_addr, value); + } else + e82545_write_register(sc, sc->io_addr, + (uint32_t)value); + break; + default: + DPRINTF("Unknown io bar write offset:0x%lx value:0x%lx size:%d\r\n", offset, value, size); + break; + } + break; + case E82545_BAR_REGISTER: + if (size != 4) { + DPRINTF("Wrong register write size:%d offset:0x%lx value:0x%lx\r\n", size, offset, value); + } else + e82545_write_register(sc, (uint32_t)offset, + (uint32_t)value); + break; + default: + DPRINTF("Unknown write bar:%d off:0x%lx val:0x%lx size:%d\r\n", + baridx, offset, value, size); + } + + pthread_mutex_unlock(&sc->esc_mtx); +} + +static uint64_t +e82545_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, + uint64_t offset, int size) +{ + struct e82545_softc *sc; + uint64_t retval; + + //DPRINTF("Read bar:%d offset:0x%lx size:%d\r\n", baridx, offset, size); + sc = pi->pi_arg; + retval = 0; + + pthread_mutex_lock(&sc->esc_mtx); + + switch (baridx) { + case E82545_BAR_IO: + switch (offset) { + case E82545_IOADDR: + if (size != 4) { + DPRINTF("Wrong io addr read sz:%d\r\n", size); + } else + retval = sc->io_addr; + break; + case E82545_IODATA: + if (size != 4) { + DPRINTF("Wrong io data read sz:%d\r\n", size); + } + if (sc->io_addr > E82545_IO_REGISTER_MAX) { + DPRINTF("Non-register io read addr:0x%x\r\n", + sc->io_addr); + } else + retval = e82545_read_register(sc, sc->io_addr); + break; + default: + DPRINTF("Unknown io bar read offset:0x%lx size:%d\r\n", + offset, size); + break; + } + break; + case E82545_BAR_REGISTER: + if (size != 4) { + DPRINTF("Wrong register read size:%d offset:0x%lx\r\n", + size, offset); + } else + retval = e82545_read_register(sc, (uint32_t)offset); + break; + default: + DPRINTF("Unknown read bar:%d offset:0x%lx size:%d\r\n", + baridx, offset, size); + break; + } + + pthread_mutex_unlock(&sc->esc_mtx); + + return (retval); +} + +static void +e82545_reset(struct e82545_softc *sc, int drvr) +{ + int i; + + e82545_rx_disable(sc); + e82545_tx_disable(sc); + + /* clear outstanding interrupts */ + if (sc->esc_irq_asserted) + pci_lintr_deassert(sc->esc_pi); + + /* misc */ + if (!drvr) { + sc->esc_FCAL = 0; + sc->esc_FCAH = 0; + sc->esc_FCT = 0; + sc->esc_VET = 0; + sc->esc_FCTTV = 0; + } + sc->esc_LEDCTL = 0x07061302; + sc->esc_PBA = 0x00100030; + + /* start nvm in opcode mode. */ + sc->nvm_opaddr = 0; + sc->nvm_mode = E82545_NVM_MODE_OPADDR; + sc->nvm_bits = E82545_NVM_OPADDR_BITS; + sc->eeprom_control = E1000_EECD_PRES | E82545_EECD_FWE_EN; + e82545_init_eeprom(sc); + + /* interrupt */ + sc->esc_ICR = 0; + sc->esc_ITR = 250; + sc->esc_ICS = 0; + sc->esc_IMS = 0; + sc->esc_IMC = 0; + + /* L2 filters */ + if (!drvr) { + memset(sc->esc_fvlan, 0, sizeof(sc->esc_fvlan)); + memset(sc->esc_fmcast, 0, sizeof(sc->esc_fmcast)); + memset(sc->esc_uni, 0, sizeof(sc->esc_uni)); + + /* XXX not necessary on 82545 ?? */ + sc->esc_uni[0].eu_valid = 1; + memcpy(sc->esc_uni[0].eu_eth.octet, sc->esc_mac.octet, + ETHER_ADDR_LEN); + } else { + /* Clear RAH valid bits */ + for (i = 0; i < 16; i++) + sc->esc_uni[i].eu_valid = 0; + } + + /* receive */ + if (!drvr) { + sc->esc_RDBAL = 0; + sc->esc_RDBAH = 0; + } + sc->esc_RCTL = 0; + sc->esc_FCRTL = 0; + sc->esc_FCRTH = 0; + sc->esc_RDLEN = 0; + sc->esc_RDH = 0; + sc->esc_RDT = 0; + sc->esc_RDTR = 0; + sc->esc_RXDCTL = (1 << 24) | (1 << 16); /* default GRAN/WTHRESH */ + sc->esc_RADV = 0; + sc->esc_RXCSUM = 0; + + /* transmit */ + if (!drvr) { + sc->esc_TDBAL = 0; + sc->esc_TDBAH = 0; + sc->esc_TIPG = 0; + sc->esc_AIT = 0; + sc->esc_TIDV = 0; + sc->esc_TADV = 0; + } + sc->esc_tdba = 0; + sc->esc_txdesc = NULL; + sc->esc_TXCW = 0; + sc->esc_TCTL = 0; + sc->esc_TDLEN = 0; + sc->esc_TDT = 0; + sc->esc_TDHr = sc->esc_TDH = 0; + sc->esc_TXDCTL = 0; +} + +static void +e82545_open_tap(struct e82545_softc *sc, char *opts) +{ + char tbuf[80]; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; +#endif + + if (opts == NULL) { + sc->esc_tapfd = -1; + return; + } + + strcpy(tbuf, "/dev/"); + strlcat(tbuf, opts, sizeof(tbuf)); + + sc->esc_tapfd = open(tbuf, O_RDWR); + if (sc->esc_tapfd == -1) { + DPRINTF("unable to open tap device %s\n", opts); + exit(4); + } + + /* + * Set non-blocking and register for read + * notifications with the event loop + */ + int opt = 1; + if (ioctl(sc->esc_tapfd, FIONBIO, &opt) < 0) { + WPRINTF("tap device O_NONBLOCK failed: %d\n", errno); + close(sc->esc_tapfd); + sc->esc_tapfd = -1; + } + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE); + if (caph_rights_limit(sc->esc_tapfd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + +#ifdef __FreeBSD__ + sc->esc_mevp = mevent_add(sc->esc_tapfd, + EVF_READ, + e82545_tap_callback, + sc); + if (sc->esc_mevp == NULL) { + DPRINTF("Could not register mevent %d\n", EVF_READ); + close(sc->esc_tapfd); + sc->esc_tapfd = -1; + } +#endif +} + +static int +e82545_parsemac(char *mac_str, uint8_t *mac_addr) +{ + struct ether_addr *ea; + char *tmpstr; + char zero_addr[ETHER_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }; + + tmpstr = strsep(&mac_str,"="); + if ((mac_str != NULL) && (!strcmp(tmpstr,"mac"))) { + ea = ether_aton(mac_str); + if (ea == NULL || ETHER_IS_MULTICAST(ea->octet) || + memcmp(ea->octet, zero_addr, ETHER_ADDR_LEN) == 0) { + fprintf(stderr, "Invalid MAC %s\n", mac_str); + return (1); + } else + memcpy(mac_addr, ea->octet, ETHER_ADDR_LEN); + } + return (0); +} + +static int +e82545_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + DPRINTF("Loading with options: %s\r\n", opts); + + MD5_CTX mdctx; + unsigned char digest[16]; + char nstr[80]; + struct e82545_softc *sc; + char *devname; + char *vtopts; + int mac_provided; + + /* Setup our softc */ + sc = calloc(1, sizeof(*sc)); + + pi->pi_arg = sc; + sc->esc_pi = pi; + sc->esc_ctx = ctx; + + pthread_mutex_init(&sc->esc_mtx, NULL); + pthread_cond_init(&sc->esc_rx_cond, NULL); + pthread_cond_init(&sc->esc_tx_cond, NULL); + pthread_create(&sc->esc_tx_tid, NULL, e82545_tx_thread, sc); + snprintf(nstr, sizeof(nstr), "e82545-%d:%d tx", pi->pi_slot, + pi->pi_func); + pthread_set_name_np(sc->esc_tx_tid, nstr); + + pci_set_cfgdata16(pi, PCIR_DEVICE, E82545_DEV_ID_82545EM_COPPER); + pci_set_cfgdata16(pi, PCIR_VENDOR, E82545_VENDOR_ID_INTEL); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); + pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_NETWORK_ETHERNET); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, E82545_SUBDEV_ID); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, E82545_VENDOR_ID_INTEL); + + pci_set_cfgdata8(pi, PCIR_HDRTYPE, PCIM_HDRTYPE_NORMAL); + pci_set_cfgdata8(pi, PCIR_INTPIN, 0x1); + + /* TODO: this card also supports msi, but the freebsd driver for it + * does not, so I have not implemented it. */ + pci_lintr_request(pi); + + pci_emul_alloc_bar(pi, E82545_BAR_REGISTER, PCIBAR_MEM32, + E82545_BAR_REGISTER_LEN); + pci_emul_alloc_bar(pi, E82545_BAR_FLASH, PCIBAR_MEM32, + E82545_BAR_FLASH_LEN); + pci_emul_alloc_bar(pi, E82545_BAR_IO, PCIBAR_IO, + E82545_BAR_IO_LEN); + + /* + * Attempt to open the tap device and read the MAC address + * if specified. Copied from virtio-net, slightly modified. + */ + mac_provided = 0; + sc->esc_tapfd = -1; + if (opts != NULL) { + int err; + + devname = vtopts = strdup(opts); + (void) strsep(&vtopts, ","); + + if (vtopts != NULL) { + err = e82545_parsemac(vtopts, sc->esc_mac.octet); + if (err != 0) { + free(devname); + return (err); + } + mac_provided = 1; + } + + if (strncmp(devname, "tap", 3) == 0 || + strncmp(devname, "vmnet", 5) == 0) + e82545_open_tap(sc, devname); + + free(devname); + } + + /* + * The default MAC address is the standard NetApp OUI of 00-a0-98, + * followed by an MD5 of the PCI slot/func number and dev name + */ + if (!mac_provided) { + snprintf(nstr, sizeof(nstr), "%d-%d-%s", pi->pi_slot, + pi->pi_func, vmname); + + MD5Init(&mdctx); + MD5Update(&mdctx, nstr, strlen(nstr)); + MD5Final(digest, &mdctx); + + sc->esc_mac.octet[0] = 0x00; + sc->esc_mac.octet[1] = 0xa0; + sc->esc_mac.octet[2] = 0x98; + sc->esc_mac.octet[3] = digest[0]; + sc->esc_mac.octet[4] = digest[1]; + sc->esc_mac.octet[5] = digest[2]; + } + + /* H/w initiated reset */ + e82545_reset(sc, 0); + + return (0); +} + +struct pci_devemu pci_de_e82545 = { + .pe_emu = "e1000", + .pe_init = e82545_init, + .pe_barwrite = e82545_write, + .pe_barread = e82545_read +}; +PCI_EMUL_SET(pci_de_e82545); + diff --git a/usr/src/cmd/bhyve/pci_emul.c b/usr/src/cmd/bhyve/pci_emul.c new file mode 100644 index 0000000000..03db632e37 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_emul.c @@ -0,0 +1,2141 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2014 Pluribus Networks Inc. + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/linker_set.h> + +#include <ctype.h> +#include <errno.h> +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <assert.h> +#include <stdbool.h> + +#include <machine/vmm.h> +#include <vmmapi.h> + +#include "acpi.h" +#include "bhyverun.h" +#include "inout.h" +#include "ioapic.h" +#include "mem.h" +#include "pci_emul.h" +#include "pci_irq.h" +#include "pci_lpc.h" + +#define CONF1_ADDR_PORT 0x0cf8 +#define CONF1_DATA_PORT 0x0cfc + +#define CONF1_ENABLE 0x80000000ul + +#define MAXBUSES (PCI_BUSMAX + 1) +#define MAXSLOTS (PCI_SLOTMAX + 1) +#define MAXFUNCS (PCI_FUNCMAX + 1) + +struct funcinfo { + char *fi_name; + char *fi_param; + struct pci_devinst *fi_devi; +}; + +struct intxinfo { + int ii_count; + int ii_pirq_pin; + int ii_ioapic_irq; +}; + +struct slotinfo { + struct intxinfo si_intpins[4]; + struct funcinfo si_funcs[MAXFUNCS]; +}; + +struct businfo { + uint16_t iobase, iolimit; /* I/O window */ + uint32_t membase32, memlimit32; /* mmio window below 4GB */ + uint64_t membase64, memlimit64; /* mmio window above 4GB */ + struct slotinfo slotinfo[MAXSLOTS]; +}; + +static struct businfo *pci_businfo[MAXBUSES]; + +SET_DECLARE(pci_devemu_set, struct pci_devemu); + +static uint64_t pci_emul_iobase; +static uint64_t pci_emul_membase32; +static uint64_t pci_emul_membase64; + +#define PCI_EMUL_IOBASE 0x2000 +#define PCI_EMUL_IOLIMIT 0x10000 + +#define PCI_EMUL_ECFG_BASE 0xE0000000 /* 3.5GB */ +#define PCI_EMUL_ECFG_SIZE (MAXBUSES * 1024 * 1024) /* 1MB per bus */ +SYSRES_MEM(PCI_EMUL_ECFG_BASE, PCI_EMUL_ECFG_SIZE); + +#define PCI_EMUL_MEMLIMIT32 PCI_EMUL_ECFG_BASE + +#define PCI_EMUL_MEMBASE64 0xD000000000UL +#define PCI_EMUL_MEMLIMIT64 0xFD00000000UL + +static struct pci_devemu *pci_emul_finddev(char *name); +static void pci_lintr_route(struct pci_devinst *pi); +static void pci_lintr_update(struct pci_devinst *pi); +static void pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, + int func, int coff, int bytes, uint32_t *val); + +static __inline void +CFGWRITE(struct pci_devinst *pi, int coff, uint32_t val, int bytes) +{ + + if (bytes == 1) + pci_set_cfgdata8(pi, coff, val); + else if (bytes == 2) + pci_set_cfgdata16(pi, coff, val); + else + pci_set_cfgdata32(pi, coff, val); +} + +static __inline uint32_t +CFGREAD(struct pci_devinst *pi, int coff, int bytes) +{ + + if (bytes == 1) + return (pci_get_cfgdata8(pi, coff)); + else if (bytes == 2) + return (pci_get_cfgdata16(pi, coff)); + else + return (pci_get_cfgdata32(pi, coff)); +} + +/* + * I/O access + */ + +/* + * Slot options are in the form: + * + * <bus>:<slot>:<func>,<emul>[,<config>] + * <slot>[:<func>],<emul>[,<config>] + * + * slot is 0..31 + * func is 0..7 + * emul is a string describing the type of PCI device e.g. virtio-net + * config is an optional string, depending on the device, that can be + * used for configuration. + * Examples are: + * 1,virtio-net,tap0 + * 3:0,dummy + */ +static void +pci_parse_slot_usage(char *aopt) +{ + + fprintf(stderr, "Invalid PCI slot info field \"%s\"\n", aopt); +} + +int +pci_parse_slot(char *opt) +{ + struct businfo *bi; + struct slotinfo *si; + char *emul, *config, *str, *cp; + int error, bnum, snum, fnum; + + error = -1; + str = strdup(opt); + + emul = config = NULL; + if ((cp = strchr(str, ',')) != NULL) { + *cp = '\0'; + emul = cp + 1; + if ((cp = strchr(emul, ',')) != NULL) { + *cp = '\0'; + config = cp + 1; + } + } else { + pci_parse_slot_usage(opt); + goto done; + } + + /* <bus>:<slot>:<func> */ + if (sscanf(str, "%d:%d:%d", &bnum, &snum, &fnum) != 3) { + bnum = 0; + /* <slot>:<func> */ + if (sscanf(str, "%d:%d", &snum, &fnum) != 2) { + fnum = 0; + /* <slot> */ + if (sscanf(str, "%d", &snum) != 1) { + snum = -1; + } + } + } + + if (bnum < 0 || bnum >= MAXBUSES || snum < 0 || snum >= MAXSLOTS || + fnum < 0 || fnum >= MAXFUNCS) { + pci_parse_slot_usage(opt); + goto done; + } + + if (pci_businfo[bnum] == NULL) + pci_businfo[bnum] = calloc(1, sizeof(struct businfo)); + + bi = pci_businfo[bnum]; + si = &bi->slotinfo[snum]; + + if (si->si_funcs[fnum].fi_name != NULL) { + fprintf(stderr, "pci slot %d:%d already occupied!\n", + snum, fnum); + goto done; + } + + if (pci_emul_finddev(emul) == NULL) { + fprintf(stderr, "pci slot %d:%d: unknown device \"%s\"\n", + snum, fnum, emul); + goto done; + } + + error = 0; + si->si_funcs[fnum].fi_name = emul; + si->si_funcs[fnum].fi_param = config; + +done: + if (error) + free(str); + + return (error); +} + +void +pci_print_supported_devices() +{ + struct pci_devemu **pdpp, *pdp; + + SET_FOREACH(pdpp, pci_devemu_set) { + pdp = *pdpp; + printf("%s\n", pdp->pe_emu); + } +} + +static int +pci_valid_pba_offset(struct pci_devinst *pi, uint64_t offset) +{ + + if (offset < pi->pi_msix.pba_offset) + return (0); + + if (offset >= pi->pi_msix.pba_offset + pi->pi_msix.pba_size) { + return (0); + } + + return (1); +} + +int +pci_emul_msix_twrite(struct pci_devinst *pi, uint64_t offset, int size, + uint64_t value) +{ + int msix_entry_offset; + int tab_index; + char *dest; + + /* support only 4 or 8 byte writes */ + if (size != 4 && size != 8) + return (-1); + + /* + * Return if table index is beyond what device supports + */ + tab_index = offset / MSIX_TABLE_ENTRY_SIZE; + if (tab_index >= pi->pi_msix.table_count) + return (-1); + + msix_entry_offset = offset % MSIX_TABLE_ENTRY_SIZE; + + /* support only aligned writes */ + if ((msix_entry_offset % size) != 0) + return (-1); + + dest = (char *)(pi->pi_msix.table + tab_index); + dest += msix_entry_offset; + + if (size == 4) + *((uint32_t *)dest) = value; + else + *((uint64_t *)dest) = value; + + return (0); +} + +uint64_t +pci_emul_msix_tread(struct pci_devinst *pi, uint64_t offset, int size) +{ + char *dest; + int msix_entry_offset; + int tab_index; + uint64_t retval = ~0; + + /* + * The PCI standard only allows 4 and 8 byte accesses to the MSI-X + * table but we also allow 1 byte access to accommodate reads from + * ddb. + */ + if (size != 1 && size != 4 && size != 8) + return (retval); + + msix_entry_offset = offset % MSIX_TABLE_ENTRY_SIZE; + + /* support only aligned reads */ + if ((msix_entry_offset % size) != 0) { + return (retval); + } + + tab_index = offset / MSIX_TABLE_ENTRY_SIZE; + + if (tab_index < pi->pi_msix.table_count) { + /* valid MSI-X Table access */ + dest = (char *)(pi->pi_msix.table + tab_index); + dest += msix_entry_offset; + + if (size == 1) + retval = *((uint8_t *)dest); + else if (size == 4) + retval = *((uint32_t *)dest); + else + retval = *((uint64_t *)dest); + } else if (pci_valid_pba_offset(pi, offset)) { + /* return 0 for PBA access */ + retval = 0; + } + + return (retval); +} + +int +pci_msix_table_bar(struct pci_devinst *pi) +{ + + if (pi->pi_msix.table != NULL) + return (pi->pi_msix.table_bar); + else + return (-1); +} + +int +pci_msix_pba_bar(struct pci_devinst *pi) +{ + + if (pi->pi_msix.table != NULL) + return (pi->pi_msix.pba_bar); + else + return (-1); +} + +static int +pci_emul_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + struct pci_devinst *pdi = arg; + struct pci_devemu *pe = pdi->pi_d; + uint64_t offset; + int i; + + for (i = 0; i <= PCI_BARMAX; i++) { + if (pdi->pi_bar[i].type == PCIBAR_IO && + port >= pdi->pi_bar[i].addr && + port + bytes <= pdi->pi_bar[i].addr + pdi->pi_bar[i].size) { + offset = port - pdi->pi_bar[i].addr; + if (in) + *eax = (*pe->pe_barread)(ctx, vcpu, pdi, i, + offset, bytes); + else + (*pe->pe_barwrite)(ctx, vcpu, pdi, i, offset, + bytes, *eax); + return (0); + } + } + return (-1); +} + +static int +pci_emul_mem_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, + int size, uint64_t *val, void *arg1, long arg2) +{ + struct pci_devinst *pdi = arg1; + struct pci_devemu *pe = pdi->pi_d; + uint64_t offset; + int bidx = (int) arg2; + + assert(bidx <= PCI_BARMAX); + assert(pdi->pi_bar[bidx].type == PCIBAR_MEM32 || + pdi->pi_bar[bidx].type == PCIBAR_MEM64); + assert(addr >= pdi->pi_bar[bidx].addr && + addr + size <= pdi->pi_bar[bidx].addr + pdi->pi_bar[bidx].size); + + offset = addr - pdi->pi_bar[bidx].addr; + + if (dir == MEM_F_WRITE) { + if (size == 8) { + (*pe->pe_barwrite)(ctx, vcpu, pdi, bidx, offset, + 4, *val & 0xffffffff); + (*pe->pe_barwrite)(ctx, vcpu, pdi, bidx, offset + 4, + 4, *val >> 32); + } else { + (*pe->pe_barwrite)(ctx, vcpu, pdi, bidx, offset, + size, *val); + } + } else { + if (size == 8) { + *val = (*pe->pe_barread)(ctx, vcpu, pdi, bidx, + offset, 4); + *val |= (*pe->pe_barread)(ctx, vcpu, pdi, bidx, + offset + 4, 4) << 32; + } else { + *val = (*pe->pe_barread)(ctx, vcpu, pdi, bidx, + offset, size); + } + } + + return (0); +} + + +static int +pci_emul_alloc_resource(uint64_t *baseptr, uint64_t limit, uint64_t size, + uint64_t *addr) +{ + uint64_t base; + + assert((size & (size - 1)) == 0); /* must be a power of 2 */ + + base = roundup2(*baseptr, size); + + if (base + size <= limit) { + *addr = base; + *baseptr = base + size; + return (0); + } else + return (-1); +} + +int +pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, enum pcibar_type type, + uint64_t size) +{ + + return (pci_emul_alloc_pbar(pdi, idx, 0, type, size)); +} + +/* + * Register (or unregister) the MMIO or I/O region associated with the BAR + * register 'idx' of an emulated pci device. + */ +static void +modify_bar_registration(struct pci_devinst *pi, int idx, int registration) +{ + int error; + struct inout_port iop; + struct mem_range mr; + + switch (pi->pi_bar[idx].type) { + case PCIBAR_IO: + bzero(&iop, sizeof(struct inout_port)); + iop.name = pi->pi_name; + iop.port = pi->pi_bar[idx].addr; + iop.size = pi->pi_bar[idx].size; + if (registration) { + iop.flags = IOPORT_F_INOUT; + iop.handler = pci_emul_io_handler; + iop.arg = pi; + error = register_inout(&iop); + } else + error = unregister_inout(&iop); + break; + case PCIBAR_MEM32: + case PCIBAR_MEM64: + bzero(&mr, sizeof(struct mem_range)); + mr.name = pi->pi_name; + mr.base = pi->pi_bar[idx].addr; + mr.size = pi->pi_bar[idx].size; + if (registration) { + mr.flags = MEM_F_RW; + mr.handler = pci_emul_mem_handler; + mr.arg1 = pi; + mr.arg2 = idx; + error = register_mem(&mr); + } else + error = unregister_mem(&mr); + break; + default: + error = EINVAL; + break; + } + assert(error == 0); +} + +static void +unregister_bar(struct pci_devinst *pi, int idx) +{ + + modify_bar_registration(pi, idx, 0); +} + +static void +register_bar(struct pci_devinst *pi, int idx) +{ + + modify_bar_registration(pi, idx, 1); +} + +/* Are we decoding i/o port accesses for the emulated pci device? */ +static int +porten(struct pci_devinst *pi) +{ + uint16_t cmd; + + cmd = pci_get_cfgdata16(pi, PCIR_COMMAND); + + return (cmd & PCIM_CMD_PORTEN); +} + +/* Are we decoding memory accesses for the emulated pci device? */ +static int +memen(struct pci_devinst *pi) +{ + uint16_t cmd; + + cmd = pci_get_cfgdata16(pi, PCIR_COMMAND); + + return (cmd & PCIM_CMD_MEMEN); +} + +/* + * Update the MMIO or I/O address that is decoded by the BAR register. + * + * If the pci device has enabled the address space decoding then intercept + * the address range decoded by the BAR register. + */ +static void +update_bar_address(struct pci_devinst *pi, uint64_t addr, int idx, int type) +{ + int decode; + + if (pi->pi_bar[idx].type == PCIBAR_IO) + decode = porten(pi); + else + decode = memen(pi); + + if (decode) + unregister_bar(pi, idx); + + switch (type) { + case PCIBAR_IO: + case PCIBAR_MEM32: + pi->pi_bar[idx].addr = addr; + break; + case PCIBAR_MEM64: + pi->pi_bar[idx].addr &= ~0xffffffffUL; + pi->pi_bar[idx].addr |= addr; + break; + case PCIBAR_MEMHI64: + pi->pi_bar[idx].addr &= 0xffffffff; + pi->pi_bar[idx].addr |= addr; + break; + default: + assert(0); + } + + if (decode) + register_bar(pi, idx); +} + +int +pci_emul_alloc_pbar(struct pci_devinst *pdi, int idx, uint64_t hostbase, + enum pcibar_type type, uint64_t size) +{ + uint64_t *baseptr = NULL; + uint64_t limit = 0, lobits = 0; + uint64_t addr, mask, bar; + int error; + + assert(idx >= 0 && idx <= PCI_BARMAX); + + if ((size & (size - 1)) != 0) + size = 1UL << flsl(size); /* round up to a power of 2 */ + + /* Enforce minimum BAR sizes required by the PCI standard */ + if (type == PCIBAR_IO) { + if (size < 4) + size = 4; + } else { + if (size < 16) + size = 16; + } + + switch (type) { + case PCIBAR_NONE: + baseptr = NULL; + addr = mask = lobits = 0; + break; + case PCIBAR_IO: + baseptr = &pci_emul_iobase; + limit = PCI_EMUL_IOLIMIT; + mask = PCIM_BAR_IO_BASE; + lobits = PCIM_BAR_IO_SPACE; + break; + case PCIBAR_MEM64: + /* + * XXX + * Some drivers do not work well if the 64-bit BAR is allocated + * above 4GB. Allow for this by allocating small requests under + * 4GB unless then allocation size is larger than some arbitrary + * number (32MB currently). + */ + if (size > 32 * 1024 * 1024) { + /* + * XXX special case for device requiring peer-peer DMA + */ + if (size == 0x100000000UL) + baseptr = &hostbase; + else + baseptr = &pci_emul_membase64; + limit = PCI_EMUL_MEMLIMIT64; + mask = PCIM_BAR_MEM_BASE; + lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | + PCIM_BAR_MEM_PREFETCH; + break; + } else { + baseptr = &pci_emul_membase32; + limit = PCI_EMUL_MEMLIMIT32; + mask = PCIM_BAR_MEM_BASE; + lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64; + } + break; + case PCIBAR_MEM32: + baseptr = &pci_emul_membase32; + limit = PCI_EMUL_MEMLIMIT32; + mask = PCIM_BAR_MEM_BASE; + lobits = PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32; + break; + default: + printf("pci_emul_alloc_base: invalid bar type %d\n", type); +#ifdef FreeBSD + assert(0); +#else + abort(); +#endif + } + + if (baseptr != NULL) { + error = pci_emul_alloc_resource(baseptr, limit, size, &addr); + if (error != 0) + return (error); + } + + pdi->pi_bar[idx].type = type; + pdi->pi_bar[idx].addr = addr; + pdi->pi_bar[idx].size = size; + + /* Initialize the BAR register in config space */ + bar = (addr & mask) | lobits; + pci_set_cfgdata32(pdi, PCIR_BAR(idx), bar); + + if (type == PCIBAR_MEM64) { + assert(idx + 1 <= PCI_BARMAX); + pdi->pi_bar[idx + 1].type = PCIBAR_MEMHI64; + pci_set_cfgdata32(pdi, PCIR_BAR(idx + 1), bar >> 32); + } + + register_bar(pdi, idx); + + return (0); +} + +#define CAP_START_OFFSET 0x40 +static int +pci_emul_add_capability(struct pci_devinst *pi, u_char *capdata, int caplen) +{ + int i, capoff, reallen; + uint16_t sts; + + assert(caplen > 0); + + reallen = roundup2(caplen, 4); /* dword aligned */ + + sts = pci_get_cfgdata16(pi, PCIR_STATUS); + if ((sts & PCIM_STATUS_CAPPRESENT) == 0) + capoff = CAP_START_OFFSET; + else + capoff = pi->pi_capend + 1; + + /* Check if we have enough space */ + if (capoff + reallen > PCI_REGMAX + 1) + return (-1); + + /* Set the previous capability pointer */ + if ((sts & PCIM_STATUS_CAPPRESENT) == 0) { + pci_set_cfgdata8(pi, PCIR_CAP_PTR, capoff); + pci_set_cfgdata16(pi, PCIR_STATUS, sts|PCIM_STATUS_CAPPRESENT); + } else + pci_set_cfgdata8(pi, pi->pi_prevcap + 1, capoff); + + /* Copy the capability */ + for (i = 0; i < caplen; i++) + pci_set_cfgdata8(pi, capoff + i, capdata[i]); + + /* Set the next capability pointer */ + pci_set_cfgdata8(pi, capoff + 1, 0); + + pi->pi_prevcap = capoff; + pi->pi_capend = capoff + reallen - 1; + return (0); +} + +static struct pci_devemu * +pci_emul_finddev(char *name) +{ + struct pci_devemu **pdpp, *pdp; + + SET_FOREACH(pdpp, pci_devemu_set) { + pdp = *pdpp; + if (!strcmp(pdp->pe_emu, name)) { + return (pdp); + } + } + + return (NULL); +} + +static int +pci_emul_init(struct vmctx *ctx, struct pci_devemu *pde, int bus, int slot, + int func, struct funcinfo *fi) +{ + struct pci_devinst *pdi; + int err; + + pdi = calloc(1, sizeof(struct pci_devinst)); + + pdi->pi_vmctx = ctx; + pdi->pi_bus = bus; + pdi->pi_slot = slot; + pdi->pi_func = func; + pthread_mutex_init(&pdi->pi_lintr.lock, NULL); + pdi->pi_lintr.pin = 0; + pdi->pi_lintr.state = IDLE; + pdi->pi_lintr.pirq_pin = 0; + pdi->pi_lintr.ioapic_irq = 0; + pdi->pi_d = pde; + snprintf(pdi->pi_name, PI_NAMESZ, "%s-pci-%d", pde->pe_emu, slot); + + /* Disable legacy interrupts */ + pci_set_cfgdata8(pdi, PCIR_INTLINE, 255); + pci_set_cfgdata8(pdi, PCIR_INTPIN, 0); + + pci_set_cfgdata8(pdi, PCIR_COMMAND, + PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); + + err = (*pde->pe_init)(ctx, pdi, fi->fi_param); + if (err == 0) + fi->fi_devi = pdi; + else + free(pdi); + + return (err); +} + +void +pci_populate_msicap(struct msicap *msicap, int msgnum, int nextptr) +{ + int mmc; + + /* Number of msi messages must be a power of 2 between 1 and 32 */ + assert((msgnum & (msgnum - 1)) == 0 && msgnum >= 1 && msgnum <= 32); + mmc = ffs(msgnum) - 1; + + bzero(msicap, sizeof(struct msicap)); + msicap->capid = PCIY_MSI; + msicap->nextptr = nextptr; + msicap->msgctrl = PCIM_MSICTRL_64BIT | (mmc << 1); +} + +int +pci_emul_add_msicap(struct pci_devinst *pi, int msgnum) +{ + struct msicap msicap; + + pci_populate_msicap(&msicap, msgnum, 0); + + return (pci_emul_add_capability(pi, (u_char *)&msicap, sizeof(msicap))); +} + +static void +pci_populate_msixcap(struct msixcap *msixcap, int msgnum, int barnum, + uint32_t msix_tab_size) +{ + + assert(msix_tab_size % 4096 == 0); + + bzero(msixcap, sizeof(struct msixcap)); + msixcap->capid = PCIY_MSIX; + + /* + * Message Control Register, all fields set to + * zero except for the Table Size. + * Note: Table size N is encoded as N-1 + */ + msixcap->msgctrl = msgnum - 1; + + /* + * MSI-X BAR setup: + * - MSI-X table start at offset 0 + * - PBA table starts at a 4K aligned offset after the MSI-X table + */ + msixcap->table_info = barnum & PCIM_MSIX_BIR_MASK; + msixcap->pba_info = msix_tab_size | (barnum & PCIM_MSIX_BIR_MASK); +} + +static void +pci_msix_table_init(struct pci_devinst *pi, int table_entries) +{ + int i, table_size; + + assert(table_entries > 0); + assert(table_entries <= MAX_MSIX_TABLE_ENTRIES); + + table_size = table_entries * MSIX_TABLE_ENTRY_SIZE; + pi->pi_msix.table = calloc(1, table_size); + + /* set mask bit of vector control register */ + for (i = 0; i < table_entries; i++) + pi->pi_msix.table[i].vector_control |= PCIM_MSIX_VCTRL_MASK; +} + +int +pci_emul_add_msixcap(struct pci_devinst *pi, int msgnum, int barnum) +{ + uint32_t tab_size; + struct msixcap msixcap; + + assert(msgnum >= 1 && msgnum <= MAX_MSIX_TABLE_ENTRIES); + assert(barnum >= 0 && barnum <= PCIR_MAX_BAR_0); + + tab_size = msgnum * MSIX_TABLE_ENTRY_SIZE; + + /* Align table size to nearest 4K */ + tab_size = roundup2(tab_size, 4096); + + pi->pi_msix.table_bar = barnum; + pi->pi_msix.pba_bar = barnum; + pi->pi_msix.table_offset = 0; + pi->pi_msix.table_count = msgnum; + pi->pi_msix.pba_offset = tab_size; + pi->pi_msix.pba_size = PBA_SIZE(msgnum); + + pci_msix_table_init(pi, msgnum); + + pci_populate_msixcap(&msixcap, msgnum, barnum, tab_size); + + /* allocate memory for MSI-X Table and PBA */ + pci_emul_alloc_bar(pi, barnum, PCIBAR_MEM32, + tab_size + pi->pi_msix.pba_size); + + return (pci_emul_add_capability(pi, (u_char *)&msixcap, + sizeof(msixcap))); +} + +void +msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, + int bytes, uint32_t val) +{ + uint16_t msgctrl, rwmask; + int off; + + off = offset - capoff; + /* Message Control Register */ + if (off == 2 && bytes == 2) { + rwmask = PCIM_MSIXCTRL_MSIX_ENABLE | PCIM_MSIXCTRL_FUNCTION_MASK; + msgctrl = pci_get_cfgdata16(pi, offset); + msgctrl &= ~rwmask; + msgctrl |= val & rwmask; + val = msgctrl; + + pi->pi_msix.enabled = val & PCIM_MSIXCTRL_MSIX_ENABLE; + pi->pi_msix.function_mask = val & PCIM_MSIXCTRL_FUNCTION_MASK; + pci_lintr_update(pi); + } + + CFGWRITE(pi, offset, val, bytes); +} + +void +msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, + int bytes, uint32_t val) +{ + uint16_t msgctrl, rwmask, msgdata, mme; + uint32_t addrlo; + + /* + * If guest is writing to the message control register make sure + * we do not overwrite read-only fields. + */ + if ((offset - capoff) == 2 && bytes == 2) { + rwmask = PCIM_MSICTRL_MME_MASK | PCIM_MSICTRL_MSI_ENABLE; + msgctrl = pci_get_cfgdata16(pi, offset); + msgctrl &= ~rwmask; + msgctrl |= val & rwmask; + val = msgctrl; + + addrlo = pci_get_cfgdata32(pi, capoff + 4); + if (msgctrl & PCIM_MSICTRL_64BIT) + msgdata = pci_get_cfgdata16(pi, capoff + 12); + else + msgdata = pci_get_cfgdata16(pi, capoff + 8); + + mme = msgctrl & PCIM_MSICTRL_MME_MASK; + pi->pi_msi.enabled = msgctrl & PCIM_MSICTRL_MSI_ENABLE ? 1 : 0; + if (pi->pi_msi.enabled) { + pi->pi_msi.addr = addrlo; + pi->pi_msi.msg_data = msgdata; + pi->pi_msi.maxmsgnum = 1 << (mme >> 4); + } else { + pi->pi_msi.maxmsgnum = 0; + } + pci_lintr_update(pi); + } + + CFGWRITE(pi, offset, val, bytes); +} + +void +pciecap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, + int bytes, uint32_t val) +{ + + /* XXX don't write to the readonly parts */ + CFGWRITE(pi, offset, val, bytes); +} + +#define PCIECAP_VERSION 0x2 +int +pci_emul_add_pciecap(struct pci_devinst *pi, int type) +{ + int err; + struct pciecap pciecap; + + if (type != PCIEM_TYPE_ROOT_PORT) + return (-1); + + bzero(&pciecap, sizeof(pciecap)); + + pciecap.capid = PCIY_EXPRESS; + pciecap.pcie_capabilities = PCIECAP_VERSION | PCIEM_TYPE_ROOT_PORT; + pciecap.link_capabilities = 0x411; /* gen1, x1 */ + pciecap.link_status = 0x11; /* gen1, x1 */ + + err = pci_emul_add_capability(pi, (u_char *)&pciecap, sizeof(pciecap)); + return (err); +} + +/* + * This function assumes that 'coff' is in the capabilities region of the + * config space. + */ +static void +pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes, uint32_t val) +{ + int capid; + uint8_t capoff, nextoff; + + /* Do not allow un-aligned writes */ + if ((offset & (bytes - 1)) != 0) + return; + + /* Find the capability that we want to update */ + capoff = CAP_START_OFFSET; + while (1) { + nextoff = pci_get_cfgdata8(pi, capoff + 1); + if (nextoff == 0) + break; + if (offset >= capoff && offset < nextoff) + break; + + capoff = nextoff; + } + assert(offset >= capoff); + + /* + * Capability ID and Next Capability Pointer are readonly. + * However, some o/s's do 4-byte writes that include these. + * For this case, trim the write back to 2 bytes and adjust + * the data. + */ + if (offset == capoff || offset == capoff + 1) { + if (offset == capoff && bytes == 4) { + bytes = 2; + offset += 2; + val >>= 16; + } else + return; + } + + capid = pci_get_cfgdata8(pi, capoff); + switch (capid) { + case PCIY_MSI: + msicap_cfgwrite(pi, capoff, offset, bytes, val); + break; + case PCIY_MSIX: + msixcap_cfgwrite(pi, capoff, offset, bytes, val); + break; + case PCIY_EXPRESS: + pciecap_cfgwrite(pi, capoff, offset, bytes, val); + break; + default: + break; + } +} + +static int +pci_emul_iscap(struct pci_devinst *pi, int offset) +{ + uint16_t sts; + + sts = pci_get_cfgdata16(pi, PCIR_STATUS); + if ((sts & PCIM_STATUS_CAPPRESENT) != 0) { + if (offset >= CAP_START_OFFSET && offset <= pi->pi_capend) + return (1); + } + return (0); +} + +static int +pci_emul_fallback_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, + int size, uint64_t *val, void *arg1, long arg2) +{ + /* + * Ignore writes; return 0xff's for reads. The mem read code + * will take care of truncating to the correct size. + */ + if (dir == MEM_F_READ) { + *val = 0xffffffffffffffff; + } + + return (0); +} + +static int +pci_emul_ecfg_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, + int bytes, uint64_t *val, void *arg1, long arg2) +{ + int bus, slot, func, coff, in; + + coff = addr & 0xfff; + func = (addr >> 12) & 0x7; + slot = (addr >> 15) & 0x1f; + bus = (addr >> 20) & 0xff; + in = (dir == MEM_F_READ); + if (in) + *val = ~0UL; + pci_cfgrw(ctx, vcpu, in, bus, slot, func, coff, bytes, (uint32_t *)val); + return (0); +} + +uint64_t +pci_ecfg_base(void) +{ + + return (PCI_EMUL_ECFG_BASE); +} + +#define BUSIO_ROUNDUP 32 +#define BUSMEM_ROUNDUP (1024 * 1024) + +int +init_pci(struct vmctx *ctx) +{ + struct mem_range mr; + struct pci_devemu *pde; + struct businfo *bi; + struct slotinfo *si; + struct funcinfo *fi; + size_t lowmem; + int bus, slot, func; + int error; + + pci_emul_iobase = PCI_EMUL_IOBASE; + pci_emul_membase32 = vm_get_lowmem_limit(ctx); + pci_emul_membase64 = PCI_EMUL_MEMBASE64; + + for (bus = 0; bus < MAXBUSES; bus++) { + if ((bi = pci_businfo[bus]) == NULL) + continue; + /* + * Keep track of the i/o and memory resources allocated to + * this bus. + */ + bi->iobase = pci_emul_iobase; + bi->membase32 = pci_emul_membase32; + bi->membase64 = pci_emul_membase64; + + for (slot = 0; slot < MAXSLOTS; slot++) { + si = &bi->slotinfo[slot]; + for (func = 0; func < MAXFUNCS; func++) { + fi = &si->si_funcs[func]; + if (fi->fi_name == NULL) + continue; + pde = pci_emul_finddev(fi->fi_name); + assert(pde != NULL); + error = pci_emul_init(ctx, pde, bus, slot, + func, fi); + if (error) + return (error); + } + } + + /* + * Add some slop to the I/O and memory resources decoded by + * this bus to give a guest some flexibility if it wants to + * reprogram the BARs. + */ + pci_emul_iobase += BUSIO_ROUNDUP; + pci_emul_iobase = roundup2(pci_emul_iobase, BUSIO_ROUNDUP); + bi->iolimit = pci_emul_iobase; + + pci_emul_membase32 += BUSMEM_ROUNDUP; + pci_emul_membase32 = roundup2(pci_emul_membase32, + BUSMEM_ROUNDUP); + bi->memlimit32 = pci_emul_membase32; + + pci_emul_membase64 += BUSMEM_ROUNDUP; + pci_emul_membase64 = roundup2(pci_emul_membase64, + BUSMEM_ROUNDUP); + bi->memlimit64 = pci_emul_membase64; + } + + /* + * PCI backends are initialized before routing INTx interrupts + * so that LPC devices are able to reserve ISA IRQs before + * routing PIRQ pins. + */ + for (bus = 0; bus < MAXBUSES; bus++) { + if ((bi = pci_businfo[bus]) == NULL) + continue; + + for (slot = 0; slot < MAXSLOTS; slot++) { + si = &bi->slotinfo[slot]; + for (func = 0; func < MAXFUNCS; func++) { + fi = &si->si_funcs[func]; + if (fi->fi_devi == NULL) + continue; + pci_lintr_route(fi->fi_devi); + } + } + } + lpc_pirq_routed(); + + /* + * The guest physical memory map looks like the following: + * [0, lowmem) guest system memory + * [lowmem, lowmem_limit) memory hole (may be absent) + * [lowmem_limit, 0xE0000000) PCI hole (32-bit BAR allocation) + * [0xE0000000, 0xF0000000) PCI extended config window + * [0xF0000000, 4GB) LAPIC, IOAPIC, HPET, firmware + * [4GB, 4GB + highmem) + */ + + /* + * Accesses to memory addresses that are not allocated to system + * memory or PCI devices return 0xff's. + */ + lowmem = vm_get_lowmem_size(ctx); + bzero(&mr, sizeof(struct mem_range)); + mr.name = "PCI hole"; + mr.flags = MEM_F_RW | MEM_F_IMMUTABLE; + mr.base = lowmem; + mr.size = (4ULL * 1024 * 1024 * 1024) - lowmem; + mr.handler = pci_emul_fallback_handler; + error = register_mem_fallback(&mr); + assert(error == 0); + + /* PCI extended config space */ + bzero(&mr, sizeof(struct mem_range)); + mr.name = "PCI ECFG"; + mr.flags = MEM_F_RW | MEM_F_IMMUTABLE; + mr.base = PCI_EMUL_ECFG_BASE; + mr.size = PCI_EMUL_ECFG_SIZE; + mr.handler = pci_emul_ecfg_handler; + error = register_mem(&mr); + assert(error == 0); + + return (0); +} + +static void +pci_apic_prt_entry(int bus, int slot, int pin, int pirq_pin, int ioapic_irq, + void *arg) +{ + + dsdt_line(" Package ()"); + dsdt_line(" {"); + dsdt_line(" 0x%X,", slot << 16 | 0xffff); + dsdt_line(" 0x%02X,", pin - 1); + dsdt_line(" Zero,"); + dsdt_line(" 0x%X", ioapic_irq); + dsdt_line(" },"); +} + +static void +pci_pirq_prt_entry(int bus, int slot, int pin, int pirq_pin, int ioapic_irq, + void *arg) +{ + char *name; + + name = lpc_pirq_name(pirq_pin); + if (name == NULL) + return; + dsdt_line(" Package ()"); + dsdt_line(" {"); + dsdt_line(" 0x%X,", slot << 16 | 0xffff); + dsdt_line(" 0x%02X,", pin - 1); + dsdt_line(" %s,", name); + dsdt_line(" 0x00"); + dsdt_line(" },"); + free(name); +} + +/* + * A bhyve virtual machine has a flat PCI hierarchy with a root port + * corresponding to each PCI bus. + */ +static void +pci_bus_write_dsdt(int bus) +{ + struct businfo *bi; + struct slotinfo *si; + struct pci_devinst *pi; + int count, func, slot; + + /* + * If there are no devices on this 'bus' then just return. + */ + if ((bi = pci_businfo[bus]) == NULL) { + /* + * Bus 0 is special because it decodes the I/O ports used + * for PCI config space access even if there are no devices + * on it. + */ + if (bus != 0) + return; + } + + dsdt_line(" Device (PC%02X)", bus); + dsdt_line(" {"); + dsdt_line(" Name (_HID, EisaId (\"PNP0A03\"))"); + dsdt_line(" Name (_ADR, Zero)"); + + dsdt_line(" Method (_BBN, 0, NotSerialized)"); + dsdt_line(" {"); + dsdt_line(" Return (0x%08X)", bus); + dsdt_line(" }"); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_line(" WordBusNumber (ResourceProducer, MinFixed, " + "MaxFixed, PosDecode,"); + dsdt_line(" 0x0000, // Granularity"); + dsdt_line(" 0x%04X, // Range Minimum", bus); + dsdt_line(" 0x%04X, // Range Maximum", bus); + dsdt_line(" 0x0000, // Translation Offset"); + dsdt_line(" 0x0001, // Length"); + dsdt_line(" ,, )"); + + if (bus == 0) { + dsdt_indent(3); + dsdt_fixed_ioport(0xCF8, 8); + dsdt_unindent(3); + + dsdt_line(" WordIO (ResourceProducer, MinFixed, MaxFixed, " + "PosDecode, EntireRange,"); + dsdt_line(" 0x0000, // Granularity"); + dsdt_line(" 0x0000, // Range Minimum"); + dsdt_line(" 0x0CF7, // Range Maximum"); + dsdt_line(" 0x0000, // Translation Offset"); + dsdt_line(" 0x0CF8, // Length"); + dsdt_line(" ,, , TypeStatic)"); + + dsdt_line(" WordIO (ResourceProducer, MinFixed, MaxFixed, " + "PosDecode, EntireRange,"); + dsdt_line(" 0x0000, // Granularity"); + dsdt_line(" 0x0D00, // Range Minimum"); + dsdt_line(" 0x%04X, // Range Maximum", + PCI_EMUL_IOBASE - 1); + dsdt_line(" 0x0000, // Translation Offset"); + dsdt_line(" 0x%04X, // Length", + PCI_EMUL_IOBASE - 0x0D00); + dsdt_line(" ,, , TypeStatic)"); + + if (bi == NULL) { + dsdt_line(" })"); + goto done; + } + } + assert(bi != NULL); + + /* i/o window */ + dsdt_line(" WordIO (ResourceProducer, MinFixed, MaxFixed, " + "PosDecode, EntireRange,"); + dsdt_line(" 0x0000, // Granularity"); + dsdt_line(" 0x%04X, // Range Minimum", bi->iobase); + dsdt_line(" 0x%04X, // Range Maximum", + bi->iolimit - 1); + dsdt_line(" 0x0000, // Translation Offset"); + dsdt_line(" 0x%04X, // Length", + bi->iolimit - bi->iobase); + dsdt_line(" ,, , TypeStatic)"); + + /* mmio window (32-bit) */ + dsdt_line(" DWordMemory (ResourceProducer, PosDecode, " + "MinFixed, MaxFixed, NonCacheable, ReadWrite,"); + dsdt_line(" 0x00000000, // Granularity"); + dsdt_line(" 0x%08X, // Range Minimum\n", bi->membase32); + dsdt_line(" 0x%08X, // Range Maximum\n", + bi->memlimit32 - 1); + dsdt_line(" 0x00000000, // Translation Offset"); + dsdt_line(" 0x%08X, // Length\n", + bi->memlimit32 - bi->membase32); + dsdt_line(" ,, , AddressRangeMemory, TypeStatic)"); + + /* mmio window (64-bit) */ + dsdt_line(" QWordMemory (ResourceProducer, PosDecode, " + "MinFixed, MaxFixed, NonCacheable, ReadWrite,"); + dsdt_line(" 0x0000000000000000, // Granularity"); + dsdt_line(" 0x%016lX, // Range Minimum\n", bi->membase64); + dsdt_line(" 0x%016lX, // Range Maximum\n", + bi->memlimit64 - 1); + dsdt_line(" 0x0000000000000000, // Translation Offset"); + dsdt_line(" 0x%016lX, // Length\n", + bi->memlimit64 - bi->membase64); + dsdt_line(" ,, , AddressRangeMemory, TypeStatic)"); + dsdt_line(" })"); + + count = pci_count_lintr(bus); + if (count != 0) { + dsdt_indent(2); + dsdt_line("Name (PPRT, Package ()"); + dsdt_line("{"); + pci_walk_lintr(bus, pci_pirq_prt_entry, NULL); + dsdt_line("})"); + dsdt_line("Name (APRT, Package ()"); + dsdt_line("{"); + pci_walk_lintr(bus, pci_apic_prt_entry, NULL); + dsdt_line("})"); + dsdt_line("Method (_PRT, 0, NotSerialized)"); + dsdt_line("{"); + dsdt_line(" If (PICM)"); + dsdt_line(" {"); + dsdt_line(" Return (APRT)"); + dsdt_line(" }"); + dsdt_line(" Else"); + dsdt_line(" {"); + dsdt_line(" Return (PPRT)"); + dsdt_line(" }"); + dsdt_line("}"); + dsdt_unindent(2); + } + + dsdt_indent(2); + for (slot = 0; slot < MAXSLOTS; slot++) { + si = &bi->slotinfo[slot]; + for (func = 0; func < MAXFUNCS; func++) { + pi = si->si_funcs[func].fi_devi; + if (pi != NULL && pi->pi_d->pe_write_dsdt != NULL) + pi->pi_d->pe_write_dsdt(pi); + } + } + dsdt_unindent(2); +done: + dsdt_line(" }"); +} + +void +pci_write_dsdt(void) +{ + int bus; + + dsdt_indent(1); + dsdt_line("Name (PICM, 0x00)"); + dsdt_line("Method (_PIC, 1, NotSerialized)"); + dsdt_line("{"); + dsdt_line(" Store (Arg0, PICM)"); + dsdt_line("}"); + dsdt_line(""); + dsdt_line("Scope (_SB)"); + dsdt_line("{"); + for (bus = 0; bus < MAXBUSES; bus++) + pci_bus_write_dsdt(bus); + dsdt_line("}"); + dsdt_unindent(1); +} + +int +pci_bus_configured(int bus) +{ + assert(bus >= 0 && bus < MAXBUSES); + return (pci_businfo[bus] != NULL); +} + +int +pci_msi_enabled(struct pci_devinst *pi) +{ + return (pi->pi_msi.enabled); +} + +int +pci_msi_maxmsgnum(struct pci_devinst *pi) +{ + if (pi->pi_msi.enabled) + return (pi->pi_msi.maxmsgnum); + else + return (0); +} + +int +pci_msix_enabled(struct pci_devinst *pi) +{ + + return (pi->pi_msix.enabled && !pi->pi_msi.enabled); +} + +void +pci_generate_msix(struct pci_devinst *pi, int index) +{ + struct msix_table_entry *mte; + + if (!pci_msix_enabled(pi)) + return; + + if (pi->pi_msix.function_mask) + return; + + if (index >= pi->pi_msix.table_count) + return; + + mte = &pi->pi_msix.table[index]; + if ((mte->vector_control & PCIM_MSIX_VCTRL_MASK) == 0) { + /* XXX Set PBA bit if interrupt is disabled */ + vm_lapic_msi(pi->pi_vmctx, mte->addr, mte->msg_data); + } +} + +void +pci_generate_msi(struct pci_devinst *pi, int index) +{ + + if (pci_msi_enabled(pi) && index < pci_msi_maxmsgnum(pi)) { + vm_lapic_msi(pi->pi_vmctx, pi->pi_msi.addr, + pi->pi_msi.msg_data + index); + } +} + +static bool +pci_lintr_permitted(struct pci_devinst *pi) +{ + uint16_t cmd; + + cmd = pci_get_cfgdata16(pi, PCIR_COMMAND); + return (!(pi->pi_msi.enabled || pi->pi_msix.enabled || + (cmd & PCIM_CMD_INTxDIS))); +} + +void +pci_lintr_request(struct pci_devinst *pi) +{ + struct businfo *bi; + struct slotinfo *si; + int bestpin, bestcount, pin; + + bi = pci_businfo[pi->pi_bus]; + assert(bi != NULL); + + /* + * Just allocate a pin from our slot. The pin will be + * assigned IRQs later when interrupts are routed. + */ + si = &bi->slotinfo[pi->pi_slot]; + bestpin = 0; + bestcount = si->si_intpins[0].ii_count; + for (pin = 1; pin < 4; pin++) { + if (si->si_intpins[pin].ii_count < bestcount) { + bestpin = pin; + bestcount = si->si_intpins[pin].ii_count; + } + } + + si->si_intpins[bestpin].ii_count++; + pi->pi_lintr.pin = bestpin + 1; + pci_set_cfgdata8(pi, PCIR_INTPIN, bestpin + 1); +} + +static void +pci_lintr_route(struct pci_devinst *pi) +{ + struct businfo *bi; + struct intxinfo *ii; + + if (pi->pi_lintr.pin == 0) + return; + + bi = pci_businfo[pi->pi_bus]; + assert(bi != NULL); + ii = &bi->slotinfo[pi->pi_slot].si_intpins[pi->pi_lintr.pin - 1]; + + /* + * Attempt to allocate an I/O APIC pin for this intpin if one + * is not yet assigned. + */ + if (ii->ii_ioapic_irq == 0) + ii->ii_ioapic_irq = ioapic_pci_alloc_irq(pi); + assert(ii->ii_ioapic_irq > 0); + + /* + * Attempt to allocate a PIRQ pin for this intpin if one is + * not yet assigned. + */ + if (ii->ii_pirq_pin == 0) + ii->ii_pirq_pin = pirq_alloc_pin(pi); + assert(ii->ii_pirq_pin > 0); + + pi->pi_lintr.ioapic_irq = ii->ii_ioapic_irq; + pi->pi_lintr.pirq_pin = ii->ii_pirq_pin; + pci_set_cfgdata8(pi, PCIR_INTLINE, pirq_irq(ii->ii_pirq_pin)); +} + +void +pci_lintr_assert(struct pci_devinst *pi) +{ + + assert(pi->pi_lintr.pin > 0); + + pthread_mutex_lock(&pi->pi_lintr.lock); + if (pi->pi_lintr.state == IDLE) { + if (pci_lintr_permitted(pi)) { + pi->pi_lintr.state = ASSERTED; + pci_irq_assert(pi); + } else + pi->pi_lintr.state = PENDING; + } + pthread_mutex_unlock(&pi->pi_lintr.lock); +} + +void +pci_lintr_deassert(struct pci_devinst *pi) +{ + + assert(pi->pi_lintr.pin > 0); + + pthread_mutex_lock(&pi->pi_lintr.lock); + if (pi->pi_lintr.state == ASSERTED) { + pi->pi_lintr.state = IDLE; + pci_irq_deassert(pi); + } else if (pi->pi_lintr.state == PENDING) + pi->pi_lintr.state = IDLE; + pthread_mutex_unlock(&pi->pi_lintr.lock); +} + +static void +pci_lintr_update(struct pci_devinst *pi) +{ + + pthread_mutex_lock(&pi->pi_lintr.lock); + if (pi->pi_lintr.state == ASSERTED && !pci_lintr_permitted(pi)) { + pci_irq_deassert(pi); + pi->pi_lintr.state = PENDING; + } else if (pi->pi_lintr.state == PENDING && pci_lintr_permitted(pi)) { + pi->pi_lintr.state = ASSERTED; + pci_irq_assert(pi); + } + pthread_mutex_unlock(&pi->pi_lintr.lock); +#ifndef __FreeBSD__ + if (pi->pi_d->pe_lintrupdate != NULL) { + pi->pi_d->pe_lintrupdate(pi); + } +#endif /* __FreeBSD__ */ +} + +int +pci_count_lintr(int bus) +{ + int count, slot, pin; + struct slotinfo *slotinfo; + + count = 0; + if (pci_businfo[bus] != NULL) { + for (slot = 0; slot < MAXSLOTS; slot++) { + slotinfo = &pci_businfo[bus]->slotinfo[slot]; + for (pin = 0; pin < 4; pin++) { + if (slotinfo->si_intpins[pin].ii_count != 0) + count++; + } + } + } + return (count); +} + +void +pci_walk_lintr(int bus, pci_lintr_cb cb, void *arg) +{ + struct businfo *bi; + struct slotinfo *si; + struct intxinfo *ii; + int slot, pin; + + if ((bi = pci_businfo[bus]) == NULL) + return; + + for (slot = 0; slot < MAXSLOTS; slot++) { + si = &bi->slotinfo[slot]; + for (pin = 0; pin < 4; pin++) { + ii = &si->si_intpins[pin]; + if (ii->ii_count != 0) + cb(bus, slot, pin + 1, ii->ii_pirq_pin, + ii->ii_ioapic_irq, arg); + } + } +} + +/* + * Return 1 if the emulated device in 'slot' is a multi-function device. + * Return 0 otherwise. + */ +static int +pci_emul_is_mfdev(int bus, int slot) +{ + struct businfo *bi; + struct slotinfo *si; + int f, numfuncs; + + numfuncs = 0; + if ((bi = pci_businfo[bus]) != NULL) { + si = &bi->slotinfo[slot]; + for (f = 0; f < MAXFUNCS; f++) { + if (si->si_funcs[f].fi_devi != NULL) { + numfuncs++; + } + } + } + return (numfuncs > 1); +} + +/* + * Ensure that the PCIM_MFDEV bit is properly set (or unset) depending on + * whether or not is a multi-function being emulated in the pci 'slot'. + */ +static void +pci_emul_hdrtype_fixup(int bus, int slot, int off, int bytes, uint32_t *rv) +{ + int mfdev; + + if (off <= PCIR_HDRTYPE && off + bytes > PCIR_HDRTYPE) { + mfdev = pci_emul_is_mfdev(bus, slot); + switch (bytes) { + case 1: + case 2: + *rv &= ~PCIM_MFDEV; + if (mfdev) { + *rv |= PCIM_MFDEV; + } + break; + case 4: + *rv &= ~(PCIM_MFDEV << 16); + if (mfdev) { + *rv |= (PCIM_MFDEV << 16); + } + break; + } + } +} + +static void +pci_emul_cmdsts_write(struct pci_devinst *pi, int coff, uint32_t new, int bytes) +{ + int i, rshift; + uint32_t cmd, cmd2, changed, old, readonly; + + cmd = pci_get_cfgdata16(pi, PCIR_COMMAND); /* stash old value */ + + /* + * From PCI Local Bus Specification 3.0 sections 6.2.2 and 6.2.3. + * + * XXX Bits 8, 11, 12, 13, 14 and 15 in the status register are + * 'write 1 to clear'. However these bits are not set to '1' by + * any device emulation so it is simpler to treat them as readonly. + */ + rshift = (coff & 0x3) * 8; + readonly = 0xFFFFF880 >> rshift; + + old = CFGREAD(pi, coff, bytes); + new &= ~readonly; + new |= (old & readonly); + CFGWRITE(pi, coff, new, bytes); /* update config */ + + cmd2 = pci_get_cfgdata16(pi, PCIR_COMMAND); /* get updated value */ + changed = cmd ^ cmd2; + + /* + * If the MMIO or I/O address space decoding has changed then + * register/unregister all BARs that decode that address space. + */ + for (i = 0; i <= PCI_BARMAX; i++) { + switch (pi->pi_bar[i].type) { + case PCIBAR_NONE: + case PCIBAR_MEMHI64: + break; + case PCIBAR_IO: + /* I/O address space decoding changed? */ + if (changed & PCIM_CMD_PORTEN) { + if (porten(pi)) + register_bar(pi, i); + else + unregister_bar(pi, i); + } + break; + case PCIBAR_MEM32: + case PCIBAR_MEM64: + /* MMIO address space decoding changed? */ + if (changed & PCIM_CMD_MEMEN) { + if (memen(pi)) + register_bar(pi, i); + else + unregister_bar(pi, i); + } + break; + default: + assert(0); + } + } + + /* + * If INTx has been unmasked and is pending, assert the + * interrupt. + */ + pci_lintr_update(pi); +} + +static void +pci_cfgrw(struct vmctx *ctx, int vcpu, int in, int bus, int slot, int func, + int coff, int bytes, uint32_t *eax) +{ + struct businfo *bi; + struct slotinfo *si; + struct pci_devinst *pi; + struct pci_devemu *pe; + int idx, needcfg; + uint64_t addr, mask; + uint64_t bar = 0; + + if ((bi = pci_businfo[bus]) != NULL) { + si = &bi->slotinfo[slot]; + pi = si->si_funcs[func].fi_devi; + } else + pi = NULL; + + /* + * Just return if there is no device at this slot:func or if the + * the guest is doing an un-aligned access. + */ + if (pi == NULL || (bytes != 1 && bytes != 2 && bytes != 4) || + (coff & (bytes - 1)) != 0) { + if (in) + *eax = 0xffffffff; + return; + } + + /* + * Ignore all writes beyond the standard config space and return all + * ones on reads. + */ + if (coff >= PCI_REGMAX + 1) { + if (in) { + *eax = 0xffffffff; + /* + * Extended capabilities begin at offset 256 in config + * space. Absence of extended capabilities is signaled + * with all 0s in the extended capability header at + * offset 256. + */ + if (coff <= PCI_REGMAX + 4) + *eax = 0x00000000; + } + return; + } + + pe = pi->pi_d; + + /* + * Config read + */ + if (in) { + /* Let the device emulation override the default handler */ + if (pe->pe_cfgread != NULL) { + needcfg = pe->pe_cfgread(ctx, vcpu, pi, coff, bytes, + eax); + } else { + needcfg = 1; + } + + if (needcfg) + *eax = CFGREAD(pi, coff, bytes); + + pci_emul_hdrtype_fixup(bus, slot, coff, bytes, eax); + } else { + /* Let the device emulation override the default handler */ + if (pe->pe_cfgwrite != NULL && + (*pe->pe_cfgwrite)(ctx, vcpu, pi, coff, bytes, *eax) == 0) + return; + + /* + * Special handling for write to BAR registers + */ + if (coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) { + /* + * Ignore writes to BAR registers that are not + * 4-byte aligned. + */ + if (bytes != 4 || (coff & 0x3) != 0) + return; + idx = (coff - PCIR_BAR(0)) / 4; + mask = ~(pi->pi_bar[idx].size - 1); + switch (pi->pi_bar[idx].type) { + case PCIBAR_NONE: + pi->pi_bar[idx].addr = bar = 0; + break; + case PCIBAR_IO: + addr = *eax & mask; + addr &= 0xffff; + bar = addr | PCIM_BAR_IO_SPACE; + /* + * Register the new BAR value for interception + */ + if (addr != pi->pi_bar[idx].addr) { + update_bar_address(pi, addr, idx, + PCIBAR_IO); + } + break; + case PCIBAR_MEM32: + addr = bar = *eax & mask; + bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_32; + if (addr != pi->pi_bar[idx].addr) { + update_bar_address(pi, addr, idx, + PCIBAR_MEM32); + } + break; + case PCIBAR_MEM64: + addr = bar = *eax & mask; + bar |= PCIM_BAR_MEM_SPACE | PCIM_BAR_MEM_64 | + PCIM_BAR_MEM_PREFETCH; + if (addr != (uint32_t)pi->pi_bar[idx].addr) { + update_bar_address(pi, addr, idx, + PCIBAR_MEM64); + } + break; + case PCIBAR_MEMHI64: + mask = ~(pi->pi_bar[idx - 1].size - 1); + addr = ((uint64_t)*eax << 32) & mask; + bar = addr >> 32; + if (bar != pi->pi_bar[idx - 1].addr >> 32) { + update_bar_address(pi, addr, idx - 1, + PCIBAR_MEMHI64); + } + break; + default: + assert(0); + } + pci_set_cfgdata32(pi, coff, bar); + + } else if (pci_emul_iscap(pi, coff)) { + pci_emul_capwrite(pi, coff, bytes, *eax); + } else if (coff >= PCIR_COMMAND && coff < PCIR_REVID) { + pci_emul_cmdsts_write(pi, coff, *eax, bytes); + } else { + CFGWRITE(pi, coff, *eax, bytes); + } + } +} + +static int cfgenable, cfgbus, cfgslot, cfgfunc, cfgoff; + +static int +pci_emul_cfgaddr(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + uint32_t x; + + if (bytes != 4) { + if (in) + *eax = (bytes == 2) ? 0xffff : 0xff; + return (0); + } + + if (in) { + x = (cfgbus << 16) | (cfgslot << 11) | (cfgfunc << 8) | cfgoff; + if (cfgenable) + x |= CONF1_ENABLE; + *eax = x; + } else { + x = *eax; + cfgenable = (x & CONF1_ENABLE) == CONF1_ENABLE; + cfgoff = x & PCI_REGMAX; + cfgfunc = (x >> 8) & PCI_FUNCMAX; + cfgslot = (x >> 11) & PCI_SLOTMAX; + cfgbus = (x >> 16) & PCI_BUSMAX; + } + + return (0); +} +INOUT_PORT(pci_cfgaddr, CONF1_ADDR_PORT, IOPORT_F_INOUT, pci_emul_cfgaddr); + +static int +pci_emul_cfgdata(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + int coff; + + assert(bytes == 1 || bytes == 2 || bytes == 4); + + coff = cfgoff + (port - CONF1_DATA_PORT); + if (cfgenable) { + pci_cfgrw(ctx, vcpu, in, cfgbus, cfgslot, cfgfunc, coff, bytes, + eax); + } else { + /* Ignore accesses to cfgdata if not enabled by cfgaddr */ + if (in) + *eax = 0xffffffff; + } + return (0); +} + +INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+0, IOPORT_F_INOUT, pci_emul_cfgdata); +INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+1, IOPORT_F_INOUT, pci_emul_cfgdata); +INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+2, IOPORT_F_INOUT, pci_emul_cfgdata); +INOUT_PORT(pci_cfgdata, CONF1_DATA_PORT+3, IOPORT_F_INOUT, pci_emul_cfgdata); + +#define PCI_EMUL_TEST +#ifdef PCI_EMUL_TEST +/* + * Define a dummy test device + */ +#define DIOSZ 8 +#define DMEMSZ 4096 +struct pci_emul_dsoftc { + uint8_t ioregs[DIOSZ]; + uint8_t memregs[2][DMEMSZ]; +}; + +#define PCI_EMUL_MSI_MSGS 4 +#define PCI_EMUL_MSIX_MSGS 16 + +static int +pci_emul_dinit(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + int error; + struct pci_emul_dsoftc *sc; + + sc = calloc(1, sizeof(struct pci_emul_dsoftc)); + + pi->pi_arg = sc; + + pci_set_cfgdata16(pi, PCIR_DEVICE, 0x0001); + pci_set_cfgdata16(pi, PCIR_VENDOR, 0x10DD); + pci_set_cfgdata8(pi, PCIR_CLASS, 0x02); + + error = pci_emul_add_msicap(pi, PCI_EMUL_MSI_MSGS); + assert(error == 0); + + error = pci_emul_alloc_bar(pi, 0, PCIBAR_IO, DIOSZ); + assert(error == 0); + + error = pci_emul_alloc_bar(pi, 1, PCIBAR_MEM32, DMEMSZ); + assert(error == 0); + + error = pci_emul_alloc_bar(pi, 2, PCIBAR_MEM32, DMEMSZ); + assert(error == 0); + + return (0); +} + +static void +pci_emul_diow(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, + uint64_t offset, int size, uint64_t value) +{ + int i; + struct pci_emul_dsoftc *sc = pi->pi_arg; + + if (baridx == 0) { + if (offset + size > DIOSZ) { + printf("diow: iow too large, offset %ld size %d\n", + offset, size); + return; + } + + if (size == 1) { + sc->ioregs[offset] = value & 0xff; + } else if (size == 2) { + *(uint16_t *)&sc->ioregs[offset] = value & 0xffff; + } else if (size == 4) { + *(uint32_t *)&sc->ioregs[offset] = value; + } else { + printf("diow: iow unknown size %d\n", size); + } + + /* + * Special magic value to generate an interrupt + */ + if (offset == 4 && size == 4 && pci_msi_enabled(pi)) + pci_generate_msi(pi, value % pci_msi_maxmsgnum(pi)); + + if (value == 0xabcdef) { + for (i = 0; i < pci_msi_maxmsgnum(pi); i++) + pci_generate_msi(pi, i); + } + } + + if (baridx == 1 || baridx == 2) { + if (offset + size > DMEMSZ) { + printf("diow: memw too large, offset %ld size %d\n", + offset, size); + return; + } + + i = baridx - 1; /* 'memregs' index */ + + if (size == 1) { + sc->memregs[i][offset] = value; + } else if (size == 2) { + *(uint16_t *)&sc->memregs[i][offset] = value; + } else if (size == 4) { + *(uint32_t *)&sc->memregs[i][offset] = value; + } else if (size == 8) { + *(uint64_t *)&sc->memregs[i][offset] = value; + } else { + printf("diow: memw unknown size %d\n", size); + } + + /* + * magic interrupt ?? + */ + } + + if (baridx > 2 || baridx < 0) { + printf("diow: unknown bar idx %d\n", baridx); + } +} + +static uint64_t +pci_emul_dior(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, + uint64_t offset, int size) +{ + struct pci_emul_dsoftc *sc = pi->pi_arg; + uint32_t value; + int i; + + value = 0; + if (baridx == 0) { + if (offset + size > DIOSZ) { + printf("dior: ior too large, offset %ld size %d\n", + offset, size); + return (0); + } + + if (size == 1) { + value = sc->ioregs[offset]; + } else if (size == 2) { + value = *(uint16_t *) &sc->ioregs[offset]; + } else if (size == 4) { + value = *(uint32_t *) &sc->ioregs[offset]; + } else { + printf("dior: ior unknown size %d\n", size); + } + } + + if (baridx == 1 || baridx == 2) { + if (offset + size > DMEMSZ) { + printf("dior: memr too large, offset %ld size %d\n", + offset, size); + return (0); + } + + i = baridx - 1; /* 'memregs' index */ + + if (size == 1) { + value = sc->memregs[i][offset]; + } else if (size == 2) { + value = *(uint16_t *) &sc->memregs[i][offset]; + } else if (size == 4) { + value = *(uint32_t *) &sc->memregs[i][offset]; + } else if (size == 8) { + value = *(uint64_t *) &sc->memregs[i][offset]; + } else { + printf("dior: ior unknown size %d\n", size); + } + } + + + if (baridx > 2 || baridx < 0) { + printf("dior: unknown bar idx %d\n", baridx); + return (0); + } + + return (value); +} + +struct pci_devemu pci_dummy = { + .pe_emu = "dummy", + .pe_init = pci_emul_dinit, + .pe_barwrite = pci_emul_diow, + .pe_barread = pci_emul_dior +}; +PCI_EMUL_SET(pci_dummy); + +#endif /* PCI_EMUL_TEST */ diff --git a/usr/src/cmd/bhyve/pci_emul.h b/usr/src/cmd/bhyve/pci_emul.h new file mode 100644 index 0000000000..0053caed99 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_emul.h @@ -0,0 +1,298 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ +/* + * Copyright 2018 Joyent, Inc. + */ + +#ifndef _PCI_EMUL_H_ +#define _PCI_EMUL_H_ + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/kernel.h> +#include <sys/_pthreadtypes.h> + +#include <dev/pci/pcireg.h> + +#include <assert.h> + +#define PCI_BARMAX PCIR_MAX_BAR_0 /* BAR registers in a Type 0 header */ + +struct vmctx; +struct pci_devinst; +struct memory_region; + +struct pci_devemu { + char *pe_emu; /* Name of device emulation */ + + /* instance creation */ + int (*pe_init)(struct vmctx *, struct pci_devinst *, + char *opts); + + /* ACPI DSDT enumeration */ + void (*pe_write_dsdt)(struct pci_devinst *); + + /* config space read/write callbacks */ + int (*pe_cfgwrite)(struct vmctx *ctx, int vcpu, + struct pci_devinst *pi, int offset, + int bytes, uint32_t val); + int (*pe_cfgread)(struct vmctx *ctx, int vcpu, + struct pci_devinst *pi, int offset, + int bytes, uint32_t *retval); + + /* BAR read/write callbacks */ + void (*pe_barwrite)(struct vmctx *ctx, int vcpu, + struct pci_devinst *pi, int baridx, + uint64_t offset, int size, uint64_t value); + uint64_t (*pe_barread)(struct vmctx *ctx, int vcpu, + struct pci_devinst *pi, int baridx, + uint64_t offset, int size); + +#ifndef __FreeBSD__ + void (*pe_lintrupdate)(struct pci_devinst *pi); +#endif /* __FreeBSD__ */ +}; +#define PCI_EMUL_SET(x) DATA_SET(pci_devemu_set, x); + +enum pcibar_type { + PCIBAR_NONE, + PCIBAR_IO, + PCIBAR_MEM32, + PCIBAR_MEM64, + PCIBAR_MEMHI64 +}; + +struct pcibar { + enum pcibar_type type; /* io or memory */ + uint64_t size; + uint64_t addr; +}; + +#define PI_NAMESZ 40 + +struct msix_table_entry { + uint64_t addr; + uint32_t msg_data; + uint32_t vector_control; +} __packed; + +/* + * In case the structure is modified to hold extra information, use a define + * for the size that should be emulated. + */ +#define MSIX_TABLE_ENTRY_SIZE 16 +#define MAX_MSIX_TABLE_ENTRIES 2048 +#define PBA_SIZE(msgnum) (roundup2((msgnum), 64) / 8) + +enum lintr_stat { + IDLE, + ASSERTED, + PENDING +}; + +struct pci_devinst { + struct pci_devemu *pi_d; + struct vmctx *pi_vmctx; + uint8_t pi_bus, pi_slot, pi_func; + char pi_name[PI_NAMESZ]; + int pi_bar_getsize; + int pi_prevcap; + int pi_capend; + + struct { + int8_t pin; + enum lintr_stat state; + int pirq_pin; + int ioapic_irq; + pthread_mutex_t lock; + } pi_lintr; + + struct { + int enabled; + uint64_t addr; + uint64_t msg_data; + int maxmsgnum; + } pi_msi; + + struct { + int enabled; + int table_bar; + int pba_bar; + uint32_t table_offset; + int table_count; + uint32_t pba_offset; + int pba_size; + int function_mask; + struct msix_table_entry *table; /* allocated at runtime */ + void *pba_page; + int pba_page_offset; + } pi_msix; + + void *pi_arg; /* devemu-private data */ + + u_char pi_cfgdata[PCI_REGMAX + 1]; + struct pcibar pi_bar[PCI_BARMAX + 1]; +}; + +struct msicap { + uint8_t capid; + uint8_t nextptr; + uint16_t msgctrl; + uint32_t addrlo; + uint32_t addrhi; + uint16_t msgdata; +} __packed; +static_assert(sizeof(struct msicap) == 14, "compile-time assertion failed"); + +struct msixcap { + uint8_t capid; + uint8_t nextptr; + uint16_t msgctrl; + uint32_t table_info; /* bar index and offset within it */ + uint32_t pba_info; /* bar index and offset within it */ +} __packed; +static_assert(sizeof(struct msixcap) == 12, "compile-time assertion failed"); + +struct pciecap { + uint8_t capid; + uint8_t nextptr; + uint16_t pcie_capabilities; + + uint32_t dev_capabilities; /* all devices */ + uint16_t dev_control; + uint16_t dev_status; + + uint32_t link_capabilities; /* devices with links */ + uint16_t link_control; + uint16_t link_status; + + uint32_t slot_capabilities; /* ports with slots */ + uint16_t slot_control; + uint16_t slot_status; + + uint16_t root_control; /* root ports */ + uint16_t root_capabilities; + uint32_t root_status; + + uint32_t dev_capabilities2; /* all devices */ + uint16_t dev_control2; + uint16_t dev_status2; + + uint32_t link_capabilities2; /* devices with links */ + uint16_t link_control2; + uint16_t link_status2; + + uint32_t slot_capabilities2; /* ports with slots */ + uint16_t slot_control2; + uint16_t slot_status2; +} __packed; +static_assert(sizeof(struct pciecap) == 60, "compile-time assertion failed"); + +typedef void (*pci_lintr_cb)(int b, int s, int pin, int pirq_pin, + int ioapic_irq, void *arg); + +int init_pci(struct vmctx *ctx); +void msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, + int bytes, uint32_t val); +void msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset, + int bytes, uint32_t val); +void pci_callback(void); +int pci_emul_alloc_bar(struct pci_devinst *pdi, int idx, + enum pcibar_type type, uint64_t size); +int pci_emul_alloc_pbar(struct pci_devinst *pdi, int idx, + uint64_t hostbase, enum pcibar_type type, uint64_t size); +int pci_emul_add_msicap(struct pci_devinst *pi, int msgnum); +int pci_emul_add_pciecap(struct pci_devinst *pi, int pcie_device_type); +void pci_generate_msi(struct pci_devinst *pi, int msgnum); +void pci_generate_msix(struct pci_devinst *pi, int msgnum); +void pci_lintr_assert(struct pci_devinst *pi); +void pci_lintr_deassert(struct pci_devinst *pi); +void pci_lintr_request(struct pci_devinst *pi); +int pci_msi_enabled(struct pci_devinst *pi); +int pci_msix_enabled(struct pci_devinst *pi); +int pci_msix_table_bar(struct pci_devinst *pi); +int pci_msix_pba_bar(struct pci_devinst *pi); +int pci_msi_maxmsgnum(struct pci_devinst *pi); +int pci_parse_slot(char *opt); +void pci_print_supported_devices(); +void pci_populate_msicap(struct msicap *cap, int msgs, int nextptr); +int pci_emul_add_msixcap(struct pci_devinst *pi, int msgnum, int barnum); +int pci_emul_msix_twrite(struct pci_devinst *pi, uint64_t offset, int size, + uint64_t value); +uint64_t pci_emul_msix_tread(struct pci_devinst *pi, uint64_t offset, int size); +int pci_count_lintr(int bus); +void pci_walk_lintr(int bus, pci_lintr_cb cb, void *arg); +void pci_write_dsdt(void); +uint64_t pci_ecfg_base(void); +int pci_bus_configured(int bus); + +static __inline void +pci_set_cfgdata8(struct pci_devinst *pi, int offset, uint8_t val) +{ + assert(offset <= PCI_REGMAX); + *(uint8_t *)(pi->pi_cfgdata + offset) = val; +} + +static __inline void +pci_set_cfgdata16(struct pci_devinst *pi, int offset, uint16_t val) +{ + assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0); + *(uint16_t *)(pi->pi_cfgdata + offset) = val; +} + +static __inline void +pci_set_cfgdata32(struct pci_devinst *pi, int offset, uint32_t val) +{ + assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0); + *(uint32_t *)(pi->pi_cfgdata + offset) = val; +} + +static __inline uint8_t +pci_get_cfgdata8(struct pci_devinst *pi, int offset) +{ + assert(offset <= PCI_REGMAX); + return (*(uint8_t *)(pi->pi_cfgdata + offset)); +} + +static __inline uint16_t +pci_get_cfgdata16(struct pci_devinst *pi, int offset) +{ + assert(offset <= (PCI_REGMAX - 1) && (offset & 1) == 0); + return (*(uint16_t *)(pi->pi_cfgdata + offset)); +} + +static __inline uint32_t +pci_get_cfgdata32(struct pci_devinst *pi, int offset) +{ + assert(offset <= (PCI_REGMAX - 3) && (offset & 3) == 0); + return (*(uint32_t *)(pi->pi_cfgdata + offset)); +} + +#endif /* _PCI_EMUL_H_ */ diff --git a/usr/src/cmd/bhyve/pci_fbuf.c b/usr/src/cmd/bhyve/pci_fbuf.c new file mode 100644 index 0000000000..8d24dde9da --- /dev/null +++ b/usr/src/cmd/bhyve/pci_fbuf.c @@ -0,0 +1,467 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Nahanni Systems, Inc. + * Copyright 2018 Joyent, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/mman.h> + +#include <machine/vmm.h> +#include <vmmapi.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <errno.h> +#include <unistd.h> + +#include "bhyvegc.h" +#include "bhyverun.h" +#include "console.h" +#include "inout.h" +#include "pci_emul.h" +#include "rfb.h" +#include "vga.h" + +/* + * bhyve Framebuffer device emulation. + * BAR0 points to the current mode information. + * BAR1 is the 32-bit framebuffer address. + * + * -s <b>,fbuf,wait,vga=on|io|off,rfb=<ip>:port,w=width,h=height + */ + +static int fbuf_debug = 1; +#define DEBUG_INFO 1 +#define DEBUG_VERBOSE 4 +#define DPRINTF(level, params) if (level <= fbuf_debug) printf params + + +#define KB (1024UL) +#define MB (1024 * 1024UL) + +#define DMEMSZ 128 + +#define FB_SIZE (16*MB) + +#define COLS_MAX 1920 +#define ROWS_MAX 1200 + +#define COLS_DEFAULT 1024 +#define ROWS_DEFAULT 768 + +#define COLS_MIN 640 +#define ROWS_MIN 480 + +struct pci_fbuf_softc { + struct pci_devinst *fsc_pi; + struct { + uint32_t fbsize; + uint16_t width; + uint16_t height; + uint16_t depth; + uint16_t refreshrate; + uint8_t reserved[116]; + } __packed memregs; + + /* rfb server */ + char *rfb_host; + char *rfb_password; + int rfb_port; +#ifndef __FreeBSD__ + char *rfb_unix; +#endif + int rfb_wait; + int vga_enabled; + int vga_full; + + uint32_t fbaddr; + char *fb_base; + uint16_t gc_width; + uint16_t gc_height; + void *vgasc; + struct bhyvegc_image *gc_image; +}; + +static struct pci_fbuf_softc *fbuf_sc; + +#define PCI_FBUF_MSI_MSGS 4 + +static void +pci_fbuf_usage(char *opt) +{ + + fprintf(stderr, "Invalid fbuf emulation option \"%s\"\r\n", opt); + fprintf(stderr, "fbuf: {wait,}{vga=on|io|off,}rfb=<ip>:port" + "{,w=width}{,h=height}\r\n"); +} + +static void +pci_fbuf_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value) +{ + struct pci_fbuf_softc *sc; + uint8_t *p; + + assert(baridx == 0); + + sc = pi->pi_arg; + + DPRINTF(DEBUG_VERBOSE, + ("fbuf wr: offset 0x%lx, size: %d, value: 0x%lx\n", + offset, size, value)); + + if (offset + size > DMEMSZ) { + printf("fbuf: write too large, offset %ld size %d\n", + offset, size); + return; + } + + p = (uint8_t *)&sc->memregs + offset; + + switch (size) { + case 1: + *p = value; + break; + case 2: + *(uint16_t *)p = value; + break; + case 4: + *(uint32_t *)p = value; + break; + case 8: + *(uint64_t *)p = value; + break; + default: + printf("fbuf: write unknown size %d\n", size); + break; + } + + if (!sc->gc_image->vgamode && sc->memregs.width == 0 && + sc->memregs.height == 0) { + DPRINTF(DEBUG_INFO, ("switching to VGA mode\r\n")); + sc->gc_image->vgamode = 1; + sc->gc_width = 0; + sc->gc_height = 0; + } else if (sc->gc_image->vgamode && sc->memregs.width != 0 && + sc->memregs.height != 0) { + DPRINTF(DEBUG_INFO, ("switching to VESA mode\r\n")); + sc->gc_image->vgamode = 0; + } +} + +uint64_t +pci_fbuf_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size) +{ + struct pci_fbuf_softc *sc; + uint8_t *p; + uint64_t value; + + assert(baridx == 0); + + sc = pi->pi_arg; + + + if (offset + size > DMEMSZ) { + printf("fbuf: read too large, offset %ld size %d\n", + offset, size); + return (0); + } + + p = (uint8_t *)&sc->memregs + offset; + value = 0; + switch (size) { + case 1: + value = *p; + break; + case 2: + value = *(uint16_t *)p; + break; + case 4: + value = *(uint32_t *)p; + break; + case 8: + value = *(uint64_t *)p; + break; + default: + printf("fbuf: read unknown size %d\n", size); + break; + } + + DPRINTF(DEBUG_VERBOSE, + ("fbuf rd: offset 0x%lx, size: %d, value: 0x%lx\n", + offset, size, value)); + + return (value); +} + +static int +pci_fbuf_parse_opts(struct pci_fbuf_softc *sc, char *opts) +{ + char *uopts, *xopts, *config; + char *tmpstr; + int ret; + + ret = 0; + uopts = strdup(opts); + for (xopts = strtok(uopts, ","); + xopts != NULL; + xopts = strtok(NULL, ",")) { + if (strcmp(xopts, "wait") == 0) { + sc->rfb_wait = 1; + continue; + } + + if ((config = strchr(xopts, '=')) == NULL) { + pci_fbuf_usage(xopts); + ret = -1; + goto done; + } + + *config++ = '\0'; + + DPRINTF(DEBUG_VERBOSE, ("pci_fbuf option %s = %s\r\n", + xopts, config)); + + if (!strcmp(xopts, "tcp") || !strcmp(xopts, "rfb")) { + /* + * IPv4 -- host-ip:port + * IPv6 -- [host-ip%zone]:port + * XXX for now port is mandatory. + */ + tmpstr = strsep(&config, "]"); + if (config) { + if (tmpstr[0] == '[') + tmpstr++; + sc->rfb_host = tmpstr; + if (config[0] == ':') + config++; + else { + pci_fbuf_usage(xopts); + ret = -1; + goto done; + } + sc->rfb_port = atoi(config); + } else { + config = tmpstr; + tmpstr = strsep(&config, ":"); + if (!config) + sc->rfb_port = atoi(tmpstr); + else { + sc->rfb_port = atoi(config); + sc->rfb_host = tmpstr; + } + } +#ifndef __FreeBSD__ + } else if (!strcmp(xopts, "unix")) { + sc->rfb_unix = config; +#endif + } else if (!strcmp(xopts, "vga")) { + if (!strcmp(config, "off")) { + sc->vga_enabled = 0; + } else if (!strcmp(config, "io")) { + sc->vga_enabled = 1; + sc->vga_full = 0; + } else if (!strcmp(config, "on")) { + sc->vga_enabled = 1; + sc->vga_full = 1; + } else { + pci_fbuf_usage(xopts); + ret = -1; + goto done; + } + } else if (!strcmp(xopts, "w")) { + sc->memregs.width = atoi(config); + if (sc->memregs.width > COLS_MAX) { + pci_fbuf_usage(xopts); + ret = -1; + goto done; + } else if (sc->memregs.width == 0) + sc->memregs.width = 1920; + } else if (!strcmp(xopts, "h")) { + sc->memregs.height = atoi(config); + if (sc->memregs.height > ROWS_MAX) { + pci_fbuf_usage(xopts); + ret = -1; + goto done; + } else if (sc->memregs.height == 0) + sc->memregs.height = 1080; + } else if (!strcmp(xopts, "password")) { + sc->rfb_password = config; + } else { + pci_fbuf_usage(xopts); + ret = -1; + goto done; + } + } + +done: + return (ret); +} + + +extern void vga_render(struct bhyvegc *gc, void *arg); + +void +pci_fbuf_render(struct bhyvegc *gc, void *arg) +{ + struct pci_fbuf_softc *sc; + + sc = arg; + + if (sc->vga_full && sc->gc_image->vgamode) { + /* TODO: mode switching to vga and vesa should use the special + * EFI-bhyve protocol port. + */ + vga_render(gc, sc->vgasc); + return; + } + if (sc->gc_width != sc->memregs.width || + sc->gc_height != sc->memregs.height) { + bhyvegc_resize(gc, sc->memregs.width, sc->memregs.height); + sc->gc_width = sc->memregs.width; + sc->gc_height = sc->memregs.height; + } + + return; +} + +static int +pci_fbuf_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + int error, prot; + struct pci_fbuf_softc *sc; + + if (fbuf_sc != NULL) { + fprintf(stderr, "Only one frame buffer device is allowed.\n"); + return (-1); + } + + sc = calloc(1, sizeof(struct pci_fbuf_softc)); + + pi->pi_arg = sc; + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, 0x40FB); + pci_set_cfgdata16(pi, PCIR_VENDOR, 0xFB5D); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_DISPLAY); + pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_DISPLAY_VGA); + + error = pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, DMEMSZ); + assert(error == 0); + + error = pci_emul_alloc_bar(pi, 1, PCIBAR_MEM32, FB_SIZE); + assert(error == 0); + + error = pci_emul_add_msicap(pi, PCI_FBUF_MSI_MSGS); + assert(error == 0); + + sc->fbaddr = pi->pi_bar[1].addr; + sc->memregs.fbsize = FB_SIZE; + sc->memregs.width = COLS_DEFAULT; + sc->memregs.height = ROWS_DEFAULT; + sc->memregs.depth = 32; + + sc->vga_enabled = 1; + sc->vga_full = 0; + + sc->fsc_pi = pi; + + error = pci_fbuf_parse_opts(sc, opts); + if (error != 0) + goto done; + + /* XXX until VGA rendering is enabled */ + if (sc->vga_full != 0) { + fprintf(stderr, "pci_fbuf: VGA rendering not enabled"); + goto done; + } + + sc->fb_base = vm_create_devmem(ctx, VM_FRAMEBUFFER, "framebuffer", FB_SIZE); + if (sc->fb_base == MAP_FAILED) { + error = -1; + goto done; + } + DPRINTF(DEBUG_INFO, ("fbuf frame buffer base: %p [sz %lu]\r\n", + sc->fb_base, FB_SIZE)); + + /* + * Map the framebuffer into the guest address space. + * XXX This may fail if the BAR is different than a prior + * run. In this case flag the error. This will be fixed + * when a change_memseg api is available. + */ + prot = PROT_READ | PROT_WRITE; + if (vm_mmap_memseg(ctx, sc->fbaddr, VM_FRAMEBUFFER, 0, FB_SIZE, prot) != 0) { + fprintf(stderr, "pci_fbuf: mapseg failed - try deleting VM and restarting\n"); + error = -1; + goto done; + } + + console_init(sc->memregs.width, sc->memregs.height, sc->fb_base); + console_fb_register(pci_fbuf_render, sc); + + if (sc->vga_enabled) + sc->vgasc = vga_init(!sc->vga_full); + sc->gc_image = console_get_image(); + + fbuf_sc = sc; + + memset((void *)sc->fb_base, 0, FB_SIZE); + +#ifdef __FreeBSD__ + error = rfb_init(sc->rfb_host, sc->rfb_port, sc->rfb_wait, sc->rfb_password); +#else + if (sc->rfb_unix != NULL) { + error = rfb_init_unix(sc->rfb_unix, sc->rfb_wait, + sc->rfb_password); + } else { + error = rfb_init(sc->rfb_host, sc->rfb_port, sc->rfb_wait, + sc->rfb_password); + } +#endif +done: + if (error) + free(sc); + + return (error); +} + +struct pci_devemu pci_fbuf = { + .pe_emu = "fbuf", + .pe_init = pci_fbuf_init, + .pe_barwrite = pci_fbuf_write, + .pe_barread = pci_fbuf_read +}; +PCI_EMUL_SET(pci_fbuf); diff --git a/usr/src/cmd/bhyve/pci_hostbridge.c b/usr/src/cmd/bhyve/pci_hostbridge.c new file mode 100644 index 0000000000..b926c7817e --- /dev/null +++ b/usr/src/cmd/bhyve/pci_hostbridge.c @@ -0,0 +1,236 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * Copyright (c) 2018 Joyent, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +#ifndef __FreeBSD__ +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <strings.h> +#endif +__FBSDID("$FreeBSD$"); + +#include "pci_emul.h" + +#ifdef __FreeBSD__ +static int +pci_hostbridge_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + + /* config space */ + pci_set_cfgdata16(pi, PCIR_VENDOR, 0x1275); /* NetApp */ + pci_set_cfgdata16(pi, PCIR_DEVICE, 0x1275); /* NetApp */ + pci_set_cfgdata8(pi, PCIR_HDRTYPE, PCIM_HDRTYPE_NORMAL); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); + pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_HOST); + + pci_emul_add_pciecap(pi, PCIEM_TYPE_ROOT_PORT); + + return (0); +} + +static int +pci_amd_hostbridge_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + (void) pci_hostbridge_init(ctx, pi, opts); + pci_set_cfgdata16(pi, PCIR_VENDOR, 0x1022); /* AMD */ + pci_set_cfgdata16(pi, PCIR_DEVICE, 0x7432); /* made up */ + + return (0); +} +#else +static void +pci_hostbridge_setup(struct pci_devinst *pi, uint16_t vendor, uint16_t device) +{ + /* config space */ + pci_set_cfgdata16(pi, PCIR_VENDOR, vendor); + pci_set_cfgdata16(pi, PCIR_DEVICE, device); + pci_set_cfgdata8(pi, PCIR_HDRTYPE, PCIM_HDRTYPE_NORMAL); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); + pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_HOST); + + pci_emul_add_pciecap(pi, PCIEM_TYPE_ROOT_PORT); +} + + +static int +pci_hostbridge_parse_pci_val(const char *in, uint16_t *val) +{ + long num; + char *endp = NULL; + + errno = 0; + num = strtol(in, &endp, 0); + if (errno != 0 || endp == NULL || *endp != '\0') { + fprintf(stderr, "pci_hostbridge: invalid num '%s'", in); + return (-1); + } else if (num < 1 || num > UINT16_MAX) { + fprintf(stderr, "pci_hostbridge: 0x%04lx out of range", num); + return (-1); + } + *val = num; + return (0); +} + +static struct pci_hostbridge_model { + const char *phm_model; + uint16_t phm_vendor; + uint16_t phm_device; +} pci_hb_models[] = { + { "amd", 0x1022, 0x7432 }, /* AMD/made-up */ + { "netapp", 0x1275, 0x1275 }, /* NetApp/NetApp */ + { "i440fx", 0x8086, 0x1237 }, /* Intel/82441 */ + { "q35", 0x8086, 0x29b0 }, /* Intel/Q35 HB */ +}; + +#define NUM_HB_MODELS (sizeof (pci_hb_models) / sizeof (pci_hb_models[0])) + +static int +pci_hostbridge_parse_args(char *opts, uint16_t *vendorp, uint16_t *devicep) +{ + const char *model = NULL; + char *next; + uint16_t vendor = 0, device = 0; + int err = 0; + + for (; opts != NULL && *opts != '\0'; opts = next) { + char *val, *cp; + + if ((cp = strchr(opts, ',')) != NULL) { + *cp = '\0'; + next = cp + 1; + } else { + next = NULL; + } + + if ((cp = strchr(opts, '=')) == NULL) { + fprintf(stderr, + "pci_hostbridge: expected value for param" + " (%s=VAL)", opts); + err = -1; + continue; + } + + /* <param>=<value> handling */ + val = cp + 1; + *cp = '\0'; + if (strcmp(opts, "model") == 0) { + model = val; + } else if (strcmp(opts, "vendor") == 0) { + if (pci_hostbridge_parse_pci_val(val, &vendor) != 0) { + err = -1; + continue; + } + } else if (strcmp(opts, "device") == 0) { + if (pci_hostbridge_parse_pci_val(val, &device) != 0) { + err = -1; + continue; + } + } else { + fprintf(stderr, + "pci_hostbridge: unrecognized option '%s'", opts); + err = -1; + continue; + } + } + if (err != 0) { + return (err); + } + + if (model != NULL && (vendor != 0 || device != 0)) { + fprintf(stderr, "pci_hostbridge: cannot specify model " + "and vendor/device"); + return (-1); + } else if ((vendor != 0 && device == 0) || + (vendor == 0 && device != 0)) { + fprintf(stderr, "pci_hostbridge: must specify both vendor and" + "device for custom hostbridge"); + return (-1); + } + if (model != NULL) { + uint_t i; + + for (i = 0; i < NUM_HB_MODELS; i++) { + if (strcmp(model, pci_hb_models[i].phm_model) != 0) + continue; + + /* found a model match */ + *vendorp = pci_hb_models[i].phm_vendor; + *devicep = pci_hb_models[i].phm_device; + return (0); + } + fprintf(stderr, "pci_hostbridge: invalid model '%s'", model); + return (-1); + } + + /* custom hostbridge ID was specified */ + *vendorp = vendor; + *devicep = device; + return (0); +} + +static int +pci_hostbridge_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + uint16_t vendor, device; + + if (opts == NULL) { + /* Fall back to NetApp default if no options are specified */ + vendor = 0x1275; + device = 0x1275; + } else if (pci_hostbridge_parse_args(opts, &vendor, &device) != 0) { + return (-1); + } + + pci_hostbridge_setup(pi, vendor, device); + return (0); +} + +static int +pci_amd_hostbridge_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + pci_hostbridge_setup(pi, 0x1022, 0x7432); + return (0); +} + +#endif /* __FreeBSD__ */ + +struct pci_devemu pci_de_amd_hostbridge = { + .pe_emu = "amd_hostbridge", + .pe_init = pci_amd_hostbridge_init, +}; +PCI_EMUL_SET(pci_de_amd_hostbridge); + +struct pci_devemu pci_de_hostbridge = { + .pe_emu = "hostbridge", + .pe_init = pci_hostbridge_init, +}; +PCI_EMUL_SET(pci_de_hostbridge); diff --git a/usr/src/cmd/bhyve/pci_irq.c b/usr/src/cmd/bhyve/pci_irq.c new file mode 100644 index 0000000000..4ecb3eddb0 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_irq.c @@ -0,0 +1,354 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Hudson River Trading LLC + * Written by: John H. Baldwin <jhb@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <machine/vmm.h> + +#include <assert.h> +#include <pthread.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <vmmapi.h> + +#include "acpi.h" +#include "inout.h" +#include "pci_emul.h" +#include "pci_irq.h" +#include "pci_lpc.h" + +/* + * Implement an 8 pin PCI interrupt router compatible with the router + * present on Intel's ICH10 chip. + */ + +/* Fields in each PIRQ register. */ +#define PIRQ_DIS 0x80 +#define PIRQ_IRQ 0x0f + +/* Only IRQs 3-7, 9-12, and 14-15 are permitted. */ +#define PERMITTED_IRQS 0xdef8 +#define IRQ_PERMITTED(irq) (((1U << (irq)) & PERMITTED_IRQS) != 0) + +/* IRQ count to disable an IRQ. */ +#define IRQ_DISABLED 0xff + +static struct pirq { + uint8_t reg; + int use_count; + int active_count; + pthread_mutex_t lock; +} pirqs[8]; + +static u_char irq_counts[16]; +static int pirq_cold = 1; + +/* + * Returns true if this pin is enabled with a valid IRQ. Setting the + * register to a reserved IRQ causes interrupts to not be asserted as + * if the pin was disabled. + */ +static bool +pirq_valid_irq(int reg) +{ + + if (reg & PIRQ_DIS) + return (false); + return (IRQ_PERMITTED(reg & PIRQ_IRQ)); +} + +uint8_t +pirq_read(int pin) +{ + + assert(pin > 0 && pin <= nitems(pirqs)); + return (pirqs[pin - 1].reg); +} + +void +pirq_write(struct vmctx *ctx, int pin, uint8_t val) +{ + struct pirq *pirq; + + assert(pin > 0 && pin <= nitems(pirqs)); + pirq = &pirqs[pin - 1]; + pthread_mutex_lock(&pirq->lock); + if (pirq->reg != (val & (PIRQ_DIS | PIRQ_IRQ))) { + if (pirq->active_count != 0 && pirq_valid_irq(pirq->reg)) + vm_isa_deassert_irq(ctx, pirq->reg & PIRQ_IRQ, -1); + pirq->reg = val & (PIRQ_DIS | PIRQ_IRQ); + if (pirq->active_count != 0 && pirq_valid_irq(pirq->reg)) + vm_isa_assert_irq(ctx, pirq->reg & PIRQ_IRQ, -1); + } + pthread_mutex_unlock(&pirq->lock); +} + +void +pci_irq_reserve(int irq) +{ + + assert(irq >= 0 && irq < nitems(irq_counts)); + assert(pirq_cold); + assert(irq_counts[irq] == 0 || irq_counts[irq] == IRQ_DISABLED); + irq_counts[irq] = IRQ_DISABLED; +} + +void +pci_irq_use(int irq) +{ + + assert(irq >= 0 && irq < nitems(irq_counts)); + assert(pirq_cold); + assert(irq_counts[irq] != IRQ_DISABLED); + irq_counts[irq]++; +} + +void +pci_irq_init(struct vmctx *ctx) +{ + int i; + + for (i = 0; i < nitems(pirqs); i++) { + pirqs[i].reg = PIRQ_DIS; + pirqs[i].use_count = 0; + pirqs[i].active_count = 0; + pthread_mutex_init(&pirqs[i].lock, NULL); + } + for (i = 0; i < nitems(irq_counts); i++) { + if (IRQ_PERMITTED(i)) + irq_counts[i] = 0; + else + irq_counts[i] = IRQ_DISABLED; + } +} + +void +pci_irq_assert(struct pci_devinst *pi) +{ + struct pirq *pirq; + + if (pi->pi_lintr.pirq_pin > 0) { + assert(pi->pi_lintr.pirq_pin <= nitems(pirqs)); + pirq = &pirqs[pi->pi_lintr.pirq_pin - 1]; + pthread_mutex_lock(&pirq->lock); + pirq->active_count++; + if (pirq->active_count == 1 && pirq_valid_irq(pirq->reg)) { + vm_isa_assert_irq(pi->pi_vmctx, pirq->reg & PIRQ_IRQ, + pi->pi_lintr.ioapic_irq); + pthread_mutex_unlock(&pirq->lock); + return; + } + pthread_mutex_unlock(&pirq->lock); + } + vm_ioapic_assert_irq(pi->pi_vmctx, pi->pi_lintr.ioapic_irq); +} + +void +pci_irq_deassert(struct pci_devinst *pi) +{ + struct pirq *pirq; + + if (pi->pi_lintr.pirq_pin > 0) { + assert(pi->pi_lintr.pirq_pin <= nitems(pirqs)); + pirq = &pirqs[pi->pi_lintr.pirq_pin - 1]; + pthread_mutex_lock(&pirq->lock); + pirq->active_count--; + if (pirq->active_count == 0 && pirq_valid_irq(pirq->reg)) { + vm_isa_deassert_irq(pi->pi_vmctx, pirq->reg & PIRQ_IRQ, + pi->pi_lintr.ioapic_irq); + pthread_mutex_unlock(&pirq->lock); + return; + } + pthread_mutex_unlock(&pirq->lock); + } + vm_ioapic_deassert_irq(pi->pi_vmctx, pi->pi_lintr.ioapic_irq); +} + +int +pirq_alloc_pin(struct pci_devinst *pi) +{ + struct vmctx *ctx = pi->pi_vmctx; + int best_count, best_irq, best_pin, irq, pin; + + pirq_cold = 0; + + if (lpc_bootrom()) { + /* For external bootrom use fixed mapping. */ + best_pin = (4 + pi->pi_slot + pi->pi_lintr.pin) % 8; + } else { + /* Find the least-used PIRQ pin. */ + best_pin = 0; + best_count = pirqs[0].use_count; + for (pin = 1; pin < nitems(pirqs); pin++) { + if (pirqs[pin].use_count < best_count) { + best_pin = pin; + best_count = pirqs[pin].use_count; + } + } + } + pirqs[best_pin].use_count++; + + /* Second, route this pin to an IRQ. */ + if (pirqs[best_pin].reg == PIRQ_DIS) { + best_irq = -1; + best_count = 0; + for (irq = 0; irq < nitems(irq_counts); irq++) { + if (irq_counts[irq] == IRQ_DISABLED) + continue; + if (best_irq == -1 || irq_counts[irq] < best_count) { + best_irq = irq; + best_count = irq_counts[irq]; + } + } + assert(best_irq >= 0); + irq_counts[best_irq]++; + pirqs[best_pin].reg = best_irq; + vm_isa_set_irq_trigger(ctx, best_irq, LEVEL_TRIGGER); + } + + return (best_pin + 1); +} + +int +pirq_irq(int pin) +{ + assert(pin > 0 && pin <= nitems(pirqs)); + return (pirqs[pin - 1].reg & PIRQ_IRQ); +} + +/* XXX: Generate $PIR table. */ + +static void +pirq_dsdt(void) +{ + char *irq_prs, *old; + int irq, pin; + + irq_prs = NULL; + for (irq = 0; irq < nitems(irq_counts); irq++) { + if (!IRQ_PERMITTED(irq)) + continue; + if (irq_prs == NULL) + asprintf(&irq_prs, "%d", irq); + else { + old = irq_prs; + asprintf(&irq_prs, "%s,%d", old, irq); + free(old); + } + } + + /* + * A helper method to validate a link register's value. This + * duplicates pirq_valid_irq(). + */ + dsdt_line(""); + dsdt_line("Method (PIRV, 1, NotSerialized)"); + dsdt_line("{"); + dsdt_line(" If (And (Arg0, 0x%02X))", PIRQ_DIS); + dsdt_line(" {"); + dsdt_line(" Return (0x00)"); + dsdt_line(" }"); + dsdt_line(" And (Arg0, 0x%02X, Local0)", PIRQ_IRQ); + dsdt_line(" If (LLess (Local0, 0x03))"); + dsdt_line(" {"); + dsdt_line(" Return (0x00)"); + dsdt_line(" }"); + dsdt_line(" If (LEqual (Local0, 0x08))"); + dsdt_line(" {"); + dsdt_line(" Return (0x00)"); + dsdt_line(" }"); + dsdt_line(" If (LEqual (Local0, 0x0D))"); + dsdt_line(" {"); + dsdt_line(" Return (0x00)"); + dsdt_line(" }"); + dsdt_line(" Return (0x01)"); + dsdt_line("}"); + + for (pin = 0; pin < nitems(pirqs); pin++) { + dsdt_line(""); + dsdt_line("Device (LNK%c)", 'A' + pin); + dsdt_line("{"); + dsdt_line(" Name (_HID, EisaId (\"PNP0C0F\"))"); + dsdt_line(" Name (_UID, 0x%02X)", pin + 1); + dsdt_line(" Method (_STA, 0, NotSerialized)"); + dsdt_line(" {"); + dsdt_line(" If (PIRV (PIR%c))", 'A' + pin); + dsdt_line(" {"); + dsdt_line(" Return (0x0B)"); + dsdt_line(" }"); + dsdt_line(" Else"); + dsdt_line(" {"); + dsdt_line(" Return (0x09)"); + dsdt_line(" }"); + dsdt_line(" }"); + dsdt_line(" Name (_PRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_line(" IRQ (Level, ActiveLow, Shared, )"); + dsdt_line(" {%s}", irq_prs); + dsdt_line(" })"); + dsdt_line(" Name (CB%02X, ResourceTemplate ()", pin + 1); + dsdt_line(" {"); + dsdt_line(" IRQ (Level, ActiveLow, Shared, )"); + dsdt_line(" {}"); + dsdt_line(" })"); + dsdt_line(" CreateWordField (CB%02X, 0x01, CIR%c)", + pin + 1, 'A' + pin); + dsdt_line(" Method (_CRS, 0, NotSerialized)"); + dsdt_line(" {"); + dsdt_line(" And (PIR%c, 0x%02X, Local0)", 'A' + pin, + PIRQ_DIS | PIRQ_IRQ); + dsdt_line(" If (PIRV (Local0))"); + dsdt_line(" {"); + dsdt_line(" ShiftLeft (0x01, Local0, CIR%c)", 'A' + pin); + dsdt_line(" }"); + dsdt_line(" Else"); + dsdt_line(" {"); + dsdt_line(" Store (0x00, CIR%c)", 'A' + pin); + dsdt_line(" }"); + dsdt_line(" Return (CB%02X)", pin + 1); + dsdt_line(" }"); + dsdt_line(" Method (_DIS, 0, NotSerialized)"); + dsdt_line(" {"); + dsdt_line(" Store (0x80, PIR%c)", 'A' + pin); + dsdt_line(" }"); + dsdt_line(" Method (_SRS, 1, NotSerialized)"); + dsdt_line(" {"); + dsdt_line(" CreateWordField (Arg0, 0x01, SIR%c)", 'A' + pin); + dsdt_line(" FindSetRightBit (SIR%c, Local0)", 'A' + pin); + dsdt_line(" Store (Decrement (Local0), PIR%c)", 'A' + pin); + dsdt_line(" }"); + dsdt_line("}"); + } + free(irq_prs); +} +LPC_DSDT(pirq_dsdt); diff --git a/usr/src/cmd/bhyve/pci_irq.h b/usr/src/cmd/bhyve/pci_irq.h new file mode 100644 index 0000000000..1ae56efc8f --- /dev/null +++ b/usr/src/cmd/bhyve/pci_irq.h @@ -0,0 +1,47 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Hudson River Trading LLC + * Written by: John H. Baldwin <jhb@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef __PCI_IRQ_H__ +#define __PCI_IRQ_H__ + +struct pci_devinst; + +void pci_irq_assert(struct pci_devinst *pi); +void pci_irq_deassert(struct pci_devinst *pi); +void pci_irq_init(struct vmctx *ctx); +void pci_irq_reserve(int irq); +void pci_irq_use(int irq); +int pirq_alloc_pin(struct pci_devinst *pi); +int pirq_irq(int pin); +uint8_t pirq_read(int pin); +void pirq_write(struct vmctx *ctx, int pin, uint8_t val); + +#endif diff --git a/usr/src/cmd/bhyve/pci_lpc.c b/usr/src/cmd/bhyve/pci_lpc.c new file mode 100644 index 0000000000..b7ddb772a1 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_lpc.c @@ -0,0 +1,481 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Neel Natu <neel@freebsd.org> + * Copyright (c) 2013 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <machine/vmm.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <vmmapi.h> + +#include "acpi.h" +#include "bootrom.h" +#include "inout.h" +#include "pci_emul.h" +#include "pci_irq.h" +#include "pci_lpc.h" +#include "uart_emul.h" + +#define IO_ICU1 0x20 +#define IO_ICU2 0xA0 + +SET_DECLARE(lpc_dsdt_set, struct lpc_dsdt); +SET_DECLARE(lpc_sysres_set, struct lpc_sysres); + +#define ELCR_PORT 0x4d0 +SYSRES_IO(ELCR_PORT, 2); + +#define IO_TIMER1_PORT 0x40 + +#define NMISC_PORT 0x61 +SYSRES_IO(NMISC_PORT, 1); + +static struct pci_devinst *lpc_bridge; + +static const char *romfile; + +#define LPC_UART_NUM 2 +static struct lpc_uart_softc { + struct uart_softc *uart_softc; + const char *opts; + int iobase; + int irq; + int enabled; +} lpc_uart_softc[LPC_UART_NUM]; + +static const char *lpc_uart_names[LPC_UART_NUM] = { "COM1", "COM2" }; + +/* + * LPC device configuration is in the following form: + * <lpc_device_name>[,<options>] + * For e.g. "com1,stdio" or "bootrom,/var/romfile" + */ +int +lpc_device_parse(const char *opts) +{ + int unit, error; + char *str, *cpy, *lpcdev; + + error = -1; + str = cpy = strdup(opts); + lpcdev = strsep(&str, ","); + if (lpcdev != NULL) { + if (strcasecmp(lpcdev, "bootrom") == 0) { + romfile = str; + error = 0; + goto done; + } + for (unit = 0; unit < LPC_UART_NUM; unit++) { + if (strcasecmp(lpcdev, lpc_uart_names[unit]) == 0) { + lpc_uart_softc[unit].opts = str; + error = 0; + goto done; + } + } + } + +done: + if (error) + free(cpy); + + return (error); +} + +void +lpc_print_supported_devices() +{ + size_t i; + + printf("bootrom\n"); + for (i = 0; i < LPC_UART_NUM; i++) + printf("%s\n", lpc_uart_names[i]); +} + +const char * +lpc_bootrom(void) +{ + + return (romfile); +} + +static void +lpc_uart_intr_assert(void *arg) +{ + struct lpc_uart_softc *sc = arg; + + assert(sc->irq >= 0); + + vm_isa_pulse_irq(lpc_bridge->pi_vmctx, sc->irq, sc->irq); +} + +static void +lpc_uart_intr_deassert(void *arg) +{ + /* + * The COM devices on the LPC bus generate edge triggered interrupts, + * so nothing more to do here. + */ +} + +static int +lpc_uart_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + int offset; + struct lpc_uart_softc *sc = arg; + + offset = port - sc->iobase; + + switch (bytes) { + case 1: + if (in) + *eax = uart_read(sc->uart_softc, offset); + else + uart_write(sc->uart_softc, offset, *eax); + break; + case 2: + if (in) { + *eax = uart_read(sc->uart_softc, offset); + *eax |= uart_read(sc->uart_softc, offset + 1) << 8; + } else { + uart_write(sc->uart_softc, offset, *eax); + uart_write(sc->uart_softc, offset + 1, *eax >> 8); + } + break; +#ifndef __FreeBSD__ + case 4: + if (in) { + *eax = uart_read(sc->uart_softc, offset); + *eax |= uart_read(sc->uart_softc, offset + 1) << 8; + *eax |= uart_read(sc->uart_softc, offset + 2) << 16; + *eax |= uart_read(sc->uart_softc, offset + 3) << 24; + } else { + uart_write(sc->uart_softc, offset, *eax); + uart_write(sc->uart_softc, offset + 1, *eax >> 8); + uart_write(sc->uart_softc, offset + 2, *eax >> 16); + uart_write(sc->uart_softc, offset + 3, *eax >> 24); + } + break; +#endif + default: + return (-1); + } + + return (0); +} + +static int +lpc_init(struct vmctx *ctx) +{ + struct lpc_uart_softc *sc; + struct inout_port iop; + const char *name; + int unit, error; + + if (romfile != NULL) { + error = bootrom_init(ctx, romfile); + if (error) + return (error); + } + + /* COM1 and COM2 */ + for (unit = 0; unit < LPC_UART_NUM; unit++) { + sc = &lpc_uart_softc[unit]; + name = lpc_uart_names[unit]; + + if (uart_legacy_alloc(unit, &sc->iobase, &sc->irq) != 0) { + fprintf(stderr, "Unable to allocate resources for " + "LPC device %s\n", name); + return (-1); + } + pci_irq_reserve(sc->irq); + + sc->uart_softc = uart_init(lpc_uart_intr_assert, + lpc_uart_intr_deassert, sc); + + if (uart_set_backend(sc->uart_softc, sc->opts) != 0) { + fprintf(stderr, "Unable to initialize backend '%s' " + "for LPC device %s\n", sc->opts, name); + return (-1); + } + + bzero(&iop, sizeof(struct inout_port)); + iop.name = name; + iop.port = sc->iobase; + iop.size = UART_IO_BAR_SIZE; + iop.flags = IOPORT_F_INOUT; + iop.handler = lpc_uart_io_handler; + iop.arg = sc; + + error = register_inout(&iop); + assert(error == 0); + sc->enabled = 1; + } + + return (0); +} + +static void +pci_lpc_write_dsdt(struct pci_devinst *pi) +{ + struct lpc_dsdt **ldpp, *ldp; + + dsdt_line(""); + dsdt_line("Device (ISA)"); + dsdt_line("{"); + dsdt_line(" Name (_ADR, 0x%04X%04X)", pi->pi_slot, pi->pi_func); + dsdt_line(" OperationRegion (LPCR, PCI_Config, 0x00, 0x100)"); + dsdt_line(" Field (LPCR, AnyAcc, NoLock, Preserve)"); + dsdt_line(" {"); + dsdt_line(" Offset (0x60),"); + dsdt_line(" PIRA, 8,"); + dsdt_line(" PIRB, 8,"); + dsdt_line(" PIRC, 8,"); + dsdt_line(" PIRD, 8,"); + dsdt_line(" Offset (0x68),"); + dsdt_line(" PIRE, 8,"); + dsdt_line(" PIRF, 8,"); + dsdt_line(" PIRG, 8,"); + dsdt_line(" PIRH, 8"); + dsdt_line(" }"); + dsdt_line(""); + + dsdt_indent(1); + SET_FOREACH(ldpp, lpc_dsdt_set) { + ldp = *ldpp; + ldp->handler(); + } + + dsdt_line(""); + dsdt_line("Device (PIC)"); + dsdt_line("{"); + dsdt_line(" Name (_HID, EisaId (\"PNP0000\"))"); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_indent(2); + dsdt_fixed_ioport(IO_ICU1, 2); + dsdt_fixed_ioport(IO_ICU2, 2); + dsdt_fixed_irq(2); + dsdt_unindent(2); + dsdt_line(" })"); + dsdt_line("}"); + + dsdt_line(""); + dsdt_line("Device (TIMR)"); + dsdt_line("{"); + dsdt_line(" Name (_HID, EisaId (\"PNP0100\"))"); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_indent(2); + dsdt_fixed_ioport(IO_TIMER1_PORT, 4); + dsdt_fixed_irq(0); + dsdt_unindent(2); + dsdt_line(" })"); + dsdt_line("}"); + dsdt_unindent(1); + + dsdt_line("}"); +} + +static void +pci_lpc_sysres_dsdt(void) +{ + struct lpc_sysres **lspp, *lsp; + + dsdt_line(""); + dsdt_line("Device (SIO)"); + dsdt_line("{"); + dsdt_line(" Name (_HID, EisaId (\"PNP0C02\"))"); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + + dsdt_indent(2); + SET_FOREACH(lspp, lpc_sysres_set) { + lsp = *lspp; + switch (lsp->type) { + case LPC_SYSRES_IO: + dsdt_fixed_ioport(lsp->base, lsp->length); + break; + case LPC_SYSRES_MEM: + dsdt_fixed_mem32(lsp->base, lsp->length); + break; + } + } + dsdt_unindent(2); + + dsdt_line(" })"); + dsdt_line("}"); +} +LPC_DSDT(pci_lpc_sysres_dsdt); + +static void +pci_lpc_uart_dsdt(void) +{ + struct lpc_uart_softc *sc; + int unit; + + for (unit = 0; unit < LPC_UART_NUM; unit++) { + sc = &lpc_uart_softc[unit]; + if (!sc->enabled) + continue; + dsdt_line(""); + dsdt_line("Device (%s)", lpc_uart_names[unit]); + dsdt_line("{"); + dsdt_line(" Name (_HID, EisaId (\"PNP0501\"))"); + dsdt_line(" Name (_UID, %d)", unit + 1); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_indent(2); + dsdt_fixed_ioport(sc->iobase, UART_IO_BAR_SIZE); + dsdt_fixed_irq(sc->irq); + dsdt_unindent(2); + dsdt_line(" })"); + dsdt_line("}"); + } +} +LPC_DSDT(pci_lpc_uart_dsdt); + +static int +pci_lpc_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int coff, int bytes, uint32_t val) +{ + int pirq_pin; + + if (bytes == 1) { + pirq_pin = 0; + if (coff >= 0x60 && coff <= 0x63) + pirq_pin = coff - 0x60 + 1; + if (coff >= 0x68 && coff <= 0x6b) + pirq_pin = coff - 0x68 + 5; + if (pirq_pin != 0) { + pirq_write(ctx, pirq_pin, val); + pci_set_cfgdata8(pi, coff, pirq_read(pirq_pin)); + return (0); + } + } + return (-1); +} + +static void +pci_lpc_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value) +{ +} + +static uint64_t +pci_lpc_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size) +{ + return (0); +} + +#define LPC_DEV 0x7000 +#define LPC_VENDOR 0x8086 + +static int +pci_lpc_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + + /* + * Do not allow more than one LPC bridge to be configured. + */ + if (lpc_bridge != NULL) { + fprintf(stderr, "Only one LPC bridge is allowed.\n"); + return (-1); + } + + /* + * Enforce that the LPC can only be configured on bus 0. This + * simplifies the ACPI DSDT because it can provide a decode for + * all legacy i/o ports behind bus 0. + */ + if (pi->pi_bus != 0) { + fprintf(stderr, "LPC bridge can be present only on bus 0.\n"); + return (-1); + } + + if (lpc_init(ctx) != 0) + return (-1); + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, LPC_DEV); + pci_set_cfgdata16(pi, PCIR_VENDOR, LPC_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); + pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_ISA); + + lpc_bridge = pi; + + return (0); +} + +char * +lpc_pirq_name(int pin) +{ + char *name; + + if (lpc_bridge == NULL) + return (NULL); + asprintf(&name, "\\_SB.PC00.ISA.LNK%c,", 'A' + pin - 1); + return (name); +} + +void +lpc_pirq_routed(void) +{ + int pin; + + if (lpc_bridge == NULL) + return; + + for (pin = 0; pin < 4; pin++) + pci_set_cfgdata8(lpc_bridge, 0x60 + pin, pirq_read(pin + 1)); + for (pin = 0; pin < 4; pin++) + pci_set_cfgdata8(lpc_bridge, 0x68 + pin, pirq_read(pin + 5)); +} + +struct pci_devemu pci_de_lpc = { + .pe_emu = "lpc", + .pe_init = pci_lpc_init, + .pe_write_dsdt = pci_lpc_write_dsdt, + .pe_cfgwrite = pci_lpc_cfgwrite, + .pe_barwrite = pci_lpc_write, + .pe_barread = pci_lpc_read +}; +PCI_EMUL_SET(pci_de_lpc); diff --git a/usr/src/cmd/bhyve/pci_lpc.h b/usr/src/cmd/bhyve/pci_lpc.h new file mode 100644 index 0000000000..9041f79c50 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_lpc.h @@ -0,0 +1,76 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Neel Natu <neel@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _LPC_H_ +#define _LPC_H_ + +#include <sys/linker_set.h> + +typedef void (*lpc_write_dsdt_t)(void); + +struct lpc_dsdt { + lpc_write_dsdt_t handler; +}; + +#define LPC_DSDT(handler) \ + static struct lpc_dsdt __CONCAT(__lpc_dsdt, __LINE__) = { \ + (handler), \ + }; \ + DATA_SET(lpc_dsdt_set, __CONCAT(__lpc_dsdt, __LINE__)) + +enum lpc_sysres_type { + LPC_SYSRES_IO, + LPC_SYSRES_MEM +}; + +struct lpc_sysres { + enum lpc_sysres_type type; + uint32_t base; + uint32_t length; +}; + +#define LPC_SYSRES(type, base, length) \ + static struct lpc_sysres __CONCAT(__lpc_sysres, __LINE__) = { \ + (type), \ + (base), \ + (length) \ + }; \ + DATA_SET(lpc_sysres_set, __CONCAT(__lpc_sysres, __LINE__)) + +#define SYSRES_IO(base, length) LPC_SYSRES(LPC_SYSRES_IO, base, length) +#define SYSRES_MEM(base, length) LPC_SYSRES(LPC_SYSRES_MEM, base, length) + +int lpc_device_parse(const char *opt); +void lpc_print_supported_devices(); +char *lpc_pirq_name(int pin); +void lpc_pirq_routed(void); +const char *lpc_bootrom(void); + +#endif diff --git a/usr/src/cmd/bhyve/pci_nvme.c b/usr/src/cmd/bhyve/pci_nvme.c new file mode 100644 index 0000000000..387611c888 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_nvme.c @@ -0,0 +1,1897 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2017 Shunsuke Mie + * Copyright (c) 2018 Leon Dang + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +/* + * bhyve PCIe-NVMe device emulation. + * + * options: + * -s <n>,nvme,devpath,maxq=#,qsz=#,ioslots=#,sectsz=#,ser=A-Z + * + * accepted devpath: + * /dev/blockdev + * /path/to/image + * ram=size_in_MiB + * + * maxq = max number of queues + * qsz = max elements in each queue + * ioslots = max number of concurrent io requests + * sectsz = sector size (defaults to blockif sector size) + * ser = serial number (20-chars max) + * + */ + +/* TODO: + - create async event for smart and log + - intr coalesce + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> + +#include <assert.h> +#include <pthread.h> +#include <semaphore.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <machine/atomic.h> +#include <machine/vmm.h> +#include <vmmapi.h> + +#include <dev/nvme/nvme.h> + +#include "bhyverun.h" +#include "block_if.h" +#include "pci_emul.h" + + +static int nvme_debug = 0; +#define DPRINTF(params) if (nvme_debug) printf params +#define WPRINTF(params) printf params + +/* defaults; can be overridden */ +#define NVME_MSIX_BAR 4 + +#define NVME_IOSLOTS 8 + +#define NVME_QUEUES 16 +#define NVME_MAX_QENTRIES 2048 + +#define NVME_PRP2_ITEMS (PAGE_SIZE/sizeof(uint64_t)) +#define NVME_MAX_BLOCKIOVS 512 + +/* helpers */ + +/* Convert a zero-based value into a one-based value */ +#define ONE_BASED(zero) ((zero) + 1) +/* Convert a one-based value into a zero-based value */ +#define ZERO_BASED(one) ((one) - 1) + +/* Encode number of SQ's and CQ's for Set/Get Features */ +#define NVME_FEATURE_NUM_QUEUES(sc) \ + (ZERO_BASED((sc)->num_squeues) & 0xffff) | \ + (ZERO_BASED((sc)->num_cqueues) & 0xffff) << 16; + +#define NVME_DOORBELL_OFFSET offsetof(struct nvme_registers, doorbell) + +enum nvme_controller_register_offsets { + NVME_CR_CAP_LOW = 0x00, + NVME_CR_CAP_HI = 0x04, + NVME_CR_VS = 0x08, + NVME_CR_INTMS = 0x0c, + NVME_CR_INTMC = 0x10, + NVME_CR_CC = 0x14, + NVME_CR_CSTS = 0x1c, + NVME_CR_NSSR = 0x20, + NVME_CR_AQA = 0x24, + NVME_CR_ASQ_LOW = 0x28, + NVME_CR_ASQ_HI = 0x2c, + NVME_CR_ACQ_LOW = 0x30, + NVME_CR_ACQ_HI = 0x34, +}; + +enum nvme_cmd_cdw11 { + NVME_CMD_CDW11_PC = 0x0001, + NVME_CMD_CDW11_IEN = 0x0002, + NVME_CMD_CDW11_IV = 0xFFFF0000, +}; + +#define NVME_CQ_INTEN 0x01 +#define NVME_CQ_INTCOAL 0x02 + +struct nvme_completion_queue { + struct nvme_completion *qbase; + uint32_t size; + uint16_t tail; /* nvme progress */ + uint16_t head; /* guest progress */ + uint16_t intr_vec; + uint32_t intr_en; + pthread_mutex_t mtx; +}; + +struct nvme_submission_queue { + struct nvme_command *qbase; + uint32_t size; + uint16_t head; /* nvme progress */ + uint16_t tail; /* guest progress */ + uint16_t cqid; /* completion queue id */ + int busy; /* queue is being processed */ + int qpriority; +}; + +enum nvme_storage_type { + NVME_STOR_BLOCKIF = 0, + NVME_STOR_RAM = 1, +}; + +struct pci_nvme_blockstore { + enum nvme_storage_type type; + void *ctx; + uint64_t size; + uint32_t sectsz; + uint32_t sectsz_bits; +}; + +struct pci_nvme_ioreq { + struct pci_nvme_softc *sc; + struct pci_nvme_ioreq *next; + struct nvme_submission_queue *nvme_sq; + uint16_t sqid; + + /* command information */ + uint16_t opc; + uint16_t cid; + uint32_t nsid; + + uint64_t prev_gpaddr; + size_t prev_size; + + /* + * lock if all iovs consumed (big IO); + * complete transaction before continuing + */ + pthread_mutex_t mtx; + pthread_cond_t cv; + + struct blockif_req io_req; + + /* pad to fit up to 512 page descriptors from guest IO request */ + struct iovec iovpadding[NVME_MAX_BLOCKIOVS-BLOCKIF_IOV_MAX]; +}; + +struct pci_nvme_softc { + struct pci_devinst *nsc_pi; + + pthread_mutex_t mtx; + + struct nvme_registers regs; + + struct nvme_namespace_data nsdata; + struct nvme_controller_data ctrldata; + + struct pci_nvme_blockstore nvstore; + + uint16_t max_qentries; /* max entries per queue */ + uint32_t max_queues; /* max number of IO SQ's or CQ's */ + uint32_t num_cqueues; + uint32_t num_squeues; + + struct pci_nvme_ioreq *ioreqs; + struct pci_nvme_ioreq *ioreqs_free; /* free list of ioreqs */ + uint32_t pending_ios; + uint32_t ioslots; + sem_t iosemlock; + + /* + * Memory mapped Submission and Completion queues + * Each array includes both Admin and IO queues + */ + struct nvme_completion_queue *compl_queues; + struct nvme_submission_queue *submit_queues; + + /* controller features */ + uint32_t intr_coales_aggr_time; /* 0x08: uS to delay intr */ + uint32_t intr_coales_aggr_thresh; /* 0x08: compl-Q entries */ + uint32_t async_ev_config; /* 0x0B: async event config */ +}; + + +static void pci_nvme_io_partial(struct blockif_req *br, int err); + +/* Controller Configuration utils */ +#define NVME_CC_GET_EN(cc) \ + ((cc) >> NVME_CC_REG_EN_SHIFT & NVME_CC_REG_EN_MASK) +#define NVME_CC_GET_CSS(cc) \ + ((cc) >> NVME_CC_REG_CSS_SHIFT & NVME_CC_REG_CSS_MASK) +#define NVME_CC_GET_SHN(cc) \ + ((cc) >> NVME_CC_REG_SHN_SHIFT & NVME_CC_REG_SHN_MASK) +#define NVME_CC_GET_IOSQES(cc) \ + ((cc) >> NVME_CC_REG_IOSQES_SHIFT & NVME_CC_REG_IOSQES_MASK) +#define NVME_CC_GET_IOCQES(cc) \ + ((cc) >> NVME_CC_REG_IOCQES_SHIFT & NVME_CC_REG_IOCQES_MASK) + +#define NVME_CC_WRITE_MASK \ + ((NVME_CC_REG_EN_MASK << NVME_CC_REG_EN_SHIFT) | \ + (NVME_CC_REG_IOSQES_MASK << NVME_CC_REG_IOSQES_SHIFT) | \ + (NVME_CC_REG_IOCQES_MASK << NVME_CC_REG_IOCQES_SHIFT)) + +#define NVME_CC_NEN_WRITE_MASK \ + ((NVME_CC_REG_CSS_MASK << NVME_CC_REG_CSS_SHIFT) | \ + (NVME_CC_REG_MPS_MASK << NVME_CC_REG_MPS_SHIFT) | \ + (NVME_CC_REG_AMS_MASK << NVME_CC_REG_AMS_SHIFT)) + +/* Controller Status utils */ +#define NVME_CSTS_GET_RDY(sts) \ + ((sts) >> NVME_CSTS_REG_RDY_SHIFT & NVME_CSTS_REG_RDY_MASK) + +#define NVME_CSTS_RDY (1 << NVME_CSTS_REG_RDY_SHIFT) + +/* Completion Queue status word utils */ +#define NVME_STATUS_P (1 << NVME_STATUS_P_SHIFT) +#define NVME_STATUS_MASK \ + ((NVME_STATUS_SCT_MASK << NVME_STATUS_SCT_SHIFT) |\ + (NVME_STATUS_SC_MASK << NVME_STATUS_SC_SHIFT)) + +static __inline void +cpywithpad(char *dst, size_t dst_size, const char *src, char pad) +{ + size_t len; + + len = strnlen(src, dst_size); + memset(dst, pad, dst_size); + memcpy(dst, src, len); +} + +static __inline void +pci_nvme_status_tc(uint16_t *status, uint16_t type, uint16_t code) +{ + + *status &= ~NVME_STATUS_MASK; + *status |= (type & NVME_STATUS_SCT_MASK) << NVME_STATUS_SCT_SHIFT | + (code & NVME_STATUS_SC_MASK) << NVME_STATUS_SC_SHIFT; +} + +static __inline void +pci_nvme_status_genc(uint16_t *status, uint16_t code) +{ + + pci_nvme_status_tc(status, NVME_SCT_GENERIC, code); +} + +static __inline void +pci_nvme_toggle_phase(uint16_t *status, int prev) +{ + + if (prev) + *status &= ~NVME_STATUS_P; + else + *status |= NVME_STATUS_P; +} + +static void +pci_nvme_init_ctrldata(struct pci_nvme_softc *sc) +{ + struct nvme_controller_data *cd = &sc->ctrldata; + + cd->vid = 0xFB5D; + cd->ssvid = 0x0000; + + cpywithpad((char *)cd->mn, sizeof(cd->mn), "bhyve-NVMe", ' '); + cpywithpad((char *)cd->fr, sizeof(cd->fr), "1.0", ' '); + + /* Num of submission commands that we can handle at a time (2^rab) */ + cd->rab = 4; + + /* FreeBSD OUI */ + cd->ieee[0] = 0x58; + cd->ieee[1] = 0x9c; + cd->ieee[2] = 0xfc; + + cd->mic = 0; + + cd->mdts = 9; /* max data transfer size (2^mdts * CAP.MPSMIN) */ + + cd->ver = 0x00010300; + + cd->oacs = 1 << NVME_CTRLR_DATA_OACS_FORMAT_SHIFT; + cd->acl = 2; + cd->aerl = 4; + + cd->lpa = 0; /* TODO: support some simple things like SMART */ + cd->elpe = 0; /* max error log page entries */ + cd->npss = 1; /* number of power states support */ + + /* Warning Composite Temperature Threshold */ + cd->wctemp = 0x0157; + + cd->sqes = (6 << NVME_CTRLR_DATA_SQES_MAX_SHIFT) | + (6 << NVME_CTRLR_DATA_SQES_MIN_SHIFT); + cd->cqes = (4 << NVME_CTRLR_DATA_CQES_MAX_SHIFT) | + (4 << NVME_CTRLR_DATA_CQES_MIN_SHIFT); + cd->nn = 1; /* number of namespaces */ + + cd->fna = 0x03; + + cd->power_state[0].mp = 10; +} + +static void +pci_nvme_init_nsdata(struct pci_nvme_softc *sc) +{ + struct nvme_namespace_data *nd; + + nd = &sc->nsdata; + + nd->nsze = sc->nvstore.size / sc->nvstore.sectsz; + nd->ncap = nd->nsze; + nd->nuse = nd->nsze; + + /* Get LBA and backstore information from backing store */ + nd->nlbaf = 1; + /* LBA data-sz = 2^lbads */ + nd->lbaf[0] = sc->nvstore.sectsz_bits << NVME_NS_DATA_LBAF_LBADS_SHIFT; + + nd->flbas = 0; +} + +static void +pci_nvme_reset_locked(struct pci_nvme_softc *sc) +{ + DPRINTF(("%s\r\n", __func__)); + + sc->regs.cap_lo = (ZERO_BASED(sc->max_qentries) & NVME_CAP_LO_REG_MQES_MASK) | + (1 << NVME_CAP_LO_REG_CQR_SHIFT) | + (60 << NVME_CAP_LO_REG_TO_SHIFT); + + sc->regs.cap_hi = 1 << NVME_CAP_HI_REG_CSS_NVM_SHIFT; + + sc->regs.vs = 0x00010300; /* NVMe v1.3 */ + + sc->regs.cc = 0; + sc->regs.csts = 0; + + sc->num_cqueues = sc->num_squeues = sc->max_queues; + if (sc->submit_queues != NULL) { + for (int i = 0; i < sc->num_squeues + 1; i++) { + /* + * The Admin Submission Queue is at index 0. + * It must not be changed at reset otherwise the + * emulation will be out of sync with the guest. + */ + if (i != 0) { + sc->submit_queues[i].qbase = NULL; + sc->submit_queues[i].size = 0; + sc->submit_queues[i].cqid = 0; + } + sc->submit_queues[i].tail = 0; + sc->submit_queues[i].head = 0; + sc->submit_queues[i].busy = 0; + } + } else + sc->submit_queues = calloc(sc->num_squeues + 1, + sizeof(struct nvme_submission_queue)); + + if (sc->compl_queues != NULL) { + for (int i = 0; i < sc->num_cqueues + 1; i++) { + /* See Admin Submission Queue note above */ + if (i != 0) { + sc->compl_queues[i].qbase = NULL; + sc->compl_queues[i].size = 0; + } + + sc->compl_queues[i].tail = 0; + sc->compl_queues[i].head = 0; + } + } else { + sc->compl_queues = calloc(sc->num_cqueues + 1, + sizeof(struct nvme_completion_queue)); + + for (int i = 0; i < sc->num_cqueues + 1; i++) + pthread_mutex_init(&sc->compl_queues[i].mtx, NULL); + } +} + +static void +pci_nvme_reset(struct pci_nvme_softc *sc) +{ + pthread_mutex_lock(&sc->mtx); + pci_nvme_reset_locked(sc); + pthread_mutex_unlock(&sc->mtx); +} + +static void +pci_nvme_init_controller(struct vmctx *ctx, struct pci_nvme_softc *sc) +{ + uint16_t acqs, asqs; + + DPRINTF(("%s\r\n", __func__)); + + asqs = (sc->regs.aqa & NVME_AQA_REG_ASQS_MASK) + 1; + sc->submit_queues[0].size = asqs; + sc->submit_queues[0].qbase = vm_map_gpa(ctx, sc->regs.asq, + sizeof(struct nvme_command) * asqs); + + DPRINTF(("%s mapping Admin-SQ guest 0x%lx, host: %p\r\n", + __func__, sc->regs.asq, sc->submit_queues[0].qbase)); + + acqs = ((sc->regs.aqa >> NVME_AQA_REG_ACQS_SHIFT) & + NVME_AQA_REG_ACQS_MASK) + 1; + sc->compl_queues[0].size = acqs; + sc->compl_queues[0].qbase = vm_map_gpa(ctx, sc->regs.acq, + sizeof(struct nvme_completion) * acqs); + DPRINTF(("%s mapping Admin-CQ guest 0x%lx, host: %p\r\n", + __func__, sc->regs.acq, sc->compl_queues[0].qbase)); +} + +static int +nvme_opc_delete_io_sq(struct pci_nvme_softc* sc, struct nvme_command* command, + struct nvme_completion* compl) +{ + uint16_t qid = command->cdw10 & 0xffff; + + DPRINTF(("%s DELETE_IO_SQ %u\r\n", __func__, qid)); + if (qid == 0 || qid > sc->num_squeues) { + WPRINTF(("%s NOT PERMITTED queue id %u / num_squeues %u\r\n", + __func__, qid, sc->num_squeues)); + pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC, + NVME_SC_INVALID_QUEUE_IDENTIFIER); + return (1); + } + + sc->submit_queues[qid].qbase = NULL; + pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); + return (1); +} + +static int +nvme_opc_create_io_sq(struct pci_nvme_softc* sc, struct nvme_command* command, + struct nvme_completion* compl) +{ + if (command->cdw11 & NVME_CMD_CDW11_PC) { + uint16_t qid = command->cdw10 & 0xffff; + struct nvme_submission_queue *nsq; + + if ((qid == 0) || (qid > sc->num_squeues)) { + WPRINTF(("%s queue index %u > num_squeues %u\r\n", + __func__, qid, sc->num_squeues)); + pci_nvme_status_tc(&compl->status, + NVME_SCT_COMMAND_SPECIFIC, + NVME_SC_INVALID_QUEUE_IDENTIFIER); + return (1); + } + + nsq = &sc->submit_queues[qid]; + nsq->size = ONE_BASED((command->cdw10 >> 16) & 0xffff); + + nsq->qbase = vm_map_gpa(sc->nsc_pi->pi_vmctx, command->prp1, + sizeof(struct nvme_command) * (size_t)nsq->size); + nsq->cqid = (command->cdw11 >> 16) & 0xffff; + nsq->qpriority = (command->cdw11 >> 1) & 0x03; + + DPRINTF(("%s sq %u size %u gaddr %p cqid %u\r\n", __func__, + qid, nsq->size, nsq->qbase, nsq->cqid)); + + pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); + + DPRINTF(("%s completed creating IOSQ qid %u\r\n", + __func__, qid)); + } else { + /* + * Guest sent non-cont submission queue request. + * This setting is unsupported by this emulation. + */ + WPRINTF(("%s unsupported non-contig (list-based) " + "create i/o submission queue\r\n", __func__)); + + pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD); + } + return (1); +} + +static int +nvme_opc_delete_io_cq(struct pci_nvme_softc* sc, struct nvme_command* command, + struct nvme_completion* compl) +{ + uint16_t qid = command->cdw10 & 0xffff; + + DPRINTF(("%s DELETE_IO_CQ %u\r\n", __func__, qid)); + if (qid == 0 || qid > sc->num_cqueues) { + WPRINTF(("%s queue index %u / num_cqueues %u\r\n", + __func__, qid, sc->num_cqueues)); + pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC, + NVME_SC_INVALID_QUEUE_IDENTIFIER); + return (1); + } + + sc->compl_queues[qid].qbase = NULL; + pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); + return (1); +} + +static int +nvme_opc_create_io_cq(struct pci_nvme_softc* sc, struct nvme_command* command, + struct nvme_completion* compl) +{ + if (command->cdw11 & NVME_CMD_CDW11_PC) { + uint16_t qid = command->cdw10 & 0xffff; + struct nvme_completion_queue *ncq; + + if ((qid == 0) || (qid > sc->num_cqueues)) { + WPRINTF(("%s queue index %u > num_cqueues %u\r\n", + __func__, qid, sc->num_cqueues)); + pci_nvme_status_tc(&compl->status, + NVME_SCT_COMMAND_SPECIFIC, + NVME_SC_INVALID_QUEUE_IDENTIFIER); + return (1); + } + + ncq = &sc->compl_queues[qid]; + ncq->intr_en = (command->cdw11 & NVME_CMD_CDW11_IEN) >> 1; + ncq->intr_vec = (command->cdw11 >> 16) & 0xffff; + ncq->size = ONE_BASED((command->cdw10 >> 16) & 0xffff); + + ncq->qbase = vm_map_gpa(sc->nsc_pi->pi_vmctx, + command->prp1, + sizeof(struct nvme_command) * (size_t)ncq->size); + + pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); + } else { + /* + * Non-contig completion queue unsupported. + */ + WPRINTF(("%s unsupported non-contig (list-based) " + "create i/o completion queue\r\n", + __func__)); + + /* 0x12 = Invalid Use of Controller Memory Buffer */ + pci_nvme_status_genc(&compl->status, 0x12); + } + + return (1); +} + +static int +nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, + struct nvme_completion* compl) +{ + uint32_t logsize = (1 + ((command->cdw10 >> 16) & 0xFFF)) * 2; + uint8_t logpage = command->cdw10 & 0xFF; +#ifdef __FreeBSD__ + void *data; +#else + /* Our compiler grumbles about this, despite it being OK */ + void *data = NULL; +#endif + + DPRINTF(("%s log page %u len %u\r\n", __func__, logpage, logsize)); + + if (logpage >= 1 && logpage <= 3) + data = vm_map_gpa(sc->nsc_pi->pi_vmctx, command->prp1, + PAGE_SIZE); + + pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); + + switch (logpage) { + case 0x01: /* Error information */ + memset(data, 0, logsize > PAGE_SIZE ? PAGE_SIZE : logsize); + break; + case 0x02: /* SMART/Health information */ + /* TODO: present some smart info */ + memset(data, 0, logsize > PAGE_SIZE ? PAGE_SIZE : logsize); + break; + case 0x03: /* Firmware slot information */ + memset(data, 0, logsize > PAGE_SIZE ? PAGE_SIZE : logsize); + break; + default: + WPRINTF(("%s get log page %x command not supported\r\n", + __func__, logpage)); + + pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC, + NVME_SC_INVALID_LOG_PAGE); + } + + return (1); +} + +static int +nvme_opc_identify(struct pci_nvme_softc* sc, struct nvme_command* command, + struct nvme_completion* compl) +{ + void *dest; + + DPRINTF(("%s identify 0x%x nsid 0x%x\r\n", __func__, + command->cdw10 & 0xFF, command->nsid)); + + switch (command->cdw10 & 0xFF) { + case 0x00: /* return Identify Namespace data structure */ + dest = vm_map_gpa(sc->nsc_pi->pi_vmctx, command->prp1, + sizeof(sc->nsdata)); + memcpy(dest, &sc->nsdata, sizeof(sc->nsdata)); + break; + case 0x01: /* return Identify Controller data structure */ + dest = vm_map_gpa(sc->nsc_pi->pi_vmctx, command->prp1, + sizeof(sc->ctrldata)); + memcpy(dest, &sc->ctrldata, sizeof(sc->ctrldata)); + break; + case 0x02: /* list of 1024 active NSIDs > CDW1.NSID */ + dest = vm_map_gpa(sc->nsc_pi->pi_vmctx, command->prp1, + sizeof(uint32_t) * 1024); + ((uint32_t *)dest)[0] = 1; + ((uint32_t *)dest)[1] = 0; + break; + case 0x11: + pci_nvme_status_genc(&compl->status, + NVME_SC_INVALID_NAMESPACE_OR_FORMAT); + return (1); + case 0x03: /* list of NSID structures in CDW1.NSID, 4096 bytes */ + case 0x10: + case 0x12: + case 0x13: + case 0x14: + case 0x15: + default: + DPRINTF(("%s unsupported identify command requested 0x%x\r\n", + __func__, command->cdw10 & 0xFF)); + pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD); + return (1); + } + + pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); + return (1); +} + +static int +nvme_set_feature_queues(struct pci_nvme_softc* sc, struct nvme_command* command, + struct nvme_completion* compl) +{ + uint16_t nqr; /* Number of Queues Requested */ + + nqr = command->cdw11 & 0xFFFF; + if (nqr == 0xffff) { + WPRINTF(("%s: Illegal NSQR value %#x\n", __func__, nqr)); + pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD); + return (-1); + } + + sc->num_squeues = ONE_BASED(nqr); + if (sc->num_squeues > sc->max_queues) { + DPRINTF(("NSQR=%u is greater than max %u\n", sc->num_squeues, + sc->max_queues)); + sc->num_squeues = sc->max_queues; + } + + nqr = (command->cdw11 >> 16) & 0xFFFF; + if (nqr == 0xffff) { + WPRINTF(("%s: Illegal NCQR value %#x\n", __func__, nqr)); + pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD); + return (-1); + } + + sc->num_cqueues = ONE_BASED(nqr); + if (sc->num_cqueues > sc->max_queues) { + DPRINTF(("NCQR=%u is greater than max %u\n", sc->num_cqueues, + sc->max_queues)); + sc->num_cqueues = sc->max_queues; + } + + compl->cdw0 = NVME_FEATURE_NUM_QUEUES(sc); + + return (0); +} + +static int +nvme_opc_set_features(struct pci_nvme_softc* sc, struct nvme_command* command, + struct nvme_completion* compl) +{ + int feature = command->cdw10 & 0xFF; + uint32_t iv; + + DPRINTF(("%s feature 0x%x\r\n", __func__, feature)); + compl->cdw0 = 0; + + switch (feature) { + case NVME_FEAT_ARBITRATION: + DPRINTF((" arbitration 0x%x\r\n", command->cdw11)); + break; + case NVME_FEAT_POWER_MANAGEMENT: + DPRINTF((" power management 0x%x\r\n", command->cdw11)); + break; + case NVME_FEAT_LBA_RANGE_TYPE: + DPRINTF((" lba range 0x%x\r\n", command->cdw11)); + break; + case NVME_FEAT_TEMPERATURE_THRESHOLD: + DPRINTF((" temperature threshold 0x%x\r\n", command->cdw11)); + break; + case NVME_FEAT_ERROR_RECOVERY: + DPRINTF((" error recovery 0x%x\r\n", command->cdw11)); + break; + case NVME_FEAT_VOLATILE_WRITE_CACHE: + DPRINTF((" volatile write cache 0x%x\r\n", command->cdw11)); + break; + case NVME_FEAT_NUMBER_OF_QUEUES: + nvme_set_feature_queues(sc, command, compl); + break; + case NVME_FEAT_INTERRUPT_COALESCING: + DPRINTF((" interrupt coalescing 0x%x\r\n", command->cdw11)); + + /* in uS */ + sc->intr_coales_aggr_time = ((command->cdw11 >> 8) & 0xFF)*100; + + sc->intr_coales_aggr_thresh = command->cdw11 & 0xFF; + break; + case NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION: + iv = command->cdw11 & 0xFFFF; + + DPRINTF((" interrupt vector configuration 0x%x\r\n", + command->cdw11)); + + for (uint32_t i = 0; i < sc->num_cqueues + 1; i++) { + if (sc->compl_queues[i].intr_vec == iv) { + if (command->cdw11 & (1 << 16)) + sc->compl_queues[i].intr_en |= + NVME_CQ_INTCOAL; + else + sc->compl_queues[i].intr_en &= + ~NVME_CQ_INTCOAL; + } + } + break; + case NVME_FEAT_WRITE_ATOMICITY: + DPRINTF((" write atomicity 0x%x\r\n", command->cdw11)); + break; + case NVME_FEAT_ASYNC_EVENT_CONFIGURATION: + DPRINTF((" async event configuration 0x%x\r\n", + command->cdw11)); + sc->async_ev_config = command->cdw11; + break; + case NVME_FEAT_SOFTWARE_PROGRESS_MARKER: + DPRINTF((" software progress marker 0x%x\r\n", + command->cdw11)); + break; + case 0x0C: + DPRINTF((" autonomous power state transition 0x%x\r\n", + command->cdw11)); + break; + default: + WPRINTF(("%s invalid feature\r\n", __func__)); + pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD); + return (1); + } + + pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); + return (1); +} + +static int +nvme_opc_get_features(struct pci_nvme_softc* sc, struct nvme_command* command, + struct nvme_completion* compl) +{ + int feature = command->cdw10 & 0xFF; + + DPRINTF(("%s feature 0x%x\r\n", __func__, feature)); + + compl->cdw0 = 0; + + switch (feature) { + case NVME_FEAT_ARBITRATION: + DPRINTF((" arbitration\r\n")); + break; + case NVME_FEAT_POWER_MANAGEMENT: + DPRINTF((" power management\r\n")); + break; + case NVME_FEAT_LBA_RANGE_TYPE: + DPRINTF((" lba range\r\n")); + break; + case NVME_FEAT_TEMPERATURE_THRESHOLD: + DPRINTF((" temperature threshold\r\n")); + switch ((command->cdw11 >> 20) & 0x3) { + case 0: + /* Over temp threshold */ + compl->cdw0 = 0xFFFF; + break; + case 1: + /* Under temp threshold */ + compl->cdw0 = 0; + break; + default: + WPRINTF((" invalid threshold type select\r\n")); + pci_nvme_status_genc(&compl->status, + NVME_SC_INVALID_FIELD); + return (1); + } + break; + case NVME_FEAT_ERROR_RECOVERY: + DPRINTF((" error recovery\r\n")); + break; + case NVME_FEAT_VOLATILE_WRITE_CACHE: + DPRINTF((" volatile write cache\r\n")); + break; + case NVME_FEAT_NUMBER_OF_QUEUES: + compl->cdw0 = NVME_FEATURE_NUM_QUEUES(sc); + + DPRINTF((" number of queues (submit %u, completion %u)\r\n", + compl->cdw0 & 0xFFFF, + (compl->cdw0 >> 16) & 0xFFFF)); + + break; + case NVME_FEAT_INTERRUPT_COALESCING: + DPRINTF((" interrupt coalescing\r\n")); + break; + case NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION: + DPRINTF((" interrupt vector configuration\r\n")); + break; + case NVME_FEAT_WRITE_ATOMICITY: + DPRINTF((" write atomicity\r\n")); + break; + case NVME_FEAT_ASYNC_EVENT_CONFIGURATION: + DPRINTF((" async event configuration\r\n")); + sc->async_ev_config = command->cdw11; + break; + case NVME_FEAT_SOFTWARE_PROGRESS_MARKER: + DPRINTF((" software progress marker\r\n")); + break; + case 0x0C: + DPRINTF((" autonomous power state transition\r\n")); + break; + default: + WPRINTF(("%s invalid feature 0x%x\r\n", __func__, feature)); + pci_nvme_status_genc(&compl->status, NVME_SC_INVALID_FIELD); + return (1); + } + + pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); + return (1); +} + +static int +nvme_opc_abort(struct pci_nvme_softc* sc, struct nvme_command* command, + struct nvme_completion* compl) +{ + DPRINTF(("%s submission queue %u, command ID 0x%x\r\n", __func__, + command->cdw10 & 0xFFFF, (command->cdw10 >> 16) & 0xFFFF)); + + /* TODO: search for the command ID and abort it */ + + compl->cdw0 = 1; + pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); + return (1); +} + +#ifdef __FreeBSD__ +static int +nvme_opc_async_event_req(struct pci_nvme_softc* sc, + struct nvme_command* command, struct nvme_completion* compl) +{ + DPRINTF(("%s async event request 0x%x\r\n", __func__, command->cdw11)); + + /* + * TODO: raise events when they happen based on the Set Features cmd. + * These events happen async, so only set completion successful if + * there is an event reflective of the request to get event. + */ + pci_nvme_status_tc(&compl->status, NVME_SCT_COMMAND_SPECIFIC, + NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED); + return (0); +} +#else +/* This is kept behind an ifdef while it's unused to appease the compiler. */ +#endif /* __FreeBSD__ */ + +static void +pci_nvme_handle_admin_cmd(struct pci_nvme_softc* sc, uint64_t value) +{ + struct nvme_completion compl; + struct nvme_command *cmd; + struct nvme_submission_queue *sq; + struct nvme_completion_queue *cq; + int do_intr = 0; + uint16_t sqhead; + + DPRINTF(("%s index %u\r\n", __func__, (uint32_t)value)); + + sq = &sc->submit_queues[0]; + + sqhead = atomic_load_acq_short(&sq->head); + + if (atomic_testandset_int(&sq->busy, 1)) { + DPRINTF(("%s SQ busy, head %u, tail %u\r\n", + __func__, sqhead, sq->tail)); + return; + } + + DPRINTF(("sqhead %u, tail %u\r\n", sqhead, sq->tail)); + + while (sqhead != atomic_load_acq_short(&sq->tail)) { + cmd = &(sq->qbase)[sqhead]; + compl.status = 0; + + switch (cmd->opc) { + case NVME_OPC_DELETE_IO_SQ: + DPRINTF(("%s command DELETE_IO_SQ\r\n", __func__)); + do_intr |= nvme_opc_delete_io_sq(sc, cmd, &compl); + break; + case NVME_OPC_CREATE_IO_SQ: + DPRINTF(("%s command CREATE_IO_SQ\r\n", __func__)); + do_intr |= nvme_opc_create_io_sq(sc, cmd, &compl); + break; + case NVME_OPC_DELETE_IO_CQ: + DPRINTF(("%s command DELETE_IO_CQ\r\n", __func__)); + do_intr |= nvme_opc_delete_io_cq(sc, cmd, &compl); + break; + case NVME_OPC_CREATE_IO_CQ: + DPRINTF(("%s command CREATE_IO_CQ\r\n", __func__)); + do_intr |= nvme_opc_create_io_cq(sc, cmd, &compl); + break; + case NVME_OPC_GET_LOG_PAGE: + DPRINTF(("%s command GET_LOG_PAGE\r\n", __func__)); + do_intr |= nvme_opc_get_log_page(sc, cmd, &compl); + break; + case NVME_OPC_IDENTIFY: + DPRINTF(("%s command IDENTIFY\r\n", __func__)); + do_intr |= nvme_opc_identify(sc, cmd, &compl); + break; + case NVME_OPC_ABORT: + DPRINTF(("%s command ABORT\r\n", __func__)); + do_intr |= nvme_opc_abort(sc, cmd, &compl); + break; + case NVME_OPC_SET_FEATURES: + DPRINTF(("%s command SET_FEATURES\r\n", __func__)); + do_intr |= nvme_opc_set_features(sc, cmd, &compl); + break; + case NVME_OPC_GET_FEATURES: + DPRINTF(("%s command GET_FEATURES\r\n", __func__)); + do_intr |= nvme_opc_get_features(sc, cmd, &compl); + break; + case NVME_OPC_ASYNC_EVENT_REQUEST: + DPRINTF(("%s command ASYNC_EVENT_REQ\r\n", __func__)); + /* XXX dont care, unhandled for now + do_intr |= nvme_opc_async_event_req(sc, cmd, &compl); + */ + break; + default: + WPRINTF(("0x%x command is not implemented\r\n", + cmd->opc)); + } + + /* for now skip async event generation */ + if (cmd->opc != NVME_OPC_ASYNC_EVENT_REQUEST) { + struct nvme_completion *cp; + int phase; + + cq = &sc->compl_queues[0]; + + cp = &(cq->qbase)[cq->tail]; + cp->cdw0 = compl.cdw0; + cp->sqid = 0; + cp->sqhd = sqhead; + cp->cid = cmd->cid; + + phase = NVME_STATUS_GET_P(cp->status); + cp->status = compl.status; + pci_nvme_toggle_phase(&cp->status, phase); + + cq->tail = (cq->tail + 1) % cq->size; + } + sqhead = (sqhead + 1) % sq->size; + } + + DPRINTF(("setting sqhead %u\r\n", sqhead)); + atomic_store_short(&sq->head, sqhead); + atomic_store_int(&sq->busy, 0); + + if (do_intr) + pci_generate_msix(sc->nsc_pi, 0); + +} + +static int +pci_nvme_append_iov_req(struct pci_nvme_softc *sc, struct pci_nvme_ioreq *req, + uint64_t gpaddr, size_t size, int do_write, uint64_t lba) +{ + int iovidx; + + if (req != NULL) { + /* concatenate contig block-iovs to minimize number of iovs */ + if ((req->prev_gpaddr + req->prev_size) == gpaddr) { + iovidx = req->io_req.br_iovcnt - 1; + + req->io_req.br_iov[iovidx].iov_base = + paddr_guest2host(req->sc->nsc_pi->pi_vmctx, + req->prev_gpaddr, size); + + req->prev_size += size; + req->io_req.br_resid += size; + + req->io_req.br_iov[iovidx].iov_len = req->prev_size; + } else { + pthread_mutex_lock(&req->mtx); + + iovidx = req->io_req.br_iovcnt; + if (iovidx == NVME_MAX_BLOCKIOVS) { + int err = 0; + + DPRINTF(("large I/O, doing partial req\r\n")); + + iovidx = 0; + req->io_req.br_iovcnt = 0; + + req->io_req.br_callback = pci_nvme_io_partial; + + if (!do_write) + err = blockif_read(sc->nvstore.ctx, + &req->io_req); + else + err = blockif_write(sc->nvstore.ctx, + &req->io_req); + + /* wait until req completes before cont */ + if (err == 0) + pthread_cond_wait(&req->cv, &req->mtx); + } + if (iovidx == 0) { + req->io_req.br_offset = lba; + req->io_req.br_resid = 0; + req->io_req.br_param = req; + } + + req->io_req.br_iov[iovidx].iov_base = + paddr_guest2host(req->sc->nsc_pi->pi_vmctx, + gpaddr, size); + + req->io_req.br_iov[iovidx].iov_len = size; + + req->prev_gpaddr = gpaddr; + req->prev_size = size; + req->io_req.br_resid += size; + + req->io_req.br_iovcnt++; + + pthread_mutex_unlock(&req->mtx); + } + } else { + /* RAM buffer: read/write directly */ + void *p = sc->nvstore.ctx; + void *gptr; + + if ((lba + size) > sc->nvstore.size) { + WPRINTF(("%s write would overflow RAM\r\n", __func__)); + return (-1); + } + + p = (void *)((uintptr_t)p + (uintptr_t)lba); + gptr = paddr_guest2host(sc->nsc_pi->pi_vmctx, gpaddr, size); + if (do_write) + memcpy(p, gptr, size); + else + memcpy(gptr, p, size); + } + return (0); +} + +static void +pci_nvme_set_completion(struct pci_nvme_softc *sc, + struct nvme_submission_queue *sq, int sqid, uint16_t cid, + uint32_t cdw0, uint16_t status, int ignore_busy) +{ + struct nvme_completion_queue *cq = &sc->compl_queues[sq->cqid]; + struct nvme_completion *compl; + int do_intr = 0; + int phase; + + DPRINTF(("%s sqid %d cqid %u cid %u status: 0x%x 0x%x\r\n", + __func__, sqid, sq->cqid, cid, NVME_STATUS_GET_SCT(status), + NVME_STATUS_GET_SC(status))); + + pthread_mutex_lock(&cq->mtx); + + assert(cq->qbase != NULL); + + compl = &cq->qbase[cq->tail]; + + compl->sqhd = atomic_load_acq_short(&sq->head); + compl->sqid = sqid; + compl->cid = cid; + + // toggle phase + phase = NVME_STATUS_GET_P(compl->status); + compl->status = status; + pci_nvme_toggle_phase(&compl->status, phase); + + cq->tail = (cq->tail + 1) % cq->size; + + if (cq->intr_en & NVME_CQ_INTEN) + do_intr = 1; + + pthread_mutex_unlock(&cq->mtx); + + if (ignore_busy || !atomic_load_acq_int(&sq->busy)) + if (do_intr) + pci_generate_msix(sc->nsc_pi, cq->intr_vec); +} + +static void +pci_nvme_release_ioreq(struct pci_nvme_softc *sc, struct pci_nvme_ioreq *req) +{ + req->sc = NULL; + req->nvme_sq = NULL; + req->sqid = 0; + + pthread_mutex_lock(&sc->mtx); + + req->next = sc->ioreqs_free; + sc->ioreqs_free = req; + sc->pending_ios--; + + /* when no more IO pending, can set to ready if device reset/enabled */ + if (sc->pending_ios == 0 && + NVME_CC_GET_EN(sc->regs.cc) && !(NVME_CSTS_GET_RDY(sc->regs.csts))) + sc->regs.csts |= NVME_CSTS_RDY; + + pthread_mutex_unlock(&sc->mtx); + + sem_post(&sc->iosemlock); +} + +static struct pci_nvme_ioreq * +pci_nvme_get_ioreq(struct pci_nvme_softc *sc) +{ + struct pci_nvme_ioreq *req = NULL;; + + sem_wait(&sc->iosemlock); + pthread_mutex_lock(&sc->mtx); + + req = sc->ioreqs_free; + assert(req != NULL); + + sc->ioreqs_free = req->next; + + req->next = NULL; + req->sc = sc; + + sc->pending_ios++; + + pthread_mutex_unlock(&sc->mtx); + + req->io_req.br_iovcnt = 0; + req->io_req.br_offset = 0; + req->io_req.br_resid = 0; + req->io_req.br_param = req; + req->prev_gpaddr = 0; + req->prev_size = 0; + + return req; +} + +static void +pci_nvme_io_done(struct blockif_req *br, int err) +{ + struct pci_nvme_ioreq *req = br->br_param; + struct nvme_submission_queue *sq = req->nvme_sq; + uint16_t code, status = 0; + + DPRINTF(("%s error %d %s\r\n", __func__, err, strerror(err))); + + /* TODO return correct error */ + code = err ? NVME_SC_DATA_TRANSFER_ERROR : NVME_SC_SUCCESS; + pci_nvme_status_genc(&status, code); + + pci_nvme_set_completion(req->sc, sq, req->sqid, req->cid, 0, status, 0); + pci_nvme_release_ioreq(req->sc, req); +} + +static void +pci_nvme_io_partial(struct blockif_req *br, int err) +{ + struct pci_nvme_ioreq *req = br->br_param; + + DPRINTF(("%s error %d %s\r\n", __func__, err, strerror(err))); + + pthread_cond_signal(&req->cv); +} + + +static void +pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx) +{ + struct nvme_submission_queue *sq; + uint16_t status = 0; + uint16_t sqhead; + int err; + + /* handle all submissions up to sq->tail index */ + sq = &sc->submit_queues[idx]; + + if (atomic_testandset_int(&sq->busy, 1)) { + DPRINTF(("%s sqid %u busy\r\n", __func__, idx)); + return; + } + + sqhead = atomic_load_acq_short(&sq->head); + + DPRINTF(("nvme_handle_io qid %u head %u tail %u cmdlist %p\r\n", + idx, sqhead, sq->tail, sq->qbase)); + + while (sqhead != atomic_load_acq_short(&sq->tail)) { + struct nvme_command *cmd; + struct pci_nvme_ioreq *req = NULL; + uint64_t lba; + uint64_t nblocks, bytes, size, cpsz; + + /* TODO: support scatter gather list handling */ + + cmd = &sq->qbase[sqhead]; + sqhead = (sqhead + 1) % sq->size; + + lba = ((uint64_t)cmd->cdw11 << 32) | cmd->cdw10; + + if (cmd->opc == NVME_OPC_FLUSH) { + pci_nvme_status_genc(&status, NVME_SC_SUCCESS); + pci_nvme_set_completion(sc, sq, idx, cmd->cid, 0, + status, 1); + + continue; + } else if (cmd->opc == 0x08) { + /* TODO: write zeroes */ + WPRINTF(("%s write zeroes lba 0x%lx blocks %u\r\n", + __func__, lba, cmd->cdw12 & 0xFFFF)); + pci_nvme_status_genc(&status, NVME_SC_SUCCESS); + pci_nvme_set_completion(sc, sq, idx, cmd->cid, 0, + status, 1); + + continue; + } + + nblocks = (cmd->cdw12 & 0xFFFF) + 1; + + bytes = nblocks * sc->nvstore.sectsz; + + if (sc->nvstore.type == NVME_STOR_BLOCKIF) { + req = pci_nvme_get_ioreq(sc); + req->nvme_sq = sq; + req->sqid = idx; + } + + /* + * If data starts mid-page and flows into the next page, then + * increase page count + */ + + DPRINTF(("[h%u:t%u:n%u] %s starting LBA 0x%lx blocks %lu " + "(%lu-bytes)\r\n", + sqhead==0 ? sq->size-1 : sqhead-1, sq->tail, sq->size, + cmd->opc == NVME_OPC_WRITE ? + "WRITE" : "READ", + lba, nblocks, bytes)); + + cmd->prp1 &= ~(0x03UL); + cmd->prp2 &= ~(0x03UL); + + DPRINTF((" prp1 0x%lx prp2 0x%lx\r\n", cmd->prp1, cmd->prp2)); + + size = bytes; + lba *= sc->nvstore.sectsz; + + cpsz = PAGE_SIZE - (cmd->prp1 % PAGE_SIZE); + + if (cpsz > bytes) + cpsz = bytes; + + if (req != NULL) { + req->io_req.br_offset = ((uint64_t)cmd->cdw11 << 32) | + cmd->cdw10; + req->opc = cmd->opc; + req->cid = cmd->cid; + req->nsid = cmd->nsid; + } + + err = pci_nvme_append_iov_req(sc, req, cmd->prp1, cpsz, + cmd->opc == NVME_OPC_WRITE, lba); + lba += cpsz; + size -= cpsz; + + if (size == 0) + goto iodone; + + if (size <= PAGE_SIZE) { + /* prp2 is second (and final) page in transfer */ + + err = pci_nvme_append_iov_req(sc, req, cmd->prp2, + size, + cmd->opc == NVME_OPC_WRITE, + lba); + } else { + uint64_t *prp_list; + int i; + + /* prp2 is pointer to a physical region page list */ + prp_list = paddr_guest2host(sc->nsc_pi->pi_vmctx, + cmd->prp2, PAGE_SIZE); + + i = 0; + while (size != 0) { + cpsz = MIN(size, PAGE_SIZE); + + /* + * Move to linked physical region page list + * in last item. + */ + if (i == (NVME_PRP2_ITEMS-1) && + size > PAGE_SIZE) { + assert((prp_list[i] & (PAGE_SIZE-1)) == 0); + prp_list = paddr_guest2host( + sc->nsc_pi->pi_vmctx, + prp_list[i], PAGE_SIZE); + i = 0; + } + if (prp_list[i] == 0) { + WPRINTF(("PRP2[%d] = 0 !!!\r\n", i)); + err = 1; + break; + } + + err = pci_nvme_append_iov_req(sc, req, + prp_list[i], cpsz, + cmd->opc == NVME_OPC_WRITE, lba); + if (err) + break; + + lba += cpsz; + size -= cpsz; + i++; + } + } + +iodone: + if (sc->nvstore.type == NVME_STOR_RAM) { + uint16_t code, status = 0; + + code = err ? NVME_SC_LBA_OUT_OF_RANGE : + NVME_SC_SUCCESS; + pci_nvme_status_genc(&status, code); + + pci_nvme_set_completion(sc, sq, idx, cmd->cid, 0, + status, 1); + + continue; + } + + + if (err) + goto do_error; + + req->io_req.br_callback = pci_nvme_io_done; + + err = 0; + switch (cmd->opc) { + case NVME_OPC_READ: + err = blockif_read(sc->nvstore.ctx, &req->io_req); + break; + case NVME_OPC_WRITE: + err = blockif_write(sc->nvstore.ctx, &req->io_req); + break; + default: + WPRINTF(("%s unhandled io command 0x%x\r\n", + __func__, cmd->opc)); + err = 1; + } + +do_error: + if (err) { + uint16_t status = 0; + + pci_nvme_status_genc(&status, + NVME_SC_DATA_TRANSFER_ERROR); + + pci_nvme_set_completion(sc, sq, idx, cmd->cid, 0, + status, 1); + pci_nvme_release_ioreq(sc, req); + } + } + + atomic_store_short(&sq->head, sqhead); + atomic_store_int(&sq->busy, 0); +} + +static void +pci_nvme_handle_doorbell(struct vmctx *ctx, struct pci_nvme_softc* sc, + uint64_t idx, int is_sq, uint64_t value) +{ + DPRINTF(("nvme doorbell %lu, %s, val 0x%lx\r\n", + idx, is_sq ? "SQ" : "CQ", value & 0xFFFF)); + + if (is_sq) { + atomic_store_short(&sc->submit_queues[idx].tail, + (uint16_t)value); + + if (idx == 0) { + pci_nvme_handle_admin_cmd(sc, value); + } else { + /* submission queue; handle new entries in SQ */ + if (idx > sc->num_squeues) { + WPRINTF(("%s SQ index %lu overflow from " + "guest (max %u)\r\n", + __func__, idx, sc->num_squeues)); + return; + } + pci_nvme_handle_io_cmd(sc, (uint16_t)idx); + } + } else { + if (idx > sc->num_cqueues) { + WPRINTF(("%s queue index %lu overflow from " + "guest (max %u)\r\n", + __func__, idx, sc->num_cqueues)); + return; + } + + sc->compl_queues[idx].head = (uint16_t)value; + } +} + +static void +pci_nvme_bar0_reg_dumps(const char *func, uint64_t offset, int iswrite) +{ + const char *s = iswrite ? "WRITE" : "READ"; + + switch (offset) { + case NVME_CR_CAP_LOW: + DPRINTF(("%s %s NVME_CR_CAP_LOW\r\n", func, s)); + break; + case NVME_CR_CAP_HI: + DPRINTF(("%s %s NVME_CR_CAP_HI\r\n", func, s)); + break; + case NVME_CR_VS: + DPRINTF(("%s %s NVME_CR_VS\r\n", func, s)); + break; + case NVME_CR_INTMS: + DPRINTF(("%s %s NVME_CR_INTMS\r\n", func, s)); + break; + case NVME_CR_INTMC: + DPRINTF(("%s %s NVME_CR_INTMC\r\n", func, s)); + break; + case NVME_CR_CC: + DPRINTF(("%s %s NVME_CR_CC\r\n", func, s)); + break; + case NVME_CR_CSTS: + DPRINTF(("%s %s NVME_CR_CSTS\r\n", func, s)); + break; + case NVME_CR_NSSR: + DPRINTF(("%s %s NVME_CR_NSSR\r\n", func, s)); + break; + case NVME_CR_AQA: + DPRINTF(("%s %s NVME_CR_AQA\r\n", func, s)); + break; + case NVME_CR_ASQ_LOW: + DPRINTF(("%s %s NVME_CR_ASQ_LOW\r\n", func, s)); + break; + case NVME_CR_ASQ_HI: + DPRINTF(("%s %s NVME_CR_ASQ_HI\r\n", func, s)); + break; + case NVME_CR_ACQ_LOW: + DPRINTF(("%s %s NVME_CR_ACQ_LOW\r\n", func, s)); + break; + case NVME_CR_ACQ_HI: + DPRINTF(("%s %s NVME_CR_ACQ_HI\r\n", func, s)); + break; + default: + DPRINTF(("unknown nvme bar-0 offset 0x%lx\r\n", offset)); + } + +} + +static void +pci_nvme_write_bar_0(struct vmctx *ctx, struct pci_nvme_softc* sc, + uint64_t offset, int size, uint64_t value) +{ + uint32_t ccreg; + + if (offset >= NVME_DOORBELL_OFFSET) { + uint64_t belloffset = offset - NVME_DOORBELL_OFFSET; + uint64_t idx = belloffset / 8; /* door bell size = 2*int */ + int is_sq = (belloffset % 8) < 4; + + if (belloffset > ((sc->max_queues+1) * 8 - 4)) { + WPRINTF(("guest attempted an overflow write offset " + "0x%lx, val 0x%lx in %s", + offset, value, __func__)); + return; + } + + pci_nvme_handle_doorbell(ctx, sc, idx, is_sq, value); + return; + } + + DPRINTF(("nvme-write offset 0x%lx, size %d, value 0x%lx\r\n", + offset, size, value)); + + if (size != 4) { + WPRINTF(("guest wrote invalid size %d (offset 0x%lx, " + "val 0x%lx) to bar0 in %s", + size, offset, value, __func__)); + /* TODO: shutdown device */ + return; + } + + pci_nvme_bar0_reg_dumps(__func__, offset, 1); + + pthread_mutex_lock(&sc->mtx); + + switch (offset) { + case NVME_CR_CAP_LOW: + case NVME_CR_CAP_HI: + /* readonly */ + break; + case NVME_CR_VS: + /* readonly */ + break; + case NVME_CR_INTMS: + /* MSI-X, so ignore */ + break; + case NVME_CR_INTMC: + /* MSI-X, so ignore */ + break; + case NVME_CR_CC: + ccreg = (uint32_t)value; + + DPRINTF(("%s NVME_CR_CC en %x css %x shn %x iosqes %u " + "iocqes %u\r\n", + __func__, + NVME_CC_GET_EN(ccreg), NVME_CC_GET_CSS(ccreg), + NVME_CC_GET_SHN(ccreg), NVME_CC_GET_IOSQES(ccreg), + NVME_CC_GET_IOCQES(ccreg))); + + if (NVME_CC_GET_SHN(ccreg)) { + /* perform shutdown - flush out data to backend */ + sc->regs.csts &= ~(NVME_CSTS_REG_SHST_MASK << + NVME_CSTS_REG_SHST_SHIFT); + sc->regs.csts |= NVME_SHST_COMPLETE << + NVME_CSTS_REG_SHST_SHIFT; + } + if (NVME_CC_GET_EN(ccreg) != NVME_CC_GET_EN(sc->regs.cc)) { + if (NVME_CC_GET_EN(ccreg) == 0) + /* transition 1-> causes controller reset */ + pci_nvme_reset_locked(sc); + else + pci_nvme_init_controller(ctx, sc); + } + + /* Insert the iocqes, iosqes and en bits from the write */ + sc->regs.cc &= ~NVME_CC_WRITE_MASK; + sc->regs.cc |= ccreg & NVME_CC_WRITE_MASK; + if (NVME_CC_GET_EN(ccreg) == 0) { + /* Insert the ams, mps and css bit fields */ + sc->regs.cc &= ~NVME_CC_NEN_WRITE_MASK; + sc->regs.cc |= ccreg & NVME_CC_NEN_WRITE_MASK; + sc->regs.csts &= ~NVME_CSTS_RDY; + } else if (sc->pending_ios == 0) { + sc->regs.csts |= NVME_CSTS_RDY; + } + break; + case NVME_CR_CSTS: + break; + case NVME_CR_NSSR: + /* ignore writes; don't support subsystem reset */ + break; + case NVME_CR_AQA: + sc->regs.aqa = (uint32_t)value; + break; + case NVME_CR_ASQ_LOW: + sc->regs.asq = (sc->regs.asq & (0xFFFFFFFF00000000)) | + (0xFFFFF000 & value); + break; + case NVME_CR_ASQ_HI: + sc->regs.asq = (sc->regs.asq & (0x00000000FFFFFFFF)) | + (value << 32); + break; + case NVME_CR_ACQ_LOW: + sc->regs.acq = (sc->regs.acq & (0xFFFFFFFF00000000)) | + (0xFFFFF000 & value); + break; + case NVME_CR_ACQ_HI: + sc->regs.acq = (sc->regs.acq & (0x00000000FFFFFFFF)) | + (value << 32); + break; + default: + DPRINTF(("%s unknown offset 0x%lx, value 0x%lx size %d\r\n", + __func__, offset, value, size)); + } + pthread_mutex_unlock(&sc->mtx); +} + +static void +pci_nvme_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value) +{ + struct pci_nvme_softc* sc = pi->pi_arg; + + if (baridx == pci_msix_table_bar(pi) || + baridx == pci_msix_pba_bar(pi)) { + DPRINTF(("nvme-write baridx %d, msix: off 0x%lx, size %d, " + " value 0x%lx\r\n", baridx, offset, size, value)); + + pci_emul_msix_twrite(pi, offset, size, value); + return; + } + + switch (baridx) { + case 0: + pci_nvme_write_bar_0(ctx, sc, offset, size, value); + break; + + default: + DPRINTF(("%s unknown baridx %d, val 0x%lx\r\n", + __func__, baridx, value)); + } +} + +static uint64_t pci_nvme_read_bar_0(struct pci_nvme_softc* sc, + uint64_t offset, int size) +{ + uint64_t value; + + pci_nvme_bar0_reg_dumps(__func__, offset, 0); + + if (offset < NVME_DOORBELL_OFFSET) { + void *p = &(sc->regs); + pthread_mutex_lock(&sc->mtx); + memcpy(&value, (void *)((uintptr_t)p + offset), size); + pthread_mutex_unlock(&sc->mtx); + } else { + value = 0; + WPRINTF(("pci_nvme: read invalid offset %ld\r\n", offset)); + } + + switch (size) { + case 1: + value &= 0xFF; + break; + case 2: + value &= 0xFFFF; + break; + case 4: + value &= 0xFFFFFFFF; + break; + } + + DPRINTF((" nvme-read offset 0x%lx, size %d -> value 0x%x\r\n", + offset, size, (uint32_t)value)); + + return (value); +} + + + +static uint64_t +pci_nvme_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, + uint64_t offset, int size) +{ + struct pci_nvme_softc* sc = pi->pi_arg; + + if (baridx == pci_msix_table_bar(pi) || + baridx == pci_msix_pba_bar(pi)) { + DPRINTF(("nvme-read bar: %d, msix: regoff 0x%lx, size %d\r\n", + baridx, offset, size)); + + return pci_emul_msix_tread(pi, offset, size); + } + + switch (baridx) { + case 0: + return pci_nvme_read_bar_0(sc, offset, size); + + default: + DPRINTF(("unknown bar %d, 0x%lx\r\n", baridx, offset)); + } + + return (0); +} + + +static int +pci_nvme_parse_opts(struct pci_nvme_softc *sc, char *opts) +{ + char bident[sizeof("XX:X:X")]; + char *uopt, *xopts, *config; + uint32_t sectsz; + int optidx; + + sc->max_queues = NVME_QUEUES; + sc->max_qentries = NVME_MAX_QENTRIES; + sc->ioslots = NVME_IOSLOTS; + sc->num_squeues = sc->max_queues; + sc->num_cqueues = sc->max_queues; + sectsz = 0; + + uopt = strdup(opts); + optidx = 0; + snprintf(sc->ctrldata.sn, sizeof(sc->ctrldata.sn), + "NVME-%d-%d", sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func); + for (xopts = strtok(uopt, ","); + xopts != NULL; + xopts = strtok(NULL, ",")) { + + if ((config = strchr(xopts, '=')) != NULL) + *config++ = '\0'; + + if (!strcmp("maxq", xopts)) { + sc->max_queues = atoi(config); + } else if (!strcmp("qsz", xopts)) { + sc->max_qentries = atoi(config); + } else if (!strcmp("ioslots", xopts)) { + sc->ioslots = atoi(config); + } else if (!strcmp("sectsz", xopts)) { + sectsz = atoi(config); + } else if (!strcmp("ser", xopts)) { + /* + * This field indicates the Product Serial Number in + * 7-bit ASCII, unused bytes should be space characters. + * Ref: NVMe v1.3c. + */ + cpywithpad((char *)sc->ctrldata.sn, + sizeof(sc->ctrldata.sn), config, ' '); + } else if (!strcmp("ram", xopts)) { + uint64_t sz = strtoull(&xopts[4], NULL, 10); + + sc->nvstore.type = NVME_STOR_RAM; + sc->nvstore.size = sz * 1024 * 1024; + sc->nvstore.ctx = calloc(1, sc->nvstore.size); + sc->nvstore.sectsz = 4096; + sc->nvstore.sectsz_bits = 12; + if (sc->nvstore.ctx == NULL) { + perror("Unable to allocate RAM"); + free(uopt); + return (-1); + } + } else if (optidx == 0) { + snprintf(bident, sizeof(bident), "%d:%d", + sc->nsc_pi->pi_slot, sc->nsc_pi->pi_func); + sc->nvstore.ctx = blockif_open(xopts, bident); + if (sc->nvstore.ctx == NULL) { + perror("Could not open backing file"); + free(uopt); + return (-1); + } + sc->nvstore.type = NVME_STOR_BLOCKIF; + sc->nvstore.size = blockif_size(sc->nvstore.ctx); + } else { + fprintf(stderr, "Invalid option %s\n", xopts); + free(uopt); + return (-1); + } + + optidx++; + } + free(uopt); + + if (sc->nvstore.ctx == NULL || sc->nvstore.size == 0) { + fprintf(stderr, "backing store not specified\n"); + return (-1); + } + if (sectsz == 512 || sectsz == 4096 || sectsz == 8192) + sc->nvstore.sectsz = sectsz; + else if (sc->nvstore.type != NVME_STOR_RAM) + sc->nvstore.sectsz = blockif_sectsz(sc->nvstore.ctx); + for (sc->nvstore.sectsz_bits = 9; + (1 << sc->nvstore.sectsz_bits) < sc->nvstore.sectsz; + sc->nvstore.sectsz_bits++); + + if (sc->max_queues <= 0 || sc->max_queues > NVME_QUEUES) + sc->max_queues = NVME_QUEUES; + + if (sc->max_qentries <= 0) { + fprintf(stderr, "Invalid qsz option\n"); + return (-1); + } + if (sc->ioslots <= 0) { + fprintf(stderr, "Invalid ioslots option\n"); + return (-1); + } + + return (0); +} + +static int +pci_nvme_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + struct pci_nvme_softc *sc; + uint32_t pci_membar_sz; + int error; + + error = 0; + + sc = calloc(1, sizeof(struct pci_nvme_softc)); + pi->pi_arg = sc; + sc->nsc_pi = pi; + + error = pci_nvme_parse_opts(sc, opts); + if (error < 0) + goto done; + else + error = 0; + + sc->ioreqs = calloc(sc->ioslots, sizeof(struct pci_nvme_ioreq)); + for (int i = 0; i < sc->ioslots; i++) { + if (i < (sc->ioslots-1)) + sc->ioreqs[i].next = &sc->ioreqs[i+1]; + pthread_mutex_init(&sc->ioreqs[i].mtx, NULL); + pthread_cond_init(&sc->ioreqs[i].cv, NULL); + } + sc->ioreqs_free = sc->ioreqs; + sc->intr_coales_aggr_thresh = 1; + + pci_set_cfgdata16(pi, PCIR_DEVICE, 0x0A0A); + pci_set_cfgdata16(pi, PCIR_VENDOR, 0xFB5D); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE); + pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_STORAGE_NVM); + pci_set_cfgdata8(pi, PCIR_PROGIF, + PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0); + + /* allocate size of nvme registers + doorbell space for all queues */ + pci_membar_sz = sizeof(struct nvme_registers) + + 2*sizeof(uint32_t)*(sc->max_queues + 1); + + DPRINTF(("nvme membar size: %u\r\n", pci_membar_sz)); + + error = pci_emul_alloc_bar(pi, 0, PCIBAR_MEM64, pci_membar_sz); + if (error) { + WPRINTF(("%s pci alloc mem bar failed\r\n", __func__)); + goto done; + } + + error = pci_emul_add_msixcap(pi, sc->max_queues + 1, NVME_MSIX_BAR); + if (error) { + WPRINTF(("%s pci add msixcap failed\r\n", __func__)); + goto done; + } + + pthread_mutex_init(&sc->mtx, NULL); + sem_init(&sc->iosemlock, 0, sc->ioslots); + + pci_nvme_reset(sc); + pci_nvme_init_ctrldata(sc); + pci_nvme_init_nsdata(sc); + + pci_lintr_request(pi); + +done: + return (error); +} + + +struct pci_devemu pci_de_nvme = { + .pe_emu = "nvme", + .pe_init = pci_nvme_init, + .pe_barwrite = pci_nvme_write, + .pe_barread = pci_nvme_read +}; +PCI_EMUL_SET(pci_de_nvme); diff --git a/usr/src/cmd/bhyve/pci_passthru.c b/usr/src/cmd/bhyve/pci_passthru.c new file mode 100644 index 0000000000..3782914cd5 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_passthru.c @@ -0,0 +1,910 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/pciio.h> +#include <sys/ioctl.h> + +#include <sys/pci.h> + +#include <dev/io/iodev.h> +#include <dev/pci/pcireg.h> + +#include <machine/iodev.h> + +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <sysexits.h> +#include <unistd.h> + +#include <machine/vmm.h> +#include <vmmapi.h> +#include <sys/ppt_dev.h> +#include "pci_emul.h" +#include "mem.h" + +#define LEGACY_SUPPORT 1 + +#define MSIX_TABLE_COUNT(ctrl) (((ctrl) & PCIM_MSIXCTRL_TABLE_SIZE) + 1) +#define MSIX_CAPLEN 12 + +struct passthru_softc { + struct pci_devinst *psc_pi; + struct pcibar psc_bar[PCI_BARMAX + 1]; + struct { + int capoff; + int msgctrl; + int emulated; + } psc_msi; + struct { + int capoff; + } psc_msix; + int pptfd; + int msi_limit; + int msix_limit; +}; + +static int +msi_caplen(int msgctrl) +{ + int len; + + len = 10; /* minimum length of msi capability */ + + if (msgctrl & PCIM_MSICTRL_64BIT) + len += 4; + +#if 0 + /* + * Ignore the 'mask' and 'pending' bits in the MSI capability. + * We'll let the guest manipulate them directly. + */ + if (msgctrl & PCIM_MSICTRL_VECTOR) + len += 10; +#endif + + return (len); +} + +static uint32_t +read_config(const struct passthru_softc *sc, long reg, int width) +{ + struct ppt_cfg_io pi; + + pi.pci_off = reg; + pi.pci_width = width; + + if (ioctl(sc->pptfd, PPT_CFG_READ, &pi) != 0) { + return (0); + } + return (pi.pci_data); +} + +static void +write_config(const struct passthru_softc *sc, long reg, int width, + uint32_t data) +{ + struct ppt_cfg_io pi; + + pi.pci_off = reg; + pi.pci_width = width; + pi.pci_data = data; + + (void) ioctl(sc->pptfd, PPT_CFG_WRITE, &pi); +} + +static int +passthru_get_bar(struct passthru_softc *sc, int bar, enum pcibar_type *type, + uint64_t *base, uint64_t *size) +{ + struct ppt_bar_query pb; + + pb.pbq_baridx = bar; + + if (ioctl(sc->pptfd, PPT_BAR_QUERY, &pb) != 0) { + return (-1); + } + + switch (pb.pbq_type) { + case PCI_ADDR_IO: + *type = PCIBAR_IO; + break; + case PCI_ADDR_MEM32: + *type = PCIBAR_MEM32; + break; + case PCI_ADDR_MEM64: + *type = PCIBAR_MEM64; + break; + default: + err(1, "unrecognized BAR type: %u\n", pb.pbq_type); + break; + } + + *base = pb.pbq_base; + *size = pb.pbq_size; + return (0); +} + +static int +passthru_dev_open(const char *path, int *pptfdp) +{ + int pptfd; + + if ((pptfd = open(path, O_RDWR)) < 0) { + return (errno); + } + + /* XXX: verify fd with ioctl? */ + *pptfdp = pptfd; + return (0); +} + +#ifdef LEGACY_SUPPORT +static int +passthru_add_msicap(struct pci_devinst *pi, int msgnum, int nextptr) +{ + int capoff, i; + struct msicap msicap; + u_char *capdata; + + pci_populate_msicap(&msicap, msgnum, nextptr); + + /* + * XXX + * Copy the msi capability structure in the last 16 bytes of the + * config space. This is wrong because it could shadow something + * useful to the device. + */ + capoff = 256 - roundup(sizeof(msicap), 4); + capdata = (u_char *)&msicap; + for (i = 0; i < sizeof(msicap); i++) + pci_set_cfgdata8(pi, capoff + i, capdata[i]); + + return (capoff); +} +#endif /* LEGACY_SUPPORT */ + +static void +passthru_intr_limit(struct passthru_softc *sc, struct msixcap *msixcap) +{ + struct pci_devinst *pi = sc->psc_pi; + int off; + + /* Reduce the number of MSI vectors if higher than OS limit */ + if ((off = sc->psc_msi.capoff) != 0 && sc->msi_limit != -1) { + int msi_limit, mmc; + + msi_limit = + sc->msi_limit > 16 ? PCIM_MSICTRL_MMC_32 : + sc->msi_limit > 8 ? PCIM_MSICTRL_MMC_16 : + sc->msi_limit > 4 ? PCIM_MSICTRL_MMC_8 : + sc->msi_limit > 2 ? PCIM_MSICTRL_MMC_4 : + sc->msi_limit > 1 ? PCIM_MSICTRL_MMC_2 : + PCIM_MSICTRL_MMC_1; + mmc = sc->psc_msi.msgctrl & PCIM_MSICTRL_MMC_MASK; + + if (mmc > msi_limit) { + sc->psc_msi.msgctrl &= ~PCIM_MSICTRL_MMC_MASK; + sc->psc_msi.msgctrl |= msi_limit; + pci_set_cfgdata16(pi, off + 2, sc->psc_msi.msgctrl); + } + } + + /* Reduce the number of MSI-X vectors if higher than OS limit */ + if ((off = sc->psc_msix.capoff) != 0 && sc->msix_limit != -1) { + if (MSIX_TABLE_COUNT(msixcap->msgctrl) > sc->msix_limit) { + msixcap->msgctrl &= ~PCIM_MSIXCTRL_TABLE_SIZE; + msixcap->msgctrl |= sc->msix_limit - 1; + pci_set_cfgdata16(pi, off + 2, msixcap->msgctrl); + } + } +} + +static int +cfginitmsi(struct passthru_softc *sc) +{ + int i, ptr, capptr, cap, sts, caplen, table_size; + uint32_t u32; + struct pci_devinst *pi = sc->psc_pi; + struct msixcap msixcap; + uint32_t *msixcap_ptr; + + /* + * Parse the capabilities and cache the location of the MSI + * and MSI-X capabilities. + */ + sts = read_config(sc, PCIR_STATUS, 2); + if (sts & PCIM_STATUS_CAPPRESENT) { + ptr = read_config(sc, PCIR_CAP_PTR, 1); + while (ptr != 0 && ptr != 0xff) { + cap = read_config(sc, ptr + PCICAP_ID, 1); + if (cap == PCIY_MSI) { + /* + * Copy the MSI capability into the config + * space of the emulated pci device + */ + sc->psc_msi.capoff = ptr; + sc->psc_msi.msgctrl = read_config(sc, + ptr + 2, 2); + sc->psc_msi.emulated = 0; + caplen = msi_caplen(sc->psc_msi.msgctrl); + capptr = ptr; + while (caplen > 0) { + u32 = read_config(sc, capptr, 4); + pci_set_cfgdata32(pi, capptr, u32); + caplen -= 4; + capptr += 4; + } + } else if (cap == PCIY_MSIX) { + /* + * Copy the MSI-X capability + */ + sc->psc_msix.capoff = ptr; + caplen = 12; + msixcap_ptr = (uint32_t*) &msixcap; + capptr = ptr; + while (caplen > 0) { + u32 = read_config(sc, capptr, 4); + *msixcap_ptr = u32; + pci_set_cfgdata32(pi, capptr, u32); + caplen -= 4; + capptr += 4; + msixcap_ptr++; + } + } + ptr = read_config(sc, ptr + PCICAP_NEXTPTR, 1); + } + } + + passthru_intr_limit(sc, &msixcap); + + if (sc->psc_msix.capoff != 0) { + pi->pi_msix.pba_bar = + msixcap.pba_info & PCIM_MSIX_BIR_MASK; + pi->pi_msix.pba_offset = + msixcap.pba_info & ~PCIM_MSIX_BIR_MASK; + pi->pi_msix.table_bar = + msixcap.table_info & PCIM_MSIX_BIR_MASK; + pi->pi_msix.table_offset = + msixcap.table_info & ~PCIM_MSIX_BIR_MASK; + pi->pi_msix.table_count = MSIX_TABLE_COUNT(msixcap.msgctrl); + pi->pi_msix.pba_size = PBA_SIZE(pi->pi_msix.table_count); + + /* Allocate the emulated MSI-X table array */ + table_size = pi->pi_msix.table_count * MSIX_TABLE_ENTRY_SIZE; + pi->pi_msix.table = calloc(1, table_size); + + /* Mask all table entries */ + for (i = 0; i < pi->pi_msix.table_count; i++) { + pi->pi_msix.table[i].vector_control |= + PCIM_MSIX_VCTRL_MASK; + } + } + +#ifdef LEGACY_SUPPORT + /* + * If the passthrough device does not support MSI then craft a + * MSI capability for it. We link the new MSI capability at the + * head of the list of capabilities. + */ + if ((sts & PCIM_STATUS_CAPPRESENT) != 0 && sc->psc_msi.capoff == 0) { + int origptr, msiptr; + origptr = read_config(sc, PCIR_CAP_PTR, 1); + msiptr = passthru_add_msicap(pi, 1, origptr); + sc->psc_msi.capoff = msiptr; + sc->psc_msi.msgctrl = pci_get_cfgdata16(pi, msiptr + 2); + sc->psc_msi.emulated = 1; + pci_set_cfgdata8(pi, PCIR_CAP_PTR, msiptr); + } +#endif + + /* Make sure one of the capabilities is present */ + if (sc->psc_msi.capoff == 0 && sc->psc_msix.capoff == 0) { + return (-1); + } else { + return (0); + } +} + +static uint64_t +passthru_msix_table_read(struct passthru_softc *sc, uint64_t offset, int size) +{ + struct pci_devinst *pi; + struct msix_table_entry *entry; + uint8_t *src8; + uint16_t *src16; + uint32_t *src32; + uint64_t *src64; + uint64_t data; + size_t entry_offset; + int index; + + pi = sc->psc_pi; + if (offset >= pi->pi_msix.pba_offset && + offset < pi->pi_msix.pba_offset + pi->pi_msix.pba_size) { + switch(size) { + case 1: + src8 = (uint8_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + data = *src8; + break; + case 2: + src16 = (uint16_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + data = *src16; + break; + case 4: + src32 = (uint32_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + data = *src32; + break; + case 8: + src64 = (uint64_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + data = *src64; + break; + default: + return (-1); + } + return (data); + } + + if (offset < pi->pi_msix.table_offset) + return (-1); + + offset -= pi->pi_msix.table_offset; + index = offset / MSIX_TABLE_ENTRY_SIZE; + if (index >= pi->pi_msix.table_count) + return (-1); + + entry = &pi->pi_msix.table[index]; + entry_offset = offset % MSIX_TABLE_ENTRY_SIZE; + + switch(size) { + case 1: + src8 = (uint8_t *)((void *)entry + entry_offset); + data = *src8; + break; + case 2: + src16 = (uint16_t *)((void *)entry + entry_offset); + data = *src16; + break; + case 4: + src32 = (uint32_t *)((void *)entry + entry_offset); + data = *src32; + break; + case 8: + src64 = (uint64_t *)((void *)entry + entry_offset); + data = *src64; + break; + default: + return (-1); + } + + return (data); +} + +static void +passthru_msix_table_write(struct vmctx *ctx, int vcpu, + struct passthru_softc *sc, uint64_t offset, int size, uint64_t data) +{ + struct pci_devinst *pi; + struct msix_table_entry *entry; + uint8_t *dest8; + uint16_t *dest16; + uint32_t *dest32; + uint64_t *dest64; + size_t entry_offset; + uint32_t vector_control; + int index; + + pi = sc->psc_pi; + if (offset >= pi->pi_msix.pba_offset && + offset < pi->pi_msix.pba_offset + pi->pi_msix.pba_size) { + switch(size) { + case 1: + dest8 = (uint8_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + *dest8 = data; + break; + case 2: + dest16 = (uint16_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + *dest16 = data; + break; + case 4: + dest32 = (uint32_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + *dest32 = data; + break; + case 8: + dest64 = (uint64_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + *dest64 = data; + break; + default: + break; + } + return; + } + + if (offset < pi->pi_msix.table_offset) + return; + + offset -= pi->pi_msix.table_offset; + index = offset / MSIX_TABLE_ENTRY_SIZE; + if (index >= pi->pi_msix.table_count) + return; + + entry = &pi->pi_msix.table[index]; + entry_offset = offset % MSIX_TABLE_ENTRY_SIZE; + + /* Only 4 byte naturally-aligned writes are supported */ + assert(size == 4); + assert(entry_offset % 4 == 0); + + vector_control = entry->vector_control; + dest32 = (uint32_t *)((void *)entry + entry_offset); + *dest32 = data; + /* If MSI-X hasn't been enabled, do nothing */ + if (pi->pi_msix.enabled) { + /* If the entry is masked, don't set it up */ + if ((entry->vector_control & PCIM_MSIX_VCTRL_MASK) == 0 || + (vector_control & PCIM_MSIX_VCTRL_MASK) == 0) { + (void) vm_setup_pptdev_msix(ctx, vcpu, sc->pptfd, + index, entry->addr, entry->msg_data, + entry->vector_control); + } + } +} + +static int +init_msix_table(struct vmctx *ctx, struct passthru_softc *sc, uint64_t base) +{ + int error, idx; + size_t len, remaining; + uint32_t table_size, table_offset; + uint32_t pba_size, pba_offset; + vm_paddr_t start; + struct pci_devinst *pi = sc->psc_pi; + + assert(pci_msix_table_bar(pi) >= 0 && pci_msix_pba_bar(pi) >= 0); + + /* + * If the MSI-X table BAR maps memory intended for + * other uses, it is at least assured that the table + * either resides in its own page within the region, + * or it resides in a page shared with only the PBA. + */ + table_offset = rounddown2(pi->pi_msix.table_offset, 4096); + + table_size = pi->pi_msix.table_offset - table_offset; + table_size += pi->pi_msix.table_count * MSIX_TABLE_ENTRY_SIZE; + table_size = roundup2(table_size, 4096); + + idx = pi->pi_msix.table_bar; + start = pi->pi_bar[idx].addr; + remaining = pi->pi_bar[idx].size; + + if (pi->pi_msix.pba_bar == pi->pi_msix.table_bar) { + pba_offset = pi->pi_msix.pba_offset; + pba_size = pi->pi_msix.pba_size; + if (pba_offset >= table_offset + table_size || + table_offset >= pba_offset + pba_size) { + /* + * If the PBA does not share a page with the MSI-x + * tables, no PBA emulation is required. + */ + pi->pi_msix.pba_page = NULL; + pi->pi_msix.pba_page_offset = 0; + } else { + /* + * The PBA overlaps with either the first or last + * page of the MSI-X table region. Map the + * appropriate page. + */ + if (pba_offset <= table_offset) + pi->pi_msix.pba_page_offset = table_offset; + else + pi->pi_msix.pba_page_offset = table_offset + + table_size - 4096; + pi->pi_msix.pba_page = mmap(NULL, 4096, PROT_READ | + PROT_WRITE, MAP_SHARED, sc->pptfd, + pi->pi_msix.pba_page_offset); + if (pi->pi_msix.pba_page == MAP_FAILED) { + warn("Failed to map PBA page for MSI-X on %d", + sc->pptfd); + return (-1); + } + } + } + + /* Map everything before the MSI-X table */ + if (table_offset > 0) { + len = table_offset; + error = vm_map_pptdev_mmio(ctx, sc->pptfd, start, len, base); + if (error) + return (error); + + base += len; + start += len; + remaining -= len; + } + + /* Skip the MSI-X table */ + base += table_size; + start += table_size; + remaining -= table_size; + + /* Map everything beyond the end of the MSI-X table */ + if (remaining > 0) { + len = remaining; + error = vm_map_pptdev_mmio(ctx, sc->pptfd, start, len, base); + if (error) + return (error); + } + + return (0); +} + +static int +cfginitbar(struct vmctx *ctx, struct passthru_softc *sc) +{ + struct pci_devinst *pi = sc->psc_pi; + uint_t i; + + /* + * Initialize BAR registers + */ + for (i = 0; i <= PCI_BARMAX; i++) { + enum pcibar_type bartype; + uint64_t base, size; + int error; + + if (passthru_get_bar(sc, i, &bartype, &base, &size) != 0) { + continue; + } + + if (bartype != PCIBAR_IO) { + if (((base | size) & PAGE_MASK) != 0) { + warnx("passthru device %d BAR %d: " + "base %#lx or size %#lx not page aligned\n", + sc->pptfd, i, base, size); + return (-1); + } + } + + /* Cache information about the "real" BAR */ + sc->psc_bar[i].type = bartype; + sc->psc_bar[i].size = size; + sc->psc_bar[i].addr = base; + + /* Allocate the BAR in the guest I/O or MMIO space */ + error = pci_emul_alloc_pbar(pi, i, base, bartype, size); + if (error) + return (-1); + + /* The MSI-X table needs special handling */ + if (i == pci_msix_table_bar(pi)) { + error = init_msix_table(ctx, sc, base); + if (error) + return (-1); + } else if (bartype != PCIBAR_IO) { + /* Map the physical BAR in the guest MMIO space */ + error = vm_map_pptdev_mmio(ctx, sc->pptfd, + pi->pi_bar[i].addr, pi->pi_bar[i].size, base); + if (error) + return (-1); + } + + /* + * 64-bit BAR takes up two slots so skip the next one. + */ + if (bartype == PCIBAR_MEM64) { + i++; + assert(i <= PCI_BARMAX); + sc->psc_bar[i].type = PCIBAR_MEMHI64; + } + } + return (0); +} + +static int +cfginit(struct vmctx *ctx, struct passthru_softc *sc) +{ + if (cfginitmsi(sc) != 0) { + warnx("failed to initialize MSI for PCI %d", sc->pptfd); + return (-1); + } + + if (cfginitbar(ctx, sc) != 0) { + warnx("failed to initialize BARs for PCI %d", sc->pptfd); + return (-1); + } + + return (0); +} + +static int +passthru_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + int error, memflags, pptfd; + struct passthru_softc *sc; + + sc = NULL; + error = 1; + + memflags = vm_get_memflags(ctx); + if (!(memflags & VM_MEM_F_WIRED)) { + warnx("passthru requires guest memory to be wired"); + goto done; + } + + if (opts == NULL || passthru_dev_open(opts, &pptfd) != 0) { + warnx("invalid passthru options"); + goto done; + } + + if (vm_assign_pptdev(ctx, pptfd) != 0) { + warnx("PCI device at %d is not using the ppt driver", pptfd); + goto done; + } + + sc = calloc(1, sizeof(struct passthru_softc)); + + pi->pi_arg = sc; + sc->psc_pi = pi; + sc->pptfd = pptfd; + + if ((error = vm_get_pptdev_limits(ctx, pptfd, &sc->msi_limit, + &sc->msix_limit)) != 0) + goto done; + + /* initialize config space */ + if ((error = cfginit(ctx, sc)) != 0) + goto done; + + error = 0; /* success */ +done: + if (error) { + free(sc); + vm_unassign_pptdev(ctx, pptfd); + } + return (error); +} + +static int +bar_access(int coff) +{ + if (coff >= PCIR_BAR(0) && coff < PCIR_BAR(PCI_BARMAX + 1)) + return (1); + else + return (0); +} + +static int +msicap_access(struct passthru_softc *sc, int coff) +{ + int caplen; + + if (sc->psc_msi.capoff == 0) + return (0); + + caplen = msi_caplen(sc->psc_msi.msgctrl); + + if (coff >= sc->psc_msi.capoff && coff < sc->psc_msi.capoff + caplen) + return (1); + else + return (0); +} + +static int +msixcap_access(struct passthru_softc *sc, int coff) +{ + if (sc->psc_msix.capoff == 0) + return (0); + + return (coff >= sc->psc_msix.capoff && + coff < sc->psc_msix.capoff + MSIX_CAPLEN); +} + +static int +passthru_cfgread(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int coff, int bytes, uint32_t *rv) +{ + struct passthru_softc *sc; + + sc = pi->pi_arg; + + /* + * PCI BARs and MSI capability is emulated. + */ + if (bar_access(coff) || msicap_access(sc, coff)) + return (-1); + + /* + * MSI-X is also emulated since a limit on interrupts may be imposed by + * the OS, altering the perceived register state. + */ + if (msixcap_access(sc, coff)) + return (-1); + +#ifdef LEGACY_SUPPORT + /* + * Emulate PCIR_CAP_PTR if this device does not support MSI capability + * natively. + */ + if (sc->psc_msi.emulated) { + if (coff >= PCIR_CAP_PTR && coff < PCIR_CAP_PTR + 4) + return (-1); + } +#endif + + /* Everything else just read from the device's config space */ + *rv = read_config(sc, coff, bytes); + + return (0); +} + +static int +passthru_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int coff, int bytes, uint32_t val) +{ + int error, msix_table_entries, i; + struct passthru_softc *sc; + + sc = pi->pi_arg; + + /* + * PCI BARs are emulated + */ + if (bar_access(coff)) + return (-1); + + /* + * MSI capability is emulated + */ + if (msicap_access(sc, coff)) { + msicap_cfgwrite(pi, sc->psc_msi.capoff, coff, bytes, val); + + error = vm_setup_pptdev_msi(ctx, vcpu, sc->pptfd, + pi->pi_msi.addr, pi->pi_msi.msg_data, pi->pi_msi.maxmsgnum); + if (error != 0) + err(1, "vm_setup_pptdev_msi"); + return (0); + } + + if (msixcap_access(sc, coff)) { + msixcap_cfgwrite(pi, sc->psc_msix.capoff, coff, bytes, val); + if (pi->pi_msix.enabled) { + msix_table_entries = pi->pi_msix.table_count; + for (i = 0; i < msix_table_entries; i++) { + error = vm_setup_pptdev_msix(ctx, vcpu, + sc->pptfd, i, + pi->pi_msix.table[i].addr, + pi->pi_msix.table[i].msg_data, + pi->pi_msix.table[i].vector_control); + + if (error) + err(1, "vm_setup_pptdev_msix"); + } + } + return (0); + } + +#ifdef LEGACY_SUPPORT + /* + * If this device does not support MSI natively then we cannot let + * the guest disable legacy interrupts from the device. It is the + * legacy interrupt that is triggering the virtual MSI to the guest. + */ + if (sc->psc_msi.emulated && pci_msi_enabled(pi)) { + if (coff == PCIR_COMMAND && bytes == 2) + val &= ~PCIM_CMD_INTxDIS; + } +#endif + + write_config(sc, coff, bytes, val); + + return (0); +} + +static void +passthru_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, + uint64_t offset, int size, uint64_t value) +{ + struct passthru_softc *sc = pi->pi_arg; + + if (baridx == pci_msix_table_bar(pi)) { + passthru_msix_table_write(ctx, vcpu, sc, offset, size, value); + } else { + struct ppt_bar_io pbi; + + assert(pi->pi_bar[baridx].type == PCIBAR_IO); + + pbi.pbi_bar = baridx; + pbi.pbi_width = size; + pbi.pbi_off = offset; + pbi.pbi_data = value; + (void) ioctl(sc->pptfd, PPT_BAR_WRITE, &pbi); + } +} + +static uint64_t +passthru_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, + uint64_t offset, int size) +{ + struct passthru_softc *sc = pi->pi_arg; + uint64_t val; + + if (baridx == pci_msix_table_bar(pi)) { + val = passthru_msix_table_read(sc, offset, size); + } else { + struct ppt_bar_io pbi; + + assert(pi->pi_bar[baridx].type == PCIBAR_IO); + + pbi.pbi_bar = baridx; + pbi.pbi_width = size; + pbi.pbi_off = offset; + if (ioctl(sc->pptfd, PPT_BAR_READ, &pbi) == 0) { + val = pbi.pbi_data; + } else { + val = 0; + } + } + + return (val); +} + +struct pci_devemu passthru = { + .pe_emu = "passthru", + .pe_init = passthru_init, + .pe_cfgwrite = passthru_cfgwrite, + .pe_cfgread = passthru_cfgread, + .pe_barwrite = passthru_write, + .pe_barread = passthru_read, +}; +PCI_EMUL_SET(passthru); diff --git a/usr/src/cmd/bhyve/pci_uart.c b/usr/src/cmd/bhyve/pci_uart.c new file mode 100644 index 0000000000..093d0cb361 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_uart.c @@ -0,0 +1,121 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> + +#include <stdio.h> + +#include "bhyverun.h" +#include "pci_emul.h" +#include "uart_emul.h" + +/* + * Pick a PCI vid/did of a chip with a single uart at + * BAR0, that most versions of FreeBSD can understand: + * Siig CyberSerial 1-port. + */ +#define COM_VENDOR 0x131f +#define COM_DEV 0x2000 + +static void +pci_uart_intr_assert(void *arg) +{ + struct pci_devinst *pi = arg; + + pci_lintr_assert(pi); +} + +static void +pci_uart_intr_deassert(void *arg) +{ + struct pci_devinst *pi = arg; + + pci_lintr_deassert(pi); +} + +static void +pci_uart_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value) +{ + + assert(baridx == 0); + assert(size == 1); + + uart_write(pi->pi_arg, offset, value); +} + +uint64_t +pci_uart_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size) +{ + uint8_t val; + + assert(baridx == 0); + assert(size == 1); + + val = uart_read(pi->pi_arg, offset); + return (val); +} + +static int +pci_uart_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + struct uart_softc *sc; + + pci_emul_alloc_bar(pi, 0, PCIBAR_IO, UART_IO_BAR_SIZE); + pci_lintr_request(pi); + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, COM_DEV); + pci_set_cfgdata16(pi, PCIR_VENDOR, COM_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_SIMPLECOMM); + + sc = uart_init(pci_uart_intr_assert, pci_uart_intr_deassert, pi); + pi->pi_arg = sc; + + if (uart_set_backend(sc, opts) != 0) { + fprintf(stderr, "Unable to initialize backend '%s' for " + "pci uart at %d:%d\n", opts, pi->pi_slot, pi->pi_func); + return (-1); + } + + return (0); +} + +struct pci_devemu pci_de_com = { + .pe_emu = "uart", + .pe_init = pci_uart_init, + .pe_barwrite = pci_uart_write, + .pe_barread = pci_uart_read +}; +PCI_EMUL_SET(pci_de_com); diff --git a/usr/src/cmd/bhyve/pci_virtio_block.c b/usr/src/cmd/bhyve/pci_virtio_block.c new file mode 100644 index 0000000000..b0c3b06187 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_virtio_block.c @@ -0,0 +1,485 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2014 Pluribus Networks Inc. + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/linker_set.h> +#include <sys/stat.h> +#include <sys/uio.h> +#include <sys/ioctl.h> +#include <sys/disk.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include <assert.h> +#include <pthread.h> +#include <md5.h> + +#include "bhyverun.h" +#include "pci_emul.h" +#include "virtio.h" +#include "block_if.h" + +#ifdef __FreeBSD__ +#define VTBLK_RINGSZ 64 +#else +/* Enlarge to match bigger BLOCKIF_IOV_MAX */ +#define VTBLK_RINGSZ 128 +#endif + +#define VTBLK_S_OK 0 +#define VTBLK_S_IOERR 1 +#define VTBLK_S_UNSUPP 2 + +#define VTBLK_BLK_ID_BYTES 20 + 1 + +/* Capability bits */ +#define VTBLK_F_SEG_MAX (1 << 2) /* Maximum request segments */ +#define VTBLK_F_BLK_SIZE (1 << 6) /* cfg block size valid */ +#define VTBLK_F_FLUSH (1 << 9) /* Cache flush support */ +#define VTBLK_F_TOPOLOGY (1 << 10) /* Optimal I/O alignment */ + +/* + * Host capabilities + */ +#define VTBLK_S_HOSTCAPS \ + ( VTBLK_F_SEG_MAX | \ + VTBLK_F_BLK_SIZE | \ + VTBLK_F_FLUSH | \ + VTBLK_F_TOPOLOGY | \ + VIRTIO_RING_F_INDIRECT_DESC ) /* indirect descriptors */ + +/* + * Config space "registers" + */ +struct vtblk_config { + uint64_t vbc_capacity; + uint32_t vbc_size_max; + uint32_t vbc_seg_max; + struct { + uint16_t cylinders; + uint8_t heads; + uint8_t sectors; + } vbc_geometry; + uint32_t vbc_blk_size; + struct { + uint8_t physical_block_exp; + uint8_t alignment_offset; + uint16_t min_io_size; + uint32_t opt_io_size; + } vbc_topology; + uint8_t vbc_writeback; +} __packed; + +/* + * Fixed-size block header + */ +struct virtio_blk_hdr { +#define VBH_OP_READ 0 +#define VBH_OP_WRITE 1 +#define VBH_OP_FLUSH 4 +#define VBH_OP_FLUSH_OUT 5 +#define VBH_OP_IDENT 8 +#define VBH_FLAG_BARRIER 0x80000000 /* OR'ed into vbh_type */ + uint32_t vbh_type; + uint32_t vbh_ioprio; + uint64_t vbh_sector; +} __packed; + +/* + * Debug printf + */ +static int pci_vtblk_debug; +#define DPRINTF(params) if (pci_vtblk_debug) printf params +#define WPRINTF(params) printf params + +struct pci_vtblk_ioreq { + struct blockif_req io_req; + struct pci_vtblk_softc *io_sc; + uint8_t *io_status; + uint16_t io_idx; +}; + +/* + * Per-device softc + */ +struct pci_vtblk_softc { + struct virtio_softc vbsc_vs; + pthread_mutex_t vsc_mtx; + struct vqueue_info vbsc_vq; + struct vtblk_config vbsc_cfg; + struct blockif_ctxt *bc; +#ifndef __FreeBSD__ + int vbsc_wce; +#endif + char vbsc_ident[VTBLK_BLK_ID_BYTES]; + struct pci_vtblk_ioreq vbsc_ios[VTBLK_RINGSZ]; +}; + +static void pci_vtblk_reset(void *); +static void pci_vtblk_notify(void *, struct vqueue_info *); +static int pci_vtblk_cfgread(void *, int, int, uint32_t *); +static int pci_vtblk_cfgwrite(void *, int, int, uint32_t); +#ifndef __FreeBSD__ +static void pci_vtblk_apply_feats(void *, uint64_t); +#endif + +static struct virtio_consts vtblk_vi_consts = { + "vtblk", /* our name */ + 1, /* we support 1 virtqueue */ + sizeof(struct vtblk_config), /* config reg size */ + pci_vtblk_reset, /* reset */ + pci_vtblk_notify, /* device-wide qnotify */ + pci_vtblk_cfgread, /* read PCI config */ + pci_vtblk_cfgwrite, /* write PCI config */ +#ifndef __FreeBSD__ + pci_vtblk_apply_feats, /* apply negotiated features */ +#else + NULL, /* apply negotiated features */ +#endif + VTBLK_S_HOSTCAPS, /* our capabilities */ +}; + +static void +pci_vtblk_reset(void *vsc) +{ + struct pci_vtblk_softc *sc = vsc; + + DPRINTF(("vtblk: device reset requested !\n")); + vi_reset_dev(&sc->vbsc_vs); +#ifndef __FreeBSD__ + /* Disable write cache until FLUSH feature is negotiated */ + (void) blockif_set_wce(sc->bc, 0); + sc->vbsc_wce = 0; +#endif +} + +static void +pci_vtblk_done_locked(struct pci_vtblk_ioreq *io, int err) +{ + struct pci_vtblk_softc *sc = io->io_sc; + + /* convert errno into a virtio block error return */ + if (err == EOPNOTSUPP || err == ENOSYS) + *io->io_status = VTBLK_S_UNSUPP; + else if (err != 0) + *io->io_status = VTBLK_S_IOERR; + else + *io->io_status = VTBLK_S_OK; + + /* + * Return the descriptor back to the host. + * We wrote 1 byte (our status) to host. + */ + vq_relchain(&sc->vbsc_vq, io->io_idx, 1); + vq_endchains(&sc->vbsc_vq, 0); +} + +static void +pci_vtblk_done(struct blockif_req *br, int err) +{ + struct pci_vtblk_ioreq *io = br->br_param; + struct pci_vtblk_softc *sc = io->io_sc; + + pthread_mutex_lock(&sc->vsc_mtx); + pci_vtblk_done_locked(io, err); + pthread_mutex_unlock(&sc->vsc_mtx); +} + +static void +pci_vtblk_proc(struct pci_vtblk_softc *sc, struct vqueue_info *vq) +{ + struct virtio_blk_hdr *vbh; + struct pci_vtblk_ioreq *io; + int i, n; + int err; + ssize_t iolen; + int writeop, type; + struct iovec iov[BLOCKIF_IOV_MAX + 2]; + uint16_t idx, flags[BLOCKIF_IOV_MAX + 2]; + + n = vq_getchain(vq, &idx, iov, BLOCKIF_IOV_MAX + 2, flags); + + /* + * The first descriptor will be the read-only fixed header, + * and the last is for status (hence +2 above and below). + * The remaining iov's are the actual data I/O vectors. + * + * XXX - note - this fails on crash dump, which does a + * VIRTIO_BLK_T_FLUSH with a zero transfer length + */ + assert(n >= 2 && n <= BLOCKIF_IOV_MAX + 2); + + io = &sc->vbsc_ios[idx]; + assert((flags[0] & VRING_DESC_F_WRITE) == 0); + assert(iov[0].iov_len == sizeof(struct virtio_blk_hdr)); + vbh = (struct virtio_blk_hdr *)iov[0].iov_base; + memcpy(&io->io_req.br_iov, &iov[1], sizeof(struct iovec) * (n - 2)); + io->io_req.br_iovcnt = n - 2; + io->io_req.br_offset = vbh->vbh_sector * DEV_BSIZE; + io->io_status = (uint8_t *)iov[--n].iov_base; + assert(iov[n].iov_len == 1); + assert(flags[n] & VRING_DESC_F_WRITE); + + /* + * XXX + * The guest should not be setting the BARRIER flag because + * we don't advertise the capability. + */ + type = vbh->vbh_type & ~VBH_FLAG_BARRIER; + writeop = (type == VBH_OP_WRITE); + + iolen = 0; + for (i = 1; i < n; i++) { + /* + * - write op implies read-only descriptor, + * - read/ident op implies write-only descriptor, + * therefore test the inverse of the descriptor bit + * to the op. + */ + assert(((flags[i] & VRING_DESC_F_WRITE) == 0) == writeop); + iolen += iov[i].iov_len; + } + io->io_req.br_resid = iolen; + + DPRINTF(("virtio-block: %s op, %zd bytes, %d segs, offset %ld\n\r", + writeop ? "write" : "read/ident", iolen, i - 1, + io->io_req.br_offset)); + + switch (type) { + case VBH_OP_READ: + err = blockif_read(sc->bc, &io->io_req); + break; + case VBH_OP_WRITE: + err = blockif_write(sc->bc, &io->io_req); + break; + case VBH_OP_FLUSH: + case VBH_OP_FLUSH_OUT: + err = blockif_flush(sc->bc, &io->io_req); + break; + case VBH_OP_IDENT: + /* Assume a single buffer */ + /* S/n equal to buffer is not zero-terminated. */ + memset(iov[1].iov_base, 0, iov[1].iov_len); + strncpy(iov[1].iov_base, sc->vbsc_ident, + MIN(iov[1].iov_len, sizeof(sc->vbsc_ident))); + pci_vtblk_done_locked(io, 0); + return; + default: + pci_vtblk_done_locked(io, EOPNOTSUPP); + return; + } + assert(err == 0); +} + +static void +pci_vtblk_notify(void *vsc, struct vqueue_info *vq) +{ + struct pci_vtblk_softc *sc = vsc; + + while (vq_has_descs(vq)) + pci_vtblk_proc(sc, vq); +} + +static int +pci_vtblk_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + char bident[sizeof("XX:X:X")]; + struct blockif_ctxt *bctxt; + MD5_CTX mdctx; + u_char digest[16]; + struct pci_vtblk_softc *sc; + off_t size; + int i, sectsz, sts, sto; + + if (opts == NULL) { + printf("virtio-block: backing device required\n"); + return (1); + } + + /* + * The supplied backing file has to exist + */ + snprintf(bident, sizeof(bident), "%d:%d", pi->pi_slot, pi->pi_func); + bctxt = blockif_open(opts, bident); + if (bctxt == NULL) { + perror("Could not open backing file"); + return (1); + } + + size = blockif_size(bctxt); + sectsz = blockif_sectsz(bctxt); + blockif_psectsz(bctxt, &sts, &sto); + + sc = calloc(1, sizeof(struct pci_vtblk_softc)); + sc->bc = bctxt; + for (i = 0; i < VTBLK_RINGSZ; i++) { + struct pci_vtblk_ioreq *io = &sc->vbsc_ios[i]; + io->io_req.br_callback = pci_vtblk_done; + io->io_req.br_param = io; + io->io_sc = sc; + io->io_idx = i; + } + +#ifndef __FreeBSD__ + /* Disable write cache until FLUSH feature is negotiated */ + (void) blockif_set_wce(sc->bc, 0); + sc->vbsc_wce = 0; +#endif + + pthread_mutex_init(&sc->vsc_mtx, NULL); + + /* init virtio softc and virtqueues */ + vi_softc_linkup(&sc->vbsc_vs, &vtblk_vi_consts, sc, pi, &sc->vbsc_vq); + sc->vbsc_vs.vs_mtx = &sc->vsc_mtx; + + sc->vbsc_vq.vq_qsize = VTBLK_RINGSZ; + /* sc->vbsc_vq.vq_notify = we have no per-queue notify */ + + /* + * Create an identifier for the backing file. Use parts of the + * md5 sum of the filename + */ + MD5Init(&mdctx); + MD5Update(&mdctx, opts, strlen(opts)); + MD5Final(digest, &mdctx); + snprintf(sc->vbsc_ident, VTBLK_BLK_ID_BYTES, + "BHYVE-%02X%02X-%02X%02X-%02X%02X", + digest[0], digest[1], digest[2], digest[3], digest[4], digest[5]); + + /* setup virtio block config space */ + sc->vbsc_cfg.vbc_capacity = size / DEV_BSIZE; /* 512-byte units */ + sc->vbsc_cfg.vbc_size_max = 0; /* not negotiated */ +#ifdef __FreeBSD__ + sc->vbsc_cfg.vbc_seg_max = BLOCKIF_IOV_MAX; +#else + /* + * If Linux is presented with a seg_max greater than the virtio queue + * size, it can stumble into situations where it violates its own + * invariants and panics. For safety, we keep seg_max clamped, paying + * heed to the two extra descriptors needed for the header and status + * of a request. + */ + sc->vbsc_cfg.vbc_seg_max = MIN(VTBLK_RINGSZ - 2, BLOCKIF_IOV_MAX); +#endif + sc->vbsc_cfg.vbc_geometry.cylinders = 0; /* no geometry */ + sc->vbsc_cfg.vbc_geometry.heads = 0; + sc->vbsc_cfg.vbc_geometry.sectors = 0; + sc->vbsc_cfg.vbc_blk_size = sectsz; + sc->vbsc_cfg.vbc_topology.physical_block_exp = + (sts > sectsz) ? (ffsll(sts / sectsz) - 1) : 0; + sc->vbsc_cfg.vbc_topology.alignment_offset = + (sto != 0) ? ((sts - sto) / sectsz) : 0; + sc->vbsc_cfg.vbc_topology.min_io_size = 0; + sc->vbsc_cfg.vbc_topology.opt_io_size = 0; + sc->vbsc_cfg.vbc_writeback = 0; + + /* + * Should we move some of this into virtio.c? Could + * have the device, class, and subdev_0 as fields in + * the virtio constants structure. + */ + pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_BLOCK); + pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_BLOCK); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); + + if (vi_intr_init(&sc->vbsc_vs, 1, fbsdrun_virtio_msix())) { + blockif_close(sc->bc); + free(sc); + return (1); + } + vi_set_io_bar(&sc->vbsc_vs, 0); + return (0); +} + +static int +pci_vtblk_cfgwrite(void *vsc, int offset, int size, uint32_t value) +{ + + DPRINTF(("vtblk: write to readonly reg %d\n\r", offset)); + return (1); +} + +static int +pci_vtblk_cfgread(void *vsc, int offset, int size, uint32_t *retval) +{ + struct pci_vtblk_softc *sc = vsc; + void *ptr; + + /* our caller has already verified offset and size */ + ptr = (uint8_t *)&sc->vbsc_cfg + offset; + memcpy(retval, ptr, size); + return (0); +} + +#ifndef __FreeBSD__ +void +pci_vtblk_apply_feats(void *vsc, uint64_t caps) +{ + struct pci_vtblk_softc *sc = vsc; + const int wce_next = ((caps & VTBLK_F_FLUSH) != 0) ? 1 : 0; + + if (sc->vbsc_wce != wce_next) { + (void) blockif_set_wce(sc->bc, wce_next); + sc->vbsc_wce = wce_next; + } +} +#endif /* __FreeBSD__ */ + +struct pci_devemu pci_de_vblk = { + .pe_emu = "virtio-blk", + .pe_init = pci_vtblk_init, + .pe_barwrite = vi_pci_write, + .pe_barread = vi_pci_read +}; +PCI_EMUL_SET(pci_de_vblk); diff --git a/usr/src/cmd/bhyve/pci_virtio_console.c b/usr/src/cmd/bhyve/pci_virtio_console.c new file mode 100644 index 0000000000..90437662df --- /dev/null +++ b/usr/src/cmd/bhyve/pci_virtio_console.c @@ -0,0 +1,701 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2016 iXsystems Inc. + * All rights reserved. + * + * This software was developed by Jakub Klama <jceel@FreeBSD.org> + * under sponsorship from iXsystems Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/linker_set.h> +#include <sys/uio.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> + +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <unistd.h> +#include <assert.h> +#include <pthread.h> +#include <libgen.h> +#include <sysexits.h> + +#include "bhyverun.h" +#include "pci_emul.h" +#include "virtio.h" +#include "mevent.h" +#include "sockstream.h" + +#define VTCON_RINGSZ 64 +#define VTCON_MAXPORTS 16 +#define VTCON_MAXQ (VTCON_MAXPORTS * 2 + 2) + +#define VTCON_DEVICE_READY 0 +#define VTCON_DEVICE_ADD 1 +#define VTCON_DEVICE_REMOVE 2 +#define VTCON_PORT_READY 3 +#define VTCON_CONSOLE_PORT 4 +#define VTCON_CONSOLE_RESIZE 5 +#define VTCON_PORT_OPEN 6 +#define VTCON_PORT_NAME 7 + +#define VTCON_F_SIZE 0 +#define VTCON_F_MULTIPORT 1 +#define VTCON_F_EMERG_WRITE 2 +#define VTCON_S_HOSTCAPS \ + (VTCON_F_SIZE | VTCON_F_MULTIPORT | VTCON_F_EMERG_WRITE) + +static int pci_vtcon_debug; +#define DPRINTF(params) if (pci_vtcon_debug) printf params +#define WPRINTF(params) printf params + +struct pci_vtcon_softc; +struct pci_vtcon_port; +struct pci_vtcon_config; +typedef void (pci_vtcon_cb_t)(struct pci_vtcon_port *, void *, struct iovec *, + int); + +struct pci_vtcon_port { + struct pci_vtcon_softc * vsp_sc; + int vsp_id; + const char * vsp_name; + bool vsp_enabled; + bool vsp_console; + bool vsp_rx_ready; + bool vsp_open; + int vsp_rxq; + int vsp_txq; + void * vsp_arg; + pci_vtcon_cb_t * vsp_cb; +}; + +struct pci_vtcon_sock +{ + struct pci_vtcon_port * vss_port; + const char * vss_path; + struct mevent * vss_server_evp; + struct mevent * vss_conn_evp; + int vss_server_fd; + int vss_conn_fd; + bool vss_open; +}; + +struct pci_vtcon_softc { + struct virtio_softc vsc_vs; + struct vqueue_info vsc_queues[VTCON_MAXQ]; + pthread_mutex_t vsc_mtx; + uint64_t vsc_cfg; + uint64_t vsc_features; + char * vsc_rootdir; + int vsc_kq; + int vsc_nports; + bool vsc_ready; + struct pci_vtcon_port vsc_control_port; + struct pci_vtcon_port vsc_ports[VTCON_MAXPORTS]; + struct pci_vtcon_config *vsc_config; +}; + +struct pci_vtcon_config { + uint16_t cols; + uint16_t rows; + uint32_t max_nr_ports; + uint32_t emerg_wr; +} __attribute__((packed)); + +struct pci_vtcon_control { + uint32_t id; + uint16_t event; + uint16_t value; +} __attribute__((packed)); + +struct pci_vtcon_console_resize { + uint16_t cols; + uint16_t rows; +} __attribute__((packed)); + +static void pci_vtcon_reset(void *); +static void pci_vtcon_notify_rx(void *, struct vqueue_info *); +static void pci_vtcon_notify_tx(void *, struct vqueue_info *); +static int pci_vtcon_cfgread(void *, int, int, uint32_t *); +static int pci_vtcon_cfgwrite(void *, int, int, uint32_t); +static void pci_vtcon_neg_features(void *, uint64_t); +static void pci_vtcon_sock_accept(int, enum ev_type, void *); +static void pci_vtcon_sock_rx(int, enum ev_type, void *); +static void pci_vtcon_sock_tx(struct pci_vtcon_port *, void *, struct iovec *, + int); +static void pci_vtcon_control_send(struct pci_vtcon_softc *, + struct pci_vtcon_control *, const void *, size_t); +static void pci_vtcon_announce_port(struct pci_vtcon_port *); +static void pci_vtcon_open_port(struct pci_vtcon_port *, bool); + +static struct virtio_consts vtcon_vi_consts = { + "vtcon", /* our name */ + VTCON_MAXQ, /* we support VTCON_MAXQ virtqueues */ + sizeof(struct pci_vtcon_config), /* config reg size */ + pci_vtcon_reset, /* reset */ + NULL, /* device-wide qnotify */ + pci_vtcon_cfgread, /* read virtio config */ + pci_vtcon_cfgwrite, /* write virtio config */ + pci_vtcon_neg_features, /* apply negotiated features */ + VTCON_S_HOSTCAPS, /* our capabilities */ +}; + + +static void +pci_vtcon_reset(void *vsc) +{ + struct pci_vtcon_softc *sc; + + sc = vsc; + + DPRINTF(("vtcon: device reset requested!\n")); + vi_reset_dev(&sc->vsc_vs); +} + +static void +pci_vtcon_neg_features(void *vsc, uint64_t negotiated_features) +{ + struct pci_vtcon_softc *sc = vsc; + + sc->vsc_features = negotiated_features; +} + +static int +pci_vtcon_cfgread(void *vsc, int offset, int size, uint32_t *retval) +{ + struct pci_vtcon_softc *sc = vsc; + void *ptr; + + ptr = (uint8_t *)sc->vsc_config + offset; + memcpy(retval, ptr, size); + return (0); +} + +static int +pci_vtcon_cfgwrite(void *vsc, int offset, int size, uint32_t val) +{ + + return (0); +} + +static inline struct pci_vtcon_port * +pci_vtcon_vq_to_port(struct pci_vtcon_softc *sc, struct vqueue_info *vq) +{ + uint16_t num = vq->vq_num; + + if (num == 0 || num == 1) + return (&sc->vsc_ports[0]); + + if (num == 2 || num == 3) + return (&sc->vsc_control_port); + + return (&sc->vsc_ports[(num / 2) - 1]); +} + +static inline struct vqueue_info * +pci_vtcon_port_to_vq(struct pci_vtcon_port *port, bool tx_queue) +{ + int qnum; + + qnum = tx_queue ? port->vsp_txq : port->vsp_rxq; + return (&port->vsp_sc->vsc_queues[qnum]); +} + +static struct pci_vtcon_port * +pci_vtcon_port_add(struct pci_vtcon_softc *sc, const char *name, + pci_vtcon_cb_t *cb, void *arg) +{ + struct pci_vtcon_port *port; + + if (sc->vsc_nports == VTCON_MAXPORTS) { + errno = EBUSY; + return (NULL); + } + + port = &sc->vsc_ports[sc->vsc_nports++]; + port->vsp_id = sc->vsc_nports - 1; + port->vsp_sc = sc; + port->vsp_name = name; + port->vsp_cb = cb; + port->vsp_arg = arg; + + if (port->vsp_id == 0) { + /* port0 */ + port->vsp_txq = 0; + port->vsp_rxq = 1; + } else { + port->vsp_txq = sc->vsc_nports * 2; + port->vsp_rxq = port->vsp_txq + 1; + } + + port->vsp_enabled = true; + return (port); +} + +static int +pci_vtcon_sock_add(struct pci_vtcon_softc *sc, const char *name, + const char *path) +{ + struct pci_vtcon_sock *sock; +#ifdef __FreeBSD__ + struct sockaddr_un sun; + char *pathcopy; +#else + /* Our compiler #defines 'sun' as '1'. Awesome. */ + struct sockaddr_un addr; +#endif + int s = -1, fd = -1, error = 0; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; +#endif + + sock = calloc(1, sizeof(struct pci_vtcon_sock)); + if (sock == NULL) { + error = -1; + goto out; + } + + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s < 0) { + error = -1; + goto out; + } + +#ifdef __FreeBSD__ + pathcopy = strdup(path); + if (pathcopy == NULL) { + error = -1; + goto out; + } + + fd = open(dirname(pathcopy), O_RDONLY | O_DIRECTORY); + if (fd < 0) { + free(pathcopy); + error = -1; + goto out; + } + + sun.sun_family = AF_UNIX; + sun.sun_len = sizeof(struct sockaddr_un); + strcpy(pathcopy, path); + strlcpy(sun.sun_path, basename(pathcopy), sizeof(sun.sun_path)); + free(pathcopy); + + if (bindat(fd, s, (struct sockaddr *)&sun, sun.sun_len) < 0) { + error = -1; + goto out; + } +#else /* __FreeBSD__ */ + /* Do a simple bind rather than the FreeBSD bindat() */ + addr.sun_family = AF_UNIX; + (void) strlcpy(addr.sun_path, path, sizeof (addr.sun_path)); + if (bind(fd, (struct sockaddr *)&addr, sizeof (addr)) < 0) { + error = -1; + goto out; + } +#endif /* __FreeBSD__ */ + + if (fcntl(s, F_SETFL, O_NONBLOCK) < 0) { + error = -1; + goto out; + } + + if (listen(s, 1) < 0) { + error = -1; + goto out; + } + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE); + if (caph_rights_limit(s, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + sock->vss_port = pci_vtcon_port_add(sc, name, pci_vtcon_sock_tx, sock); + if (sock->vss_port == NULL) { + error = -1; + goto out; + } + + sock->vss_open = false; + sock->vss_conn_fd = -1; + sock->vss_server_fd = s; + sock->vss_server_evp = mevent_add(s, EVF_READ, pci_vtcon_sock_accept, + sock); + + if (sock->vss_server_evp == NULL) { + error = -1; + goto out; + } + +out: + if (fd != -1) + close(fd); + + if (error != 0 && s != -1) + close(s); + + return (error); +} + +static void +pci_vtcon_sock_accept(int fd __unused, enum ev_type t __unused, void *arg) +{ + struct pci_vtcon_sock *sock = (struct pci_vtcon_sock *)arg; + int s; + + s = accept(sock->vss_server_fd, NULL, NULL); + if (s < 0) + return; + + if (sock->vss_open) { + close(s); + return; + } + + sock->vss_open = true; + sock->vss_conn_fd = s; + sock->vss_conn_evp = mevent_add(s, EVF_READ, pci_vtcon_sock_rx, sock); + + pci_vtcon_open_port(sock->vss_port, true); +} + +static void +pci_vtcon_sock_rx(int fd __unused, enum ev_type t __unused, void *arg) +{ + struct pci_vtcon_port *port; + struct pci_vtcon_sock *sock = (struct pci_vtcon_sock *)arg; + struct vqueue_info *vq; + struct iovec iov; + static char dummybuf[2048]; + int len, n; + uint16_t idx; + + port = sock->vss_port; + vq = pci_vtcon_port_to_vq(port, true); + + if (!sock->vss_open || !port->vsp_rx_ready) { + len = read(sock->vss_conn_fd, dummybuf, sizeof(dummybuf)); + if (len == 0) + goto close; + + return; + } + + if (!vq_has_descs(vq)) { + len = read(sock->vss_conn_fd, dummybuf, sizeof(dummybuf)); + vq_endchains(vq, 1); + if (len == 0) + goto close; + + return; + } + + do { + n = vq_getchain(vq, &idx, &iov, 1, NULL); + len = readv(sock->vss_conn_fd, &iov, n); + + if (len == 0 || (len < 0 && errno == EWOULDBLOCK)) { + vq_retchain(vq); + vq_endchains(vq, 0); + if (len == 0) + goto close; + + return; + } + + vq_relchain(vq, idx, len); + } while (vq_has_descs(vq)); + + vq_endchains(vq, 1); + +close: + mevent_delete_close(sock->vss_conn_evp); + sock->vss_conn_fd = -1; + sock->vss_open = false; +} + +static void +pci_vtcon_sock_tx(struct pci_vtcon_port *port, void *arg, struct iovec *iov, + int niov) +{ + struct pci_vtcon_sock *sock; +#ifdef __FreeBSD__ + int i, ret; +#else + int i, ret = 0; +#endif + + sock = (struct pci_vtcon_sock *)arg; + + if (sock->vss_conn_fd == -1) + return; + + for (i = 0; i < niov; i++) { + ret = stream_write(sock->vss_conn_fd, iov[i].iov_base, + iov[i].iov_len); + if (ret <= 0) + break; + } + + if (ret <= 0) { + mevent_delete_close(sock->vss_conn_evp); + sock->vss_conn_fd = -1; + sock->vss_open = false; + } +} + +static void +pci_vtcon_control_tx(struct pci_vtcon_port *port, void *arg, struct iovec *iov, + int niov) +{ + struct pci_vtcon_softc *sc; + struct pci_vtcon_port *tmp; + struct pci_vtcon_control resp, *ctrl; + int i; + + assert(niov == 1); + + sc = port->vsp_sc; + ctrl = (struct pci_vtcon_control *)iov->iov_base; + + switch (ctrl->event) { + case VTCON_DEVICE_READY: + sc->vsc_ready = true; + /* set port ready events for registered ports */ + for (i = 0; i < VTCON_MAXPORTS; i++) { + tmp = &sc->vsc_ports[i]; + if (tmp->vsp_enabled) + pci_vtcon_announce_port(tmp); + + if (tmp->vsp_open) + pci_vtcon_open_port(tmp, true); + } + break; + + case VTCON_PORT_READY: + if (ctrl->id >= sc->vsc_nports) { + WPRINTF(("VTCON_PORT_READY event for unknown port %d\n", + ctrl->id)); + return; + } + + tmp = &sc->vsc_ports[ctrl->id]; + if (tmp->vsp_console) { + resp.event = VTCON_CONSOLE_PORT; + resp.id = ctrl->id; + resp.value = 1; + pci_vtcon_control_send(sc, &resp, NULL, 0); + } + break; + } +} + +static void +pci_vtcon_announce_port(struct pci_vtcon_port *port) +{ + struct pci_vtcon_control event; + + event.id = port->vsp_id; + event.event = VTCON_DEVICE_ADD; + event.value = 1; + pci_vtcon_control_send(port->vsp_sc, &event, NULL, 0); + + event.event = VTCON_PORT_NAME; + pci_vtcon_control_send(port->vsp_sc, &event, port->vsp_name, + strlen(port->vsp_name)); +} + +static void +pci_vtcon_open_port(struct pci_vtcon_port *port, bool open) +{ + struct pci_vtcon_control event; + + if (!port->vsp_sc->vsc_ready) { + port->vsp_open = true; + return; + } + + event.id = port->vsp_id; + event.event = VTCON_PORT_OPEN; + event.value = (int)open; + pci_vtcon_control_send(port->vsp_sc, &event, NULL, 0); +} + +static void +pci_vtcon_control_send(struct pci_vtcon_softc *sc, + struct pci_vtcon_control *ctrl, const void *payload, size_t len) +{ + struct vqueue_info *vq; + struct iovec iov; + uint16_t idx; + int n; + + vq = pci_vtcon_port_to_vq(&sc->vsc_control_port, true); + + if (!vq_has_descs(vq)) + return; + + n = vq_getchain(vq, &idx, &iov, 1, NULL); + + assert(n == 1); + + memcpy(iov.iov_base, ctrl, sizeof(struct pci_vtcon_control)); + if (payload != NULL && len > 0) + memcpy(iov.iov_base + sizeof(struct pci_vtcon_control), + payload, len); + + vq_relchain(vq, idx, sizeof(struct pci_vtcon_control) + len); + vq_endchains(vq, 1); +} + + +static void +pci_vtcon_notify_tx(void *vsc, struct vqueue_info *vq) +{ + struct pci_vtcon_softc *sc; + struct pci_vtcon_port *port; + struct iovec iov[1]; + uint16_t idx, n; + uint16_t flags[8]; + + sc = vsc; + port = pci_vtcon_vq_to_port(sc, vq); + + while (vq_has_descs(vq)) { + n = vq_getchain(vq, &idx, iov, 1, flags); + assert(n >= 1); + if (port != NULL) + port->vsp_cb(port, port->vsp_arg, iov, 1); + + /* + * Release this chain and handle more + */ + vq_relchain(vq, idx, 0); + } + vq_endchains(vq, 1); /* Generate interrupt if appropriate. */ +} + +static void +pci_vtcon_notify_rx(void *vsc, struct vqueue_info *vq) +{ + struct pci_vtcon_softc *sc; + struct pci_vtcon_port *port; + + sc = vsc; + port = pci_vtcon_vq_to_port(sc, vq); + + if (!port->vsp_rx_ready) { + port->vsp_rx_ready = 1; + vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; + } +} + +static int +pci_vtcon_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + struct pci_vtcon_softc *sc; + char *portname = NULL; + char *portpath = NULL; + char *opt; + int i; + + sc = calloc(1, sizeof(struct pci_vtcon_softc)); + sc->vsc_config = calloc(1, sizeof(struct pci_vtcon_config)); + sc->vsc_config->max_nr_ports = VTCON_MAXPORTS; + sc->vsc_config->cols = 80; + sc->vsc_config->rows = 25; + + vi_softc_linkup(&sc->vsc_vs, &vtcon_vi_consts, sc, pi, sc->vsc_queues); + sc->vsc_vs.vs_mtx = &sc->vsc_mtx; + + for (i = 0; i < VTCON_MAXQ; i++) { + sc->vsc_queues[i].vq_qsize = VTCON_RINGSZ; + sc->vsc_queues[i].vq_notify = i % 2 == 0 + ? pci_vtcon_notify_rx + : pci_vtcon_notify_tx; + } + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_CONSOLE); + pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_SIMPLECOMM); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_CONSOLE); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); + + if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix())) + return (1); + vi_set_io_bar(&sc->vsc_vs, 0); + + /* create control port */ + sc->vsc_control_port.vsp_sc = sc; + sc->vsc_control_port.vsp_txq = 2; + sc->vsc_control_port.vsp_rxq = 3; + sc->vsc_control_port.vsp_cb = pci_vtcon_control_tx; + sc->vsc_control_port.vsp_enabled = true; + + while ((opt = strsep(&opts, ",")) != NULL) { + portname = strsep(&opt, "="); + portpath = opt; + + /* create port */ + if (pci_vtcon_sock_add(sc, portname, portpath) < 0) { + fprintf(stderr, "cannot create port %s: %s\n", + portname, strerror(errno)); + return (1); + } + } + + return (0); +} + +struct pci_devemu pci_de_vcon = { + .pe_emu = "virtio-console", + .pe_init = pci_vtcon_init, + .pe_barwrite = vi_pci_write, + .pe_barread = vi_pci_read +}; +PCI_EMUL_SET(pci_de_vcon); diff --git a/usr/src/cmd/bhyve/pci_virtio_net.c b/usr/src/cmd/bhyve/pci_virtio_net.c new file mode 100644 index 0000000000..74efbcaee1 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_virtio_net.c @@ -0,0 +1,1169 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2013 Pluribus Networks Inc. + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/linker_set.h> +#include <sys/select.h> +#include <sys/uio.h> +#include <sys/ioctl.h> +#include <machine/atomic.h> +#include <net/ethernet.h> +#ifdef __FreeBSD__ +#ifndef NETMAP_WITH_LIBS +#define NETMAP_WITH_LIBS +#endif +#include <net/netmap_user.h> +#endif + +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include <assert.h> +#include <md5.h> +#include <pthread.h> +#include <pthread_np.h> +#include <sysexits.h> +#ifndef __FreeBSD__ +#include <poll.h> +#include <libdlpi.h> +#endif + +#include "bhyverun.h" +#include "pci_emul.h" +#ifdef __FreeBSD__ +#include "mevent.h" +#endif +#include "virtio.h" + +#define VTNET_RINGSZ 1024 + +#define VTNET_MAXSEGS 256 + +/* + * Host capabilities. Note that we only offer a few of these. + */ +#define VIRTIO_NET_F_CSUM (1 << 0) /* host handles partial cksum */ +#define VIRTIO_NET_F_GUEST_CSUM (1 << 1) /* guest handles partial cksum */ +#define VIRTIO_NET_F_MAC (1 << 5) /* host supplies MAC */ +#define VIRTIO_NET_F_GSO_DEPREC (1 << 6) /* deprecated: host handles GSO */ +#define VIRTIO_NET_F_GUEST_TSO4 (1 << 7) /* guest can rcv TSOv4 */ +#define VIRTIO_NET_F_GUEST_TSO6 (1 << 8) /* guest can rcv TSOv6 */ +#define VIRTIO_NET_F_GUEST_ECN (1 << 9) /* guest can rcv TSO with ECN */ +#define VIRTIO_NET_F_GUEST_UFO (1 << 10) /* guest can rcv UFO */ +#define VIRTIO_NET_F_HOST_TSO4 (1 << 11) /* host can rcv TSOv4 */ +#define VIRTIO_NET_F_HOST_TSO6 (1 << 12) /* host can rcv TSOv6 */ +#define VIRTIO_NET_F_HOST_ECN (1 << 13) /* host can rcv TSO with ECN */ +#define VIRTIO_NET_F_HOST_UFO (1 << 14) /* host can rcv UFO */ +#define VIRTIO_NET_F_MRG_RXBUF (1 << 15) /* host can merge RX buffers */ +#define VIRTIO_NET_F_STATUS (1 << 16) /* config status field available */ +#define VIRTIO_NET_F_CTRL_VQ (1 << 17) /* control channel available */ +#define VIRTIO_NET_F_CTRL_RX (1 << 18) /* control channel RX mode support */ +#define VIRTIO_NET_F_CTRL_VLAN (1 << 19) /* control channel VLAN filtering */ +#define VIRTIO_NET_F_GUEST_ANNOUNCE \ + (1 << 21) /* guest can send gratuitous pkts */ + +#define VTNET_S_HOSTCAPS \ + ( VIRTIO_NET_F_MAC | VIRTIO_NET_F_MRG_RXBUF | VIRTIO_NET_F_STATUS | \ + VIRTIO_F_NOTIFY_ON_EMPTY | VIRTIO_RING_F_INDIRECT_DESC) + +/* + * PCI config-space "registers" + */ +struct virtio_net_config { + uint8_t mac[6]; + uint16_t status; +} __packed; + +/* + * Queue definitions. + */ +#define VTNET_RXQ 0 +#define VTNET_TXQ 1 +#define VTNET_CTLQ 2 /* NB: not yet supported */ + +#define VTNET_MAXQ 3 + +/* + * Fixed network header size + */ +struct virtio_net_rxhdr { + uint8_t vrh_flags; + uint8_t vrh_gso_type; + uint16_t vrh_hdr_len; + uint16_t vrh_gso_size; + uint16_t vrh_csum_start; + uint16_t vrh_csum_offset; + uint16_t vrh_bufs; +} __packed; + +/* + * Debug printf + */ +static int pci_vtnet_debug; +#define DPRINTF(params) if (pci_vtnet_debug) printf params +#define WPRINTF(params) printf params + +/* + * Per-device softc + */ +struct pci_vtnet_softc { + struct virtio_softc vsc_vs; + struct vqueue_info vsc_queues[VTNET_MAXQ - 1]; + pthread_mutex_t vsc_mtx; + struct mevent *vsc_mevp; + +#ifdef __FreeBSD + int vsc_tapfd; +#else + dlpi_handle_t vsc_dhp; + int vsc_dlpifd; +#endif + struct nm_desc *vsc_nmd; + + int vsc_rx_ready; + volatile int resetting; /* set and checked outside lock */ + + uint64_t vsc_features; /* negotiated features */ + + struct virtio_net_config vsc_config; + + pthread_mutex_t rx_mtx; + int rx_in_progress; + int rx_vhdrlen; + int rx_merge; /* merged rx bufs in use */ + + pthread_t tx_tid; + pthread_mutex_t tx_mtx; + pthread_cond_t tx_cond; + int tx_in_progress; + + void (*pci_vtnet_rx)(struct pci_vtnet_softc *sc); + void (*pci_vtnet_tx)(struct pci_vtnet_softc *sc, struct iovec *iov, + int iovcnt, int len); +}; + +static void pci_vtnet_reset(void *); +/* static void pci_vtnet_notify(void *, struct vqueue_info *); */ +static int pci_vtnet_cfgread(void *, int, int, uint32_t *); +static int pci_vtnet_cfgwrite(void *, int, int, uint32_t); +static void pci_vtnet_neg_features(void *, uint64_t); + +static struct virtio_consts vtnet_vi_consts = { + "vtnet", /* our name */ + VTNET_MAXQ - 1, /* we currently support 2 virtqueues */ + sizeof(struct virtio_net_config), /* config reg size */ + pci_vtnet_reset, /* reset */ + NULL, /* device-wide qnotify -- not used */ + pci_vtnet_cfgread, /* read PCI config */ + pci_vtnet_cfgwrite, /* write PCI config */ + pci_vtnet_neg_features, /* apply negotiated features */ + VTNET_S_HOSTCAPS, /* our capabilities */ +}; + +/* + * If the transmit thread is active then stall until it is done. + */ +static void +pci_vtnet_txwait(struct pci_vtnet_softc *sc) +{ + + pthread_mutex_lock(&sc->tx_mtx); + while (sc->tx_in_progress) { + pthread_mutex_unlock(&sc->tx_mtx); + usleep(10000); + pthread_mutex_lock(&sc->tx_mtx); + } + pthread_mutex_unlock(&sc->tx_mtx); +} + +/* + * If the receive thread is active then stall until it is done. + */ +static void +pci_vtnet_rxwait(struct pci_vtnet_softc *sc) +{ + + pthread_mutex_lock(&sc->rx_mtx); + while (sc->rx_in_progress) { + pthread_mutex_unlock(&sc->rx_mtx); + usleep(10000); + pthread_mutex_lock(&sc->rx_mtx); + } + pthread_mutex_unlock(&sc->rx_mtx); +} + +static void +pci_vtnet_reset(void *vsc) +{ + struct pci_vtnet_softc *sc = vsc; + + DPRINTF(("vtnet: device reset requested !\n")); + + sc->resetting = 1; + + /* + * Wait for the transmit and receive threads to finish their + * processing. + */ + pci_vtnet_txwait(sc); + pci_vtnet_rxwait(sc); + + sc->vsc_rx_ready = 0; + sc->rx_merge = 1; + sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr); + + /* now reset rings, MSI-X vectors, and negotiated capabilities */ + vi_reset_dev(&sc->vsc_vs); + + sc->resetting = 0; +} + +/* + * Called to send a buffer chain out to the tap device + */ +#ifdef __FreeBSD__ +static void +pci_vtnet_tap_tx(struct pci_vtnet_softc *sc, struct iovec *iov, int iovcnt, + int len) +{ + static char pad[60]; /* all zero bytes */ + + if (sc->vsc_tapfd == -1) + return; + + /* + * If the length is < 60, pad out to that and add the + * extra zero'd segment to the iov. It is guaranteed that + * there is always an extra iov available by the caller. + */ + if (len < 60) { + iov[iovcnt].iov_base = pad; + iov[iovcnt].iov_len = 60 - len; + iovcnt++; + } + (void) writev(sc->vsc_tapfd, iov, iovcnt); +} +#else +static void +pci_vtnet_tap_tx(struct pci_vtnet_softc *sc, struct iovec *iov, int iovcnt, + int len) +{ + int i; + + for (i = 0; i < iovcnt; i++) { + (void) dlpi_send(sc->vsc_dhp, NULL, NULL, + iov[i].iov_base, iov[i].iov_len, NULL); + } +} +#endif /* __FreeBSD__ */ + +#ifdef __FreeBSD__ +/* + * Called when there is read activity on the tap file descriptor. + * Each buffer posted by the guest is assumed to be able to contain + * an entire ethernet frame + rx header. + * MP note: the dummybuf is only used for discarding frames, so there + * is no need for it to be per-vtnet or locked. + */ +static uint8_t dummybuf[2048]; +#endif /* __FreeBSD__ */ + +static __inline struct iovec * +rx_iov_trim(struct iovec *iov, int *niov, int tlen) +{ + struct iovec *riov; + + /* XXX short-cut: assume first segment is >= tlen */ + assert(iov[0].iov_len >= tlen); + + iov[0].iov_len -= tlen; + if (iov[0].iov_len == 0) { + assert(*niov > 1); + *niov -= 1; + riov = &iov[1]; + } else { + iov[0].iov_base = (void *)((uintptr_t)iov[0].iov_base + tlen); + riov = &iov[0]; + } + + return (riov); +} + +static void +pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) +{ + struct iovec iov[VTNET_MAXSEGS], *riov; + struct vqueue_info *vq; + void *vrx; + int n; +#ifdef __FreeBSD__ + int len; +#else + size_t len; + int ret; +#endif + uint16_t idx; + + /* + * Should never be called without a valid tap fd + */ +#ifdef __FreeBSD__ + assert(sc->vsc_tapfd != -1); +#else + assert(sc->vsc_dlpifd != -1); +#endif + + /* + * But, will be called when the rx ring hasn't yet + * been set up or the guest is resetting the device. + */ + if (!sc->vsc_rx_ready || sc->resetting) { +#ifdef __FreeBSD__ + /* + * Drop the packet and try later. + */ + (void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf)); +#endif + return; + } + + /* + * Check for available rx buffers + */ + vq = &sc->vsc_queues[VTNET_RXQ]; + if (!vq_has_descs(vq)) { + /* + * Drop the packet and try later. Interrupt on + * empty, if that's negotiated. + */ +#ifdef __FreeBSD__ + (void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf)); +#endif + vq_endchains(vq, 1); + return; + } + + do { + /* + * Get descriptor chain + */ + n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); + assert(n >= 1 && n <= VTNET_MAXSEGS); + + /* + * Get a pointer to the rx header, and use the + * data immediately following it for the packet buffer. + */ + vrx = iov[0].iov_base; + riov = rx_iov_trim(iov, &n, sc->rx_vhdrlen); +#ifdef __FreeBSD__ + len = readv(sc->vsc_tapfd, riov, n); +#else + len = riov[0].iov_len; + ret = dlpi_recv(sc->vsc_dhp, NULL, NULL, + (uint8_t *)riov[0].iov_base, &len, 0, NULL); + if (ret != DLPI_SUCCESS) { + errno = EWOULDBLOCK; + len = 0; + } +#endif + if (len <= 0 && errno == EWOULDBLOCK) { + /* + * No more packets, but still some avail ring + * entries. Interrupt if needed/appropriate. + */ + vq_retchain(vq); + vq_endchains(vq, 0); + return; + } + + /* + * The only valid field in the rx packet header is the + * number of buffers if merged rx bufs were negotiated. + */ + memset(vrx, 0, sc->rx_vhdrlen); + + if (sc->rx_merge) { + struct virtio_net_rxhdr *vrxh; + + vrxh = vrx; + vrxh->vrh_bufs = 1; + } + + /* + * Release this chain and handle more chains. + */ + vq_relchain(vq, idx, len + sc->rx_vhdrlen); + } while (vq_has_descs(vq)); + + /* Interrupt if needed, including for NOTIFY_ON_EMPTY. */ + vq_endchains(vq, 1); +} + +#ifdef __FreeBSD__ +static __inline int +pci_vtnet_netmap_writev(struct nm_desc *nmd, struct iovec *iov, int iovcnt) +{ + int r, i; + int len = 0; + + for (r = nmd->cur_tx_ring; ; ) { + struct netmap_ring *ring = NETMAP_TXRING(nmd->nifp, r); + uint32_t cur, idx; + char *buf; + + if (nm_ring_empty(ring)) { + r++; + if (r > nmd->last_tx_ring) + r = nmd->first_tx_ring; + if (r == nmd->cur_tx_ring) + break; + continue; + } + cur = ring->cur; + idx = ring->slot[cur].buf_idx; + buf = NETMAP_BUF(ring, idx); + + for (i = 0; i < iovcnt; i++) { + if (len + iov[i].iov_len > 2048) + break; + memcpy(&buf[len], iov[i].iov_base, iov[i].iov_len); + len += iov[i].iov_len; + } + ring->slot[cur].len = len; + ring->head = ring->cur = nm_ring_next(ring, cur); + nmd->cur_tx_ring = r; + ioctl(nmd->fd, NIOCTXSYNC, NULL); + break; + } + + return (len); +} + +static __inline int +pci_vtnet_netmap_readv(struct nm_desc *nmd, struct iovec *iov, int iovcnt) +{ + int len = 0; + int i = 0; + int r; + + for (r = nmd->cur_rx_ring; ; ) { + struct netmap_ring *ring = NETMAP_RXRING(nmd->nifp, r); + uint32_t cur, idx; + char *buf; + size_t left; + + if (nm_ring_empty(ring)) { + r++; + if (r > nmd->last_rx_ring) + r = nmd->first_rx_ring; + if (r == nmd->cur_rx_ring) + break; + continue; + } + cur = ring->cur; + idx = ring->slot[cur].buf_idx; + buf = NETMAP_BUF(ring, idx); + left = ring->slot[cur].len; + + for (i = 0; i < iovcnt && left > 0; i++) { + if (iov[i].iov_len > left) + iov[i].iov_len = left; + memcpy(iov[i].iov_base, &buf[len], iov[i].iov_len); + len += iov[i].iov_len; + left -= iov[i].iov_len; + } + ring->head = ring->cur = nm_ring_next(ring, cur); + nmd->cur_rx_ring = r; + ioctl(nmd->fd, NIOCRXSYNC, NULL); + break; + } + for (; i < iovcnt; i++) + iov[i].iov_len = 0; + + return (len); +} + +/* + * Called to send a buffer chain out to the vale port + */ +static void +pci_vtnet_netmap_tx(struct pci_vtnet_softc *sc, struct iovec *iov, int iovcnt, + int len) +{ + static char pad[60]; /* all zero bytes */ + + if (sc->vsc_nmd == NULL) + return; + + /* + * If the length is < 60, pad out to that and add the + * extra zero'd segment to the iov. It is guaranteed that + * there is always an extra iov available by the caller. + */ + if (len < 60) { + iov[iovcnt].iov_base = pad; + iov[iovcnt].iov_len = 60 - len; + iovcnt++; + } + (void) pci_vtnet_netmap_writev(sc->vsc_nmd, iov, iovcnt); +} + +static void +pci_vtnet_netmap_rx(struct pci_vtnet_softc *sc) +{ + struct iovec iov[VTNET_MAXSEGS], *riov; + struct vqueue_info *vq; + void *vrx; + int len, n; + uint16_t idx; + + /* + * Should never be called without a valid netmap descriptor + */ + assert(sc->vsc_nmd != NULL); + + /* + * But, will be called when the rx ring hasn't yet + * been set up or the guest is resetting the device. + */ + if (!sc->vsc_rx_ready || sc->resetting) { + /* + * Drop the packet and try later. + */ + (void) nm_nextpkt(sc->vsc_nmd, (void *)dummybuf); + return; + } + + /* + * Check for available rx buffers + */ + vq = &sc->vsc_queues[VTNET_RXQ]; + if (!vq_has_descs(vq)) { + /* + * Drop the packet and try later. Interrupt on + * empty, if that's negotiated. + */ + (void) nm_nextpkt(sc->vsc_nmd, (void *)dummybuf); + vq_endchains(vq, 1); + return; + } + + do { + /* + * Get descriptor chain. + */ + n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); + assert(n >= 1 && n <= VTNET_MAXSEGS); + + /* + * Get a pointer to the rx header, and use the + * data immediately following it for the packet buffer. + */ + vrx = iov[0].iov_base; + riov = rx_iov_trim(iov, &n, sc->rx_vhdrlen); + + len = pci_vtnet_netmap_readv(sc->vsc_nmd, riov, n); + + if (len == 0) { + /* + * No more packets, but still some avail ring + * entries. Interrupt if needed/appropriate. + */ + vq_retchain(vq); + vq_endchains(vq, 0); + return; + } + + /* + * The only valid field in the rx packet header is the + * number of buffers if merged rx bufs were negotiated. + */ + memset(vrx, 0, sc->rx_vhdrlen); + + if (sc->rx_merge) { + struct virtio_net_rxhdr *vrxh; + + vrxh = vrx; + vrxh->vrh_bufs = 1; + } + + /* + * Release this chain and handle more chains. + */ + vq_relchain(vq, idx, len + sc->rx_vhdrlen); + } while (vq_has_descs(vq)); + + /* Interrupt if needed, including for NOTIFY_ON_EMPTY. */ + vq_endchains(vq, 1); +} +#endif /* __FreeBSD__ */ + +#ifdef __FreeBSD__ +static void +pci_vtnet_rx_callback(int fd, enum ev_type type, void *param) +{ + struct pci_vtnet_softc *sc = param; + + pthread_mutex_lock(&sc->rx_mtx); + sc->rx_in_progress = 1; + sc->pci_vtnet_rx(sc); + sc->rx_in_progress = 0; + pthread_mutex_unlock(&sc->rx_mtx); + +} +#else +static void * +pci_vtnet_poll_thread(void *param) +{ + struct pci_vtnet_softc *sc = param; + pollfd_t pollset; + + pollset.fd = sc->vsc_dlpifd; + pollset.events = POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND; + + for (;;) { + if (poll(&pollset, 1, -1) < 0) { + if (errno == EINTR) + continue; + fprintf(stderr, "pci_vtnet_poll_thread poll() error %d\n", errno); + continue; + } + pthread_mutex_lock(&sc->vsc_mtx); + sc->rx_in_progress = 1; + pci_vtnet_tap_rx(sc); + sc->rx_in_progress = 0; + pthread_mutex_unlock(&sc->vsc_mtx); + } + + return (NULL); +} +#endif /* __FreeBSD__ */ + +static void +pci_vtnet_ping_rxq(void *vsc, struct vqueue_info *vq) +{ + struct pci_vtnet_softc *sc = vsc; + + /* + * A qnotify means that the rx process can now begin + */ + if (sc->vsc_rx_ready == 0) { + sc->vsc_rx_ready = 1; + vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; + } +} + +static void +pci_vtnet_proctx(struct pci_vtnet_softc *sc, struct vqueue_info *vq) +{ + struct iovec iov[VTNET_MAXSEGS + 1]; + int i, n; + int plen, tlen; + uint16_t idx; + + /* + * Obtain chain of descriptors. The first one is + * really the header descriptor, so we need to sum + * up two lengths: packet length and transfer length. + */ + n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); + assert(n >= 1 && n <= VTNET_MAXSEGS); + plen = 0; + tlen = iov[0].iov_len; + for (i = 1; i < n; i++) { + plen += iov[i].iov_len; + tlen += iov[i].iov_len; + } + + DPRINTF(("virtio: packet send, %d bytes, %d segs\n\r", plen, n)); + sc->pci_vtnet_tx(sc, &iov[1], n - 1, plen); + + /* chain is processed, release it and set tlen */ + vq_relchain(vq, idx, tlen); +} + +static void +pci_vtnet_ping_txq(void *vsc, struct vqueue_info *vq) +{ + struct pci_vtnet_softc *sc = vsc; + + /* + * Any ring entries to process? + */ + if (!vq_has_descs(vq)) + return; + + /* Signal the tx thread for processing */ + pthread_mutex_lock(&sc->tx_mtx); + vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; + if (sc->tx_in_progress == 0) + pthread_cond_signal(&sc->tx_cond); + pthread_mutex_unlock(&sc->tx_mtx); +} + +/* + * Thread which will handle processing of TX desc + */ +static void * +pci_vtnet_tx_thread(void *param) +{ + struct pci_vtnet_softc *sc = param; + struct vqueue_info *vq; + int error; + + vq = &sc->vsc_queues[VTNET_TXQ]; + + /* + * Let us wait till the tx queue pointers get initialised & + * first tx signaled + */ + pthread_mutex_lock(&sc->tx_mtx); + error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx); + assert(error == 0); + + for (;;) { + /* note - tx mutex is locked here */ + while (sc->resetting || !vq_has_descs(vq)) { + vq->vq_used->vu_flags &= ~VRING_USED_F_NO_NOTIFY; + mb(); + if (!sc->resetting && vq_has_descs(vq)) + break; + + sc->tx_in_progress = 0; + error = pthread_cond_wait(&sc->tx_cond, &sc->tx_mtx); + assert(error == 0); + } + vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; + sc->tx_in_progress = 1; + pthread_mutex_unlock(&sc->tx_mtx); + + do { + /* + * Run through entries, placing them into + * iovecs and sending when an end-of-packet + * is found + */ + pci_vtnet_proctx(sc, vq); + } while (vq_has_descs(vq)); + + /* + * Generate an interrupt if needed. + */ + vq_endchains(vq, 1); + + pthread_mutex_lock(&sc->tx_mtx); + } + return (NULL); +} + +#ifdef __FreeBSD__ +static void +pci_vtnet_ping_ctlq(void *vsc, struct vqueue_info *vq) +{ + + DPRINTF(("vtnet: control qnotify!\n\r")); +} +#endif /* __FreeBSD__ */ + +#ifdef __FreeBSD__ +static int +pci_vtnet_parsemac(char *mac_str, uint8_t *mac_addr) +{ + struct ether_addr *ea; + char *tmpstr; + char zero_addr[ETHER_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }; + + tmpstr = strsep(&mac_str,"="); + + if ((mac_str != NULL) && (!strcmp(tmpstr,"mac"))) { + ea = ether_aton(mac_str); + + if (ea == NULL || ETHER_IS_MULTICAST(ea->octet) || + memcmp(ea->octet, zero_addr, ETHER_ADDR_LEN) == 0) { + fprintf(stderr, "Invalid MAC %s\n", mac_str); + return (EINVAL); + } else + memcpy(mac_addr, ea->octet, ETHER_ADDR_LEN); + } + + return (0); +} +#endif /* __FreeBSD__ */ + +static void +pci_vtnet_tap_setup(struct pci_vtnet_softc *sc, char *devname) +{ + char tbuf[80]; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; +#endif +#ifndef __FreeBSD__ + uchar_t physaddr[DLPI_PHYSADDR_MAX]; + size_t physaddrlen = DLPI_PHYSADDR_MAX; + int error; +#endif + + strcpy(tbuf, "/dev/"); + strlcat(tbuf, devname, sizeof(tbuf)); + + sc->pci_vtnet_rx = pci_vtnet_tap_rx; + sc->pci_vtnet_tx = pci_vtnet_tap_tx; +#ifdef __FreeBSD__ + sc->vsc_tapfd = open(tbuf, O_RDWR); + if (sc->vsc_tapfd == -1) { + WPRINTF(("open of tap device %s failed\n", tbuf)); + return; + } + + /* + * Set non-blocking and register for read + * notifications with the event loop + */ + int opt = 1; + if (ioctl(sc->vsc_tapfd, FIONBIO, &opt) < 0) { + WPRINTF(("tap device O_NONBLOCK failed\n")); + close(sc->vsc_tapfd); + sc->vsc_tapfd = -1; + } + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE); + if (caph_rights_limit(sc->vsc_tapfd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + sc->vsc_mevp = mevent_add(sc->vsc_tapfd, + EVF_READ, + pci_vtnet_rx_callback, + sc); + if (sc->vsc_mevp == NULL) { + WPRINTF(("Could not register event\n")); + close(sc->vsc_tapfd); + sc->vsc_tapfd = -1; + } +#else + if (dlpi_open(devname, &sc->vsc_dhp, DLPI_RAW) != DLPI_SUCCESS) { + WPRINTF(("open of vnic device %s failed\n", devname)); + } + + if (dlpi_get_physaddr(sc->vsc_dhp, DL_CURR_PHYS_ADDR, physaddr, + &physaddrlen) != DLPI_SUCCESS) { + WPRINTF(("read MAC address of vnic device %s failed\n", + devname)); + } + if (physaddrlen != ETHERADDRL) { + WPRINTF(("bad MAC address len %d on vnic device %s\n", + physaddrlen, devname)); + } + memcpy(sc->vsc_config.mac, physaddr, ETHERADDRL); + + if (dlpi_bind(sc->vsc_dhp, DLPI_ANY_SAP, NULL) != DLPI_SUCCESS) { + WPRINTF(("bind of vnic device %s failed\n", devname)); + } + + if (dlpi_promiscon(sc->vsc_dhp, DL_PROMISC_PHYS) != DLPI_SUCCESS) { + WPRINTF(("enable promiscous mode(physical) of vnic device %s " + "failed\n", devname)); + } + if (dlpi_promiscon(sc->vsc_dhp, DL_PROMISC_SAP) != DLPI_SUCCESS) { + WPRINTF(("enable promiscous mode(SAP) of vnic device %s " + "failed\n", devname)); + } + + sc->vsc_dlpifd = dlpi_fd(sc->vsc_dhp); + + if (fcntl(sc->vsc_dlpifd, F_SETFL, O_NONBLOCK) < 0) { + WPRINTF(("enable O_NONBLOCK of vnic device %s failed\n", + devname)); + dlpi_close(sc->vsc_dhp); + sc->vsc_dlpifd = -1; + } + + error = pthread_create(NULL, NULL, pci_vtnet_poll_thread, sc); + assert(error == 0); +#endif +} + +#ifdef __FreeBSD__ +static void +pci_vtnet_netmap_setup(struct pci_vtnet_softc *sc, char *ifname) +{ + sc->pci_vtnet_rx = pci_vtnet_netmap_rx; + sc->pci_vtnet_tx = pci_vtnet_netmap_tx; + + sc->vsc_nmd = nm_open(ifname, NULL, 0, 0); + if (sc->vsc_nmd == NULL) { + WPRINTF(("open of netmap device %s failed\n", ifname)); + return; + } + + sc->vsc_mevp = mevent_add(sc->vsc_nmd->fd, + EVF_READ, + pci_vtnet_rx_callback, + sc); + if (sc->vsc_mevp == NULL) { + WPRINTF(("Could not register event\n")); + nm_close(sc->vsc_nmd); + sc->vsc_nmd = NULL; + } +} +#endif /* __FreeBSD__ */ + +static int +pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ +#ifdef __FreeBSD__ + MD5_CTX mdctx; + unsigned char digest[16]; + char nstr[80]; +#endif + char tname[MAXCOMLEN + 1]; + struct pci_vtnet_softc *sc; + const char *env_msi; + char *devname; + char *vtopts; +#ifdef __FreeBSD__ + int mac_provided; +#endif + int use_msix; + + sc = calloc(1, sizeof(struct pci_vtnet_softc)); + + pthread_mutex_init(&sc->vsc_mtx, NULL); + + vi_softc_linkup(&sc->vsc_vs, &vtnet_vi_consts, sc, pi, sc->vsc_queues); + sc->vsc_vs.vs_mtx = &sc->vsc_mtx; + + sc->vsc_queues[VTNET_RXQ].vq_qsize = VTNET_RINGSZ; + sc->vsc_queues[VTNET_RXQ].vq_notify = pci_vtnet_ping_rxq; + sc->vsc_queues[VTNET_TXQ].vq_qsize = VTNET_RINGSZ; + sc->vsc_queues[VTNET_TXQ].vq_notify = pci_vtnet_ping_txq; +#ifdef __FreeBSD__ + sc->vsc_queues[VTNET_CTLQ].vq_qsize = VTNET_RINGSZ; + sc->vsc_queues[VTNET_CTLQ].vq_notify = pci_vtnet_ping_ctlq; +#endif + + /* + * Use MSI if set by user + */ + use_msix = 1; + if ((env_msi = getenv("BHYVE_USE_MSI")) != NULL) { + if (strcasecmp(env_msi, "yes") == 0) + use_msix = 0; + } + + /* + * Attempt to open the tap device and read the MAC address + * if specified + */ +#ifdef __FreeBSD__ + mac_provided = 0; + sc->vsc_tapfd = -1; +#endif + sc->vsc_nmd = NULL; + if (opts != NULL) { +#ifdef __FreeBSD__ + int err; +#endif + + devname = vtopts = strdup(opts); + (void) strsep(&vtopts, ","); + +#ifdef __FreBSD__ + if (vtopts != NULL) { + err = pci_vtnet_parsemac(vtopts, sc->vsc_config.mac); + if (err != 0) { + free(devname); + return (err); + } + mac_provided = 1; + } +#endif + +#ifdef __FreeBSD__ + if (strncmp(devname, "vale", 4) == 0) + pci_vtnet_netmap_setup(sc, devname); +#endif + if (strncmp(devname, "tap", 3) == 0 || + strncmp(devname, "vmnet", 5) == 0) + pci_vtnet_tap_setup(sc, devname); + + free(devname); + } + +#ifdef __FreeBSD__ + /* + * The default MAC address is the standard NetApp OUI of 00-a0-98, + * followed by an MD5 of the PCI slot/func number and dev name + */ + if (!mac_provided) { + snprintf(nstr, sizeof(nstr), "%d-%d-%s", pi->pi_slot, + pi->pi_func, vmname); + + MD5Init(&mdctx); + MD5Update(&mdctx, nstr, strlen(nstr)); + MD5Final(digest, &mdctx); + + sc->vsc_config.mac[0] = 0x00; + sc->vsc_config.mac[1] = 0xa0; + sc->vsc_config.mac[2] = 0x98; + sc->vsc_config.mac[3] = digest[0]; + sc->vsc_config.mac[4] = digest[1]; + sc->vsc_config.mac[5] = digest[2]; + } +#endif + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_NET); + pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); + + /* Link is up if we managed to open tap device or vale port. */ +#ifdef __FreeBSD__ + sc->vsc_config.status = (opts == NULL || sc->vsc_tapfd >= 0 || +#else + sc->vsc_config.status = (opts == NULL || sc->vsc_dlpifd >= 0 || +#endif + sc->vsc_nmd != NULL); + + /* use BAR 1 to map MSI-X table and PBA, if we're using MSI-X */ + if (vi_intr_init(&sc->vsc_vs, 1, use_msix)) + return (1); + + /* use BAR 0 to map config regs in IO space */ + vi_set_io_bar(&sc->vsc_vs, 0); + + sc->resetting = 0; + + sc->rx_merge = 1; + sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr); + sc->rx_in_progress = 0; + pthread_mutex_init(&sc->rx_mtx, NULL); + + /* + * Initialize tx semaphore & spawn TX processing thread. + * As of now, only one thread for TX desc processing is + * spawned. + */ + sc->tx_in_progress = 0; + pthread_mutex_init(&sc->tx_mtx, NULL); + pthread_cond_init(&sc->tx_cond, NULL); + pthread_create(&sc->tx_tid, NULL, pci_vtnet_tx_thread, (void *)sc); + snprintf(tname, sizeof(tname), "vtnet-%d:%d tx", pi->pi_slot, + pi->pi_func); + pthread_set_name_np(sc->tx_tid, tname); + + return (0); +} + +static int +pci_vtnet_cfgwrite(void *vsc, int offset, int size, uint32_t value) +{ + struct pci_vtnet_softc *sc = vsc; + void *ptr; + + if (offset < 6) { + assert(offset + size <= 6); + /* + * The driver is allowed to change the MAC address + */ + ptr = &sc->vsc_config.mac[offset]; + memcpy(ptr, &value, size); + } else { + /* silently ignore other writes */ + DPRINTF(("vtnet: write to readonly reg %d\n\r", offset)); + } + + return (0); +} + +static int +pci_vtnet_cfgread(void *vsc, int offset, int size, uint32_t *retval) +{ + struct pci_vtnet_softc *sc = vsc; + void *ptr; + + ptr = (uint8_t *)&sc->vsc_config + offset; + memcpy(retval, ptr, size); + return (0); +} + +static void +pci_vtnet_neg_features(void *vsc, uint64_t negotiated_features) +{ + struct pci_vtnet_softc *sc = vsc; + + sc->vsc_features = negotiated_features; + + if (!(sc->vsc_features & VIRTIO_NET_F_MRG_RXBUF)) { + sc->rx_merge = 0; + /* non-merge rx header is 2 bytes shorter */ + sc->rx_vhdrlen -= 2; + } +} + +struct pci_devemu pci_de_vnet = { + .pe_emu = "virtio-net", + .pe_init = pci_vtnet_init, + .pe_barwrite = vi_pci_write, + .pe_barread = vi_pci_read +}; +PCI_EMUL_SET(pci_de_vnet); diff --git a/usr/src/cmd/bhyve/pci_virtio_rnd.c b/usr/src/cmd/bhyve/pci_virtio_rnd.c new file mode 100644 index 0000000000..5f470c03a6 --- /dev/null +++ b/usr/src/cmd/bhyve/pci_virtio_rnd.c @@ -0,0 +1,209 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Nahanni Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +/* + * virtio entropy device emulation. + * Randomness is sourced from /dev/random which does not block + * once it has been seeded at bootup. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/linker_set.h> +#include <sys/uio.h> + +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <assert.h> +#include <pthread.h> +#include <sysexits.h> + +#include "bhyverun.h" +#include "pci_emul.h" +#include "virtio.h" + +#define VTRND_RINGSZ 64 + + +static int pci_vtrnd_debug; +#define DPRINTF(params) if (pci_vtrnd_debug) printf params +#define WPRINTF(params) printf params + +/* + * Per-device softc + */ +struct pci_vtrnd_softc { + struct virtio_softc vrsc_vs; + struct vqueue_info vrsc_vq; + pthread_mutex_t vrsc_mtx; + uint64_t vrsc_cfg; + int vrsc_fd; +}; + +static void pci_vtrnd_reset(void *); +static void pci_vtrnd_notify(void *, struct vqueue_info *); + +static struct virtio_consts vtrnd_vi_consts = { + "vtrnd", /* our name */ + 1, /* we support 1 virtqueue */ + 0, /* config reg size */ + pci_vtrnd_reset, /* reset */ + pci_vtrnd_notify, /* device-wide qnotify */ + NULL, /* read virtio config */ + NULL, /* write virtio config */ + NULL, /* apply negotiated features */ + 0, /* our capabilities */ +}; + + +static void +pci_vtrnd_reset(void *vsc) +{ + struct pci_vtrnd_softc *sc; + + sc = vsc; + + DPRINTF(("vtrnd: device reset requested !\n")); + vi_reset_dev(&sc->vrsc_vs); +} + + +static void +pci_vtrnd_notify(void *vsc, struct vqueue_info *vq) +{ + struct iovec iov; + struct pci_vtrnd_softc *sc; + int len; + uint16_t idx; + + sc = vsc; + + if (sc->vrsc_fd < 0) { + vq_endchains(vq, 0); + return; + } + + while (vq_has_descs(vq)) { + vq_getchain(vq, &idx, &iov, 1, NULL); + + len = read(sc->vrsc_fd, iov.iov_base, iov.iov_len); + + DPRINTF(("vtrnd: vtrnd_notify(): %d\r\n", len)); + + /* Catastrophe if unable to read from /dev/random */ + assert(len > 0); + + /* + * Release this chain and handle more + */ + vq_relchain(vq, idx, len); + } + vq_endchains(vq, 1); /* Generate interrupt if appropriate. */ +} + + +static int +pci_vtrnd_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + struct pci_vtrnd_softc *sc; + int fd; + int len; + uint8_t v; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; +#endif + + /* + * Should always be able to open /dev/random. + */ + fd = open("/dev/random", O_RDONLY | O_NONBLOCK); + + assert(fd >= 0); + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_READ); + if (caph_rights_limit(fd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + /* + * Check that device is seeded and non-blocking. + */ + len = read(fd, &v, sizeof(v)); + if (len <= 0) { + WPRINTF(("vtrnd: /dev/random not ready, read(): %d", len)); + close(fd); + return (1); + } + + sc = calloc(1, sizeof(struct pci_vtrnd_softc)); + + vi_softc_linkup(&sc->vrsc_vs, &vtrnd_vi_consts, sc, pi, &sc->vrsc_vq); + sc->vrsc_vs.vs_mtx = &sc->vrsc_mtx; + + sc->vrsc_vq.vq_qsize = VTRND_RINGSZ; + + /* keep /dev/random opened while emulating */ + sc->vrsc_fd = fd; + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_RANDOM); + pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_CRYPTO); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_ENTROPY); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); + + if (vi_intr_init(&sc->vrsc_vs, 1, fbsdrun_virtio_msix())) + return (1); + vi_set_io_bar(&sc->vrsc_vs, 0); + + return (0); +} + + +struct pci_devemu pci_de_vrnd = { + .pe_emu = "virtio-rnd", + .pe_init = pci_vtrnd_init, + .pe_barwrite = vi_pci_write, + .pe_barread = vi_pci_read +}; +PCI_EMUL_SET(pci_de_vrnd); diff --git a/usr/src/cmd/bhyve/pci_virtio_scsi.c b/usr/src/cmd/bhyve/pci_virtio_scsi.c new file mode 100644 index 0000000000..238f07398b --- /dev/null +++ b/usr/src/cmd/bhyve/pci_virtio_scsi.c @@ -0,0 +1,737 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2016 Jakub Klama <jceel@FreeBSD.org>. + * Copyright (c) 2018 Marcelo Araujo <araujo@FreeBSD.org>. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer + * in this position and unchanged. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/linker_set.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <sys/time.h> +#include <sys/queue.h> +#include <sys/sbuf.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <unistd.h> +#include <assert.h> +#include <pthread.h> +#include <pthread_np.h> + +#include <cam/scsi/scsi_all.h> +#include <cam/scsi/scsi_message.h> +#include <cam/ctl/ctl.h> +#include <cam/ctl/ctl_io.h> +#include <cam/ctl/ctl_backend.h> +#include <cam/ctl/ctl_ioctl.h> +#include <cam/ctl/ctl_util.h> +#include <cam/ctl/ctl_scsi_all.h> +#include <camlib.h> + +#include "bhyverun.h" +#include "pci_emul.h" +#include "virtio.h" +#include "iov.h" + +#define VTSCSI_RINGSZ 64 +#define VTSCSI_REQUESTQ 1 +#define VTSCSI_THR_PER_Q 16 +#define VTSCSI_MAXQ (VTSCSI_REQUESTQ + 2) +#define VTSCSI_MAXSEG 64 + +#define VTSCSI_IN_HEADER_LEN(_sc) \ + (sizeof(struct pci_vtscsi_req_cmd_rd) + _sc->vss_config.cdb_size) + +#define VTSCSI_OUT_HEADER_LEN(_sc) \ + (sizeof(struct pci_vtscsi_req_cmd_wr) + _sc->vss_config.sense_size) + +#define VIRTIO_SCSI_MAX_CHANNEL 0 +#define VIRTIO_SCSI_MAX_TARGET 0 +#define VIRTIO_SCSI_MAX_LUN 16383 + +#define VIRTIO_SCSI_F_INOUT (1 << 0) +#define VIRTIO_SCSI_F_HOTPLUG (1 << 1) +#define VIRTIO_SCSI_F_CHANGE (1 << 2) + +static int pci_vtscsi_debug = 0; +#define DPRINTF(params) if (pci_vtscsi_debug) printf params +#define WPRINTF(params) printf params + +struct pci_vtscsi_config { + uint32_t num_queues; + uint32_t seg_max; + uint32_t max_sectors; + uint32_t cmd_per_lun; + uint32_t event_info_size; + uint32_t sense_size; + uint32_t cdb_size; + uint16_t max_channel; + uint16_t max_target; + uint32_t max_lun; +} __attribute__((packed)); + +struct pci_vtscsi_queue { + struct pci_vtscsi_softc * vsq_sc; + struct vqueue_info * vsq_vq; + pthread_mutex_t vsq_mtx; + pthread_mutex_t vsq_qmtx; + pthread_cond_t vsq_cv; + STAILQ_HEAD(, pci_vtscsi_request) vsq_requests; + LIST_HEAD(, pci_vtscsi_worker) vsq_workers; +}; + +struct pci_vtscsi_worker { + struct pci_vtscsi_queue * vsw_queue; + pthread_t vsw_thread; + bool vsw_exiting; + LIST_ENTRY(pci_vtscsi_worker) vsw_link; +}; + +struct pci_vtscsi_request { + struct pci_vtscsi_queue * vsr_queue; + struct iovec vsr_iov_in[VTSCSI_MAXSEG]; + int vsr_niov_in; + struct iovec vsr_iov_out[VTSCSI_MAXSEG]; + int vsr_niov_out; + uint32_t vsr_idx; + STAILQ_ENTRY(pci_vtscsi_request) vsr_link; +}; + +/* + * Per-device softc + */ +struct pci_vtscsi_softc { + struct virtio_softc vss_vs; + struct vqueue_info vss_vq[VTSCSI_MAXQ]; + struct pci_vtscsi_queue vss_queues[VTSCSI_REQUESTQ]; + pthread_mutex_t vss_mtx; + int vss_iid; + int vss_ctl_fd; + uint32_t vss_features; + struct pci_vtscsi_config vss_config; +}; + +#define VIRTIO_SCSI_T_TMF 0 +#define VIRTIO_SCSI_T_TMF_ABORT_TASK 0 +#define VIRTIO_SCSI_T_TMF_ABORT_TASK_SET 1 +#define VIRTIO_SCSI_T_TMF_CLEAR_ACA 2 +#define VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET 3 +#define VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET 4 +#define VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET 5 +#define VIRTIO_SCSI_T_TMF_QUERY_TASK 6 +#define VIRTIO_SCSI_T_TMF_QUERY_TASK_SET 7 + +/* command-specific response values */ +#define VIRTIO_SCSI_S_FUNCTION_COMPLETE 0 +#define VIRTIO_SCSI_S_FUNCTION_SUCCEEDED 10 +#define VIRTIO_SCSI_S_FUNCTION_REJECTED 11 + +struct pci_vtscsi_ctrl_tmf { + uint32_t type; + uint32_t subtype; + uint8_t lun[8]; + uint64_t id; + uint8_t response; +} __attribute__((packed)); + +#define VIRTIO_SCSI_T_AN_QUERY 1 +#define VIRTIO_SCSI_EVT_ASYNC_OPERATIONAL_CHANGE 2 +#define VIRTIO_SCSI_EVT_ASYNC_POWER_MGMT 4 +#define VIRTIO_SCSI_EVT_ASYNC_EXTERNAL_REQUEST 8 +#define VIRTIO_SCSI_EVT_ASYNC_MEDIA_CHANGE 16 +#define VIRTIO_SCSI_EVT_ASYNC_MULTI_HOST 32 +#define VIRTIO_SCSI_EVT_ASYNC_DEVICE_BUSY 64 + +struct pci_vtscsi_ctrl_an { + uint32_t type; + uint8_t lun[8]; + uint32_t event_requested; + uint32_t event_actual; + uint8_t response; +} __attribute__((packed)); + +/* command-specific response values */ +#define VIRTIO_SCSI_S_OK 0 +#define VIRTIO_SCSI_S_OVERRUN 1 +#define VIRTIO_SCSI_S_ABORTED 2 +#define VIRTIO_SCSI_S_BAD_TARGET 3 +#define VIRTIO_SCSI_S_RESET 4 +#define VIRTIO_SCSI_S_BUSY 5 +#define VIRTIO_SCSI_S_TRANSPORT_FAILURE 6 +#define VIRTIO_SCSI_S_TARGET_FAILURE 7 +#define VIRTIO_SCSI_S_NEXUS_FAILURE 8 +#define VIRTIO_SCSI_S_FAILURE 9 +#define VIRTIO_SCSI_S_INCORRECT_LUN 12 + +/* task_attr */ +#define VIRTIO_SCSI_S_SIMPLE 0 +#define VIRTIO_SCSI_S_ORDERED 1 +#define VIRTIO_SCSI_S_HEAD 2 +#define VIRTIO_SCSI_S_ACA 3 + +struct pci_vtscsi_event { + uint32_t event; + uint8_t lun[8]; + uint32_t reason; +} __attribute__((packed)); + +struct pci_vtscsi_req_cmd_rd { + uint8_t lun[8]; + uint64_t id; + uint8_t task_attr; + uint8_t prio; + uint8_t crn; + uint8_t cdb[]; +} __attribute__((packed)); + +struct pci_vtscsi_req_cmd_wr { + uint32_t sense_len; + uint32_t residual; + uint16_t status_qualifier; + uint8_t status; + uint8_t response; + uint8_t sense[]; +} __attribute__((packed)); + +static void *pci_vtscsi_proc(void *); +static void pci_vtscsi_reset(void *); +static void pci_vtscsi_neg_features(void *, uint64_t); +static int pci_vtscsi_cfgread(void *, int, int, uint32_t *); +static int pci_vtscsi_cfgwrite(void *, int, int, uint32_t); +static inline int pci_vtscsi_get_lun(uint8_t *); +static int pci_vtscsi_control_handle(struct pci_vtscsi_softc *, void *, size_t); +static int pci_vtscsi_tmf_handle(struct pci_vtscsi_softc *, + struct pci_vtscsi_ctrl_tmf *); +static int pci_vtscsi_an_handle(struct pci_vtscsi_softc *, + struct pci_vtscsi_ctrl_an *); +static int pci_vtscsi_request_handle(struct pci_vtscsi_queue *, struct iovec *, + int, struct iovec *, int); +static void pci_vtscsi_controlq_notify(void *, struct vqueue_info *); +static void pci_vtscsi_eventq_notify(void *, struct vqueue_info *); +static void pci_vtscsi_requestq_notify(void *, struct vqueue_info *); +static int pci_vtscsi_init_queue(struct pci_vtscsi_softc *, + struct pci_vtscsi_queue *, int); +static int pci_vtscsi_init(struct vmctx *, struct pci_devinst *, char *); + +static struct virtio_consts vtscsi_vi_consts = { + "vtscsi", /* our name */ + VTSCSI_MAXQ, /* we support 2+n virtqueues */ + sizeof(struct pci_vtscsi_config), /* config reg size */ + pci_vtscsi_reset, /* reset */ + NULL, /* device-wide qnotify */ + pci_vtscsi_cfgread, /* read virtio config */ + pci_vtscsi_cfgwrite, /* write virtio config */ + pci_vtscsi_neg_features, /* apply negotiated features */ + 0, /* our capabilities */ +}; + +static void * +pci_vtscsi_proc(void *arg) +{ + struct pci_vtscsi_worker *worker = (struct pci_vtscsi_worker *)arg; + struct pci_vtscsi_queue *q = worker->vsw_queue; + struct pci_vtscsi_request *req; + int iolen; + + for (;;) { + pthread_mutex_lock(&q->vsq_mtx); + + while (STAILQ_EMPTY(&q->vsq_requests) + && !worker->vsw_exiting) + pthread_cond_wait(&q->vsq_cv, &q->vsq_mtx); + + if (worker->vsw_exiting) + break; + + req = STAILQ_FIRST(&q->vsq_requests); + STAILQ_REMOVE_HEAD(&q->vsq_requests, vsr_link); + + pthread_mutex_unlock(&q->vsq_mtx); + iolen = pci_vtscsi_request_handle(q, req->vsr_iov_in, + req->vsr_niov_in, req->vsr_iov_out, req->vsr_niov_out); + + pthread_mutex_lock(&q->vsq_qmtx); + vq_relchain(q->vsq_vq, req->vsr_idx, iolen); + vq_endchains(q->vsq_vq, 0); + pthread_mutex_unlock(&q->vsq_qmtx); + + DPRINTF(("virtio-scsi: request <idx=%d> completed\n", + req->vsr_idx)); + free(req); + } + + pthread_mutex_unlock(&q->vsq_mtx); + return (NULL); +} + +static void +pci_vtscsi_reset(void *vsc) +{ + struct pci_vtscsi_softc *sc; + + sc = vsc; + + DPRINTF(("vtscsi: device reset requested\n")); + vi_reset_dev(&sc->vss_vs); + + /* initialize config structure */ + sc->vss_config = (struct pci_vtscsi_config){ + .num_queues = VTSCSI_REQUESTQ, + .seg_max = VTSCSI_MAXSEG, + .max_sectors = 2, + .cmd_per_lun = 1, + .event_info_size = sizeof(struct pci_vtscsi_event), + .sense_size = 96, + .cdb_size = 32, + .max_channel = VIRTIO_SCSI_MAX_CHANNEL, + .max_target = VIRTIO_SCSI_MAX_TARGET, + .max_lun = VIRTIO_SCSI_MAX_LUN + }; +} + +static void +pci_vtscsi_neg_features(void *vsc, uint64_t negotiated_features) +{ + struct pci_vtscsi_softc *sc = vsc; + + sc->vss_features = negotiated_features; +} + +static int +pci_vtscsi_cfgread(void *vsc, int offset, int size, uint32_t *retval) +{ + struct pci_vtscsi_softc *sc = vsc; + void *ptr; + + ptr = (uint8_t *)&sc->vss_config + offset; + memcpy(retval, ptr, size); + return (0); +} + +static int +pci_vtscsi_cfgwrite(void *vsc, int offset, int size, uint32_t val) +{ + + return (0); +} + +static inline int +pci_vtscsi_get_lun(uint8_t *lun) +{ + + return (((lun[2] << 8) | lun[3]) & 0x3fff); +} + +static int +pci_vtscsi_control_handle(struct pci_vtscsi_softc *sc, void *buf, + size_t bufsize) +{ + struct pci_vtscsi_ctrl_tmf *tmf; + struct pci_vtscsi_ctrl_an *an; + uint32_t type; + + type = *(uint32_t *)buf; + + if (type == VIRTIO_SCSI_T_TMF) { + tmf = (struct pci_vtscsi_ctrl_tmf *)buf; + return (pci_vtscsi_tmf_handle(sc, tmf)); + } + + if (type == VIRTIO_SCSI_T_AN_QUERY) { + an = (struct pci_vtscsi_ctrl_an *)buf; + return (pci_vtscsi_an_handle(sc, an)); + } + + return (0); +} + +static int +pci_vtscsi_tmf_handle(struct pci_vtscsi_softc *sc, + struct pci_vtscsi_ctrl_tmf *tmf) +{ + union ctl_io *io; + int err; + + io = ctl_scsi_alloc_io(sc->vss_iid); + ctl_scsi_zero_io(io); + + io->io_hdr.io_type = CTL_IO_TASK; + io->io_hdr.nexus.initid = sc->vss_iid; + io->io_hdr.nexus.targ_lun = pci_vtscsi_get_lun(tmf->lun); + io->taskio.tag_type = CTL_TAG_SIMPLE; + io->taskio.tag_num = (uint32_t)tmf->id; + + switch (tmf->subtype) { + case VIRTIO_SCSI_T_TMF_ABORT_TASK: + io->taskio.task_action = CTL_TASK_ABORT_TASK; + break; + + case VIRTIO_SCSI_T_TMF_ABORT_TASK_SET: + io->taskio.task_action = CTL_TASK_ABORT_TASK_SET; + break; + + case VIRTIO_SCSI_T_TMF_CLEAR_ACA: + io->taskio.task_action = CTL_TASK_CLEAR_ACA; + break; + + case VIRTIO_SCSI_T_TMF_CLEAR_TASK_SET: + io->taskio.task_action = CTL_TASK_CLEAR_TASK_SET; + break; + + case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET: + io->taskio.task_action = CTL_TASK_I_T_NEXUS_RESET; + break; + + case VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET: + io->taskio.task_action = CTL_TASK_LUN_RESET; + break; + + case VIRTIO_SCSI_T_TMF_QUERY_TASK: + io->taskio.task_action = CTL_TASK_QUERY_TASK; + break; + + case VIRTIO_SCSI_T_TMF_QUERY_TASK_SET: + io->taskio.task_action = CTL_TASK_QUERY_TASK_SET; + break; + } + + if (pci_vtscsi_debug) { + struct sbuf *sb = sbuf_new_auto(); + ctl_io_sbuf(io, sb); + sbuf_finish(sb); + DPRINTF(("pci_virtio_scsi: %s", sbuf_data(sb))); + sbuf_delete(sb); + } + + err = ioctl(sc->vss_ctl_fd, CTL_IO, io); + if (err != 0) + WPRINTF(("CTL_IO: err=%d (%s)\n", errno, strerror(errno))); + + tmf->response = io->taskio.task_status; + ctl_scsi_free_io(io); + return (1); +} + +static int +pci_vtscsi_an_handle(struct pci_vtscsi_softc *sc, + struct pci_vtscsi_ctrl_an *an) +{ + + return (0); +} + +static int +pci_vtscsi_request_handle(struct pci_vtscsi_queue *q, struct iovec *iov_in, + int niov_in, struct iovec *iov_out, int niov_out) +{ + struct pci_vtscsi_softc *sc = q->vsq_sc; + struct pci_vtscsi_req_cmd_rd *cmd_rd = NULL; + struct pci_vtscsi_req_cmd_wr *cmd_wr; + struct iovec data_iov_in[VTSCSI_MAXSEG], data_iov_out[VTSCSI_MAXSEG]; + union ctl_io *io; + int data_niov_in, data_niov_out; + void *ext_data_ptr = NULL; + uint32_t ext_data_len = 0, ext_sg_entries = 0; + int err; + + seek_iov(iov_in, niov_in, data_iov_in, &data_niov_in, + VTSCSI_IN_HEADER_LEN(sc)); + seek_iov(iov_out, niov_out, data_iov_out, &data_niov_out, + VTSCSI_OUT_HEADER_LEN(sc)); + + truncate_iov(iov_in, &niov_in, VTSCSI_IN_HEADER_LEN(sc)); + truncate_iov(iov_out, &niov_out, VTSCSI_OUT_HEADER_LEN(sc)); + iov_to_buf(iov_in, niov_in, (void **)&cmd_rd); + + cmd_wr = malloc(VTSCSI_OUT_HEADER_LEN(sc)); + io = ctl_scsi_alloc_io(sc->vss_iid); + ctl_scsi_zero_io(io); + + io->io_hdr.nexus.initid = sc->vss_iid; + io->io_hdr.nexus.targ_lun = pci_vtscsi_get_lun(cmd_rd->lun); + + io->io_hdr.io_type = CTL_IO_SCSI; + + if (data_niov_in > 0) { + ext_data_ptr = (void *)data_iov_in; + ext_sg_entries = data_niov_in; + ext_data_len = count_iov(data_iov_in, data_niov_in); + io->io_hdr.flags |= CTL_FLAG_DATA_OUT; + } else if (data_niov_out > 0) { + ext_data_ptr = (void *)data_iov_out; + ext_sg_entries = data_niov_out; + ext_data_len = count_iov(data_iov_out, data_niov_out); + io->io_hdr.flags |= CTL_FLAG_DATA_IN; + } + + io->scsiio.sense_len = sc->vss_config.sense_size; + io->scsiio.tag_num = (uint32_t)cmd_rd->id; + switch (cmd_rd->task_attr) { + case VIRTIO_SCSI_S_ORDERED: + io->scsiio.tag_type = CTL_TAG_ORDERED; + break; + case VIRTIO_SCSI_S_HEAD: + io->scsiio.tag_type = CTL_TAG_HEAD_OF_QUEUE; + break; + case VIRTIO_SCSI_S_ACA: + io->scsiio.tag_type = CTL_TAG_ACA; + break; + case VIRTIO_SCSI_S_SIMPLE: + default: + io->scsiio.tag_type = CTL_TAG_SIMPLE; + break; + } + io->scsiio.ext_sg_entries = ext_sg_entries; + io->scsiio.ext_data_ptr = ext_data_ptr; + io->scsiio.ext_data_len = ext_data_len; + io->scsiio.ext_data_filled = 0; + io->scsiio.cdb_len = sc->vss_config.cdb_size; + memcpy(io->scsiio.cdb, cmd_rd->cdb, sc->vss_config.cdb_size); + + if (pci_vtscsi_debug) { + struct sbuf *sb = sbuf_new_auto(); + ctl_io_sbuf(io, sb); + sbuf_finish(sb); + DPRINTF(("pci_virtio_scsi: %s", sbuf_data(sb))); + sbuf_delete(sb); + } + + err = ioctl(sc->vss_ctl_fd, CTL_IO, io); + if (err != 0) { + WPRINTF(("CTL_IO: err=%d (%s)\n", errno, strerror(errno))); + cmd_wr->response = VIRTIO_SCSI_S_FAILURE; + } else { + cmd_wr->sense_len = MIN(io->scsiio.sense_len, + sc->vss_config.sense_size); + cmd_wr->residual = io->scsiio.residual; + cmd_wr->status = io->scsiio.scsi_status; + cmd_wr->response = VIRTIO_SCSI_S_OK; + memcpy(&cmd_wr->sense, &io->scsiio.sense_data, + cmd_wr->sense_len); + } + + buf_to_iov(cmd_wr, VTSCSI_OUT_HEADER_LEN(sc), iov_out, niov_out, 0); + free(cmd_rd); + free(cmd_wr); + ctl_scsi_free_io(io); + return (VTSCSI_OUT_HEADER_LEN(sc) + io->scsiio.ext_data_filled); +} + +static void +pci_vtscsi_controlq_notify(void *vsc, struct vqueue_info *vq) +{ + struct pci_vtscsi_softc *sc; + struct iovec iov[VTSCSI_MAXSEG]; + uint16_t idx, n; + void *buf = NULL; + size_t bufsize; + int iolen; + + sc = vsc; + + while (vq_has_descs(vq)) { + n = vq_getchain(vq, &idx, iov, VTSCSI_MAXSEG, NULL); + bufsize = iov_to_buf(iov, n, &buf); + iolen = pci_vtscsi_control_handle(sc, buf, bufsize); + buf_to_iov(buf + bufsize - iolen, iolen, iov, n, + bufsize - iolen); + + /* + * Release this chain and handle more + */ + vq_relchain(vq, idx, iolen); + } + vq_endchains(vq, 1); /* Generate interrupt if appropriate. */ + free(buf); +} + +static void +pci_vtscsi_eventq_notify(void *vsc, struct vqueue_info *vq) +{ + + vq->vq_used->vu_flags |= VRING_USED_F_NO_NOTIFY; +} + +static void +pci_vtscsi_requestq_notify(void *vsc, struct vqueue_info *vq) +{ + struct pci_vtscsi_softc *sc; + struct pci_vtscsi_queue *q; + struct pci_vtscsi_request *req; + struct iovec iov[VTSCSI_MAXSEG]; + uint16_t flags[VTSCSI_MAXSEG]; + uint16_t idx, n, i; + int readable; + + sc = vsc; + q = &sc->vss_queues[vq->vq_num - 2]; + + while (vq_has_descs(vq)) { + readable = 0; + n = vq_getchain(vq, &idx, iov, VTSCSI_MAXSEG, flags); + + /* Count readable descriptors */ + for (i = 0; i < n; i++) { + if (flags[i] & VRING_DESC_F_WRITE) + break; + + readable++; + } + + req = calloc(1, sizeof(struct pci_vtscsi_request)); + req->vsr_idx = idx; + req->vsr_queue = q; + req->vsr_niov_in = readable; + req->vsr_niov_out = n - readable; + memcpy(req->vsr_iov_in, iov, + req->vsr_niov_in * sizeof(struct iovec)); + memcpy(req->vsr_iov_out, iov + readable, + req->vsr_niov_out * sizeof(struct iovec)); + + pthread_mutex_lock(&q->vsq_mtx); + STAILQ_INSERT_TAIL(&q->vsq_requests, req, vsr_link); + pthread_cond_signal(&q->vsq_cv); + pthread_mutex_unlock(&q->vsq_mtx); + + DPRINTF(("virtio-scsi: request <idx=%d> enqueued\n", idx)); + } +} + +static int +pci_vtscsi_init_queue(struct pci_vtscsi_softc *sc, + struct pci_vtscsi_queue *queue, int num) +{ + struct pci_vtscsi_worker *worker; + char threadname[16]; + int i; + + queue->vsq_sc = sc; + queue->vsq_vq = &sc->vss_vq[num + 2]; + + pthread_mutex_init(&queue->vsq_mtx, NULL); + pthread_mutex_init(&queue->vsq_qmtx, NULL); + pthread_cond_init(&queue->vsq_cv, NULL); + STAILQ_INIT(&queue->vsq_requests); + LIST_INIT(&queue->vsq_workers); + + for (i = 0; i < VTSCSI_THR_PER_Q; i++) { + worker = calloc(1, sizeof(struct pci_vtscsi_worker)); + worker->vsw_queue = queue; + + pthread_create(&worker->vsw_thread, NULL, &pci_vtscsi_proc, + (void *)worker); + + sprintf(threadname, "virtio-scsi:%d-%d", num, i); + pthread_set_name_np(worker->vsw_thread, threadname); + LIST_INSERT_HEAD(&queue->vsq_workers, worker, vsw_link); + } + + return (0); +} + +static int +pci_vtscsi_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + struct pci_vtscsi_softc *sc; + char *opt, *optname; + const char *devname; + int i, optidx = 0; + + sc = calloc(1, sizeof(struct pci_vtscsi_softc)); + devname = "/dev/cam/ctl"; + while ((opt = strsep(&opts, ",")) != NULL) { + optname = strsep(&opt, "="); + if (opt == NULL && optidx == 0) { + if (optname[0] != 0) + devname = optname; + } else if (strcmp(optname, "dev") == 0 && opt != NULL) { + devname = opt; + } else if (strcmp(optname, "iid") == 0 && opt != NULL) { + sc->vss_iid = strtoul(opt, NULL, 10); + } else { + fprintf(stderr, "Invalid option %s\n", optname); + free(sc); + return (1); + } + optidx++; + } + + sc->vss_ctl_fd = open(devname, O_RDWR); + if (sc->vss_ctl_fd < 0) { + WPRINTF(("cannot open %s: %s\n", devname, strerror(errno))); + free(sc); + return (1); + } + + vi_softc_linkup(&sc->vss_vs, &vtscsi_vi_consts, sc, pi, sc->vss_vq); + sc->vss_vs.vs_mtx = &sc->vss_mtx; + + /* controlq */ + sc->vss_vq[0].vq_qsize = VTSCSI_RINGSZ; + sc->vss_vq[0].vq_notify = pci_vtscsi_controlq_notify; + + /* eventq */ + sc->vss_vq[1].vq_qsize = VTSCSI_RINGSZ; + sc->vss_vq[1].vq_notify = pci_vtscsi_eventq_notify; + + /* request queues */ + for (i = 2; i < VTSCSI_MAXQ; i++) { + sc->vss_vq[i].vq_qsize = VTSCSI_RINGSZ; + sc->vss_vq[i].vq_notify = pci_vtscsi_requestq_notify; + pci_vtscsi_init_queue(sc, &sc->vss_queues[i - 2], i - 2); + } + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_SCSI); + pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_STORAGE); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_SCSI); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); + + if (vi_intr_init(&sc->vss_vs, 1, fbsdrun_virtio_msix())) + return (1); + vi_set_io_bar(&sc->vss_vs, 0); + + return (0); +} + + +struct pci_devemu pci_de_vscsi = { + .pe_emu = "virtio-scsi", + .pe_init = pci_vtscsi_init, + .pe_barwrite = vi_pci_write, + .pe_barread = vi_pci_read +}; +PCI_EMUL_SET(pci_de_vscsi); diff --git a/usr/src/cmd/bhyve/pci_virtio_viona.c b/usr/src/cmd/bhyve/pci_virtio_viona.c new file mode 100644 index 0000000000..26c8cdeeba --- /dev/null +++ b/usr/src/cmd/bhyve/pci_virtio_viona.c @@ -0,0 +1,837 @@ +/* + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2015 Pluribus Networks Inc. + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> + +#include <sys/param.h> +#include <sys/linker_set.h> +#include <sys/ioctl.h> +#include <sys/viona_io.h> + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <strings.h> +#include <unistd.h> +#include <assert.h> +#include <pthread.h> +#include <signal.h> +#include <poll.h> +#include <libdladm.h> +#include <libdllink.h> +#include <libdlvnic.h> + +#include <machine/vmm.h> +#include <vmmapi.h> + +#include "bhyverun.h" +#include "pci_emul.h" +#include "virtio.h" + +#define VIONA_RINGSZ 1024 + +/* + * PCI config-space register offsets + */ +#define VIONA_R_CFG0 24 +#define VIONA_R_CFG1 25 +#define VIONA_R_CFG2 26 +#define VIONA_R_CFG3 27 +#define VIONA_R_CFG4 28 +#define VIONA_R_CFG5 29 +#define VIONA_R_CFG6 30 +#define VIONA_R_CFG7 31 +#define VIONA_R_MAX 31 + +#define VIONA_REGSZ VIONA_R_MAX+1 + +/* + * Queue definitions. + */ +#define VIONA_RXQ 0 +#define VIONA_TXQ 1 +#define VIONA_CTLQ 2 + +#define VIONA_MAXQ 3 + +/* + * Debug printf + */ +static volatile int pci_viona_debug; +#define DPRINTF(params) if (pci_viona_debug) printf params +#define WPRINTF(params) printf params + +/* + * Per-device softc + */ +struct pci_viona_softc { + struct pci_devinst *vsc_pi; + pthread_mutex_t vsc_mtx; + + int vsc_curq; + int vsc_status; + int vsc_isr; + + datalink_id_t vsc_linkid; + int vsc_vnafd; + + /* Configurable parameters */ + char vsc_linkname[MAXLINKNAMELEN]; + uint32_t vsc_feature_mask; + uint16_t vsc_vq_size; + + uint32_t vsc_features; + uint8_t vsc_macaddr[6]; + + uint64_t vsc_pfn[VIONA_MAXQ]; + uint16_t vsc_msix_table_idx[VIONA_MAXQ]; + boolean_t vsc_msix_active; +}; + +/* + * Return the size of IO BAR that maps virtio header and device specific + * region. The size would vary depending on whether MSI-X is enabled or + * not. + */ +static uint64_t +pci_viona_iosize(struct pci_devinst *pi) +{ + if (pci_msix_enabled(pi)) + return (VIONA_REGSZ); + else + return (VIONA_REGSZ - (VTCFG_R_CFG1 - VTCFG_R_MSIX)); +} + +static uint16_t +pci_viona_qsize(struct pci_viona_softc *sc, int qnum) +{ + /* XXX no ctl queue currently */ + if (qnum == VIONA_CTLQ) { + return (0); + } + + return (sc->vsc_vq_size); +} + +static void +pci_viona_ring_reset(struct pci_viona_softc *sc, int ring) +{ + assert(ring < VIONA_MAXQ); + + switch (ring) { + case VIONA_RXQ: + case VIONA_TXQ: + break; + case VIONA_CTLQ: + default: + return; + } + + for (;;) { + int res; + + res = ioctl(sc->vsc_vnafd, VNA_IOC_RING_RESET, ring); + if (res == 0) { + break; + } else if (errno != EINTR) { + WPRINTF(("ioctl viona ring %d reset failed %d\n", + ring, errno)); + return; + } + } + + sc->vsc_pfn[ring] = 0; +} + +static void +pci_viona_update_status(struct pci_viona_softc *sc, uint32_t value) +{ + + if (value == 0) { + DPRINTF(("viona: device reset requested !\n")); + pci_viona_ring_reset(sc, VIONA_RXQ); + pci_viona_ring_reset(sc, VIONA_TXQ); + } + + sc->vsc_status = value; +} + +static void * +pci_viona_poll_thread(void *param) +{ + struct pci_viona_softc *sc = param; + pollfd_t pollset; + const int fd = sc->vsc_vnafd; + + pollset.fd = fd; + pollset.events = POLLRDBAND; + + for (;;) { + if (poll(&pollset, 1, -1) < 0) { + if (errno == EINTR || errno == EAGAIN) { + continue; + } else { + WPRINTF(("pci_viona_poll_thread poll()" + "error %d\n", errno)); + break; + } + } + if (pollset.revents & POLLRDBAND) { + vioc_intr_poll_t vip; + uint_t i; + int res; + boolean_t assert_lintr = B_FALSE; + const boolean_t do_msix = pci_msix_enabled(sc->vsc_pi); + + res = ioctl(fd, VNA_IOC_INTR_POLL, &vip); + for (i = 0; res > 0 && i < VIONA_VQ_MAX; i++) { + if (vip.vip_status[i] == 0) { + continue; + } + if (do_msix) { + pci_generate_msix(sc->vsc_pi, + sc->vsc_msix_table_idx[i]); + } else { + assert_lintr = B_TRUE; + } + res = ioctl(fd, VNA_IOC_RING_INTR_CLR, i); + if (res != 0) { + WPRINTF(("ioctl viona vq %d intr " + "clear failed %d\n", i, errno)); + } + } + if (assert_lintr) { + pthread_mutex_lock(&sc->vsc_mtx); + sc->vsc_isr |= VTCFG_ISR_QUEUES; + pci_lintr_assert(sc->vsc_pi); + pthread_mutex_unlock(&sc->vsc_mtx); + } + } + } + + pthread_exit(NULL); +} + +static void +pci_viona_ring_init(struct pci_viona_softc *sc, uint64_t pfn) +{ + int qnum = sc->vsc_curq; + vioc_ring_init_t vna_ri; + int error; + + assert(qnum < VIONA_MAXQ); + + if (qnum == VIONA_CTLQ) { + return; + } + + sc->vsc_pfn[qnum] = (pfn << VRING_PFN); + + vna_ri.ri_index = qnum; + vna_ri.ri_qsize = pci_viona_qsize(sc, qnum); + vna_ri.ri_qaddr = (pfn << VRING_PFN); + error = ioctl(sc->vsc_vnafd, VNA_IOC_RING_INIT, &vna_ri); + + if (error != 0) { + WPRINTF(("ioctl viona ring %u init failed %d\n", qnum, errno)); + } +} + +static int +pci_viona_viona_init(struct vmctx *ctx, struct pci_viona_softc *sc) +{ + vioc_create_t vna_create; + int error; + + sc->vsc_vnafd = open("/dev/viona", O_RDWR | O_EXCL); + if (sc->vsc_vnafd == -1) { + WPRINTF(("open viona ctl failed: %d\n", errno)); + return (-1); + } + + vna_create.c_linkid = sc->vsc_linkid; + vna_create.c_vmfd = vm_get_device_fd(ctx); + error = ioctl(sc->vsc_vnafd, VNA_IOC_CREATE, &vna_create); + if (error != 0) { + (void) close(sc->vsc_vnafd); + WPRINTF(("ioctl viona create failed %d\n", errno)); + return (-1); + } + + return (0); +} + +static int +pci_viona_parse_opts(struct pci_viona_softc *sc, char *opts) +{ + char *next, *cp, *vnic = NULL; + int err = 0; + + sc->vsc_vq_size = VIONA_RINGSZ; + sc->vsc_feature_mask = 0; + + for (; opts != NULL && *opts != '\0'; opts = next) { + char *val; + + if ((cp = strchr(opts, ',')) != NULL) { + *cp = '\0'; + next = cp + 1; + } else { + next = NULL; + } + + if ((cp = strchr(opts, '=')) == NULL) { + /* vnic chosen with bare name */ + if (vnic != NULL) { + fprintf(stderr, + "viona: unexpected vnic name '%s'", opts); + err = -1; + } else { + vnic = opts; + } + continue; + } + + /* <param>=<value> handling */ + val = cp + 1; + *cp = '\0'; + if (strcmp(opts, "feature_mask") == 0) { + long num; + + errno = 0; + num = strtol(val, NULL, 0); + if (errno != 0 || num < 0) { + fprintf(stderr, + "viona: invalid mask '%s'", val); + } else { + sc->vsc_feature_mask = num; + } + } else if (strcmp(opts, "vqsize") == 0) { + long num; + + errno = 0; + num = strtol(val, NULL, 0); + if (errno != 0) { + fprintf(stderr, + "viona: invalid vsqize '%s'", val); + err = -1; + } else if (num <= 2 || num > 32768) { + fprintf(stderr, + "viona: vqsize out of range", num); + err = -1; + } else if ((1 << (ffs(num) - 1)) != num) { + fprintf(stderr, + "viona: vqsize must be power of 2", num); + err = -1; + } else { + sc->vsc_vq_size = num; + } + } else { + fprintf(stderr, + "viona: unrecognized option '%s'", opts); + err = -1; + } + } + if (vnic == NULL) { + fprintf(stderr, "viona: vnic name required"); + sc->vsc_linkname[0] = '\0'; + err = -1; + } else { + (void) strlcpy(sc->vsc_linkname, vnic, MAXLINKNAMELEN); + } + + DPRINTF(("viona=%p dev=%s vqsize=%x feature_mask=%x\n", sc, + sc->vsc_linkname, sc->vsc_vq_size, sc->vsc_feature_mask)); + return (err); +} + +static int +pci_viona_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + dladm_handle_t handle; + dladm_status_t status; + dladm_vnic_attr_t attr; + char errmsg[DLADM_STRSIZE]; + int error, i; + struct pci_viona_softc *sc; + uint64_t ioport; + + if (opts == NULL) { + printf("virtio-viona: vnic required\n"); + return (1); + } + + sc = malloc(sizeof (struct pci_viona_softc)); + memset(sc, 0, sizeof (struct pci_viona_softc)); + + pi->pi_arg = sc; + sc->vsc_pi = pi; + + pthread_mutex_init(&sc->vsc_mtx, NULL); + + if (pci_viona_parse_opts(sc, opts) != 0) { + free(sc); + return (1); + } + + if ((status = dladm_open(&handle)) != DLADM_STATUS_OK) { + WPRINTF(("could not open /dev/dld")); + free(sc); + return (1); + } + + if (dladm_name2info(handle, sc->vsc_linkname, &sc->vsc_linkid, + NULL, NULL, NULL) != DLADM_STATUS_OK) { + WPRINTF(("dladm_name2info() for %s failed: %s\n", opts, + dladm_status2str(status, errmsg))); + dladm_close(handle); + free(sc); + return (1); + } + + if (dladm_vnic_info(handle, sc->vsc_linkid, &attr, + DLADM_OPT_ACTIVE) != DLADM_STATUS_OK) { + WPRINTF(("dladm_vnic_info() for %s failed: %s\n", opts, + dladm_status2str(status, errmsg))); + dladm_close(handle); + free(sc); + return (1); + } + + memcpy(sc->vsc_macaddr, attr.va_mac_addr, ETHERADDRL); + + dladm_close(handle); + + error = pci_viona_viona_init(ctx, sc); + if (error != 0) { + free(sc); + return (1); + } + + error = pthread_create(NULL, NULL, pci_viona_poll_thread, sc); + assert(error == 0); + + /* initialize config space */ + pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_NET); + pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); + + /* MSI-X support */ + for (i = 0; i < VIONA_MAXQ; i++) + sc->vsc_msix_table_idx[i] = VIRTIO_MSI_NO_VECTOR; + + /* BAR 1 used to map MSI-X table and PBA */ + if (pci_emul_add_msixcap(pi, VIONA_MAXQ, 1)) { + free(sc); + return (1); + } + + /* BAR 0 for legacy-style virtio register access. */ + error = pci_emul_alloc_bar(pi, 0, PCIBAR_IO, VIONA_REGSZ); + if (error != NULL) { + WPRINTF(("could not allocate virtio BAR\n")); + free(sc); + return (1); + } + + /* Install ioport hook for virtqueue notification */ + ioport = pi->pi_bar[0].addr + VTCFG_R_QNOTIFY; + error = ioctl(sc->vsc_vnafd, VNA_IOC_SET_NOTIFY_IOP, ioport); + if (error != 0) { + WPRINTF(("could not install ioport hook at %x\n", ioport)); + free(sc); + return (1); + } + + /* + * Need a legacy interrupt for virtio compliance, even though MSI-X + * operation is _strongly_ suggested for adequate performance. + */ + pci_lintr_request(pi); + + return (0); +} + +static uint64_t +viona_adjust_offset(struct pci_devinst *pi, uint64_t offset) +{ + /* + * Device specific offsets used by guest would change based on + * whether MSI-X capability is enabled or not + */ + if (!pci_msix_enabled(pi)) { + if (offset >= VTCFG_R_MSIX) + return (offset + (VTCFG_R_CFG1 - VTCFG_R_MSIX)); + } + + return (offset); +} + +static void +pci_viona_ring_set_msix(struct pci_devinst *pi, uint_t ring) +{ + struct pci_viona_softc *sc = pi->pi_arg; + struct msix_table_entry mte; + uint16_t tab_index; + vioc_ring_msi_t vrm; + int res; + + assert(ring <= VIONA_VQ_TX); + + vrm.rm_index = ring; + vrm.rm_addr = 0; + vrm.rm_msg = 0; + tab_index = sc->vsc_msix_table_idx[ring]; + + if (tab_index != VIRTIO_MSI_NO_VECTOR && sc->vsc_msix_active) { + mte = pi->pi_msix.table[tab_index]; + if ((mte.vector_control & PCIM_MSIX_VCTRL_MASK) == 0) { + vrm.rm_addr = mte.addr; + vrm.rm_msg = mte.msg_data; + } + } + + res = ioctl(sc->vsc_vnafd, VNA_IOC_RING_SET_MSI, &vrm); + if (res != 0) { + WPRINTF(("ioctl viona set_msi %d failed %d\n", ring, errno)); + } +} + +static void +pci_viona_lintrupdate(struct pci_devinst *pi) +{ + struct pci_viona_softc *sc = pi->pi_arg; + boolean_t msix_on = B_FALSE; + + pthread_mutex_lock(&sc->vsc_mtx); + msix_on = pci_msix_enabled(pi) && (pi->pi_msix.function_mask == 0); + if ((sc->vsc_msix_active && !msix_on) || + (msix_on && !sc->vsc_msix_active)) { + uint_t i; + + sc->vsc_msix_active = msix_on; + /* Update in-kernel ring configs */ + for (i = 0; i <= VIONA_VQ_TX; i++) { + pci_viona_ring_set_msix(pi, i); + } + } + pthread_mutex_unlock(&sc->vsc_mtx); +} + +static void +pci_viona_msix_update(struct pci_devinst *pi, uint64_t offset) +{ + struct pci_viona_softc *sc = pi->pi_arg; + uint_t tab_index, i; + + pthread_mutex_lock(&sc->vsc_mtx); + if (!sc->vsc_msix_active) { + pthread_mutex_unlock(&sc->vsc_mtx); + return; + } + + /* + * Rather than update every possible MSI-X vector, cheat and use the + * offset to calculate the entry within the table. Since this should + * only be called when a write to the table succeeds, the index should + * be valid. + */ + tab_index = offset / MSIX_TABLE_ENTRY_SIZE; + + for (i = 0; i <= VIONA_VQ_TX; i++) { + if (sc->vsc_msix_table_idx[i] != tab_index) { + continue; + } + pci_viona_ring_set_msix(pi, i); + } + + pthread_mutex_unlock(&sc->vsc_mtx); +} + +static void +pci_viona_qnotify(struct pci_viona_softc *sc, int ring) +{ + int error; + + switch (ring) { + case VIONA_TXQ: + case VIONA_RXQ: + error = ioctl(sc->vsc_vnafd, VNA_IOC_RING_KICK, ring); + if (error != 0) { + WPRINTF(("ioctl viona ring %d kick failed %d\n", + ring, errno)); + } + break; + case VIONA_CTLQ: + DPRINTF(("viona: control qnotify!\n")); + break; + default: + break; + } +} + +static void +pci_viona_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value) +{ + struct pci_viona_softc *sc = pi->pi_arg; + void *ptr; + int err = 0; + + if (baridx == pci_msix_table_bar(pi) || + baridx == pci_msix_pba_bar(pi)) { + if (pci_emul_msix_twrite(pi, offset, size, value) == 0) { + pci_viona_msix_update(pi, offset); + } + return; + } + + assert(baridx == 0); + + if (offset + size > pci_viona_iosize(pi)) { + DPRINTF(("viona_write: 2big, offset %ld size %d\n", + offset, size)); + return; + } + + pthread_mutex_lock(&sc->vsc_mtx); + + offset = viona_adjust_offset(pi, offset); + + switch (offset) { + case VTCFG_R_GUESTCAP: + assert(size == 4); + value &= ~(sc->vsc_feature_mask); + err = ioctl(sc->vsc_vnafd, VNA_IOC_SET_FEATURES, &value); + if (err != 0) { + WPRINTF(("ioctl feature negotiation returned" + " err = %d\n", errno)); + } else { + sc->vsc_features = value; + } + break; + case VTCFG_R_PFN: + assert(size == 4); + pci_viona_ring_init(sc, value); + break; + case VTCFG_R_QSEL: + assert(size == 2); + assert(value < VIONA_MAXQ); + sc->vsc_curq = value; + break; + case VTCFG_R_QNOTIFY: + assert(size == 2); + assert(value < VIONA_MAXQ); + pci_viona_qnotify(sc, value); + break; + case VTCFG_R_STATUS: + assert(size == 1); + pci_viona_update_status(sc, value); + break; + case VTCFG_R_CFGVEC: + assert(size == 2); + sc->vsc_msix_table_idx[VIONA_CTLQ] = value; + break; + case VTCFG_R_QVEC: + assert(size == 2); + assert(sc->vsc_curq != VIONA_CTLQ); + sc->vsc_msix_table_idx[sc->vsc_curq] = value; + pci_viona_ring_set_msix(pi, sc->vsc_curq); + break; + case VIONA_R_CFG0: + case VIONA_R_CFG1: + case VIONA_R_CFG2: + case VIONA_R_CFG3: + case VIONA_R_CFG4: + case VIONA_R_CFG5: + assert((size + offset) <= (VIONA_R_CFG5 + 1)); + ptr = &sc->vsc_macaddr[offset - VIONA_R_CFG0]; + /* + * The driver is allowed to change the MAC address + */ + sc->vsc_macaddr[offset - VIONA_R_CFG0] = value; + if (size == 1) { + *(uint8_t *)ptr = value; + } else if (size == 2) { + *(uint16_t *)ptr = value; + } else { + *(uint32_t *)ptr = value; + } + break; + case VTCFG_R_HOSTCAP: + case VTCFG_R_QNUM: + case VTCFG_R_ISR: + case VIONA_R_CFG6: + case VIONA_R_CFG7: + DPRINTF(("viona: write to readonly reg %ld\n\r", offset)); + break; + default: + DPRINTF(("viona: unknown i/o write offset %ld\n\r", offset)); + value = 0; + break; + } + + pthread_mutex_unlock(&sc->vsc_mtx); +} + +static uint64_t +pci_viona_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size) +{ + struct pci_viona_softc *sc = pi->pi_arg; + void *ptr; + uint64_t value; + int err = 0; + + if (baridx == pci_msix_table_bar(pi) || + baridx == pci_msix_pba_bar(pi)) { + return (pci_emul_msix_tread(pi, offset, size)); + } + + assert(baridx == 0); + + if (offset + size > pci_viona_iosize(pi)) { + DPRINTF(("viona_read: 2big, offset %ld size %d\n", + offset, size)); + return (0); + } + + pthread_mutex_lock(&sc->vsc_mtx); + + offset = viona_adjust_offset(pi, offset); + + switch (offset) { + case VTCFG_R_HOSTCAP: + assert(size == 4); + err = ioctl(sc->vsc_vnafd, VNA_IOC_GET_FEATURES, &value); + if (err != 0) { + WPRINTF(("ioctl get host features returned" + " err = %d\n", errno)); + } + value &= ~sc->vsc_feature_mask; + break; + case VTCFG_R_GUESTCAP: + assert(size == 4); + value = sc->vsc_features; /* XXX never read ? */ + break; + case VTCFG_R_PFN: + assert(size == 4); + value = sc->vsc_pfn[sc->vsc_curq] >> VRING_PFN; + break; + case VTCFG_R_QNUM: + assert(size == 2); + value = pci_viona_qsize(sc, sc->vsc_curq); + break; + case VTCFG_R_QSEL: + assert(size == 2); + value = sc->vsc_curq; /* XXX never read ? */ + break; + case VTCFG_R_QNOTIFY: + assert(size == 2); + value = sc->vsc_curq; /* XXX never read ? */ + break; + case VTCFG_R_STATUS: + assert(size == 1); + value = sc->vsc_status; + break; + case VTCFG_R_ISR: + assert(size == 1); + value = sc->vsc_isr; + sc->vsc_isr = 0; /* a read clears this flag */ + if (value != 0) { + pci_lintr_deassert(pi); + } + break; + case VTCFG_R_CFGVEC: + assert(size == 2); + value = sc->vsc_msix_table_idx[VIONA_CTLQ]; + break; + case VTCFG_R_QVEC: + assert(size == 2); + assert(sc->vsc_curq != VIONA_CTLQ); + value = sc->vsc_msix_table_idx[sc->vsc_curq]; + break; + case VIONA_R_CFG0: + case VIONA_R_CFG1: + case VIONA_R_CFG2: + case VIONA_R_CFG3: + case VIONA_R_CFG4: + case VIONA_R_CFG5: + assert((size + offset) <= (VIONA_R_CFG5 + 1)); + ptr = &sc->vsc_macaddr[offset - VIONA_R_CFG0]; + if (size == 1) { + value = *(uint8_t *)ptr; + } else if (size == 2) { + value = *(uint16_t *)ptr; + } else { + value = *(uint32_t *)ptr; + } + break; + case VIONA_R_CFG6: + assert(size != 4); + value = 0x01; /* XXX link always up */ + break; + case VIONA_R_CFG7: + assert(size == 1); + value = 0; /* XXX link status in LSB */ + break; + default: + DPRINTF(("viona: unknown i/o read offset %ld\n\r", offset)); + value = 0; + break; + } + + pthread_mutex_unlock(&sc->vsc_mtx); + + return (value); +} + +struct pci_devemu pci_de_viona = { + .pe_emu = "virtio-net-viona", + .pe_init = pci_viona_init, + .pe_barwrite = pci_viona_write, + .pe_barread = pci_viona_read, + .pe_lintrupdate = pci_viona_lintrupdate +}; +PCI_EMUL_SET(pci_de_viona); diff --git a/usr/src/cmd/bhyve/pci_xhci.c b/usr/src/cmd/bhyve/pci_xhci.c new file mode 100644 index 0000000000..988e6933cc --- /dev/null +++ b/usr/src/cmd/bhyve/pci_xhci.c @@ -0,0 +1,2862 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Leon Dang <ldang@nahannisys.com> + * Copyright 2018 Joyent, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ +/* + XHCI options: + -s <n>,xhci,{devices} + + devices: + tablet USB tablet mouse + */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/uio.h> +#include <sys/types.h> +#include <sys/queue.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <errno.h> +#include <pthread.h> +#include <unistd.h> + +#include <dev/usb/usbdi.h> +#include <dev/usb/usb.h> +#include <dev/usb/usb_freebsd.h> +#include <xhcireg.h> + +#include "bhyverun.h" +#include "pci_emul.h" +#include "pci_xhci.h" +#include "usb_emul.h" + + +static int xhci_debug = 0; +#define DPRINTF(params) if (xhci_debug) printf params +#define WPRINTF(params) printf params + + +#define XHCI_NAME "xhci" +#define XHCI_MAX_DEVS 8 /* 4 USB3 + 4 USB2 devs */ + +#define XHCI_MAX_SLOTS 64 /* min allowed by Windows drivers */ + +/* + * XHCI data structures can be up to 64k, but limit paddr_guest2host mapping + * to 4k to avoid going over the guest physical memory barrier. + */ +#define XHCI_PADDR_SZ 4096 /* paddr_guest2host max size */ + +#define XHCI_ERST_MAX 0 /* max 2^entries event ring seg tbl */ + +#define XHCI_CAPLEN (4*8) /* offset of op register space */ +#define XHCI_HCCPRAMS2 0x1C /* offset of HCCPARAMS2 register */ +#define XHCI_PORTREGS_START 0x400 +#define XHCI_DOORBELL_MAX 256 + +#define XHCI_STREAMS_MAX 1 /* 4-15 in XHCI spec */ + +/* caplength and hci-version registers */ +#define XHCI_SET_CAPLEN(x) ((x) & 0xFF) +#define XHCI_SET_HCIVERSION(x) (((x) & 0xFFFF) << 16) +#define XHCI_GET_HCIVERSION(x) (((x) >> 16) & 0xFFFF) + +/* hcsparams1 register */ +#define XHCI_SET_HCSP1_MAXSLOTS(x) ((x) & 0xFF) +#define XHCI_SET_HCSP1_MAXINTR(x) (((x) & 0x7FF) << 8) +#define XHCI_SET_HCSP1_MAXPORTS(x) (((x) & 0xFF) << 24) + +/* hcsparams2 register */ +#define XHCI_SET_HCSP2_IST(x) ((x) & 0x0F) +#define XHCI_SET_HCSP2_ERSTMAX(x) (((x) & 0x0F) << 4) +#define XHCI_SET_HCSP2_MAXSCRATCH_HI(x) (((x) & 0x1F) << 21) +#define XHCI_SET_HCSP2_MAXSCRATCH_LO(x) (((x) & 0x1F) << 27) + +/* hcsparams3 register */ +#define XHCI_SET_HCSP3_U1EXITLATENCY(x) ((x) & 0xFF) +#define XHCI_SET_HCSP3_U2EXITLATENCY(x) (((x) & 0xFFFF) << 16) + +/* hccparams1 register */ +#define XHCI_SET_HCCP1_AC64(x) ((x) & 0x01) +#define XHCI_SET_HCCP1_BNC(x) (((x) & 0x01) << 1) +#define XHCI_SET_HCCP1_CSZ(x) (((x) & 0x01) << 2) +#define XHCI_SET_HCCP1_PPC(x) (((x) & 0x01) << 3) +#define XHCI_SET_HCCP1_PIND(x) (((x) & 0x01) << 4) +#define XHCI_SET_HCCP1_LHRC(x) (((x) & 0x01) << 5) +#define XHCI_SET_HCCP1_LTC(x) (((x) & 0x01) << 6) +#define XHCI_SET_HCCP1_NSS(x) (((x) & 0x01) << 7) +#define XHCI_SET_HCCP1_PAE(x) (((x) & 0x01) << 8) +#define XHCI_SET_HCCP1_SPC(x) (((x) & 0x01) << 9) +#define XHCI_SET_HCCP1_SEC(x) (((x) & 0x01) << 10) +#define XHCI_SET_HCCP1_CFC(x) (((x) & 0x01) << 11) +#define XHCI_SET_HCCP1_MAXPSA(x) (((x) & 0x0F) << 12) +#define XHCI_SET_HCCP1_XECP(x) (((x) & 0xFFFF) << 16) + +/* hccparams2 register */ +#define XHCI_SET_HCCP2_U3C(x) ((x) & 0x01) +#define XHCI_SET_HCCP2_CMC(x) (((x) & 0x01) << 1) +#define XHCI_SET_HCCP2_FSC(x) (((x) & 0x01) << 2) +#define XHCI_SET_HCCP2_CTC(x) (((x) & 0x01) << 3) +#define XHCI_SET_HCCP2_LEC(x) (((x) & 0x01) << 4) +#define XHCI_SET_HCCP2_CIC(x) (((x) & 0x01) << 5) + +/* other registers */ +#define XHCI_SET_DOORBELL(x) ((x) & ~0x03) +#define XHCI_SET_RTSOFFSET(x) ((x) & ~0x0F) + +/* register masks */ +#define XHCI_PS_PLS_MASK (0xF << 5) /* port link state */ +#define XHCI_PS_SPEED_MASK (0xF << 10) /* port speed */ +#define XHCI_PS_PIC_MASK (0x3 << 14) /* port indicator */ + +/* port register set */ +#define XHCI_PORTREGS_BASE 0x400 /* base offset */ +#define XHCI_PORTREGS_PORT0 0x3F0 +#define XHCI_PORTREGS_SETSZ 0x10 /* size of a set */ + +#define MASK_64_HI(x) ((x) & ~0xFFFFFFFFULL) +#define MASK_64_LO(x) ((x) & 0xFFFFFFFFULL) + +#define FIELD_REPLACE(a,b,m,s) (((a) & ~((m) << (s))) | \ + (((b) & (m)) << (s))) +#define FIELD_COPY(a,b,m,s) (((a) & ~((m) << (s))) | \ + (((b) & ((m) << (s))))) + +struct pci_xhci_trb_ring { + uint64_t ringaddr; /* current dequeue guest address */ + uint32_t ccs; /* consumer cycle state */ +}; + +/* device endpoint transfer/stream rings */ +struct pci_xhci_dev_ep { + union { + struct xhci_trb *_epu_tr; + struct xhci_stream_ctx *_epu_sctx; + } _ep_trbsctx; +#define ep_tr _ep_trbsctx._epu_tr +#define ep_sctx _ep_trbsctx._epu_sctx + + union { + struct pci_xhci_trb_ring _epu_trb; + struct pci_xhci_trb_ring *_epu_sctx_trbs; + } _ep_trb_rings; +#define ep_ringaddr _ep_trb_rings._epu_trb.ringaddr +#define ep_ccs _ep_trb_rings._epu_trb.ccs +#define ep_sctx_trbs _ep_trb_rings._epu_sctx_trbs + + struct usb_data_xfer *ep_xfer; /* transfer chain */ +}; + +/* device context base address array: maps slot->device context */ +struct xhci_dcbaa { + uint64_t dcba[USB_MAX_DEVICES+1]; /* xhci_dev_ctx ptrs */ +}; + +/* port status registers */ +struct pci_xhci_portregs { + uint32_t portsc; /* port status and control */ + uint32_t portpmsc; /* port pwr mgmt status & control */ + uint32_t portli; /* port link info */ + uint32_t porthlpmc; /* port hardware LPM control */ +} __packed; +#define XHCI_PS_SPEED_SET(x) (((x) & 0xF) << 10) + +/* xHC operational registers */ +struct pci_xhci_opregs { + uint32_t usbcmd; /* usb command */ + uint32_t usbsts; /* usb status */ + uint32_t pgsz; /* page size */ + uint32_t dnctrl; /* device notification control */ + uint64_t crcr; /* command ring control */ + uint64_t dcbaap; /* device ctx base addr array ptr */ + uint32_t config; /* configure */ + + /* guest mapped addresses: */ + struct xhci_trb *cr_p; /* crcr dequeue */ + struct xhci_dcbaa *dcbaa_p; /* dev ctx array ptr */ +}; + +/* xHC runtime registers */ +struct pci_xhci_rtsregs { + uint32_t mfindex; /* microframe index */ + struct { /* interrupter register set */ + uint32_t iman; /* interrupter management */ + uint32_t imod; /* interrupter moderation */ + uint32_t erstsz; /* event ring segment table size */ + uint32_t rsvd; + uint64_t erstba; /* event ring seg-tbl base addr */ + uint64_t erdp; /* event ring dequeue ptr */ + } intrreg __packed; + + /* guest mapped addresses */ + struct xhci_event_ring_seg *erstba_p; + struct xhci_trb *erst_p; /* event ring segment tbl */ + int er_deq_seg; /* event ring dequeue segment */ + int er_enq_idx; /* event ring enqueue index - xHCI */ + int er_enq_seg; /* event ring enqueue segment */ + uint32_t er_events_cnt; /* number of events in ER */ + uint32_t event_pcs; /* producer cycle state flag */ +}; + + +struct pci_xhci_softc; + + +/* + * USB device emulation container. + * This is referenced from usb_hci->hci_sc; 1 pci_xhci_dev_emu for each + * emulated device instance. + */ +struct pci_xhci_dev_emu { + struct pci_xhci_softc *xsc; + + /* XHCI contexts */ + struct xhci_dev_ctx *dev_ctx; + struct pci_xhci_dev_ep eps[XHCI_MAX_ENDPOINTS]; + int dev_slotstate; + + struct usb_devemu *dev_ue; /* USB emulated dev */ + void *dev_sc; /* device's softc */ + + struct usb_hci hci; +}; + +struct pci_xhci_softc { + struct pci_devinst *xsc_pi; + + pthread_mutex_t mtx; + + uint32_t caplength; /* caplen & hciversion */ + uint32_t hcsparams1; /* structural parameters 1 */ + uint32_t hcsparams2; /* structural parameters 2 */ + uint32_t hcsparams3; /* structural parameters 3 */ + uint32_t hccparams1; /* capability parameters 1 */ + uint32_t dboff; /* doorbell offset */ + uint32_t rtsoff; /* runtime register space offset */ + uint32_t hccparams2; /* capability parameters 2 */ + + uint32_t regsend; /* end of configuration registers */ + + struct pci_xhci_opregs opregs; + struct pci_xhci_rtsregs rtsregs; + + struct pci_xhci_portregs *portregs; + struct pci_xhci_dev_emu **devices; /* XHCI[port] = device */ + struct pci_xhci_dev_emu **slots; /* slots assigned from 1 */ + int ndevices; + + int usb2_port_start; + int usb3_port_start; +}; + + +/* portregs and devices arrays are set up to start from idx=1 */ +#define XHCI_PORTREG_PTR(x,n) &(x)->portregs[(n)] +#define XHCI_DEVINST_PTR(x,n) (x)->devices[(n)] +#define XHCI_SLOTDEV_PTR(x,n) (x)->slots[(n)] + +#define XHCI_HALTED(sc) ((sc)->opregs.usbsts & XHCI_STS_HCH) + +#define XHCI_GADDR(sc,a) paddr_guest2host((sc)->xsc_pi->pi_vmctx, \ + (a), \ + XHCI_PADDR_SZ - ((a) & (XHCI_PADDR_SZ-1))) + +static int xhci_in_use; + +/* map USB errors to XHCI */ +static const int xhci_usb_errors[USB_ERR_MAX] = { + [USB_ERR_NORMAL_COMPLETION] = XHCI_TRB_ERROR_SUCCESS, + [USB_ERR_PENDING_REQUESTS] = XHCI_TRB_ERROR_RESOURCE, + [USB_ERR_NOT_STARTED] = XHCI_TRB_ERROR_ENDP_NOT_ON, + [USB_ERR_INVAL] = XHCI_TRB_ERROR_INVALID, + [USB_ERR_NOMEM] = XHCI_TRB_ERROR_RESOURCE, + [USB_ERR_CANCELLED] = XHCI_TRB_ERROR_STOPPED, + [USB_ERR_BAD_ADDRESS] = XHCI_TRB_ERROR_PARAMETER, + [USB_ERR_BAD_BUFSIZE] = XHCI_TRB_ERROR_PARAMETER, + [USB_ERR_BAD_FLAG] = XHCI_TRB_ERROR_PARAMETER, + [USB_ERR_NO_CALLBACK] = XHCI_TRB_ERROR_STALL, + [USB_ERR_IN_USE] = XHCI_TRB_ERROR_RESOURCE, + [USB_ERR_NO_ADDR] = XHCI_TRB_ERROR_RESOURCE, + [USB_ERR_NO_PIPE] = XHCI_TRB_ERROR_RESOURCE, + [USB_ERR_ZERO_NFRAMES] = XHCI_TRB_ERROR_UNDEFINED, + [USB_ERR_ZERO_MAXP] = XHCI_TRB_ERROR_UNDEFINED, + [USB_ERR_SET_ADDR_FAILED] = XHCI_TRB_ERROR_RESOURCE, + [USB_ERR_NO_POWER] = XHCI_TRB_ERROR_ENDP_NOT_ON, + [USB_ERR_TOO_DEEP] = XHCI_TRB_ERROR_RESOURCE, + [USB_ERR_IOERROR] = XHCI_TRB_ERROR_TRB, + [USB_ERR_NOT_CONFIGURED] = XHCI_TRB_ERROR_ENDP_NOT_ON, + [USB_ERR_TIMEOUT] = XHCI_TRB_ERROR_CMD_ABORTED, + [USB_ERR_SHORT_XFER] = XHCI_TRB_ERROR_SHORT_PKT, + [USB_ERR_STALLED] = XHCI_TRB_ERROR_STALL, + [USB_ERR_INTERRUPTED] = XHCI_TRB_ERROR_CMD_ABORTED, + [USB_ERR_DMA_LOAD_FAILED] = XHCI_TRB_ERROR_DATA_BUF, + [USB_ERR_BAD_CONTEXT] = XHCI_TRB_ERROR_TRB, + [USB_ERR_NO_ROOT_HUB] = XHCI_TRB_ERROR_UNDEFINED, + [USB_ERR_NO_INTR_THREAD] = XHCI_TRB_ERROR_UNDEFINED, + [USB_ERR_NOT_LOCKED] = XHCI_TRB_ERROR_UNDEFINED, +}; +#define USB_TO_XHCI_ERR(e) ((e) < USB_ERR_MAX ? xhci_usb_errors[(e)] : \ + XHCI_TRB_ERROR_INVALID) + +static int pci_xhci_insert_event(struct pci_xhci_softc *sc, + struct xhci_trb *evtrb, int do_intr); +static void pci_xhci_dump_trb(struct xhci_trb *trb); +static void pci_xhci_assert_interrupt(struct pci_xhci_softc *sc); +static void pci_xhci_reset_slot(struct pci_xhci_softc *sc, int slot); +static void pci_xhci_reset_port(struct pci_xhci_softc *sc, int portn, int warm); +static void pci_xhci_update_ep_ring(struct pci_xhci_softc *sc, + struct pci_xhci_dev_emu *dev, struct pci_xhci_dev_ep *devep, + struct xhci_endp_ctx *ep_ctx, uint32_t streamid, + uint64_t ringaddr, int ccs); + +static void +pci_xhci_set_evtrb(struct xhci_trb *evtrb, uint64_t port, uint32_t errcode, + uint32_t evtype) +{ + evtrb->qwTrb0 = port << 24; + evtrb->dwTrb2 = XHCI_TRB_2_ERROR_SET(errcode); + evtrb->dwTrb3 = XHCI_TRB_3_TYPE_SET(evtype); +} + + +/* controller reset */ +static void +pci_xhci_reset(struct pci_xhci_softc *sc) +{ + int i; + + sc->rtsregs.er_enq_idx = 0; + sc->rtsregs.er_events_cnt = 0; + sc->rtsregs.event_pcs = 1; + + for (i = 1; i <= XHCI_MAX_SLOTS; i++) { + pci_xhci_reset_slot(sc, i); + } +} + +static uint32_t +pci_xhci_usbcmd_write(struct pci_xhci_softc *sc, uint32_t cmd) +{ + int do_intr = 0; + int i; + + if (cmd & XHCI_CMD_RS) { + do_intr = (sc->opregs.usbcmd & XHCI_CMD_RS) == 0; + + sc->opregs.usbcmd |= XHCI_CMD_RS; + sc->opregs.usbsts &= ~XHCI_STS_HCH; + sc->opregs.usbsts |= XHCI_STS_PCD; + + /* Queue port change event on controller run from stop */ + if (do_intr) + for (i = 1; i <= XHCI_MAX_DEVS; i++) { + struct pci_xhci_dev_emu *dev; + struct pci_xhci_portregs *port; + struct xhci_trb evtrb; + + if ((dev = XHCI_DEVINST_PTR(sc, i)) == NULL) + continue; + + port = XHCI_PORTREG_PTR(sc, i); + port->portsc |= XHCI_PS_CSC | XHCI_PS_CCS; + port->portsc &= ~XHCI_PS_PLS_MASK; + + /* + * XHCI 4.19.3 USB2 RxDetect->Polling, + * USB3 Polling->U0 + */ + if (dev->dev_ue->ue_usbver == 2) + port->portsc |= + XHCI_PS_PLS_SET(UPS_PORT_LS_POLL); + else + port->portsc |= + XHCI_PS_PLS_SET(UPS_PORT_LS_U0); + + pci_xhci_set_evtrb(&evtrb, i, + XHCI_TRB_ERROR_SUCCESS, + XHCI_TRB_EVENT_PORT_STS_CHANGE); + + if (pci_xhci_insert_event(sc, &evtrb, 0) != + XHCI_TRB_ERROR_SUCCESS) + break; + } + } else { + sc->opregs.usbcmd &= ~XHCI_CMD_RS; + sc->opregs.usbsts |= XHCI_STS_HCH; + sc->opregs.usbsts &= ~XHCI_STS_PCD; + } + + /* start execution of schedule; stop when set to 0 */ + cmd |= sc->opregs.usbcmd & XHCI_CMD_RS; + + if (cmd & XHCI_CMD_HCRST) { + /* reset controller */ + pci_xhci_reset(sc); + cmd &= ~XHCI_CMD_HCRST; + } + + cmd &= ~(XHCI_CMD_CSS | XHCI_CMD_CRS); + + if (do_intr) + pci_xhci_assert_interrupt(sc); + + return (cmd); +} + +static void +pci_xhci_portregs_write(struct pci_xhci_softc *sc, uint64_t offset, + uint64_t value) +{ + struct xhci_trb evtrb; + struct pci_xhci_portregs *p; + int port; + uint32_t oldpls, newpls; + + if (sc->portregs == NULL) + return; + + port = (offset - XHCI_PORTREGS_PORT0) / XHCI_PORTREGS_SETSZ; + offset = (offset - XHCI_PORTREGS_PORT0) % XHCI_PORTREGS_SETSZ; + + DPRINTF(("pci_xhci: portregs wr offset 0x%lx, port %u: 0x%lx\r\n", + offset, port, value)); + + assert(port >= 0); + + if (port > XHCI_MAX_DEVS) { + DPRINTF(("pci_xhci: portregs_write port %d > ndevices\r\n", + port)); + return; + } + + if (XHCI_DEVINST_PTR(sc, port) == NULL) { + DPRINTF(("pci_xhci: portregs_write to unattached port %d\r\n", + port)); + } + + p = XHCI_PORTREG_PTR(sc, port); + switch (offset) { + case 0: + /* port reset or warm reset */ + if (value & (XHCI_PS_PR | XHCI_PS_WPR)) { + pci_xhci_reset_port(sc, port, value & XHCI_PS_WPR); + break; + } + + if ((p->portsc & XHCI_PS_PP) == 0) { + WPRINTF(("pci_xhci: portregs_write to unpowered " + "port %d\r\n", port)); + break; + } + + /* Port status and control register */ + oldpls = XHCI_PS_PLS_GET(p->portsc); + newpls = XHCI_PS_PLS_GET(value); + + p->portsc &= XHCI_PS_PED | XHCI_PS_PLS_MASK | + XHCI_PS_SPEED_MASK | XHCI_PS_PIC_MASK; + + if (XHCI_DEVINST_PTR(sc, port)) + p->portsc |= XHCI_PS_CCS; + + p->portsc |= (value & + ~(XHCI_PS_OCA | + XHCI_PS_PR | + XHCI_PS_PED | + XHCI_PS_PLS_MASK | /* link state */ + XHCI_PS_SPEED_MASK | + XHCI_PS_PIC_MASK | /* port indicator */ + XHCI_PS_LWS | XHCI_PS_DR | XHCI_PS_WPR)); + + /* clear control bits */ + p->portsc &= ~(value & + (XHCI_PS_CSC | + XHCI_PS_PEC | + XHCI_PS_WRC | + XHCI_PS_OCC | + XHCI_PS_PRC | + XHCI_PS_PLC | + XHCI_PS_CEC | + XHCI_PS_CAS)); + + /* port disable request; for USB3, don't care */ + if (value & XHCI_PS_PED) + DPRINTF(("Disable port %d request\r\n", port)); + + if (!(value & XHCI_PS_LWS)) + break; + + DPRINTF(("Port new PLS: %d\r\n", newpls)); + switch (newpls) { + case 0: /* U0 */ + case 3: /* U3 */ + if (oldpls != newpls) { + p->portsc &= ~XHCI_PS_PLS_MASK; + p->portsc |= XHCI_PS_PLS_SET(newpls) | + XHCI_PS_PLC; + + if (oldpls != 0 && newpls == 0) { + pci_xhci_set_evtrb(&evtrb, port, + XHCI_TRB_ERROR_SUCCESS, + XHCI_TRB_EVENT_PORT_STS_CHANGE); + + pci_xhci_insert_event(sc, &evtrb, 1); + } + } + break; + + default: + DPRINTF(("Unhandled change port %d PLS %u\r\n", + port, newpls)); + break; + } + break; + case 4: + /* Port power management status and control register */ + p->portpmsc = value; + break; + case 8: + /* Port link information register */ + DPRINTF(("pci_xhci attempted write to PORTLI, port %d\r\n", + port)); + break; + case 12: + /* + * Port hardware LPM control register. + * For USB3, this register is reserved. + */ + p->porthlpmc = value; + break; + } +} + +struct xhci_dev_ctx * +pci_xhci_get_dev_ctx(struct pci_xhci_softc *sc, uint32_t slot) +{ + uint64_t devctx_addr; + struct xhci_dev_ctx *devctx; + + assert(slot > 0 && slot <= sc->ndevices); + assert(sc->opregs.dcbaa_p != NULL); + + devctx_addr = sc->opregs.dcbaa_p->dcba[slot]; + + if (devctx_addr == 0) { + DPRINTF(("get_dev_ctx devctx_addr == 0\r\n")); + return (NULL); + } + + DPRINTF(("pci_xhci: get dev ctx, slot %u devctx addr %016lx\r\n", + slot, devctx_addr)); + devctx = XHCI_GADDR(sc, devctx_addr & ~0x3FUL); + + return (devctx); +} + +struct xhci_trb * +pci_xhci_trb_next(struct pci_xhci_softc *sc, struct xhci_trb *curtrb, + uint64_t *guestaddr) +{ + struct xhci_trb *next; + + assert(curtrb != NULL); + + if (XHCI_TRB_3_TYPE_GET(curtrb->dwTrb3) == XHCI_TRB_TYPE_LINK) { + if (guestaddr) + *guestaddr = curtrb->qwTrb0 & ~0xFUL; + + next = XHCI_GADDR(sc, curtrb->qwTrb0 & ~0xFUL); + } else { + if (guestaddr) + *guestaddr += sizeof(struct xhci_trb) & ~0xFUL; + + next = curtrb + 1; + } + + return (next); +} + +static void +pci_xhci_assert_interrupt(struct pci_xhci_softc *sc) +{ + + sc->rtsregs.intrreg.erdp |= XHCI_ERDP_LO_BUSY; + sc->rtsregs.intrreg.iman |= XHCI_IMAN_INTR_PEND; + sc->opregs.usbsts |= XHCI_STS_EINT; + + /* only trigger interrupt if permitted */ + if ((sc->opregs.usbcmd & XHCI_CMD_INTE) && + (sc->rtsregs.intrreg.iman & XHCI_IMAN_INTR_ENA)) { + if (pci_msi_enabled(sc->xsc_pi)) + pci_generate_msi(sc->xsc_pi, 0); + else + pci_lintr_assert(sc->xsc_pi); + } +} + +static void +pci_xhci_deassert_interrupt(struct pci_xhci_softc *sc) +{ + + if (!pci_msi_enabled(sc->xsc_pi)) + pci_lintr_assert(sc->xsc_pi); +} + +static void +pci_xhci_init_ep(struct pci_xhci_dev_emu *dev, int epid) +{ + struct xhci_dev_ctx *dev_ctx; + struct pci_xhci_dev_ep *devep; + struct xhci_endp_ctx *ep_ctx; + uint32_t pstreams; + int i; + + dev_ctx = dev->dev_ctx; + ep_ctx = &dev_ctx->ctx_ep[epid]; + devep = &dev->eps[epid]; + pstreams = XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0); + if (pstreams > 0) { + DPRINTF(("init_ep %d with pstreams %d\r\n", epid, pstreams)); + assert(devep->ep_sctx_trbs == NULL); + + devep->ep_sctx = XHCI_GADDR(dev->xsc, ep_ctx->qwEpCtx2 & + XHCI_EPCTX_2_TR_DQ_PTR_MASK); + devep->ep_sctx_trbs = calloc(pstreams, + sizeof(struct pci_xhci_trb_ring)); + for (i = 0; i < pstreams; i++) { + devep->ep_sctx_trbs[i].ringaddr = + devep->ep_sctx[i].qwSctx0 & + XHCI_SCTX_0_TR_DQ_PTR_MASK; + devep->ep_sctx_trbs[i].ccs = + XHCI_SCTX_0_DCS_GET(devep->ep_sctx[i].qwSctx0); + } + } else { + DPRINTF(("init_ep %d with no pstreams\r\n", epid)); + devep->ep_ringaddr = ep_ctx->qwEpCtx2 & + XHCI_EPCTX_2_TR_DQ_PTR_MASK; + devep->ep_ccs = XHCI_EPCTX_2_DCS_GET(ep_ctx->qwEpCtx2); + devep->ep_tr = XHCI_GADDR(dev->xsc, devep->ep_ringaddr); + DPRINTF(("init_ep tr DCS %x\r\n", devep->ep_ccs)); + } + + if (devep->ep_xfer == NULL) { + devep->ep_xfer = malloc(sizeof(struct usb_data_xfer)); + USB_DATA_XFER_INIT(devep->ep_xfer); + } +} + +static void +pci_xhci_disable_ep(struct pci_xhci_dev_emu *dev, int epid) +{ + struct xhci_dev_ctx *dev_ctx; + struct pci_xhci_dev_ep *devep; + struct xhci_endp_ctx *ep_ctx; + + DPRINTF(("pci_xhci disable_ep %d\r\n", epid)); + + dev_ctx = dev->dev_ctx; + ep_ctx = &dev_ctx->ctx_ep[epid]; + ep_ctx->dwEpCtx0 = (ep_ctx->dwEpCtx0 & ~0x7) | XHCI_ST_EPCTX_DISABLED; + + devep = &dev->eps[epid]; + if (XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0) > 0 && + devep->ep_sctx_trbs != NULL) + free(devep->ep_sctx_trbs); + + if (devep->ep_xfer != NULL) { + free(devep->ep_xfer); + devep->ep_xfer = NULL; + } + + memset(devep, 0, sizeof(struct pci_xhci_dev_ep)); +} + + +/* reset device at slot and data structures related to it */ +static void +pci_xhci_reset_slot(struct pci_xhci_softc *sc, int slot) +{ + struct pci_xhci_dev_emu *dev; + + dev = XHCI_SLOTDEV_PTR(sc, slot); + + if (!dev) { + DPRINTF(("xhci reset unassigned slot (%d)?\r\n", slot)); + } else { + dev->dev_slotstate = XHCI_ST_DISABLED; + } + + /* TODO: reset ring buffer pointers */ +} + +static int +pci_xhci_insert_event(struct pci_xhci_softc *sc, struct xhci_trb *evtrb, + int do_intr) +{ + struct pci_xhci_rtsregs *rts; + uint64_t erdp; + int erdp_idx; + int err; + struct xhci_trb *evtrbptr; + + err = XHCI_TRB_ERROR_SUCCESS; + + rts = &sc->rtsregs; + + erdp = rts->intrreg.erdp & ~0xF; + erdp_idx = (erdp - rts->erstba_p[rts->er_deq_seg].qwEvrsTablePtr) / + sizeof(struct xhci_trb); + + DPRINTF(("pci_xhci: insert event 0[%lx] 2[%x] 3[%x]\r\n" + "\terdp idx %d/seg %d, enq idx %d/seg %d, pcs %u\r\n" + "\t(erdp=0x%lx, erst=0x%lx, tblsz=%u, do_intr %d)\r\n", + evtrb->qwTrb0, evtrb->dwTrb2, evtrb->dwTrb3, + erdp_idx, rts->er_deq_seg, rts->er_enq_idx, + rts->er_enq_seg, + rts->event_pcs, erdp, rts->erstba_p->qwEvrsTablePtr, + rts->erstba_p->dwEvrsTableSize, do_intr)); + + evtrbptr = &rts->erst_p[rts->er_enq_idx]; + + /* TODO: multi-segment table */ + if (rts->er_events_cnt >= rts->erstba_p->dwEvrsTableSize) { + DPRINTF(("pci_xhci[%d] cannot insert event; ring full\r\n", + __LINE__)); + err = XHCI_TRB_ERROR_EV_RING_FULL; + goto done; + } + + if (rts->er_events_cnt == rts->erstba_p->dwEvrsTableSize - 1) { + struct xhci_trb errev; + + if ((evtrbptr->dwTrb3 & 0x1) == (rts->event_pcs & 0x1)) { + + DPRINTF(("pci_xhci[%d] insert evt err: ring full\r\n", + __LINE__)); + + errev.qwTrb0 = 0; + errev.dwTrb2 = XHCI_TRB_2_ERROR_SET( + XHCI_TRB_ERROR_EV_RING_FULL); + errev.dwTrb3 = XHCI_TRB_3_TYPE_SET( + XHCI_TRB_EVENT_HOST_CTRL) | + rts->event_pcs; + rts->er_events_cnt++; + memcpy(&rts->erst_p[rts->er_enq_idx], &errev, + sizeof(struct xhci_trb)); + rts->er_enq_idx = (rts->er_enq_idx + 1) % + rts->erstba_p->dwEvrsTableSize; + err = XHCI_TRB_ERROR_EV_RING_FULL; + do_intr = 1; + + goto done; + } + } else { + rts->er_events_cnt++; + } + + evtrb->dwTrb3 &= ~XHCI_TRB_3_CYCLE_BIT; + evtrb->dwTrb3 |= rts->event_pcs; + + memcpy(&rts->erst_p[rts->er_enq_idx], evtrb, sizeof(struct xhci_trb)); + rts->er_enq_idx = (rts->er_enq_idx + 1) % + rts->erstba_p->dwEvrsTableSize; + + if (rts->er_enq_idx == 0) + rts->event_pcs ^= 1; + +done: + if (do_intr) + pci_xhci_assert_interrupt(sc); + + return (err); +} + +static uint32_t +pci_xhci_cmd_enable_slot(struct pci_xhci_softc *sc, uint32_t *slot) +{ + struct pci_xhci_dev_emu *dev; + uint32_t cmderr; + int i; + + cmderr = XHCI_TRB_ERROR_NO_SLOTS; + if (sc->portregs != NULL) + for (i = 1; i <= XHCI_MAX_SLOTS; i++) { + dev = XHCI_SLOTDEV_PTR(sc, i); + if (dev && dev->dev_slotstate == XHCI_ST_DISABLED) { + *slot = i; + dev->dev_slotstate = XHCI_ST_ENABLED; + cmderr = XHCI_TRB_ERROR_SUCCESS; + dev->hci.hci_address = i; + break; + } + } + + DPRINTF(("pci_xhci enable slot (error=%d) slot %u\r\n", + cmderr != XHCI_TRB_ERROR_SUCCESS, *slot)); + + return (cmderr); +} + +static uint32_t +pci_xhci_cmd_disable_slot(struct pci_xhci_softc *sc, uint32_t slot) +{ + struct pci_xhci_dev_emu *dev; + uint32_t cmderr; + + DPRINTF(("pci_xhci disable slot %u\r\n", slot)); + + cmderr = XHCI_TRB_ERROR_NO_SLOTS; + if (sc->portregs == NULL) + goto done; + + if (slot > sc->ndevices) { + cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON; + goto done; + } + + dev = XHCI_SLOTDEV_PTR(sc, slot); + if (dev) { + if (dev->dev_slotstate == XHCI_ST_DISABLED) { + cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON; + } else { + dev->dev_slotstate = XHCI_ST_DISABLED; + cmderr = XHCI_TRB_ERROR_SUCCESS; + /* TODO: reset events and endpoints */ + } + } + +done: + return (cmderr); +} + +static uint32_t +pci_xhci_cmd_reset_device(struct pci_xhci_softc *sc, uint32_t slot) +{ + struct pci_xhci_dev_emu *dev; + struct xhci_dev_ctx *dev_ctx; + struct xhci_endp_ctx *ep_ctx; + uint32_t cmderr; + int i; + + cmderr = XHCI_TRB_ERROR_NO_SLOTS; + if (sc->portregs == NULL) + goto done; + + DPRINTF(("pci_xhci reset device slot %u\r\n", slot)); + + dev = XHCI_SLOTDEV_PTR(sc, slot); + if (!dev || dev->dev_slotstate == XHCI_ST_DISABLED) + cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON; + else { + dev->dev_slotstate = XHCI_ST_DEFAULT; + + dev->hci.hci_address = 0; + dev_ctx = pci_xhci_get_dev_ctx(sc, slot); + + /* slot state */ + dev_ctx->ctx_slot.dwSctx3 = FIELD_REPLACE( + dev_ctx->ctx_slot.dwSctx3, XHCI_ST_SLCTX_DEFAULT, + 0x1F, 27); + + /* number of contexts */ + dev_ctx->ctx_slot.dwSctx0 = FIELD_REPLACE( + dev_ctx->ctx_slot.dwSctx0, 1, 0x1F, 27); + + /* reset all eps other than ep-0 */ + for (i = 2; i <= 31; i++) { + ep_ctx = &dev_ctx->ctx_ep[i]; + ep_ctx->dwEpCtx0 = FIELD_REPLACE( ep_ctx->dwEpCtx0, + XHCI_ST_EPCTX_DISABLED, 0x7, 0); + } + + cmderr = XHCI_TRB_ERROR_SUCCESS; + } + + pci_xhci_reset_slot(sc, slot); + +done: + return (cmderr); +} + +static uint32_t +pci_xhci_cmd_address_device(struct pci_xhci_softc *sc, uint32_t slot, + struct xhci_trb *trb) +{ + struct pci_xhci_dev_emu *dev; + struct xhci_input_dev_ctx *input_ctx; + struct xhci_slot_ctx *islot_ctx; + struct xhci_dev_ctx *dev_ctx; + struct xhci_endp_ctx *ep0_ctx; + uint32_t cmderr; + + input_ctx = XHCI_GADDR(sc, trb->qwTrb0 & ~0xFUL); + islot_ctx = &input_ctx->ctx_slot; + ep0_ctx = &input_ctx->ctx_ep[1]; + + cmderr = XHCI_TRB_ERROR_SUCCESS; + + DPRINTF(("pci_xhci: address device, input ctl: D 0x%08x A 0x%08x,\r\n" + " slot %08x %08x %08x %08x\r\n" + " ep0 %08x %08x %016lx %08x\r\n", + input_ctx->ctx_input.dwInCtx0, input_ctx->ctx_input.dwInCtx1, + islot_ctx->dwSctx0, islot_ctx->dwSctx1, + islot_ctx->dwSctx2, islot_ctx->dwSctx3, + ep0_ctx->dwEpCtx0, ep0_ctx->dwEpCtx1, ep0_ctx->qwEpCtx2, + ep0_ctx->dwEpCtx4)); + + /* when setting address: drop-ctx=0, add-ctx=slot+ep0 */ + if ((input_ctx->ctx_input.dwInCtx0 != 0) || + (input_ctx->ctx_input.dwInCtx1 & 0x03) != 0x03) { + DPRINTF(("pci_xhci: address device, input ctl invalid\r\n")); + cmderr = XHCI_TRB_ERROR_TRB; + goto done; + } + + /* assign address to slot */ + dev_ctx = pci_xhci_get_dev_ctx(sc, slot); + + DPRINTF(("pci_xhci: address device, dev ctx\r\n" + " slot %08x %08x %08x %08x\r\n", + dev_ctx->ctx_slot.dwSctx0, dev_ctx->ctx_slot.dwSctx1, + dev_ctx->ctx_slot.dwSctx2, dev_ctx->ctx_slot.dwSctx3)); + + dev = XHCI_SLOTDEV_PTR(sc, slot); + assert(dev != NULL); + + dev->hci.hci_address = slot; + dev->dev_ctx = dev_ctx; + + if (dev->dev_ue->ue_reset == NULL || + dev->dev_ue->ue_reset(dev->dev_sc) < 0) { + cmderr = XHCI_TRB_ERROR_ENDP_NOT_ON; + goto done; + } + + memcpy(&dev_ctx->ctx_slot, islot_ctx, sizeof(struct xhci_slot_ctx)); + + dev_ctx->ctx_slot.dwSctx3 = + XHCI_SCTX_3_SLOT_STATE_SET(XHCI_ST_SLCTX_ADDRESSED) | + XHCI_SCTX_3_DEV_ADDR_SET(slot); + + memcpy(&dev_ctx->ctx_ep[1], ep0_ctx, sizeof(struct xhci_endp_ctx)); + ep0_ctx = &dev_ctx->ctx_ep[1]; + ep0_ctx->dwEpCtx0 = (ep0_ctx->dwEpCtx0 & ~0x7) | + XHCI_EPCTX_0_EPSTATE_SET(XHCI_ST_EPCTX_RUNNING); + + pci_xhci_init_ep(dev, 1); + + dev->dev_slotstate = XHCI_ST_ADDRESSED; + + DPRINTF(("pci_xhci: address device, output ctx\r\n" + " slot %08x %08x %08x %08x\r\n" + " ep0 %08x %08x %016lx %08x\r\n", + dev_ctx->ctx_slot.dwSctx0, dev_ctx->ctx_slot.dwSctx1, + dev_ctx->ctx_slot.dwSctx2, dev_ctx->ctx_slot.dwSctx3, + ep0_ctx->dwEpCtx0, ep0_ctx->dwEpCtx1, ep0_ctx->qwEpCtx2, + ep0_ctx->dwEpCtx4)); + +done: + return (cmderr); +} + +static uint32_t +pci_xhci_cmd_config_ep(struct pci_xhci_softc *sc, uint32_t slot, + struct xhci_trb *trb) +{ + struct xhci_input_dev_ctx *input_ctx; + struct pci_xhci_dev_emu *dev; + struct xhci_dev_ctx *dev_ctx; + struct xhci_endp_ctx *ep_ctx, *iep_ctx; + uint32_t cmderr; + int i; + + cmderr = XHCI_TRB_ERROR_SUCCESS; + + DPRINTF(("pci_xhci config_ep slot %u\r\n", slot)); + + dev = XHCI_SLOTDEV_PTR(sc, slot); + assert(dev != NULL); + + if ((trb->dwTrb3 & XHCI_TRB_3_DCEP_BIT) != 0) { + DPRINTF(("pci_xhci config_ep - deconfigure ep slot %u\r\n", + slot)); + if (dev->dev_ue->ue_stop != NULL) + dev->dev_ue->ue_stop(dev->dev_sc); + + dev->dev_slotstate = XHCI_ST_ADDRESSED; + + dev->hci.hci_address = 0; + dev_ctx = pci_xhci_get_dev_ctx(sc, slot); + + /* number of contexts */ + dev_ctx->ctx_slot.dwSctx0 = FIELD_REPLACE( + dev_ctx->ctx_slot.dwSctx0, 1, 0x1F, 27); + + /* slot state */ + dev_ctx->ctx_slot.dwSctx3 = FIELD_REPLACE( + dev_ctx->ctx_slot.dwSctx3, XHCI_ST_SLCTX_ADDRESSED, + 0x1F, 27); + + /* disable endpoints */ + for (i = 2; i < 32; i++) + pci_xhci_disable_ep(dev, i); + + cmderr = XHCI_TRB_ERROR_SUCCESS; + + goto done; + } + + if (dev->dev_slotstate < XHCI_ST_ADDRESSED) { + DPRINTF(("pci_xhci: config_ep slotstate x%x != addressed\r\n", + dev->dev_slotstate)); + cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON; + goto done; + } + + /* In addressed/configured state; + * for each drop endpoint ctx flag: + * ep->state = DISABLED + * for each add endpoint ctx flag: + * cp(ep-in, ep-out) + * ep->state = RUNNING + * for each drop+add endpoint flag: + * reset ep resources + * cp(ep-in, ep-out) + * ep->state = RUNNING + * if input->DisabledCtx[2-31] < 30: (at least 1 ep not disabled) + * slot->state = configured + */ + + input_ctx = XHCI_GADDR(sc, trb->qwTrb0 & ~0xFUL); + dev_ctx = dev->dev_ctx; + DPRINTF(("pci_xhci: config_ep inputctx: D:x%08x A:x%08x 7:x%08x\r\n", + input_ctx->ctx_input.dwInCtx0, input_ctx->ctx_input.dwInCtx1, + input_ctx->ctx_input.dwInCtx7)); + + for (i = 2; i <= 31; i++) { + ep_ctx = &dev_ctx->ctx_ep[i]; + + if (input_ctx->ctx_input.dwInCtx0 & + XHCI_INCTX_0_DROP_MASK(i)) { + DPRINTF((" config ep - dropping ep %d\r\n", i)); + pci_xhci_disable_ep(dev, i); + } + + if (input_ctx->ctx_input.dwInCtx1 & + XHCI_INCTX_1_ADD_MASK(i)) { + iep_ctx = &input_ctx->ctx_ep[i]; + + DPRINTF((" enable ep[%d] %08x %08x %016lx %08x\r\n", + i, iep_ctx->dwEpCtx0, iep_ctx->dwEpCtx1, + iep_ctx->qwEpCtx2, iep_ctx->dwEpCtx4)); + + memcpy(ep_ctx, iep_ctx, sizeof(struct xhci_endp_ctx)); + + pci_xhci_init_ep(dev, i); + + /* ep state */ + ep_ctx->dwEpCtx0 = FIELD_REPLACE( + ep_ctx->dwEpCtx0, XHCI_ST_EPCTX_RUNNING, 0x7, 0); + } + } + + /* slot state to configured */ + dev_ctx->ctx_slot.dwSctx3 = FIELD_REPLACE( + dev_ctx->ctx_slot.dwSctx3, XHCI_ST_SLCTX_CONFIGURED, 0x1F, 27); + dev_ctx->ctx_slot.dwSctx0 = FIELD_COPY( + dev_ctx->ctx_slot.dwSctx0, input_ctx->ctx_slot.dwSctx0, 0x1F, 27); + dev->dev_slotstate = XHCI_ST_CONFIGURED; + + DPRINTF(("EP configured; slot %u [0]=0x%08x [1]=0x%08x [2]=0x%08x " + "[3]=0x%08x\r\n", + slot, dev_ctx->ctx_slot.dwSctx0, dev_ctx->ctx_slot.dwSctx1, + dev_ctx->ctx_slot.dwSctx2, dev_ctx->ctx_slot.dwSctx3)); + +done: + return (cmderr); +} + +static uint32_t +pci_xhci_cmd_reset_ep(struct pci_xhci_softc *sc, uint32_t slot, + struct xhci_trb *trb) +{ + struct pci_xhci_dev_emu *dev; + struct pci_xhci_dev_ep *devep; + struct xhci_dev_ctx *dev_ctx; + struct xhci_endp_ctx *ep_ctx; + uint32_t cmderr, epid; + uint32_t type; + + epid = XHCI_TRB_3_EP_GET(trb->dwTrb3); + + DPRINTF(("pci_xhci: reset ep %u: slot %u\r\n", epid, slot)); + + cmderr = XHCI_TRB_ERROR_SUCCESS; + + type = XHCI_TRB_3_TYPE_GET(trb->dwTrb3); + + dev = XHCI_SLOTDEV_PTR(sc, slot); + assert(dev != NULL); + + if (type == XHCI_TRB_TYPE_STOP_EP && + (trb->dwTrb3 & XHCI_TRB_3_SUSP_EP_BIT) != 0) { + /* XXX suspend endpoint for 10ms */ + } + + if (epid < 1 || epid > 31) { + DPRINTF(("pci_xhci: reset ep: invalid epid %u\r\n", epid)); + cmderr = XHCI_TRB_ERROR_TRB; + goto done; + } + + devep = &dev->eps[epid]; + if (devep->ep_xfer != NULL) + USB_DATA_XFER_RESET(devep->ep_xfer); + + dev_ctx = dev->dev_ctx; + assert(dev_ctx != NULL); + + ep_ctx = &dev_ctx->ctx_ep[epid]; + + ep_ctx->dwEpCtx0 = (ep_ctx->dwEpCtx0 & ~0x7) | XHCI_ST_EPCTX_STOPPED; + + if (XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0) == 0) + ep_ctx->qwEpCtx2 = devep->ep_ringaddr | devep->ep_ccs; + + DPRINTF(("pci_xhci: reset ep[%u] %08x %08x %016lx %08x\r\n", + epid, ep_ctx->dwEpCtx0, ep_ctx->dwEpCtx1, ep_ctx->qwEpCtx2, + ep_ctx->dwEpCtx4)); + + if (type == XHCI_TRB_TYPE_RESET_EP && + (dev->dev_ue->ue_reset == NULL || + dev->dev_ue->ue_reset(dev->dev_sc) < 0)) { + cmderr = XHCI_TRB_ERROR_ENDP_NOT_ON; + goto done; + } + +done: + return (cmderr); +} + + +static uint32_t +pci_xhci_find_stream(struct pci_xhci_softc *sc, struct xhci_endp_ctx *ep, + uint32_t streamid, struct xhci_stream_ctx **osctx) +{ + struct xhci_stream_ctx *sctx; + uint32_t maxpstreams; + + maxpstreams = XHCI_EPCTX_0_MAXP_STREAMS_GET(ep->dwEpCtx0); + if (maxpstreams == 0) + return (XHCI_TRB_ERROR_TRB); + + if (maxpstreams > XHCI_STREAMS_MAX) + return (XHCI_TRB_ERROR_INVALID_SID); + + if (XHCI_EPCTX_0_LSA_GET(ep->dwEpCtx0) == 0) { + DPRINTF(("pci_xhci: find_stream; LSA bit not set\r\n")); + return (XHCI_TRB_ERROR_INVALID_SID); + } + + /* only support primary stream */ + if (streamid > maxpstreams) + return (XHCI_TRB_ERROR_STREAM_TYPE); + + sctx = XHCI_GADDR(sc, ep->qwEpCtx2 & ~0xFUL) + streamid; + if (!XHCI_SCTX_0_SCT_GET(sctx->qwSctx0)) + return (XHCI_TRB_ERROR_STREAM_TYPE); + + *osctx = sctx; + + return (XHCI_TRB_ERROR_SUCCESS); +} + + +static uint32_t +pci_xhci_cmd_set_tr(struct pci_xhci_softc *sc, uint32_t slot, + struct xhci_trb *trb) +{ + struct pci_xhci_dev_emu *dev; + struct pci_xhci_dev_ep *devep; + struct xhci_dev_ctx *dev_ctx; + struct xhci_endp_ctx *ep_ctx; + uint32_t cmderr, epid; + uint32_t streamid; + + cmderr = XHCI_TRB_ERROR_SUCCESS; + + dev = XHCI_SLOTDEV_PTR(sc, slot); + assert(dev != NULL); + + DPRINTF(("pci_xhci set_tr: new-tr x%016lx, SCT %u DCS %u\r\n" + " stream-id %u, slot %u, epid %u, C %u\r\n", + (trb->qwTrb0 & ~0xF), (uint32_t)((trb->qwTrb0 >> 1) & 0x7), + (uint32_t)(trb->qwTrb0 & 0x1), (trb->dwTrb2 >> 16) & 0xFFFF, + XHCI_TRB_3_SLOT_GET(trb->dwTrb3), + XHCI_TRB_3_EP_GET(trb->dwTrb3), trb->dwTrb3 & 0x1)); + + epid = XHCI_TRB_3_EP_GET(trb->dwTrb3); + if (epid < 1 || epid > 31) { + DPRINTF(("pci_xhci: set_tr_deq: invalid epid %u\r\n", epid)); + cmderr = XHCI_TRB_ERROR_TRB; + goto done; + } + + dev_ctx = dev->dev_ctx; + assert(dev_ctx != NULL); + + ep_ctx = &dev_ctx->ctx_ep[epid]; + devep = &dev->eps[epid]; + + switch (XHCI_EPCTX_0_EPSTATE_GET(ep_ctx->dwEpCtx0)) { + case XHCI_ST_EPCTX_STOPPED: + case XHCI_ST_EPCTX_ERROR: + break; + default: + DPRINTF(("pci_xhci cmd set_tr invalid state %x\r\n", + XHCI_EPCTX_0_EPSTATE_GET(ep_ctx->dwEpCtx0))); + cmderr = XHCI_TRB_ERROR_CONTEXT_STATE; + goto done; + } + + streamid = XHCI_TRB_2_STREAM_GET(trb->dwTrb2); + if (XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0) > 0) { + struct xhci_stream_ctx *sctx; + + sctx = NULL; + cmderr = pci_xhci_find_stream(sc, ep_ctx, streamid, &sctx); + if (sctx != NULL) { + assert(devep->ep_sctx != NULL); + + devep->ep_sctx[streamid].qwSctx0 = trb->qwTrb0; + devep->ep_sctx_trbs[streamid].ringaddr = + trb->qwTrb0 & ~0xF; + devep->ep_sctx_trbs[streamid].ccs = + XHCI_EPCTX_2_DCS_GET(trb->qwTrb0); + } + } else { + if (streamid != 0) { + DPRINTF(("pci_xhci cmd set_tr streamid %x != 0\r\n", + streamid)); + } + ep_ctx->qwEpCtx2 = trb->qwTrb0 & ~0xFUL; + devep->ep_ringaddr = ep_ctx->qwEpCtx2 & ~0xFUL; + devep->ep_ccs = trb->qwTrb0 & 0x1; + devep->ep_tr = XHCI_GADDR(sc, devep->ep_ringaddr); + + DPRINTF(("pci_xhci set_tr first TRB:\r\n")); + pci_xhci_dump_trb(devep->ep_tr); + } + ep_ctx->dwEpCtx0 = (ep_ctx->dwEpCtx0 & ~0x7) | XHCI_ST_EPCTX_STOPPED; + +done: + return (cmderr); +} + +static uint32_t +pci_xhci_cmd_eval_ctx(struct pci_xhci_softc *sc, uint32_t slot, + struct xhci_trb *trb) +{ + struct xhci_input_dev_ctx *input_ctx; + struct xhci_slot_ctx *islot_ctx; + struct xhci_dev_ctx *dev_ctx; + struct xhci_endp_ctx *ep0_ctx; + uint32_t cmderr; + + input_ctx = XHCI_GADDR(sc, trb->qwTrb0 & ~0xFUL); + islot_ctx = &input_ctx->ctx_slot; + ep0_ctx = &input_ctx->ctx_ep[1]; + + cmderr = XHCI_TRB_ERROR_SUCCESS; + DPRINTF(("pci_xhci: eval ctx, input ctl: D 0x%08x A 0x%08x,\r\n" + " slot %08x %08x %08x %08x\r\n" + " ep0 %08x %08x %016lx %08x\r\n", + input_ctx->ctx_input.dwInCtx0, input_ctx->ctx_input.dwInCtx1, + islot_ctx->dwSctx0, islot_ctx->dwSctx1, + islot_ctx->dwSctx2, islot_ctx->dwSctx3, + ep0_ctx->dwEpCtx0, ep0_ctx->dwEpCtx1, ep0_ctx->qwEpCtx2, + ep0_ctx->dwEpCtx4)); + + /* this command expects drop-ctx=0 & add-ctx=slot+ep0 */ + if ((input_ctx->ctx_input.dwInCtx0 != 0) || + (input_ctx->ctx_input.dwInCtx1 & 0x03) == 0) { + DPRINTF(("pci_xhci: eval ctx, input ctl invalid\r\n")); + cmderr = XHCI_TRB_ERROR_TRB; + goto done; + } + + /* assign address to slot; in this emulation, slot_id = address */ + dev_ctx = pci_xhci_get_dev_ctx(sc, slot); + + DPRINTF(("pci_xhci: eval ctx, dev ctx\r\n" + " slot %08x %08x %08x %08x\r\n", + dev_ctx->ctx_slot.dwSctx0, dev_ctx->ctx_slot.dwSctx1, + dev_ctx->ctx_slot.dwSctx2, dev_ctx->ctx_slot.dwSctx3)); + + if (input_ctx->ctx_input.dwInCtx1 & 0x01) { /* slot ctx */ + /* set max exit latency */ + dev_ctx->ctx_slot.dwSctx1 = FIELD_COPY( + dev_ctx->ctx_slot.dwSctx1, input_ctx->ctx_slot.dwSctx1, + 0xFFFF, 0); + + /* set interrupter target */ + dev_ctx->ctx_slot.dwSctx2 = FIELD_COPY( + dev_ctx->ctx_slot.dwSctx2, input_ctx->ctx_slot.dwSctx2, + 0x3FF, 22); + } + if (input_ctx->ctx_input.dwInCtx1 & 0x02) { /* control ctx */ + /* set max packet size */ + dev_ctx->ctx_ep[1].dwEpCtx1 = FIELD_COPY( + dev_ctx->ctx_ep[1].dwEpCtx1, ep0_ctx->dwEpCtx1, + 0xFFFF, 16); + + ep0_ctx = &dev_ctx->ctx_ep[1]; + } + + DPRINTF(("pci_xhci: eval ctx, output ctx\r\n" + " slot %08x %08x %08x %08x\r\n" + " ep0 %08x %08x %016lx %08x\r\n", + dev_ctx->ctx_slot.dwSctx0, dev_ctx->ctx_slot.dwSctx1, + dev_ctx->ctx_slot.dwSctx2, dev_ctx->ctx_slot.dwSctx3, + ep0_ctx->dwEpCtx0, ep0_ctx->dwEpCtx1, ep0_ctx->qwEpCtx2, + ep0_ctx->dwEpCtx4)); + +done: + return (cmderr); +} + +static int +pci_xhci_complete_commands(struct pci_xhci_softc *sc) +{ + struct xhci_trb evtrb; + struct xhci_trb *trb; + uint64_t crcr; + uint32_t ccs; /* cycle state (XHCI 4.9.2) */ + uint32_t type; + uint32_t slot; + uint32_t cmderr; + int error; + + error = 0; + sc->opregs.crcr |= XHCI_CRCR_LO_CRR; + + trb = sc->opregs.cr_p; + ccs = sc->opregs.crcr & XHCI_CRCR_LO_RCS; + crcr = sc->opregs.crcr & ~0xF; + + while (1) { + sc->opregs.cr_p = trb; + + type = XHCI_TRB_3_TYPE_GET(trb->dwTrb3); + + if ((trb->dwTrb3 & XHCI_TRB_3_CYCLE_BIT) != + (ccs & XHCI_TRB_3_CYCLE_BIT)) + break; + + DPRINTF(("pci_xhci: cmd type 0x%x, Trb0 x%016lx dwTrb2 x%08x" + " dwTrb3 x%08x, TRB_CYCLE %u/ccs %u\r\n", + type, trb->qwTrb0, trb->dwTrb2, trb->dwTrb3, + trb->dwTrb3 & XHCI_TRB_3_CYCLE_BIT, ccs)); + + cmderr = XHCI_TRB_ERROR_SUCCESS; + evtrb.dwTrb2 = 0; + evtrb.dwTrb3 = (ccs & XHCI_TRB_3_CYCLE_BIT) | + XHCI_TRB_3_TYPE_SET(XHCI_TRB_EVENT_CMD_COMPLETE); + slot = 0; + + switch (type) { + case XHCI_TRB_TYPE_LINK: /* 0x06 */ + if (trb->dwTrb3 & XHCI_TRB_3_TC_BIT) + ccs ^= XHCI_CRCR_LO_RCS; + break; + + case XHCI_TRB_TYPE_ENABLE_SLOT: /* 0x09 */ + cmderr = pci_xhci_cmd_enable_slot(sc, &slot); + break; + + case XHCI_TRB_TYPE_DISABLE_SLOT: /* 0x0A */ + slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); + cmderr = pci_xhci_cmd_disable_slot(sc, slot); + break; + + case XHCI_TRB_TYPE_ADDRESS_DEVICE: /* 0x0B */ + slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); + cmderr = pci_xhci_cmd_address_device(sc, slot, trb); + break; + + case XHCI_TRB_TYPE_CONFIGURE_EP: /* 0x0C */ + slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); + cmderr = pci_xhci_cmd_config_ep(sc, slot, trb); + break; + + case XHCI_TRB_TYPE_EVALUATE_CTX: /* 0x0D */ + slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); + cmderr = pci_xhci_cmd_eval_ctx(sc, slot, trb); + break; + + case XHCI_TRB_TYPE_RESET_EP: /* 0x0E */ + DPRINTF(("Reset Endpoint on slot %d\r\n", slot)); + slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); + cmderr = pci_xhci_cmd_reset_ep(sc, slot, trb); + break; + + case XHCI_TRB_TYPE_STOP_EP: /* 0x0F */ + DPRINTF(("Stop Endpoint on slot %d\r\n", slot)); + slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); + cmderr = pci_xhci_cmd_reset_ep(sc, slot, trb); + break; + + case XHCI_TRB_TYPE_SET_TR_DEQUEUE: /* 0x10 */ + slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); + cmderr = pci_xhci_cmd_set_tr(sc, slot, trb); + break; + + case XHCI_TRB_TYPE_RESET_DEVICE: /* 0x11 */ + slot = XHCI_TRB_3_SLOT_GET(trb->dwTrb3); + cmderr = pci_xhci_cmd_reset_device(sc, slot); + break; + + case XHCI_TRB_TYPE_FORCE_EVENT: /* 0x12 */ + /* TODO: */ + break; + + case XHCI_TRB_TYPE_NEGOTIATE_BW: /* 0x13 */ + break; + + case XHCI_TRB_TYPE_SET_LATENCY_TOL: /* 0x14 */ + break; + + case XHCI_TRB_TYPE_GET_PORT_BW: /* 0x15 */ + break; + + case XHCI_TRB_TYPE_FORCE_HEADER: /* 0x16 */ + break; + + case XHCI_TRB_TYPE_NOOP_CMD: /* 0x17 */ + break; + + default: + DPRINTF(("pci_xhci: unsupported cmd %x\r\n", type)); + break; + } + + if (type != XHCI_TRB_TYPE_LINK) { + /* + * insert command completion event and assert intr + */ + evtrb.qwTrb0 = crcr; + evtrb.dwTrb2 |= XHCI_TRB_2_ERROR_SET(cmderr); + evtrb.dwTrb3 |= XHCI_TRB_3_SLOT_SET(slot); + DPRINTF(("pci_xhci: command 0x%x result: 0x%x\r\n", + type, cmderr)); + pci_xhci_insert_event(sc, &evtrb, 1); + } + + trb = pci_xhci_trb_next(sc, trb, &crcr); + } + + sc->opregs.crcr = crcr | (sc->opregs.crcr & XHCI_CRCR_LO_CA) | ccs; + sc->opregs.crcr &= ~XHCI_CRCR_LO_CRR; + return (error); +} + +static void +pci_xhci_dump_trb(struct xhci_trb *trb) +{ + static const char *trbtypes[] = { + "RESERVED", + "NORMAL", + "SETUP_STAGE", + "DATA_STAGE", + "STATUS_STAGE", + "ISOCH", + "LINK", + "EVENT_DATA", + "NOOP", + "ENABLE_SLOT", + "DISABLE_SLOT", + "ADDRESS_DEVICE", + "CONFIGURE_EP", + "EVALUATE_CTX", + "RESET_EP", + "STOP_EP", + "SET_TR_DEQUEUE", + "RESET_DEVICE", + "FORCE_EVENT", + "NEGOTIATE_BW", + "SET_LATENCY_TOL", + "GET_PORT_BW", + "FORCE_HEADER", + "NOOP_CMD" + }; + uint32_t type; + + type = XHCI_TRB_3_TYPE_GET(trb->dwTrb3); + DPRINTF(("pci_xhci: trb[@%p] type x%02x %s 0:x%016lx 2:x%08x 3:x%08x\r\n", + trb, type, + type <= XHCI_TRB_TYPE_NOOP_CMD ? trbtypes[type] : "INVALID", + trb->qwTrb0, trb->dwTrb2, trb->dwTrb3)); +} + +static int +pci_xhci_xfer_complete(struct pci_xhci_softc *sc, struct usb_data_xfer *xfer, + uint32_t slot, uint32_t epid, int *do_intr) +{ + struct pci_xhci_dev_emu *dev; + struct pci_xhci_dev_ep *devep; + struct xhci_dev_ctx *dev_ctx; + struct xhci_endp_ctx *ep_ctx; + struct xhci_trb *trb; + struct xhci_trb evtrb; + uint32_t trbflags; + uint32_t edtla; + int i, err; + + dev = XHCI_SLOTDEV_PTR(sc, slot); + devep = &dev->eps[epid]; + dev_ctx = pci_xhci_get_dev_ctx(sc, slot); + + assert(dev_ctx != NULL); + + ep_ctx = &dev_ctx->ctx_ep[epid]; + + err = XHCI_TRB_ERROR_SUCCESS; + *do_intr = 0; + edtla = 0; + + /* go through list of TRBs and insert event(s) */ + for (i = xfer->head; xfer->ndata > 0; ) { + evtrb.qwTrb0 = (uint64_t)xfer->data[i].hci_data; + trb = XHCI_GADDR(sc, evtrb.qwTrb0); + trbflags = trb->dwTrb3; + + DPRINTF(("pci_xhci: xfer[%d] done?%u:%d trb %x %016lx %x " + "(err %d) IOC?%d\r\n", + i, xfer->data[i].processed, xfer->data[i].blen, + XHCI_TRB_3_TYPE_GET(trbflags), evtrb.qwTrb0, + trbflags, err, + trb->dwTrb3 & XHCI_TRB_3_IOC_BIT ? 1 : 0)); + + if (!xfer->data[i].processed) { + xfer->head = i; + break; + } + + xfer->ndata--; + edtla += xfer->data[i].bdone; + + trb->dwTrb3 = (trb->dwTrb3 & ~0x1) | (xfer->data[i].ccs); + + pci_xhci_update_ep_ring(sc, dev, devep, ep_ctx, + xfer->data[i].streamid, xfer->data[i].trbnext, + xfer->data[i].ccs); + + /* Only interrupt if IOC or short packet */ + if (!(trb->dwTrb3 & XHCI_TRB_3_IOC_BIT) && + !((err == XHCI_TRB_ERROR_SHORT_PKT) && + (trb->dwTrb3 & XHCI_TRB_3_ISP_BIT))) { + + i = (i + 1) % USB_MAX_XFER_BLOCKS; + continue; + } + + evtrb.dwTrb2 = XHCI_TRB_2_ERROR_SET(err) | + XHCI_TRB_2_REM_SET(xfer->data[i].blen); + + evtrb.dwTrb3 = XHCI_TRB_3_TYPE_SET(XHCI_TRB_EVENT_TRANSFER) | + XHCI_TRB_3_SLOT_SET(slot) | XHCI_TRB_3_EP_SET(epid); + + if (XHCI_TRB_3_TYPE_GET(trbflags) == XHCI_TRB_TYPE_EVENT_DATA) { + DPRINTF(("pci_xhci EVENT_DATA edtla %u\r\n", edtla)); + evtrb.qwTrb0 = trb->qwTrb0; + evtrb.dwTrb2 = (edtla & 0xFFFFF) | + XHCI_TRB_2_ERROR_SET(err); + evtrb.dwTrb3 |= XHCI_TRB_3_ED_BIT; + edtla = 0; + } + + *do_intr = 1; + + err = pci_xhci_insert_event(sc, &evtrb, 0); + if (err != XHCI_TRB_ERROR_SUCCESS) { + break; + } + + i = (i + 1) % USB_MAX_XFER_BLOCKS; + } + + return (err); +} + +static void +pci_xhci_update_ep_ring(struct pci_xhci_softc *sc, struct pci_xhci_dev_emu *dev, + struct pci_xhci_dev_ep *devep, struct xhci_endp_ctx *ep_ctx, + uint32_t streamid, uint64_t ringaddr, int ccs) +{ + + if (XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0) != 0) { + devep->ep_sctx[streamid].qwSctx0 = (ringaddr & ~0xFUL) | + (ccs & 0x1); + + devep->ep_sctx_trbs[streamid].ringaddr = ringaddr & ~0xFUL; + devep->ep_sctx_trbs[streamid].ccs = ccs & 0x1; + ep_ctx->qwEpCtx2 = (ep_ctx->qwEpCtx2 & ~0x1) | (ccs & 0x1); + + DPRINTF(("xhci update ep-ring stream %d, addr %lx\r\n", + streamid, devep->ep_sctx[streamid].qwSctx0)); + } else { + devep->ep_ringaddr = ringaddr & ~0xFUL; + devep->ep_ccs = ccs & 0x1; + devep->ep_tr = XHCI_GADDR(sc, ringaddr & ~0xFUL); + ep_ctx->qwEpCtx2 = (ringaddr & ~0xFUL) | (ccs & 0x1); + + DPRINTF(("xhci update ep-ring, addr %lx\r\n", + (devep->ep_ringaddr | devep->ep_ccs))); + } +} + +/* + * Outstanding transfer still in progress (device NAK'd earlier) so retry + * the transfer again to see if it succeeds. + */ +static int +pci_xhci_try_usb_xfer(struct pci_xhci_softc *sc, + struct pci_xhci_dev_emu *dev, struct pci_xhci_dev_ep *devep, + struct xhci_endp_ctx *ep_ctx, uint32_t slot, uint32_t epid) +{ + struct usb_data_xfer *xfer; + int err; + int do_intr; + + ep_ctx->dwEpCtx0 = FIELD_REPLACE( + ep_ctx->dwEpCtx0, XHCI_ST_EPCTX_RUNNING, 0x7, 0); + + err = 0; + do_intr = 0; + + xfer = devep->ep_xfer; +#ifdef __FreeBSD__ + USB_DATA_XFER_LOCK(xfer); +#else + /* + * At least one caller needs to hold this lock across the call to this + * function and other code. To avoid deadlock from a recursive mutex + * enter, we ensure that all callers hold this lock. + */ + assert(USB_DATA_XFER_LOCK_HELD(xfer)); +#endif + + /* outstanding requests queued up */ + if (dev->dev_ue->ue_data != NULL) { + err = dev->dev_ue->ue_data(dev->dev_sc, xfer, + epid & 0x1 ? USB_XFER_IN : USB_XFER_OUT, epid/2); + if (err == USB_ERR_CANCELLED) { + if (USB_DATA_GET_ERRCODE(&xfer->data[xfer->head]) == + USB_NAK) + err = XHCI_TRB_ERROR_SUCCESS; + } else { + err = pci_xhci_xfer_complete(sc, xfer, slot, epid, + &do_intr); + if (err == XHCI_TRB_ERROR_SUCCESS && do_intr) { + pci_xhci_assert_interrupt(sc); + } + + + /* XXX should not do it if error? */ + USB_DATA_XFER_RESET(xfer); + } + } + +#ifdef __FreeBSD__ + USB_DATA_XFER_UNLOCK(xfer); +#endif + + return (err); +} + + +static int +pci_xhci_handle_transfer(struct pci_xhci_softc *sc, + struct pci_xhci_dev_emu *dev, struct pci_xhci_dev_ep *devep, + struct xhci_endp_ctx *ep_ctx, struct xhci_trb *trb, uint32_t slot, + uint32_t epid, uint64_t addr, uint32_t ccs, uint32_t streamid) +{ + struct xhci_trb *setup_trb; + struct usb_data_xfer *xfer; + struct usb_data_xfer_block *xfer_block; + uint64_t val; + uint32_t trbflags; + int do_intr, err; + int do_retry; + + ep_ctx->dwEpCtx0 = FIELD_REPLACE(ep_ctx->dwEpCtx0, + XHCI_ST_EPCTX_RUNNING, 0x7, 0); + + xfer = devep->ep_xfer; + USB_DATA_XFER_LOCK(xfer); + + DPRINTF(("pci_xhci handle_transfer slot %u\r\n", slot)); + +retry: + err = 0; + do_retry = 0; + do_intr = 0; + setup_trb = NULL; + + while (1) { + pci_xhci_dump_trb(trb); + + trbflags = trb->dwTrb3; + + if (XHCI_TRB_3_TYPE_GET(trbflags) != XHCI_TRB_TYPE_LINK && + (trbflags & XHCI_TRB_3_CYCLE_BIT) != + (ccs & XHCI_TRB_3_CYCLE_BIT)) { + DPRINTF(("Cycle-bit changed trbflags %x, ccs %x\r\n", + trbflags & XHCI_TRB_3_CYCLE_BIT, ccs)); + break; + } + + xfer_block = NULL; + + switch (XHCI_TRB_3_TYPE_GET(trbflags)) { + case XHCI_TRB_TYPE_LINK: + if (trb->dwTrb3 & XHCI_TRB_3_TC_BIT) + ccs ^= 0x1; + + xfer_block = usb_data_xfer_append(xfer, NULL, 0, + (void *)addr, ccs); + xfer_block->processed = 1; + break; + + case XHCI_TRB_TYPE_SETUP_STAGE: + if ((trbflags & XHCI_TRB_3_IDT_BIT) == 0 || + XHCI_TRB_2_BYTES_GET(trb->dwTrb2) != 8) { + DPRINTF(("pci_xhci: invalid setup trb\r\n")); + err = XHCI_TRB_ERROR_TRB; + goto errout; + } + setup_trb = trb; + + val = trb->qwTrb0; + if (!xfer->ureq) + xfer->ureq = malloc( + sizeof(struct usb_device_request)); + memcpy(xfer->ureq, &val, + sizeof(struct usb_device_request)); + + xfer_block = usb_data_xfer_append(xfer, NULL, 0, + (void *)addr, ccs); + xfer_block->processed = 1; + break; + + case XHCI_TRB_TYPE_NORMAL: + case XHCI_TRB_TYPE_ISOCH: + if (setup_trb != NULL) { + DPRINTF(("pci_xhci: trb not supposed to be in " + "ctl scope\r\n")); + err = XHCI_TRB_ERROR_TRB; + goto errout; + } + /* fall through */ + + case XHCI_TRB_TYPE_DATA_STAGE: + xfer_block = usb_data_xfer_append(xfer, + (void *)(trbflags & XHCI_TRB_3_IDT_BIT ? + &trb->qwTrb0 : XHCI_GADDR(sc, trb->qwTrb0)), + trb->dwTrb2 & 0x1FFFF, (void *)addr, ccs); + break; + + case XHCI_TRB_TYPE_STATUS_STAGE: + xfer_block = usb_data_xfer_append(xfer, NULL, 0, + (void *)addr, ccs); + break; + + case XHCI_TRB_TYPE_NOOP: + xfer_block = usb_data_xfer_append(xfer, NULL, 0, + (void *)addr, ccs); + xfer_block->processed = 1; + break; + + case XHCI_TRB_TYPE_EVENT_DATA: + xfer_block = usb_data_xfer_append(xfer, NULL, 0, + (void *)addr, ccs); + if ((epid > 1) && (trbflags & XHCI_TRB_3_IOC_BIT)) { + xfer_block->processed = 1; + } + break; + + default: + DPRINTF(("pci_xhci: handle xfer unexpected trb type " + "0x%x\r\n", + XHCI_TRB_3_TYPE_GET(trbflags))); + err = XHCI_TRB_ERROR_TRB; + goto errout; + } + + trb = pci_xhci_trb_next(sc, trb, &addr); + + DPRINTF(("pci_xhci: next trb: 0x%lx\r\n", (uint64_t)trb)); + + if (xfer_block) { + xfer_block->trbnext = addr; + xfer_block->streamid = streamid; + } + + if (!setup_trb && !(trbflags & XHCI_TRB_3_CHAIN_BIT) && + XHCI_TRB_3_TYPE_GET(trbflags) != XHCI_TRB_TYPE_LINK) { + break; + } + + /* handle current batch that requires interrupt on complete */ + if (trbflags & XHCI_TRB_3_IOC_BIT) { + DPRINTF(("pci_xhci: trb IOC bit set\r\n")); + if (epid == 1) + do_retry = 1; + break; + } + } + + DPRINTF(("pci_xhci[%d]: xfer->ndata %u\r\n", __LINE__, xfer->ndata)); + + if (epid == 1) { + err = USB_ERR_NOT_STARTED; + if (dev->dev_ue->ue_request != NULL) + err = dev->dev_ue->ue_request(dev->dev_sc, xfer); + setup_trb = NULL; + } else { + /* handle data transfer */ + pci_xhci_try_usb_xfer(sc, dev, devep, ep_ctx, slot, epid); + err = XHCI_TRB_ERROR_SUCCESS; + goto errout; + } + + err = USB_TO_XHCI_ERR(err); + if ((err == XHCI_TRB_ERROR_SUCCESS) || + (err == XHCI_TRB_ERROR_SHORT_PKT)) { + err = pci_xhci_xfer_complete(sc, xfer, slot, epid, &do_intr); + if (err != XHCI_TRB_ERROR_SUCCESS) + do_retry = 0; + } + +errout: + if (err == XHCI_TRB_ERROR_EV_RING_FULL) + DPRINTF(("pci_xhci[%d]: event ring full\r\n", __LINE__)); + + if (!do_retry) + USB_DATA_XFER_UNLOCK(xfer); + + if (do_intr) + pci_xhci_assert_interrupt(sc); + + if (do_retry) { + USB_DATA_XFER_RESET(xfer); + DPRINTF(("pci_xhci[%d]: retry:continuing with next TRBs\r\n", + __LINE__)); + goto retry; + } + + if (epid == 1) + USB_DATA_XFER_RESET(xfer); + + return (err); +} + +static void +pci_xhci_device_doorbell(struct pci_xhci_softc *sc, uint32_t slot, + uint32_t epid, uint32_t streamid) +{ + struct pci_xhci_dev_emu *dev; + struct pci_xhci_dev_ep *devep; + struct xhci_dev_ctx *dev_ctx; + struct xhci_endp_ctx *ep_ctx; + struct pci_xhci_trb_ring *sctx_tr; + struct xhci_trb *trb; + uint64_t ringaddr; + uint32_t ccs; + + DPRINTF(("pci_xhci doorbell slot %u epid %u stream %u\r\n", + slot, epid, streamid)); + + if (slot == 0 || slot > sc->ndevices) { + DPRINTF(("pci_xhci: invalid doorbell slot %u\r\n", slot)); + return; + } + + dev = XHCI_SLOTDEV_PTR(sc, slot); + devep = &dev->eps[epid]; + dev_ctx = pci_xhci_get_dev_ctx(sc, slot); + if (!dev_ctx) { + return; + } + ep_ctx = &dev_ctx->ctx_ep[epid]; + + sctx_tr = NULL; + + DPRINTF(("pci_xhci: device doorbell ep[%u] %08x %08x %016lx %08x\r\n", + epid, ep_ctx->dwEpCtx0, ep_ctx->dwEpCtx1, ep_ctx->qwEpCtx2, + ep_ctx->dwEpCtx4)); + + if (ep_ctx->qwEpCtx2 == 0) + return; + + /* handle pending transfers */ + if (devep->ep_xfer->ndata > 0) { +#ifndef __FreeBSD__ + USB_DATA_XFER_LOCK(devep->ep_xfer); +#endif + pci_xhci_try_usb_xfer(sc, dev, devep, ep_ctx, slot, epid); +#ifndef __FreeBSD__ + USB_DATA_XFER_UNLOCK(devep->ep_xfer); +#endif + return; + } + + /* get next trb work item */ + if (XHCI_EPCTX_0_MAXP_STREAMS_GET(ep_ctx->dwEpCtx0) != 0) { + sctx_tr = &devep->ep_sctx_trbs[streamid]; + ringaddr = sctx_tr->ringaddr; + ccs = sctx_tr->ccs; + trb = XHCI_GADDR(sc, sctx_tr->ringaddr & ~0xFUL); + DPRINTF(("doorbell, stream %u, ccs %lx, trb ccs %x\r\n", + streamid, ep_ctx->qwEpCtx2 & XHCI_TRB_3_CYCLE_BIT, + trb->dwTrb3 & XHCI_TRB_3_CYCLE_BIT)); + } else { + ringaddr = devep->ep_ringaddr; + ccs = devep->ep_ccs; + trb = devep->ep_tr; + DPRINTF(("doorbell, ccs %lx, trb ccs %x\r\n", + ep_ctx->qwEpCtx2 & XHCI_TRB_3_CYCLE_BIT, + trb->dwTrb3 & XHCI_TRB_3_CYCLE_BIT)); + } + + if (XHCI_TRB_3_TYPE_GET(trb->dwTrb3) == 0) { + DPRINTF(("pci_xhci: ring %lx trb[%lx] EP %u is RESERVED?\r\n", + ep_ctx->qwEpCtx2, devep->ep_ringaddr, epid)); + return; + } + + pci_xhci_handle_transfer(sc, dev, devep, ep_ctx, trb, slot, epid, + ringaddr, ccs, streamid); +} + +static void +pci_xhci_dbregs_write(struct pci_xhci_softc *sc, uint64_t offset, + uint64_t value) +{ + + offset = (offset - sc->dboff) / sizeof(uint32_t); + + DPRINTF(("pci_xhci: doorbell write offset 0x%lx: 0x%lx\r\n", + offset, value)); + + if (XHCI_HALTED(sc)) { + DPRINTF(("pci_xhci: controller halted\r\n")); + return; + } + + if (offset == 0) + pci_xhci_complete_commands(sc); + else if (sc->portregs != NULL) + pci_xhci_device_doorbell(sc, offset, + XHCI_DB_TARGET_GET(value), XHCI_DB_SID_GET(value)); +} + +static void +pci_xhci_rtsregs_write(struct pci_xhci_softc *sc, uint64_t offset, + uint64_t value) +{ + struct pci_xhci_rtsregs *rts; + + offset -= sc->rtsoff; + + if (offset == 0) { + DPRINTF(("pci_xhci attempted write to MFINDEX\r\n")); + return; + } + + DPRINTF(("pci_xhci: runtime regs write offset 0x%lx: 0x%lx\r\n", + offset, value)); + + offset -= 0x20; /* start of intrreg */ + + rts = &sc->rtsregs; + + switch (offset) { + case 0x00: + if (value & XHCI_IMAN_INTR_PEND) + rts->intrreg.iman &= ~XHCI_IMAN_INTR_PEND; + rts->intrreg.iman = (value & XHCI_IMAN_INTR_ENA) | + (rts->intrreg.iman & XHCI_IMAN_INTR_PEND); + + if (!(value & XHCI_IMAN_INTR_ENA)) + pci_xhci_deassert_interrupt(sc); + + break; + + case 0x04: + rts->intrreg.imod = value; + break; + + case 0x08: + rts->intrreg.erstsz = value & 0xFFFF; + break; + + case 0x10: + /* ERSTBA low bits */ + rts->intrreg.erstba = MASK_64_HI(sc->rtsregs.intrreg.erstba) | + (value & ~0x3F); + break; + + case 0x14: + /* ERSTBA high bits */ + rts->intrreg.erstba = (value << 32) | + MASK_64_LO(sc->rtsregs.intrreg.erstba); + + rts->erstba_p = XHCI_GADDR(sc, + sc->rtsregs.intrreg.erstba & ~0x3FUL); + + rts->erst_p = XHCI_GADDR(sc, + sc->rtsregs.erstba_p->qwEvrsTablePtr & ~0x3FUL); + + rts->er_enq_idx = 0; + rts->er_events_cnt = 0; + + DPRINTF(("pci_xhci: wr erstba erst (%p) ptr 0x%lx, sz %u\r\n", + rts->erstba_p, + rts->erstba_p->qwEvrsTablePtr, + rts->erstba_p->dwEvrsTableSize)); + break; + + case 0x18: + /* ERDP low bits */ + rts->intrreg.erdp = + MASK_64_HI(sc->rtsregs.intrreg.erdp) | + (rts->intrreg.erdp & XHCI_ERDP_LO_BUSY) | + (value & ~0xF); + if (value & XHCI_ERDP_LO_BUSY) { + rts->intrreg.erdp &= ~XHCI_ERDP_LO_BUSY; + rts->intrreg.iman &= ~XHCI_IMAN_INTR_PEND; + } + + rts->er_deq_seg = XHCI_ERDP_LO_SINDEX(value); + + break; + + case 0x1C: + /* ERDP high bits */ + rts->intrreg.erdp = (value << 32) | + MASK_64_LO(sc->rtsregs.intrreg.erdp); + + if (rts->er_events_cnt > 0) { + uint64_t erdp; + uint32_t erdp_i; + + erdp = rts->intrreg.erdp & ~0xF; + erdp_i = (erdp - rts->erstba_p->qwEvrsTablePtr) / + sizeof(struct xhci_trb); + + if (erdp_i <= rts->er_enq_idx) + rts->er_events_cnt = rts->er_enq_idx - erdp_i; + else + rts->er_events_cnt = + rts->erstba_p->dwEvrsTableSize - + (erdp_i - rts->er_enq_idx); + + DPRINTF(("pci_xhci: erdp 0x%lx, events cnt %u\r\n", + erdp, rts->er_events_cnt)); + } + + break; + + default: + DPRINTF(("pci_xhci attempted write to RTS offset 0x%lx\r\n", + offset)); + break; + } +} + +static uint64_t +pci_xhci_portregs_read(struct pci_xhci_softc *sc, uint64_t offset) +{ + int port; + uint32_t *p; + + if (sc->portregs == NULL) + return (0); + + port = (offset - 0x3F0) / 0x10; + + if (port > XHCI_MAX_DEVS) { + DPRINTF(("pci_xhci: portregs_read port %d >= XHCI_MAX_DEVS\r\n", + port)); + + /* return default value for unused port */ + return (XHCI_PS_SPEED_SET(3)); + } + + offset = (offset - 0x3F0) % 0x10; + + p = &sc->portregs[port].portsc; + p += offset / sizeof(uint32_t); + + DPRINTF(("pci_xhci: portregs read offset 0x%lx port %u -> 0x%x\r\n", + offset, port, *p)); + + return (*p); +} + +static void +pci_xhci_hostop_write(struct pci_xhci_softc *sc, uint64_t offset, + uint64_t value) +{ + offset -= XHCI_CAPLEN; + + if (offset < 0x400) + DPRINTF(("pci_xhci: hostop write offset 0x%lx: 0x%lx\r\n", + offset, value)); + + switch (offset) { + case XHCI_USBCMD: + sc->opregs.usbcmd = pci_xhci_usbcmd_write(sc, value & 0x3F0F); + break; + + case XHCI_USBSTS: + /* clear bits on write */ + sc->opregs.usbsts &= ~(value & + (XHCI_STS_HSE|XHCI_STS_EINT|XHCI_STS_PCD|XHCI_STS_SSS| + XHCI_STS_RSS|XHCI_STS_SRE|XHCI_STS_CNR)); + break; + + case XHCI_PAGESIZE: + /* read only */ + break; + + case XHCI_DNCTRL: + sc->opregs.dnctrl = value & 0xFFFF; + break; + + case XHCI_CRCR_LO: + if (sc->opregs.crcr & XHCI_CRCR_LO_CRR) { + sc->opregs.crcr &= ~(XHCI_CRCR_LO_CS|XHCI_CRCR_LO_CA); + sc->opregs.crcr |= value & + (XHCI_CRCR_LO_CS|XHCI_CRCR_LO_CA); + } else { + sc->opregs.crcr = MASK_64_HI(sc->opregs.crcr) | + (value & (0xFFFFFFC0 | XHCI_CRCR_LO_RCS)); + } + break; + + case XHCI_CRCR_HI: + if (!(sc->opregs.crcr & XHCI_CRCR_LO_CRR)) { + sc->opregs.crcr = MASK_64_LO(sc->opregs.crcr) | + (value << 32); + + sc->opregs.cr_p = XHCI_GADDR(sc, + sc->opregs.crcr & ~0xF); + } + + if (sc->opregs.crcr & XHCI_CRCR_LO_CS) { + /* Stop operation of Command Ring */ + } + + if (sc->opregs.crcr & XHCI_CRCR_LO_CA) { + /* Abort command */ + } + + break; + + case XHCI_DCBAAP_LO: + sc->opregs.dcbaap = MASK_64_HI(sc->opregs.dcbaap) | + (value & 0xFFFFFFC0); + break; + + case XHCI_DCBAAP_HI: + sc->opregs.dcbaap = MASK_64_LO(sc->opregs.dcbaap) | + (value << 32); + sc->opregs.dcbaa_p = XHCI_GADDR(sc, sc->opregs.dcbaap & ~0x3FUL); + + DPRINTF(("pci_xhci: opregs dcbaap = 0x%lx (vaddr 0x%lx)\r\n", + sc->opregs.dcbaap, (uint64_t)sc->opregs.dcbaa_p)); + break; + + case XHCI_CONFIG: + sc->opregs.config = value & 0x03FF; + break; + + default: + if (offset >= 0x400) + pci_xhci_portregs_write(sc, offset, value); + + break; + } +} + + +static void +pci_xhci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value) +{ + struct pci_xhci_softc *sc; + + sc = pi->pi_arg; + + assert(baridx == 0); + + + pthread_mutex_lock(&sc->mtx); + if (offset < XHCI_CAPLEN) /* read only registers */ + WPRINTF(("pci_xhci: write RO-CAPs offset %ld\r\n", offset)); + else if (offset < sc->dboff) + pci_xhci_hostop_write(sc, offset, value); + else if (offset < sc->rtsoff) + pci_xhci_dbregs_write(sc, offset, value); + else if (offset < sc->regsend) + pci_xhci_rtsregs_write(sc, offset, value); + else + WPRINTF(("pci_xhci: write invalid offset %ld\r\n", offset)); + + pthread_mutex_unlock(&sc->mtx); +} + +static uint64_t +pci_xhci_hostcap_read(struct pci_xhci_softc *sc, uint64_t offset) +{ + uint64_t value; + + switch (offset) { + case XHCI_CAPLENGTH: /* 0x00 */ + value = sc->caplength; + break; + + case XHCI_HCSPARAMS1: /* 0x04 */ + value = sc->hcsparams1; + break; + + case XHCI_HCSPARAMS2: /* 0x08 */ + value = sc->hcsparams2; + break; + + case XHCI_HCSPARAMS3: /* 0x0C */ + value = sc->hcsparams3; + break; + + case XHCI_HCSPARAMS0: /* 0x10 */ + value = sc->hccparams1; + break; + + case XHCI_DBOFF: /* 0x14 */ + value = sc->dboff; + break; + + case XHCI_RTSOFF: /* 0x18 */ + value = sc->rtsoff; + break; + + case XHCI_HCCPRAMS2: /* 0x1C */ + value = sc->hccparams2; + break; + + default: + value = 0; + break; + } + + DPRINTF(("pci_xhci: hostcap read offset 0x%lx -> 0x%lx\r\n", + offset, value)); + + return (value); +} + +static uint64_t +pci_xhci_hostop_read(struct pci_xhci_softc *sc, uint64_t offset) +{ + uint64_t value; + + offset = (offset - XHCI_CAPLEN); + + switch (offset) { + case XHCI_USBCMD: /* 0x00 */ + value = sc->opregs.usbcmd; + break; + + case XHCI_USBSTS: /* 0x04 */ + value = sc->opregs.usbsts; + break; + + case XHCI_PAGESIZE: /* 0x08 */ + value = sc->opregs.pgsz; + break; + + case XHCI_DNCTRL: /* 0x14 */ + value = sc->opregs.dnctrl; + break; + + case XHCI_CRCR_LO: /* 0x18 */ + value = sc->opregs.crcr & XHCI_CRCR_LO_CRR; + break; + + case XHCI_CRCR_HI: /* 0x1C */ + value = 0; + break; + + case XHCI_DCBAAP_LO: /* 0x30 */ + value = sc->opregs.dcbaap & 0xFFFFFFFF; + break; + + case XHCI_DCBAAP_HI: /* 0x34 */ + value = (sc->opregs.dcbaap >> 32) & 0xFFFFFFFF; + break; + + case XHCI_CONFIG: /* 0x38 */ + value = sc->opregs.config; + break; + + default: + if (offset >= 0x400) + value = pci_xhci_portregs_read(sc, offset); + else + value = 0; + + break; + } + + if (offset < 0x400) + DPRINTF(("pci_xhci: hostop read offset 0x%lx -> 0x%lx\r\n", + offset, value)); + + return (value); +} + +static uint64_t +pci_xhci_dbregs_read(struct pci_xhci_softc *sc, uint64_t offset) +{ + + /* read doorbell always returns 0 */ + return (0); +} + +static uint64_t +pci_xhci_rtsregs_read(struct pci_xhci_softc *sc, uint64_t offset) +{ + uint32_t value; + + offset -= sc->rtsoff; + value = 0; + + if (offset == XHCI_MFINDEX) { + value = sc->rtsregs.mfindex; + } else if (offset >= 0x20) { + int item; + uint32_t *p; + + offset -= 0x20; + item = offset % 32; + + assert(offset < sizeof(sc->rtsregs.intrreg)); + + p = &sc->rtsregs.intrreg.iman; + p += item / sizeof(uint32_t); + value = *p; + } + + DPRINTF(("pci_xhci: rtsregs read offset 0x%lx -> 0x%x\r\n", + offset, value)); + + return (value); +} + +static uint64_t +pci_xhci_xecp_read(struct pci_xhci_softc *sc, uint64_t offset) +{ + uint32_t value; + + offset -= sc->regsend; + value = 0; + + switch (offset) { + case 0: + /* rev major | rev minor | next-cap | cap-id */ + value = (0x02 << 24) | (4 << 8) | XHCI_ID_PROTOCOLS; + break; + case 4: + /* name string = "USB" */ + value = 0x20425355; + break; + case 8: + /* psic | proto-defined | compat # | compat offset */ + value = ((XHCI_MAX_DEVS/2) << 8) | sc->usb2_port_start; + break; + case 12: + break; + case 16: + /* rev major | rev minor | next-cap | cap-id */ + value = (0x03 << 24) | XHCI_ID_PROTOCOLS; + break; + case 20: + /* name string = "USB" */ + value = 0x20425355; + break; + case 24: + /* psic | proto-defined | compat # | compat offset */ + value = ((XHCI_MAX_DEVS/2) << 8) | sc->usb3_port_start; + break; + case 28: + break; + default: + DPRINTF(("pci_xhci: xecp invalid offset 0x%lx\r\n", offset)); + break; + } + + DPRINTF(("pci_xhci: xecp read offset 0x%lx -> 0x%x\r\n", + offset, value)); + + return (value); +} + + +static uint64_t +pci_xhci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, + uint64_t offset, int size) +{ + struct pci_xhci_softc *sc; + uint32_t value; + + sc = pi->pi_arg; + + assert(baridx == 0); + + pthread_mutex_lock(&sc->mtx); + if (offset < XHCI_CAPLEN) + value = pci_xhci_hostcap_read(sc, offset); + else if (offset < sc->dboff) + value = pci_xhci_hostop_read(sc, offset); + else if (offset < sc->rtsoff) + value = pci_xhci_dbregs_read(sc, offset); + else if (offset < sc->regsend) + value = pci_xhci_rtsregs_read(sc, offset); + else if (offset < (sc->regsend + 4*32)) + value = pci_xhci_xecp_read(sc, offset); + else { + value = 0; + WPRINTF(("pci_xhci: read invalid offset %ld\r\n", offset)); + } + + pthread_mutex_unlock(&sc->mtx); + + switch (size) { + case 1: + value &= 0xFF; + break; + case 2: + value &= 0xFFFF; + break; + case 4: + value &= 0xFFFFFFFF; + break; + } + + return (value); +} + +static void +pci_xhci_reset_port(struct pci_xhci_softc *sc, int portn, int warm) +{ + struct pci_xhci_portregs *port; + struct pci_xhci_dev_emu *dev; + struct xhci_trb evtrb; + int error; + + assert(portn <= XHCI_MAX_DEVS); + + DPRINTF(("xhci reset port %d\r\n", portn)); + + port = XHCI_PORTREG_PTR(sc, portn); + dev = XHCI_DEVINST_PTR(sc, portn); + if (dev) { + port->portsc &= ~(XHCI_PS_PLS_MASK | XHCI_PS_PR | XHCI_PS_PRC); + port->portsc |= XHCI_PS_PED | + XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed); + + if (warm && dev->dev_ue->ue_usbver == 3) { + port->portsc |= XHCI_PS_WRC; + } + + if ((port->portsc & XHCI_PS_PRC) == 0) { + port->portsc |= XHCI_PS_PRC; + + pci_xhci_set_evtrb(&evtrb, portn, + XHCI_TRB_ERROR_SUCCESS, + XHCI_TRB_EVENT_PORT_STS_CHANGE); + error = pci_xhci_insert_event(sc, &evtrb, 1); + if (error != XHCI_TRB_ERROR_SUCCESS) + DPRINTF(("xhci reset port insert event " + "failed\r\n")); + } + } +} + +static void +pci_xhci_init_port(struct pci_xhci_softc *sc, int portn) +{ + struct pci_xhci_portregs *port; + struct pci_xhci_dev_emu *dev; + + port = XHCI_PORTREG_PTR(sc, portn); + dev = XHCI_DEVINST_PTR(sc, portn); + if (dev) { + port->portsc = XHCI_PS_CCS | /* connected */ + XHCI_PS_PP; /* port power */ + + if (dev->dev_ue->ue_usbver == 2) { + port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_POLL) | + XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed); + } else { + port->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_U0) | + XHCI_PS_PED | /* enabled */ + XHCI_PS_SPEED_SET(dev->dev_ue->ue_usbspeed); + } + + DPRINTF(("Init port %d 0x%x\n", portn, port->portsc)); + } else { + port->portsc = XHCI_PS_PLS_SET(UPS_PORT_LS_RX_DET) | XHCI_PS_PP; + DPRINTF(("Init empty port %d 0x%x\n", portn, port->portsc)); + } +} + +static int +pci_xhci_dev_intr(struct usb_hci *hci, int epctx) +{ + struct pci_xhci_dev_emu *dev; + struct xhci_dev_ctx *dev_ctx; + struct xhci_trb evtrb; + struct pci_xhci_softc *sc; + struct pci_xhci_portregs *p; + struct xhci_endp_ctx *ep_ctx; + int error; + int dir_in; + int epid; + + dir_in = epctx & 0x80; + epid = epctx & ~0x80; + + /* HW endpoint contexts are 0-15; convert to epid based on dir */ + epid = (epid * 2) + (dir_in ? 1 : 0); + + assert(epid >= 1 && epid <= 31); + + dev = hci->hci_sc; + sc = dev->xsc; + + /* check if device is ready; OS has to initialise it */ + if (sc->rtsregs.erstba_p == NULL || + (sc->opregs.usbcmd & XHCI_CMD_RS) == 0 || + dev->dev_ctx == NULL) + return (0); + + p = XHCI_PORTREG_PTR(sc, hci->hci_port); + + /* raise event if link U3 (suspended) state */ + if (XHCI_PS_PLS_GET(p->portsc) == 3) { + p->portsc &= ~XHCI_PS_PLS_MASK; + p->portsc |= XHCI_PS_PLS_SET(UPS_PORT_LS_RESUME); + if ((p->portsc & XHCI_PS_PLC) != 0) + return (0); + + p->portsc |= XHCI_PS_PLC; + + pci_xhci_set_evtrb(&evtrb, hci->hci_port, + XHCI_TRB_ERROR_SUCCESS, XHCI_TRB_EVENT_PORT_STS_CHANGE); + error = pci_xhci_insert_event(sc, &evtrb, 0); + if (error != XHCI_TRB_ERROR_SUCCESS) + goto done; + } + + dev_ctx = dev->dev_ctx; + ep_ctx = &dev_ctx->ctx_ep[epid]; + if ((ep_ctx->dwEpCtx0 & 0x7) == XHCI_ST_EPCTX_DISABLED) { + DPRINTF(("xhci device interrupt on disabled endpoint %d\r\n", + epid)); + return (0); + } + + DPRINTF(("xhci device interrupt on endpoint %d\r\n", epid)); + + pci_xhci_device_doorbell(sc, hci->hci_port, epid, 0); + +done: + return (error); +} + +static int +pci_xhci_dev_event(struct usb_hci *hci, enum hci_usbev evid, void *param) +{ + + DPRINTF(("xhci device event port %d\r\n", hci->hci_port)); + return (0); +} + + + +static void +pci_xhci_device_usage(char *opt) +{ + + fprintf(stderr, "Invalid USB emulation \"%s\"\r\n", opt); +} + +static int +pci_xhci_parse_opts(struct pci_xhci_softc *sc, char *opts) +{ + struct pci_xhci_dev_emu **devices; + struct pci_xhci_dev_emu *dev; + struct usb_devemu *ue; + void *devsc; +#ifdef __FreeBSD__ + char *uopt, *xopts, *config; +#else + char *uopt = NULL, *xopts, *config; +#endif + int usb3_port, usb2_port, i; + + usb3_port = sc->usb3_port_start - 1; + usb2_port = sc->usb2_port_start - 1; + devices = NULL; + + if (opts == NULL) + goto portsfinal; + + devices = calloc(XHCI_MAX_DEVS, sizeof(struct pci_xhci_dev_emu *)); + + sc->slots = calloc(XHCI_MAX_SLOTS, sizeof(struct pci_xhci_dev_emu *)); + sc->devices = devices; + sc->ndevices = 0; + + uopt = strdup(opts); + for (xopts = strtok(uopt, ","); + xopts != NULL; + xopts = strtok(NULL, ",")) { + if (usb2_port == ((sc->usb2_port_start-1) + XHCI_MAX_DEVS/2) || + usb3_port == ((sc->usb3_port_start-1) + XHCI_MAX_DEVS/2)) { + WPRINTF(("pci_xhci max number of USB 2 or 3 " + "devices reached, max %d\r\n", XHCI_MAX_DEVS/2)); + usb2_port = usb3_port = -1; + goto done; + } + + /* device[=<config>] */ + if ((config = strchr(xopts, '=')) == NULL) + config = ""; /* no config */ + else + *config++ = '\0'; + + ue = usb_emu_finddev(xopts); + if (ue == NULL) { + pci_xhci_device_usage(xopts); + DPRINTF(("pci_xhci device not found %s\r\n", xopts)); + usb2_port = usb3_port = -1; + goto done; + } + + DPRINTF(("pci_xhci adding device %s, opts \"%s\"\r\n", + xopts, config)); + + dev = calloc(1, sizeof(struct pci_xhci_dev_emu)); + dev->xsc = sc; + dev->hci.hci_sc = dev; + dev->hci.hci_intr = pci_xhci_dev_intr; + dev->hci.hci_event = pci_xhci_dev_event; + + if (ue->ue_usbver == 2) { + dev->hci.hci_port = usb2_port + 1; + devices[usb2_port] = dev; + usb2_port++; + } else { + dev->hci.hci_port = usb3_port + 1; + devices[usb3_port] = dev; + usb3_port++; + } + + dev->hci.hci_address = 0; + devsc = ue->ue_init(&dev->hci, config); + if (devsc == NULL) { + pci_xhci_device_usage(xopts); + usb2_port = usb3_port = -1; + goto done; + } + + dev->dev_ue = ue; + dev->dev_sc = devsc; + + /* assign slot number to device */ + sc->slots[sc->ndevices] = dev; + + sc->ndevices++; + } +#ifdef __FreeBSD__ + if (uopt != NULL) + free(uopt); +#endif + +portsfinal: + sc->portregs = calloc(XHCI_MAX_DEVS, sizeof(struct pci_xhci_portregs)); + + if (sc->ndevices > 0) { + /* port and slot numbering start from 1 */ + sc->devices--; + sc->portregs--; + sc->slots--; + + for (i = 1; i <= XHCI_MAX_DEVS; i++) { + pci_xhci_init_port(sc, i); + } + } else { + WPRINTF(("pci_xhci no USB devices configured\r\n")); + sc->ndevices = 1; + } + +done: + if (devices != NULL) { + if (usb2_port <= 0 && usb3_port <= 0) { + sc->devices = NULL; + for (i = 0; devices[i] != NULL; i++) + free(devices[i]); + sc->ndevices = -1; + + free(devices); + } + } + free(uopt); + return (sc->ndevices); +} + +static int +pci_xhci_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + struct pci_xhci_softc *sc; + int error; + + if (xhci_in_use) { + WPRINTF(("pci_xhci controller already defined\r\n")); + return (-1); + } + xhci_in_use = 1; + + sc = calloc(1, sizeof(struct pci_xhci_softc)); + pi->pi_arg = sc; + sc->xsc_pi = pi; + + sc->usb2_port_start = (XHCI_MAX_DEVS/2) + 1; + sc->usb3_port_start = 1; + + /* discover devices */ + error = pci_xhci_parse_opts(sc, opts); + if (error < 0) + goto done; + else + error = 0; + + sc->caplength = XHCI_SET_CAPLEN(XHCI_CAPLEN) | + XHCI_SET_HCIVERSION(0x0100); + sc->hcsparams1 = XHCI_SET_HCSP1_MAXPORTS(XHCI_MAX_DEVS) | + XHCI_SET_HCSP1_MAXINTR(1) | /* interrupters */ + XHCI_SET_HCSP1_MAXSLOTS(XHCI_MAX_SLOTS); + sc->hcsparams2 = XHCI_SET_HCSP2_ERSTMAX(XHCI_ERST_MAX) | + XHCI_SET_HCSP2_IST(0x04); + sc->hcsparams3 = 0; /* no latency */ + sc->hccparams1 = XHCI_SET_HCCP1_NSS(1) | /* no 2nd-streams */ + XHCI_SET_HCCP1_SPC(1) | /* short packet */ + XHCI_SET_HCCP1_MAXPSA(XHCI_STREAMS_MAX); + sc->hccparams2 = XHCI_SET_HCCP2_LEC(1) | + XHCI_SET_HCCP2_U3C(1); + sc->dboff = XHCI_SET_DOORBELL(XHCI_CAPLEN + XHCI_PORTREGS_START + + XHCI_MAX_DEVS * sizeof(struct pci_xhci_portregs)); + + /* dboff must be 32-bit aligned */ + if (sc->dboff & 0x3) + sc->dboff = (sc->dboff + 0x3) & ~0x3; + + /* rtsoff must be 32-bytes aligned */ + sc->rtsoff = XHCI_SET_RTSOFFSET(sc->dboff + (XHCI_MAX_SLOTS+1) * 32); + if (sc->rtsoff & 0x1F) + sc->rtsoff = (sc->rtsoff + 0x1F) & ~0x1F; + + DPRINTF(("pci_xhci dboff: 0x%x, rtsoff: 0x%x\r\n", sc->dboff, + sc->rtsoff)); + + sc->opregs.usbsts = XHCI_STS_HCH; + sc->opregs.pgsz = XHCI_PAGESIZE_4K; + + pci_xhci_reset(sc); + + sc->regsend = sc->rtsoff + 0x20 + 32; /* only 1 intrpter */ + + /* + * Set extended capabilities pointer to be after regsend; + * value of xecp field is 32-bit offset. + */ + sc->hccparams1 |= XHCI_SET_HCCP1_XECP(sc->regsend/4); + + pci_set_cfgdata16(pi, PCIR_DEVICE, 0x1E31); + pci_set_cfgdata16(pi, PCIR_VENDOR, 0x8086); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_SERIALBUS); + pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_SERIALBUS_USB); + pci_set_cfgdata8(pi, PCIR_PROGIF,PCIP_SERIALBUS_USB_XHCI); + pci_set_cfgdata8(pi, PCI_USBREV, PCI_USB_REV_3_0); + + pci_emul_add_msicap(pi, 1); + + /* regsend + xecp registers */ + pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, sc->regsend + 4*32); + DPRINTF(("pci_xhci pci_emu_alloc: %d\r\n", sc->regsend + 4*32)); + + + pci_lintr_request(pi); + + pthread_mutex_init(&sc->mtx, NULL); + +done: + if (error) { + free(sc); + } + + return (error); +} + + + +struct pci_devemu pci_de_xhci = { + .pe_emu = "xhci", + .pe_init = pci_xhci_init, + .pe_barwrite = pci_xhci_write, + .pe_barread = pci_xhci_read +}; +PCI_EMUL_SET(pci_de_xhci); diff --git a/usr/src/cmd/bhyve/pci_xhci.h b/usr/src/cmd/bhyve/pci_xhci.h new file mode 100644 index 0000000000..7502f9396a --- /dev/null +++ b/usr/src/cmd/bhyve/pci_xhci.h @@ -0,0 +1,355 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Leon Dang <ldang@nahannisys.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _PCI_XHCI_H_ +#define _PCI_XHCI_H_ + +#define PCI_USBREV 0x60 /* USB protocol revision */ + + +enum { /* dsc_slotstate */ + XHCI_ST_DISABLED, + XHCI_ST_ENABLED, + XHCI_ST_DEFAULT, + XHCI_ST_ADDRESSED, + XHCI_ST_CONFIGURED, + XHCI_ST_MAX +}; + +enum { + XHCI_ST_SLCTX_DISABLED, + XHCI_ST_SLCTX_DEFAULT, + XHCI_ST_SLCTX_ADDRESSED, + XHCI_ST_SLCTX_CONFIGURED +}; + +enum { + XHCI_ST_EPCTX_DISABLED, + XHCI_ST_EPCTX_RUNNING, + XHCI_ST_EPCTX_HALTED, + XHCI_ST_EPCTX_STOPPED, + XHCI_ST_EPCTX_ERROR +}; + +#define XHCI_MAX_DEVICES MIN(USB_MAX_DEVICES, 128) +#define XHCI_MAX_ENDPOINTS 32 /* hardcoded - do not change */ +#define XHCI_MAX_SCRATCHPADS 32 +#define XHCI_MAX_EVENTS (16 * 13) +#define XHCI_MAX_COMMANDS (16 * 1) +#define XHCI_MAX_RSEG 1 +#define XHCI_MAX_TRANSFERS 4 +#if USB_MAX_EP_STREAMS == 8 +#define XHCI_MAX_STREAMS 8 +#define XHCI_MAX_STREAMS_LOG 3 +#elif USB_MAX_EP_STREAMS == 1 +#define XHCI_MAX_STREAMS 1 +#define XHCI_MAX_STREAMS_LOG 0 +#else +#error "The USB_MAX_EP_STREAMS value is not supported." +#endif +#define XHCI_DEV_CTX_ADDR_ALIGN 64 /* bytes */ +#define XHCI_DEV_CTX_ALIGN 64 /* bytes */ +#define XHCI_INPUT_CTX_ALIGN 64 /* bytes */ +#define XHCI_SLOT_CTX_ALIGN 32 /* bytes */ +#define XHCI_ENDP_CTX_ALIGN 32 /* bytes */ +#define XHCI_STREAM_CTX_ALIGN 16 /* bytes */ +#define XHCI_TRANS_RING_SEG_ALIGN 16 /* bytes */ +#define XHCI_CMD_RING_SEG_ALIGN 64 /* bytes */ +#define XHCI_EVENT_RING_SEG_ALIGN 64 /* bytes */ +#define XHCI_SCRATCH_BUF_ARRAY_ALIGN 64 /* bytes */ +#define XHCI_SCRATCH_BUFFER_ALIGN USB_PAGE_SIZE +#define XHCI_TRB_ALIGN 16 /* bytes */ +#define XHCI_TD_ALIGN 64 /* bytes */ +#define XHCI_PAGE_SIZE 4096 /* bytes */ + +struct xhci_slot_ctx { + volatile uint32_t dwSctx0; +#define XHCI_SCTX_0_ROUTE_SET(x) ((x) & 0xFFFFF) +#define XHCI_SCTX_0_ROUTE_GET(x) ((x) & 0xFFFFF) +#define XHCI_SCTX_0_SPEED_SET(x) (((x) & 0xF) << 20) +#define XHCI_SCTX_0_SPEED_GET(x) (((x) >> 20) & 0xF) +#define XHCI_SCTX_0_MTT_SET(x) (((x) & 0x1) << 25) +#define XHCI_SCTX_0_MTT_GET(x) (((x) >> 25) & 0x1) +#define XHCI_SCTX_0_HUB_SET(x) (((x) & 0x1) << 26) +#define XHCI_SCTX_0_HUB_GET(x) (((x) >> 26) & 0x1) +#define XHCI_SCTX_0_CTX_NUM_SET(x) (((x) & 0x1F) << 27) +#define XHCI_SCTX_0_CTX_NUM_GET(x) (((x) >> 27) & 0x1F) + volatile uint32_t dwSctx1; +#define XHCI_SCTX_1_MAX_EL_SET(x) ((x) & 0xFFFF) +#define XHCI_SCTX_1_MAX_EL_GET(x) ((x) & 0xFFFF) +#define XHCI_SCTX_1_RH_PORT_SET(x) (((x) & 0xFF) << 16) +#define XHCI_SCTX_1_RH_PORT_GET(x) (((x) >> 16) & 0xFF) +#define XHCI_SCTX_1_NUM_PORTS_SET(x) (((x) & 0xFF) << 24) +#define XHCI_SCTX_1_NUM_PORTS_GET(x) (((x) >> 24) & 0xFF) + volatile uint32_t dwSctx2; +#define XHCI_SCTX_2_TT_HUB_SID_SET(x) ((x) & 0xFF) +#define XHCI_SCTX_2_TT_HUB_SID_GET(x) ((x) & 0xFF) +#define XHCI_SCTX_2_TT_PORT_NUM_SET(x) (((x) & 0xFF) << 8) +#define XHCI_SCTX_2_TT_PORT_NUM_GET(x) (((x) >> 8) & 0xFF) +#define XHCI_SCTX_2_TT_THINK_TIME_SET(x) (((x) & 0x3) << 16) +#define XHCI_SCTX_2_TT_THINK_TIME_GET(x) (((x) >> 16) & 0x3) +#define XHCI_SCTX_2_IRQ_TARGET_SET(x) (((x) & 0x3FF) << 22) +#define XHCI_SCTX_2_IRQ_TARGET_GET(x) (((x) >> 22) & 0x3FF) + volatile uint32_t dwSctx3; +#define XHCI_SCTX_3_DEV_ADDR_SET(x) ((x) & 0xFF) +#define XHCI_SCTX_3_DEV_ADDR_GET(x) ((x) & 0xFF) +#define XHCI_SCTX_3_SLOT_STATE_SET(x) (((x) & 0x1F) << 27) +#define XHCI_SCTX_3_SLOT_STATE_GET(x) (((x) >> 27) & 0x1F) + volatile uint32_t dwSctx4; + volatile uint32_t dwSctx5; + volatile uint32_t dwSctx6; + volatile uint32_t dwSctx7; +}; + +struct xhci_endp_ctx { + volatile uint32_t dwEpCtx0; +#define XHCI_EPCTX_0_EPSTATE_SET(x) ((x) & 0x7) +#define XHCI_EPCTX_0_EPSTATE_GET(x) ((x) & 0x7) +#define XHCI_EPCTX_0_MULT_SET(x) (((x) & 0x3) << 8) +#define XHCI_EPCTX_0_MULT_GET(x) (((x) >> 8) & 0x3) +#define XHCI_EPCTX_0_MAXP_STREAMS_SET(x) (((x) & 0x1F) << 10) +#define XHCI_EPCTX_0_MAXP_STREAMS_GET(x) (((x) >> 10) & 0x1F) +#define XHCI_EPCTX_0_LSA_SET(x) (((x) & 0x1) << 15) +#define XHCI_EPCTX_0_LSA_GET(x) (((x) >> 15) & 0x1) +#define XHCI_EPCTX_0_IVAL_SET(x) (((x) & 0xFF) << 16) +#define XHCI_EPCTX_0_IVAL_GET(x) (((x) >> 16) & 0xFF) + volatile uint32_t dwEpCtx1; +#define XHCI_EPCTX_1_CERR_SET(x) (((x) & 0x3) << 1) +#define XHCI_EPCTX_1_CERR_GET(x) (((x) >> 1) & 0x3) +#define XHCI_EPCTX_1_EPTYPE_SET(x) (((x) & 0x7) << 3) +#define XHCI_EPCTX_1_EPTYPE_GET(x) (((x) >> 3) & 0x7) +#define XHCI_EPCTX_1_HID_SET(x) (((x) & 0x1) << 7) +#define XHCI_EPCTX_1_HID_GET(x) (((x) >> 7) & 0x1) +#define XHCI_EPCTX_1_MAXB_SET(x) (((x) & 0xFF) << 8) +#define XHCI_EPCTX_1_MAXB_GET(x) (((x) >> 8) & 0xFF) +#define XHCI_EPCTX_1_MAXP_SIZE_SET(x) (((x) & 0xFFFF) << 16) +#define XHCI_EPCTX_1_MAXP_SIZE_GET(x) (((x) >> 16) & 0xFFFF) + volatile uint64_t qwEpCtx2; +#define XHCI_EPCTX_2_DCS_SET(x) ((x) & 0x1) +#define XHCI_EPCTX_2_DCS_GET(x) ((x) & 0x1) +#define XHCI_EPCTX_2_TR_DQ_PTR_MASK 0xFFFFFFFFFFFFFFF0U + volatile uint32_t dwEpCtx4; +#define XHCI_EPCTX_4_AVG_TRB_LEN_SET(x) ((x) & 0xFFFF) +#define XHCI_EPCTX_4_AVG_TRB_LEN_GET(x) ((x) & 0xFFFF) +#define XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_SET(x) (((x) & 0xFFFF) << 16) +#define XHCI_EPCTX_4_MAX_ESIT_PAYLOAD_GET(x) (((x) >> 16) & 0xFFFF) + volatile uint32_t dwEpCtx5; + volatile uint32_t dwEpCtx6; + volatile uint32_t dwEpCtx7; +}; + +struct xhci_input_ctx { +#define XHCI_INCTX_NON_CTRL_MASK 0xFFFFFFFCU + volatile uint32_t dwInCtx0; +#define XHCI_INCTX_0_DROP_MASK(n) (1U << (n)) + volatile uint32_t dwInCtx1; +#define XHCI_INCTX_1_ADD_MASK(n) (1U << (n)) + volatile uint32_t dwInCtx2; + volatile uint32_t dwInCtx3; + volatile uint32_t dwInCtx4; + volatile uint32_t dwInCtx5; + volatile uint32_t dwInCtx6; + volatile uint32_t dwInCtx7; +}; + +struct xhci_input_dev_ctx { + struct xhci_input_ctx ctx_input; + union { + struct xhci_slot_ctx u_slot; + struct xhci_endp_ctx u_ep[XHCI_MAX_ENDPOINTS]; + } ctx_dev_slep; +}; + +struct xhci_dev_ctx { + union { + struct xhci_slot_ctx u_slot; + struct xhci_endp_ctx u_ep[XHCI_MAX_ENDPOINTS]; + } ctx_dev_slep; +} __aligned(XHCI_DEV_CTX_ALIGN); +#define ctx_slot ctx_dev_slep.u_slot +#define ctx_ep ctx_dev_slep.u_ep + +struct xhci_stream_ctx { + volatile uint64_t qwSctx0; +#define XHCI_SCTX_0_DCS_GET(x) ((x) & 0x1) +#define XHCI_SCTX_0_DCS_SET(x) ((x) & 0x1) +#define XHCI_SCTX_0_SCT_SET(x) (((x) & 0x7) << 1) +#define XHCI_SCTX_0_SCT_GET(x) (((x) >> 1) & 0x7) +#define XHCI_SCTX_0_SCT_SEC_TR_RING 0x0 +#define XHCI_SCTX_0_SCT_PRIM_TR_RING 0x1 +#define XHCI_SCTX_0_SCT_PRIM_SSA_8 0x2 +#define XHCI_SCTX_0_SCT_PRIM_SSA_16 0x3 +#define XHCI_SCTX_0_SCT_PRIM_SSA_32 0x4 +#define XHCI_SCTX_0_SCT_PRIM_SSA_64 0x5 +#define XHCI_SCTX_0_SCT_PRIM_SSA_128 0x6 +#define XHCI_SCTX_0_SCT_PRIM_SSA_256 0x7 +#define XHCI_SCTX_0_TR_DQ_PTR_MASK 0xFFFFFFFFFFFFFFF0U + volatile uint32_t dwSctx2; + volatile uint32_t dwSctx3; +}; + +struct xhci_trb { + volatile uint64_t qwTrb0; +#define XHCI_TRB_0_DIR_IN_MASK (0x80ULL << 0) +#define XHCI_TRB_0_WLENGTH_MASK (0xFFFFULL << 48) + volatile uint32_t dwTrb2; +#define XHCI_TRB_2_ERROR_GET(x) (((x) >> 24) & 0xFF) +#define XHCI_TRB_2_ERROR_SET(x) (((x) & 0xFF) << 24) +#define XHCI_TRB_2_TDSZ_GET(x) (((x) >> 17) & 0x1F) +#define XHCI_TRB_2_TDSZ_SET(x) (((x) & 0x1F) << 17) +#define XHCI_TRB_2_REM_GET(x) ((x) & 0xFFFFFF) +#define XHCI_TRB_2_REM_SET(x) ((x) & 0xFFFFFF) +#define XHCI_TRB_2_BYTES_GET(x) ((x) & 0x1FFFF) +#define XHCI_TRB_2_BYTES_SET(x) ((x) & 0x1FFFF) +#define XHCI_TRB_2_IRQ_GET(x) (((x) >> 22) & 0x3FF) +#define XHCI_TRB_2_IRQ_SET(x) (((x) & 0x3FF) << 22) +#define XHCI_TRB_2_STREAM_GET(x) (((x) >> 16) & 0xFFFF) +#define XHCI_TRB_2_STREAM_SET(x) (((x) & 0xFFFF) << 16) + + volatile uint32_t dwTrb3; +#define XHCI_TRB_3_TYPE_GET(x) (((x) >> 10) & 0x3F) +#define XHCI_TRB_3_TYPE_SET(x) (((x) & 0x3F) << 10) +#define XHCI_TRB_3_CYCLE_BIT (1U << 0) +#define XHCI_TRB_3_TC_BIT (1U << 1) /* command ring only */ +#define XHCI_TRB_3_ENT_BIT (1U << 1) /* transfer ring only */ +#define XHCI_TRB_3_ISP_BIT (1U << 2) +#define XHCI_TRB_3_ED_BIT (1U << 2) +#define XHCI_TRB_3_NSNOOP_BIT (1U << 3) +#define XHCI_TRB_3_CHAIN_BIT (1U << 4) +#define XHCI_TRB_3_IOC_BIT (1U << 5) +#define XHCI_TRB_3_IDT_BIT (1U << 6) +#define XHCI_TRB_3_TBC_GET(x) (((x) >> 7) & 3) +#define XHCI_TRB_3_TBC_SET(x) (((x) & 3) << 7) +#define XHCI_TRB_3_BEI_BIT (1U << 9) +#define XHCI_TRB_3_DCEP_BIT (1U << 9) +#define XHCI_TRB_3_PRSV_BIT (1U << 9) +#define XHCI_TRB_3_BSR_BIT (1U << 9) +#define XHCI_TRB_3_TRT_MASK (3U << 16) +#define XHCI_TRB_3_TRT_NONE (0U << 16) +#define XHCI_TRB_3_TRT_OUT (2U << 16) +#define XHCI_TRB_3_TRT_IN (3U << 16) +#define XHCI_TRB_3_DIR_IN (1U << 16) +#define XHCI_TRB_3_TLBPC_GET(x) (((x) >> 16) & 0xF) +#define XHCI_TRB_3_TLBPC_SET(x) (((x) & 0xF) << 16) +#define XHCI_TRB_3_EP_GET(x) (((x) >> 16) & 0x1F) +#define XHCI_TRB_3_EP_SET(x) (((x) & 0x1F) << 16) +#define XHCI_TRB_3_FRID_GET(x) (((x) >> 20) & 0x7FF) +#define XHCI_TRB_3_FRID_SET(x) (((x) & 0x7FF) << 20) +#define XHCI_TRB_3_ISO_SIA_BIT (1U << 31) +#define XHCI_TRB_3_SUSP_EP_BIT (1U << 23) +#define XHCI_TRB_3_SLOT_GET(x) (((x) >> 24) & 0xFF) +#define XHCI_TRB_3_SLOT_SET(x) (((x) & 0xFF) << 24) + +/* Commands */ +#define XHCI_TRB_TYPE_RESERVED 0x00 +#define XHCI_TRB_TYPE_NORMAL 0x01 +#define XHCI_TRB_TYPE_SETUP_STAGE 0x02 +#define XHCI_TRB_TYPE_DATA_STAGE 0x03 +#define XHCI_TRB_TYPE_STATUS_STAGE 0x04 +#define XHCI_TRB_TYPE_ISOCH 0x05 +#define XHCI_TRB_TYPE_LINK 0x06 +#define XHCI_TRB_TYPE_EVENT_DATA 0x07 +#define XHCI_TRB_TYPE_NOOP 0x08 +#define XHCI_TRB_TYPE_ENABLE_SLOT 0x09 +#define XHCI_TRB_TYPE_DISABLE_SLOT 0x0A +#define XHCI_TRB_TYPE_ADDRESS_DEVICE 0x0B +#define XHCI_TRB_TYPE_CONFIGURE_EP 0x0C +#define XHCI_TRB_TYPE_EVALUATE_CTX 0x0D +#define XHCI_TRB_TYPE_RESET_EP 0x0E +#define XHCI_TRB_TYPE_STOP_EP 0x0F +#define XHCI_TRB_TYPE_SET_TR_DEQUEUE 0x10 +#define XHCI_TRB_TYPE_RESET_DEVICE 0x11 +#define XHCI_TRB_TYPE_FORCE_EVENT 0x12 +#define XHCI_TRB_TYPE_NEGOTIATE_BW 0x13 +#define XHCI_TRB_TYPE_SET_LATENCY_TOL 0x14 +#define XHCI_TRB_TYPE_GET_PORT_BW 0x15 +#define XHCI_TRB_TYPE_FORCE_HEADER 0x16 +#define XHCI_TRB_TYPE_NOOP_CMD 0x17 + +/* Events */ +#define XHCI_TRB_EVENT_TRANSFER 0x20 +#define XHCI_TRB_EVENT_CMD_COMPLETE 0x21 +#define XHCI_TRB_EVENT_PORT_STS_CHANGE 0x22 +#define XHCI_TRB_EVENT_BW_REQUEST 0x23 +#define XHCI_TRB_EVENT_DOORBELL 0x24 +#define XHCI_TRB_EVENT_HOST_CTRL 0x25 +#define XHCI_TRB_EVENT_DEVICE_NOTIFY 0x26 +#define XHCI_TRB_EVENT_MFINDEX_WRAP 0x27 + +/* Error codes */ +#define XHCI_TRB_ERROR_INVALID 0x00 +#define XHCI_TRB_ERROR_SUCCESS 0x01 +#define XHCI_TRB_ERROR_DATA_BUF 0x02 +#define XHCI_TRB_ERROR_BABBLE 0x03 +#define XHCI_TRB_ERROR_XACT 0x04 +#define XHCI_TRB_ERROR_TRB 0x05 +#define XHCI_TRB_ERROR_STALL 0x06 +#define XHCI_TRB_ERROR_RESOURCE 0x07 +#define XHCI_TRB_ERROR_BANDWIDTH 0x08 +#define XHCI_TRB_ERROR_NO_SLOTS 0x09 +#define XHCI_TRB_ERROR_STREAM_TYPE 0x0A +#define XHCI_TRB_ERROR_SLOT_NOT_ON 0x0B +#define XHCI_TRB_ERROR_ENDP_NOT_ON 0x0C +#define XHCI_TRB_ERROR_SHORT_PKT 0x0D +#define XHCI_TRB_ERROR_RING_UNDERRUN 0x0E +#define XHCI_TRB_ERROR_RING_OVERRUN 0x0F +#define XHCI_TRB_ERROR_VF_RING_FULL 0x10 +#define XHCI_TRB_ERROR_PARAMETER 0x11 +#define XHCI_TRB_ERROR_BW_OVERRUN 0x12 +#define XHCI_TRB_ERROR_CONTEXT_STATE 0x13 +#define XHCI_TRB_ERROR_NO_PING_RESP 0x14 +#define XHCI_TRB_ERROR_EV_RING_FULL 0x15 +#define XHCI_TRB_ERROR_INCOMPAT_DEV 0x16 +#define XHCI_TRB_ERROR_MISSED_SERVICE 0x17 +#define XHCI_TRB_ERROR_CMD_RING_STOP 0x18 +#define XHCI_TRB_ERROR_CMD_ABORTED 0x19 +#define XHCI_TRB_ERROR_STOPPED 0x1A +#define XHCI_TRB_ERROR_LENGTH 0x1B +#define XHCI_TRB_ERROR_BAD_MELAT 0x1D +#define XHCI_TRB_ERROR_ISOC_OVERRUN 0x1F +#define XHCI_TRB_ERROR_EVENT_LOST 0x20 +#define XHCI_TRB_ERROR_UNDEFINED 0x21 +#define XHCI_TRB_ERROR_INVALID_SID 0x22 +#define XHCI_TRB_ERROR_SEC_BW 0x23 +#define XHCI_TRB_ERROR_SPLIT_XACT 0x24 +} __aligned(4); + +struct xhci_dev_endpoint_trbs { + struct xhci_trb trb[(XHCI_MAX_STREAMS * + XHCI_MAX_TRANSFERS) + XHCI_MAX_STREAMS]; +}; + +struct xhci_event_ring_seg { + volatile uint64_t qwEvrsTablePtr; + volatile uint32_t dwEvrsTableSize; + volatile uint32_t dwEvrsReserved; +}; + +#endif /* _PCI_XHCI_H_ */ diff --git a/usr/src/cmd/bhyve/pm.c b/usr/src/cmd/bhyve/pm.c new file mode 100644 index 0000000000..be188b79f2 --- /dev/null +++ b/usr/src/cmd/bhyve/pm.c @@ -0,0 +1,378 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Hudson River Trading LLC + * Written by: John H. Baldwin <jhb@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ +/* + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <machine/vmm.h> + +#include <assert.h> +#include <errno.h> +#include <pthread.h> +#ifndef __FreeBSD__ +#include <stdlib.h> +#endif +#include <signal.h> +#include <vmmapi.h> + +#include "acpi.h" +#include "inout.h" +#ifdef __FreeBSD__ +#include "mevent.h" +#endif +#include "pci_irq.h" +#include "pci_lpc.h" + +static pthread_mutex_t pm_lock = PTHREAD_MUTEX_INITIALIZER; +#ifdef __FreeBSD__ +static struct mevent *power_button; +static sig_t old_power_handler; +#else +struct vmctx *pwr_ctx; +#endif + +/* + * Reset Control register at I/O port 0xcf9. Bit 2 forces a system + * reset when it transitions from 0 to 1. Bit 1 selects the type of + * reset to attempt: 0 selects a "soft" reset, and 1 selects a "hard" + * reset. + */ +static int +reset_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + int error; + + static uint8_t reset_control; + + if (bytes != 1) + return (-1); + if (in) + *eax = reset_control; + else { + reset_control = *eax; + + /* Treat hard and soft resets the same. */ + if (reset_control & 0x4) { + error = vm_suspend(ctx, VM_SUSPEND_RESET); + assert(error == 0 || errno == EALREADY); + } + } + return (0); +} +INOUT_PORT(reset_reg, 0xCF9, IOPORT_F_INOUT, reset_handler); + +/* + * ACPI's SCI is a level-triggered interrupt. + */ +static int sci_active; + +static void +sci_assert(struct vmctx *ctx) +{ + + if (sci_active) + return; + vm_isa_assert_irq(ctx, SCI_INT, SCI_INT); + sci_active = 1; +} + +static void +sci_deassert(struct vmctx *ctx) +{ + + if (!sci_active) + return; + vm_isa_deassert_irq(ctx, SCI_INT, SCI_INT); + sci_active = 0; +} + +/* + * Power Management 1 Event Registers + * + * The only power management event supported is a power button upon + * receiving SIGTERM. + */ +static uint16_t pm1_enable, pm1_status; + +#define PM1_TMR_STS 0x0001 +#define PM1_BM_STS 0x0010 +#define PM1_GBL_STS 0x0020 +#define PM1_PWRBTN_STS 0x0100 +#define PM1_SLPBTN_STS 0x0200 +#define PM1_RTC_STS 0x0400 +#define PM1_WAK_STS 0x8000 + +#define PM1_TMR_EN 0x0001 +#define PM1_GBL_EN 0x0020 +#define PM1_PWRBTN_EN 0x0100 +#define PM1_SLPBTN_EN 0x0200 +#define PM1_RTC_EN 0x0400 + +static void +sci_update(struct vmctx *ctx) +{ + int need_sci; + + /* See if the SCI should be active or not. */ + need_sci = 0; + if ((pm1_enable & PM1_TMR_EN) && (pm1_status & PM1_TMR_STS)) + need_sci = 1; + if ((pm1_enable & PM1_GBL_EN) && (pm1_status & PM1_GBL_STS)) + need_sci = 1; + if ((pm1_enable & PM1_PWRBTN_EN) && (pm1_status & PM1_PWRBTN_STS)) + need_sci = 1; + if ((pm1_enable & PM1_SLPBTN_EN) && (pm1_status & PM1_SLPBTN_STS)) + need_sci = 1; + if ((pm1_enable & PM1_RTC_EN) && (pm1_status & PM1_RTC_STS)) + need_sci = 1; + if (need_sci) + sci_assert(ctx); + else + sci_deassert(ctx); +} + +static int +pm1_status_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + + if (bytes != 2) + return (-1); + + pthread_mutex_lock(&pm_lock); + if (in) + *eax = pm1_status; + else { + /* + * Writes are only permitted to clear certain bits by + * writing 1 to those flags. + */ + pm1_status &= ~(*eax & (PM1_WAK_STS | PM1_RTC_STS | + PM1_SLPBTN_STS | PM1_PWRBTN_STS | PM1_BM_STS)); + sci_update(ctx); + } + pthread_mutex_unlock(&pm_lock); + return (0); +} + +static int +pm1_enable_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + + if (bytes != 2) + return (-1); + + pthread_mutex_lock(&pm_lock); + if (in) + *eax = pm1_enable; + else { + /* + * Only permit certain bits to be set. We never use + * the global lock, but ACPI-CA whines profusely if it + * can't set GBL_EN. + */ + pm1_enable = *eax & (PM1_PWRBTN_EN | PM1_GBL_EN); + sci_update(ctx); + } + pthread_mutex_unlock(&pm_lock); + return (0); +} +INOUT_PORT(pm1_status, PM1A_EVT_ADDR, IOPORT_F_INOUT, pm1_status_handler); +INOUT_PORT(pm1_enable, PM1A_EVT_ADDR + 2, IOPORT_F_INOUT, pm1_enable_handler); + +#ifdef __FreeBSD__ +static void +power_button_handler(int signal, enum ev_type type, void *arg) +{ + struct vmctx *ctx; + + ctx = arg; + pthread_mutex_lock(&pm_lock); + if (!(pm1_status & PM1_PWRBTN_STS)) { + pm1_status |= PM1_PWRBTN_STS; + sci_update(ctx); + } + pthread_mutex_unlock(&pm_lock); +} + +#else +/* + * Initiate graceful power off. + */ +/*ARGSUSED*/ +static void +power_button_handler(int signal, siginfo_t *type, void *cp) +{ + /* + * In theory, taking the 'pm_lock' mutex from within this signal + * handler could lead to deadlock if the main thread already held this + * mutex. In reality, this mutex is local to this file and all of the + * other usage in this file only occurs in functions which are FreeBSD + * specific (and thus currently not used). Thus, for consistency with + * the other code in this file, we take the mutex, but in the future, + * if these other functions are ever enabled for use on non-FreeBSD + * systems and these functions could be called directly by a thread + * (which would then hold the mutex), then we need to revisit the use + * of this mutex in this signal handler. + */ + pthread_mutex_lock(&pm_lock); + if (!(pm1_status & PM1_PWRBTN_STS)) { + pm1_status |= PM1_PWRBTN_STS; + sci_update(pwr_ctx); + } + pthread_mutex_unlock(&pm_lock); +} +#endif + +/* + * Power Management 1 Control Register + * + * This is mostly unimplemented except that we wish to handle writes that + * set SPL_EN to handle S5 (soft power off). + */ +static uint16_t pm1_control; + +#define PM1_SCI_EN 0x0001 +#define PM1_SLP_TYP 0x1c00 +#define PM1_SLP_EN 0x2000 +#define PM1_ALWAYS_ZERO 0xc003 + +static int +pm1_control_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + int error; + + if (bytes != 2) + return (-1); + if (in) + *eax = pm1_control; + else { + /* + * Various bits are write-only or reserved, so force them + * to zero in pm1_control. Always preserve SCI_EN as OSPM + * can never change it. + */ + pm1_control = (pm1_control & PM1_SCI_EN) | + (*eax & ~(PM1_SLP_EN | PM1_ALWAYS_ZERO)); + + /* + * If SLP_EN is set, check for S5. Bhyve's _S5_ method + * says that '5' should be stored in SLP_TYP for S5. + */ + if (*eax & PM1_SLP_EN) { + if ((pm1_control & PM1_SLP_TYP) >> 10 == 5) { + error = vm_suspend(ctx, VM_SUSPEND_POWEROFF); + assert(error == 0 || errno == EALREADY); + } + } + } + return (0); +} +INOUT_PORT(pm1_control, PM1A_CNT_ADDR, IOPORT_F_INOUT, pm1_control_handler); +#ifdef __FreeBSD__ +SYSRES_IO(PM1A_EVT_ADDR, 8); +#endif + +/* + * ACPI SMI Command Register + * + * This write-only register is used to enable and disable ACPI. + */ +static int +smi_cmd_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + + assert(!in); + if (bytes != 1) + return (-1); + + pthread_mutex_lock(&pm_lock); + switch (*eax) { + case BHYVE_ACPI_ENABLE: + pm1_control |= PM1_SCI_EN; +#ifdef __FreeBSD__ + if (power_button == NULL) { + power_button = mevent_add(SIGTERM, EVF_SIGNAL, + power_button_handler, ctx); + old_power_handler = signal(SIGTERM, SIG_IGN); + } +#endif + break; + case BHYVE_ACPI_DISABLE: + pm1_control &= ~PM1_SCI_EN; +#ifdef __FreeBSD__ + if (power_button != NULL) { + mevent_delete(power_button); + power_button = NULL; + signal(SIGTERM, old_power_handler); + } +#endif + break; + } + pthread_mutex_unlock(&pm_lock); + return (0); +} +INOUT_PORT(smi_cmd, SMI_CMD, IOPORT_F_OUT, smi_cmd_handler); +#ifdef __FreeBSD__ +SYSRES_IO(SMI_CMD, 1); +#endif + +void +sci_init(struct vmctx *ctx) +{ + + /* + * Mark ACPI's SCI as level trigger and bump its use count + * in the PIRQ router. + */ + pci_irq_use(SCI_INT); + vm_isa_set_irq_trigger(ctx, SCI_INT, LEVEL_TRIGGER); + +#ifndef __FreeBSD__ + { + /* + * Install SIGTERM signal handler for graceful power off. + */ + struct sigaction act; + + pwr_ctx = ctx; + act.sa_flags = 0; + act.sa_sigaction = power_button_handler; + (void) sigaction(SIGTERM, &act, NULL); + } +#endif +} diff --git a/usr/src/cmd/bhyve/post.c b/usr/src/cmd/bhyve/post.c new file mode 100644 index 0000000000..d3040a8df7 --- /dev/null +++ b/usr/src/cmd/bhyve/post.c @@ -0,0 +1,55 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> + +#include <assert.h> + +#include "inout.h" +#include "pci_lpc.h" + +static int +post_data_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + assert(in == 1); + + if (bytes != 1) + return (-1); + + *eax = 0xff; /* return some garbage */ + return (0); +} + +INOUT_PORT(post, 0x84, IOPORT_F_IN, post_data_handler); +SYSRES_IO(0x84, 1); diff --git a/usr/src/cmd/bhyve/ps2kbd.c b/usr/src/cmd/bhyve/ps2kbd.c new file mode 100644 index 0000000000..5453a26949 --- /dev/null +++ b/usr/src/cmd/bhyve/ps2kbd.c @@ -0,0 +1,383 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * Copyright (c) 2015 Nahanni Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <pthread.h> +#include <pthread_np.h> + +#include "atkbdc.h" +#include "console.h" + +/* keyboard device commands */ +#define PS2KC_RESET_DEV 0xff +#define PS2KC_DISABLE 0xf5 +#define PS2KC_ENABLE 0xf4 +#define PS2KC_SET_TYPEMATIC 0xf3 +#define PS2KC_SEND_DEV_ID 0xf2 +#define PS2KC_SET_SCANCODE_SET 0xf0 +#define PS2KC_ECHO 0xee +#define PS2KC_SET_LEDS 0xed + +#define PS2KC_BAT_SUCCESS 0xaa +#define PS2KC_ACK 0xfa + +#define PS2KBD_FIFOSZ 16 + +struct fifo { + uint8_t buf[PS2KBD_FIFOSZ]; + int rindex; /* index to read from */ + int windex; /* index to write to */ + int num; /* number of bytes in the fifo */ + int size; /* size of the fifo */ +}; + +struct ps2kbd_softc { + struct atkbdc_softc *atkbdc_sc; + pthread_mutex_t mtx; + + bool enabled; + struct fifo fifo; + + uint8_t curcmd; /* current command for next byte */ +}; + +#define SCANCODE_E0_PREFIX 1 +struct extended_translation { + uint32_t keysym; + uint8_t scancode; + int flags; +}; + +/* + * FIXME: Pause/break and Print Screen/SysRq require special handling. + */ +static const struct extended_translation extended_translations[] = { + {0xff08, 0x66}, /* Back space */ + {0xff09, 0x0d}, /* Tab */ + {0xff0d, 0x5a}, /* Return */ + {0xff1b, 0x76}, /* Escape */ + {0xff50, 0x6c, SCANCODE_E0_PREFIX}, /* Home */ + {0xff51, 0x6b, SCANCODE_E0_PREFIX}, /* Left arrow */ + {0xff52, 0x75, SCANCODE_E0_PREFIX}, /* Up arrow */ + {0xff53, 0x74, SCANCODE_E0_PREFIX}, /* Right arrow */ + {0xff54, 0x72, SCANCODE_E0_PREFIX}, /* Down arrow */ + {0xff55, 0x7d, SCANCODE_E0_PREFIX}, /* PgUp */ + {0xff56, 0x7a, SCANCODE_E0_PREFIX}, /* PgDown */ + {0xff57, 0x69, SCANCODE_E0_PREFIX}, /* End */ + {0xff63, 0x70, SCANCODE_E0_PREFIX}, /* Ins */ + {0xff8d, 0x5a, SCANCODE_E0_PREFIX}, /* Keypad Enter */ + {0xffe1, 0x12}, /* Left shift */ + {0xffe2, 0x59}, /* Right shift */ + {0xffe3, 0x14}, /* Left control */ + {0xffe4, 0x14, SCANCODE_E0_PREFIX}, /* Right control */ + /* {0xffe7, XXX}, Left meta */ + /* {0xffe8, XXX}, Right meta */ + {0xffe9, 0x11}, /* Left alt */ + {0xfe03, 0x11, SCANCODE_E0_PREFIX}, /* AltGr */ + {0xffea, 0x11, SCANCODE_E0_PREFIX}, /* Right alt */ + {0xffeb, 0x1f, SCANCODE_E0_PREFIX}, /* Left Windows */ + {0xffec, 0x27, SCANCODE_E0_PREFIX}, /* Right Windows */ + {0xffbe, 0x05}, /* F1 */ + {0xffbf, 0x06}, /* F2 */ + {0xffc0, 0x04}, /* F3 */ + {0xffc1, 0x0c}, /* F4 */ + {0xffc2, 0x03}, /* F5 */ + {0xffc3, 0x0b}, /* F6 */ + {0xffc4, 0x83}, /* F7 */ + {0xffc5, 0x0a}, /* F8 */ + {0xffc6, 0x01}, /* F9 */ + {0xffc7, 0x09}, /* F10 */ + {0xffc8, 0x78}, /* F11 */ + {0xffc9, 0x07}, /* F12 */ + {0xffff, 0x71, SCANCODE_E0_PREFIX}, /* Del */ + {0xff14, 0x7e}, /* ScrollLock */ + /* NumLock and Keypads*/ + {0xff7f, 0x77}, /* NumLock */ + {0xffaf, 0x4a, SCANCODE_E0_PREFIX}, /* Keypad slash */ + {0xffaa, 0x7c}, /* Keypad asterisk */ + {0xffad, 0x7b}, /* Keypad minus */ + {0xffab, 0x79}, /* Keypad plus */ + {0xffb7, 0x6c}, /* Keypad 7 */ + {0xff95, 0x6c}, /* Keypad home */ + {0xffb8, 0x75}, /* Keypad 8 */ + {0xff97, 0x75}, /* Keypad up arrow */ + {0xffb9, 0x7d}, /* Keypad 9 */ + {0xff9a, 0x7d}, /* Keypad PgUp */ + {0xffb4, 0x6b}, /* Keypad 4 */ + {0xff96, 0x6b}, /* Keypad left arrow */ + {0xffb5, 0x73}, /* Keypad 5 */ + {0xff9d, 0x73}, /* Keypad empty */ + {0xffb6, 0x74}, /* Keypad 6 */ + {0xff98, 0x74}, /* Keypad right arrow */ + {0xffb1, 0x69}, /* Keypad 1 */ + {0xff9c, 0x69}, /* Keypad end */ + {0xffb2, 0x72}, /* Keypad 2 */ + {0xff99, 0x72}, /* Keypad down arrow */ + {0xffb3, 0x7a}, /* Keypad 3 */ + {0xff9b, 0x7a}, /* Keypad PgDown */ + {0xffb0, 0x70}, /* Keypad 0 */ + {0xff9e, 0x70}, /* Keypad ins */ + {0xffae, 0x71}, /* Keypad . */ + {0xff9f, 0x71}, /* Keypad del */ + {0, 0, 0} /* Terminator */ +}; + +/* ASCII to type 2 scancode lookup table */ +static const uint8_t ascii_translations[128] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x29, 0x16, 0x52, 0x26, 0x25, 0x2e, 0x3d, 0x52, + 0x46, 0x45, 0x3e, 0x55, 0x41, 0x4e, 0x49, 0x4a, + 0x45, 0x16, 0x1e, 0x26, 0x25, 0x2e, 0x36, 0x3d, + 0x3e, 0x46, 0x4c, 0x4c, 0x41, 0x55, 0x49, 0x4a, + 0x1e, 0x1c, 0x32, 0x21, 0x23, 0x24, 0x2b, 0x34, + 0x33, 0x43, 0x3b, 0x42, 0x4b, 0x3a, 0x31, 0x44, + 0x4d, 0x15, 0x2d, 0x1b, 0x2c, 0x3c, 0x2a, 0x1d, + 0x22, 0x35, 0x1a, 0x54, 0x5d, 0x5b, 0x36, 0x4e, + 0x0e, 0x1c, 0x32, 0x21, 0x23, 0x24, 0x2b, 0x34, + 0x33, 0x43, 0x3b, 0x42, 0x4b, 0x3a, 0x31, 0x44, + 0x4d, 0x15, 0x2d, 0x1b, 0x2c, 0x3c, 0x2a, 0x1d, + 0x22, 0x35, 0x1a, 0x54, 0x5d, 0x5b, 0x0e, 0x00, +}; + +static void +fifo_init(struct ps2kbd_softc *sc) +{ + struct fifo *fifo; + + fifo = &sc->fifo; + fifo->size = sizeof(((struct fifo *)0)->buf); +} + +static void +fifo_reset(struct ps2kbd_softc *sc) +{ + struct fifo *fifo; + + fifo = &sc->fifo; + bzero(fifo, sizeof(struct fifo)); + fifo->size = sizeof(((struct fifo *)0)->buf); +} + +static void +fifo_put(struct ps2kbd_softc *sc, uint8_t val) +{ + struct fifo *fifo; + + fifo = &sc->fifo; + if (fifo->num < fifo->size) { + fifo->buf[fifo->windex] = val; + fifo->windex = (fifo->windex + 1) % fifo->size; + fifo->num++; + } +} + +static int +fifo_get(struct ps2kbd_softc *sc, uint8_t *val) +{ + struct fifo *fifo; + + fifo = &sc->fifo; + if (fifo->num > 0) { + *val = fifo->buf[fifo->rindex]; + fifo->rindex = (fifo->rindex + 1) % fifo->size; + fifo->num--; + return (0); + } + + return (-1); +} + +int +ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val) +{ + int retval; + + pthread_mutex_lock(&sc->mtx); + retval = fifo_get(sc, val); + pthread_mutex_unlock(&sc->mtx); + + return (retval); +} + +void +ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val) +{ + pthread_mutex_lock(&sc->mtx); + if (sc->curcmd) { + switch (sc->curcmd) { + case PS2KC_SET_TYPEMATIC: + fifo_put(sc, PS2KC_ACK); + break; + case PS2KC_SET_SCANCODE_SET: + fifo_put(sc, PS2KC_ACK); + break; + case PS2KC_SET_LEDS: + fifo_put(sc, PS2KC_ACK); + break; + default: + fprintf(stderr, "Unhandled ps2 keyboard current " + "command byte 0x%02x\n", val); + break; + } + sc->curcmd = 0; + } else { + switch (val) { + case 0x00: + fifo_put(sc, PS2KC_ACK); + break; + case PS2KC_RESET_DEV: + fifo_reset(sc); + fifo_put(sc, PS2KC_ACK); + fifo_put(sc, PS2KC_BAT_SUCCESS); + break; + case PS2KC_DISABLE: + sc->enabled = false; + fifo_put(sc, PS2KC_ACK); + break; + case PS2KC_ENABLE: + sc->enabled = true; + fifo_reset(sc); + fifo_put(sc, PS2KC_ACK); + break; + case PS2KC_SET_TYPEMATIC: + sc->curcmd = val; + fifo_put(sc, PS2KC_ACK); + break; + case PS2KC_SEND_DEV_ID: + fifo_put(sc, PS2KC_ACK); + fifo_put(sc, 0xab); + fifo_put(sc, 0x83); + break; + case PS2KC_SET_SCANCODE_SET: + sc->curcmd = val; + fifo_put(sc, PS2KC_ACK); + break; + case PS2KC_ECHO: + fifo_put(sc, PS2KC_ECHO); + break; + case PS2KC_SET_LEDS: + sc->curcmd = val; + fifo_put(sc, PS2KC_ACK); + break; + default: + fprintf(stderr, "Unhandled ps2 keyboard command " + "0x%02x\n", val); + break; + } + } + pthread_mutex_unlock(&sc->mtx); +} + +/* + * Translate keysym to type 2 scancode and insert into keyboard buffer. + */ +static void +ps2kbd_keysym_queue(struct ps2kbd_softc *sc, + int down, uint32_t keysym) +{ + assert(pthread_mutex_isowned_np(&sc->mtx)); + int e0_prefix, found; + uint8_t code; + const struct extended_translation *trans; + + found = 0; + if (keysym < 0x80) { + code = ascii_translations[keysym]; + e0_prefix = 0; + found = 1; + } else { + for (trans = &(extended_translations[0]); trans->keysym != 0; + trans++) { + if (keysym == trans->keysym) { + code = trans->scancode; + e0_prefix = trans->flags & SCANCODE_E0_PREFIX; + found = 1; + break; + } + } + } + + if (!found) { + fprintf(stderr, "Unhandled ps2 keyboard keysym 0x%x\n", keysym); + return; + } + + if (e0_prefix) + fifo_put(sc, 0xe0); + if (!down) + fifo_put(sc, 0xf0); + fifo_put(sc, code); +} + +static void +ps2kbd_event(int down, uint32_t keysym, void *arg) +{ + struct ps2kbd_softc *sc = arg; + int fifo_full; + + pthread_mutex_lock(&sc->mtx); + if (!sc->enabled) { + pthread_mutex_unlock(&sc->mtx); + return; + } + fifo_full = sc->fifo.num == PS2KBD_FIFOSZ; + ps2kbd_keysym_queue(sc, down, keysym); + pthread_mutex_unlock(&sc->mtx); + + if (!fifo_full) + atkbdc_event(sc->atkbdc_sc, 1); +} + +struct ps2kbd_softc * +ps2kbd_init(struct atkbdc_softc *atkbdc_sc) +{ + struct ps2kbd_softc *sc; + + sc = calloc(1, sizeof (struct ps2kbd_softc)); + pthread_mutex_init(&sc->mtx, NULL); + fifo_init(sc); + sc->atkbdc_sc = atkbdc_sc; + + console_kbd_register(ps2kbd_event, sc, 1); + + return (sc); +} + diff --git a/usr/src/cmd/bhyve/ps2kbd.h b/usr/src/cmd/bhyve/ps2kbd.h new file mode 100644 index 0000000000..17be6d0466 --- /dev/null +++ b/usr/src/cmd/bhyve/ps2kbd.h @@ -0,0 +1,41 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _PS2KBD_H_ +#define _PS2KBD_H_ + +struct atkbdc_softc; + +struct ps2kbd_softc *ps2kbd_init(struct atkbdc_softc *sc); + +int ps2kbd_read(struct ps2kbd_softc *sc, uint8_t *val); +void ps2kbd_write(struct ps2kbd_softc *sc, uint8_t val); + +#endif /* _PS2KBD_H_ */ diff --git a/usr/src/cmd/bhyve/ps2mouse.c b/usr/src/cmd/bhyve/ps2mouse.c new file mode 100644 index 0000000000..b2e08262b1 --- /dev/null +++ b/usr/src/cmd/bhyve/ps2mouse.c @@ -0,0 +1,418 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * Copyright (c) 2015 Nahanni Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> + +#include <assert.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <pthread.h> +#include <pthread_np.h> + +#include "atkbdc.h" +#include "console.h" + +/* mouse device commands */ +#define PS2MC_RESET_DEV 0xff +#define PS2MC_SET_DEFAULTS 0xf6 +#define PS2MC_DISABLE 0xf5 +#define PS2MC_ENABLE 0xf4 +#define PS2MC_SET_SAMPLING_RATE 0xf3 +#define PS2MC_SEND_DEV_ID 0xf2 +#define PS2MC_SET_REMOTE_MODE 0xf0 +#define PS2MC_SEND_DEV_DATA 0xeb +#define PS2MC_SET_STREAM_MODE 0xea +#define PS2MC_SEND_DEV_STATUS 0xe9 +#define PS2MC_SET_RESOLUTION 0xe8 +#define PS2MC_SET_SCALING1 0xe7 +#define PS2MC_SET_SCALING2 0xe6 + +#define PS2MC_BAT_SUCCESS 0xaa +#define PS2MC_ACK 0xfa + +/* mouse device id */ +#define PS2MOUSE_DEV_ID 0x0 + +/* mouse data bits */ +#define PS2M_DATA_Y_OFLOW 0x80 +#define PS2M_DATA_X_OFLOW 0x40 +#define PS2M_DATA_Y_SIGN 0x20 +#define PS2M_DATA_X_SIGN 0x10 +#define PS2M_DATA_AONE 0x08 +#define PS2M_DATA_MID_BUTTON 0x04 +#define PS2M_DATA_RIGHT_BUTTON 0x02 +#define PS2M_DATA_LEFT_BUTTON 0x01 + +/* mouse status bits */ +#define PS2M_STS_REMOTE_MODE 0x40 +#define PS2M_STS_ENABLE_DEV 0x20 +#define PS2M_STS_SCALING_21 0x10 +#define PS2M_STS_MID_BUTTON 0x04 +#define PS2M_STS_RIGHT_BUTTON 0x02 +#define PS2M_STS_LEFT_BUTTON 0x01 + +#define PS2MOUSE_FIFOSZ 16 + +struct fifo { + uint8_t buf[PS2MOUSE_FIFOSZ]; + int rindex; /* index to read from */ + int windex; /* index to write to */ + int num; /* number of bytes in the fifo */ + int size; /* size of the fifo */ +}; + +struct ps2mouse_softc { + struct atkbdc_softc *atkbdc_sc; + pthread_mutex_t mtx; + + uint8_t status; + uint8_t resolution; + uint8_t sampling_rate; + int ctrlenable; + struct fifo fifo; + + uint8_t curcmd; /* current command for next byte */ + + int cur_x, cur_y; + int delta_x, delta_y; +}; + +static void +fifo_init(struct ps2mouse_softc *sc) +{ + struct fifo *fifo; + + fifo = &sc->fifo; + fifo->size = sizeof(((struct fifo *)0)->buf); +} + +static void +fifo_reset(struct ps2mouse_softc *sc) +{ + struct fifo *fifo; + + fifo = &sc->fifo; + bzero(fifo, sizeof(struct fifo)); + fifo->size = sizeof(((struct fifo *)0)->buf); +} + +static void +fifo_put(struct ps2mouse_softc *sc, uint8_t val) +{ + struct fifo *fifo; + + fifo = &sc->fifo; + if (fifo->num < fifo->size) { + fifo->buf[fifo->windex] = val; + fifo->windex = (fifo->windex + 1) % fifo->size; + fifo->num++; + } +} + +static int +fifo_get(struct ps2mouse_softc *sc, uint8_t *val) +{ + struct fifo *fifo; + + fifo = &sc->fifo; + if (fifo->num > 0) { + *val = fifo->buf[fifo->rindex]; + fifo->rindex = (fifo->rindex + 1) % fifo->size; + fifo->num--; + return (0); + } + + return (-1); +} + +static void +movement_reset(struct ps2mouse_softc *sc) +{ + assert(pthread_mutex_isowned_np(&sc->mtx)); + + sc->delta_x = 0; + sc->delta_y = 0; +} + +static void +movement_update(struct ps2mouse_softc *sc, int x, int y) +{ + sc->delta_x += x - sc->cur_x; + sc->delta_y += sc->cur_y - y; + sc->cur_x = x; + sc->cur_y = y; +} + +static void +movement_get(struct ps2mouse_softc *sc) +{ + uint8_t val0, val1, val2; + + assert(pthread_mutex_isowned_np(&sc->mtx)); + + val0 = PS2M_DATA_AONE; + val0 |= sc->status & (PS2M_DATA_LEFT_BUTTON | + PS2M_DATA_RIGHT_BUTTON | PS2M_DATA_MID_BUTTON); + + if (sc->delta_x >= 0) { + if (sc->delta_x > 255) { + val0 |= PS2M_DATA_X_OFLOW; + val1 = 255; + } else + val1 = sc->delta_x; + } else { + val0 |= PS2M_DATA_X_SIGN; + if (sc->delta_x < -255) { + val0 |= PS2M_DATA_X_OFLOW; + val1 = 255; + } else + val1 = sc->delta_x; + } + sc->delta_x = 0; + + if (sc->delta_y >= 0) { + if (sc->delta_y > 255) { + val0 |= PS2M_DATA_Y_OFLOW; + val2 = 255; + } else + val2 = sc->delta_y; + } else { + val0 |= PS2M_DATA_Y_SIGN; + if (sc->delta_y < -255) { + val0 |= PS2M_DATA_Y_OFLOW; + val2 = 255; + } else + val2 = sc->delta_y; + } + sc->delta_y = 0; + + if (sc->fifo.num < (sc->fifo.size - 3)) { + fifo_put(sc, val0); + fifo_put(sc, val1); + fifo_put(sc, val2); + } +} + +static void +ps2mouse_reset(struct ps2mouse_softc *sc) +{ + assert(pthread_mutex_isowned_np(&sc->mtx)); + fifo_reset(sc); + movement_reset(sc); + sc->status = PS2M_STS_ENABLE_DEV; + sc->resolution = 4; + sc->sampling_rate = 100; + + sc->cur_x = 0; + sc->cur_y = 0; + sc->delta_x = 0; + sc->delta_y = 0; +} + +int +ps2mouse_read(struct ps2mouse_softc *sc, uint8_t *val) +{ + int retval; + + pthread_mutex_lock(&sc->mtx); + retval = fifo_get(sc, val); + pthread_mutex_unlock(&sc->mtx); + + return (retval); +} + +int +ps2mouse_fifocnt(struct ps2mouse_softc *sc) +{ + return (sc->fifo.num); +} + +void +ps2mouse_toggle(struct ps2mouse_softc *sc, int enable) +{ + pthread_mutex_lock(&sc->mtx); + if (enable) + sc->ctrlenable = 1; + else { + sc->ctrlenable = 0; + sc->fifo.rindex = 0; + sc->fifo.windex = 0; + sc->fifo.num = 0; + } + pthread_mutex_unlock(&sc->mtx); +} + +void +ps2mouse_write(struct ps2mouse_softc *sc, uint8_t val, int insert) +{ + pthread_mutex_lock(&sc->mtx); + fifo_reset(sc); + if (sc->curcmd) { + switch (sc->curcmd) { + case PS2MC_SET_SAMPLING_RATE: + sc->sampling_rate = val; + fifo_put(sc, PS2MC_ACK); + break; + case PS2MC_SET_RESOLUTION: + sc->resolution = val; + fifo_put(sc, PS2MC_ACK); + break; + default: + fprintf(stderr, "Unhandled ps2 mouse current " + "command byte 0x%02x\n", val); + break; + } + sc->curcmd = 0; + + } else if (insert) { + fifo_put(sc, val); + } else { + switch (val) { + case 0x00: + fifo_put(sc, PS2MC_ACK); + break; + case PS2MC_RESET_DEV: + ps2mouse_reset(sc); + fifo_put(sc, PS2MC_ACK); + fifo_put(sc, PS2MC_BAT_SUCCESS); + fifo_put(sc, PS2MOUSE_DEV_ID); + break; + case PS2MC_SET_DEFAULTS: + ps2mouse_reset(sc); + fifo_put(sc, PS2MC_ACK); + break; + case PS2MC_DISABLE: + fifo_reset(sc); + sc->status &= ~PS2M_STS_ENABLE_DEV; + fifo_put(sc, PS2MC_ACK); + break; + case PS2MC_ENABLE: + fifo_reset(sc); + sc->status |= PS2M_STS_ENABLE_DEV; + fifo_put(sc, PS2MC_ACK); + break; + case PS2MC_SET_SAMPLING_RATE: + sc->curcmd = val; + fifo_put(sc, PS2MC_ACK); + break; + case PS2MC_SEND_DEV_ID: + fifo_put(sc, PS2MC_ACK); + fifo_put(sc, PS2MOUSE_DEV_ID); + break; + case PS2MC_SET_REMOTE_MODE: + sc->status |= PS2M_STS_REMOTE_MODE; + fifo_put(sc, PS2MC_ACK); + break; + case PS2MC_SEND_DEV_DATA: + fifo_put(sc, PS2MC_ACK); + movement_get(sc); + break; + case PS2MC_SET_STREAM_MODE: + sc->status &= ~PS2M_STS_REMOTE_MODE; + fifo_put(sc, PS2MC_ACK); + break; + case PS2MC_SEND_DEV_STATUS: + fifo_put(sc, PS2MC_ACK); + fifo_put(sc, sc->status); + fifo_put(sc, sc->resolution); + fifo_put(sc, sc->sampling_rate); + break; + case PS2MC_SET_RESOLUTION: + sc->curcmd = val; + fifo_put(sc, PS2MC_ACK); + break; + case PS2MC_SET_SCALING1: + case PS2MC_SET_SCALING2: + fifo_put(sc, PS2MC_ACK); + break; + default: + fifo_put(sc, PS2MC_ACK); + fprintf(stderr, "Unhandled ps2 mouse command " + "0x%02x\n", val); + break; + } + } + pthread_mutex_unlock(&sc->mtx); +} + +static void +ps2mouse_event(uint8_t button, int x, int y, void *arg) +{ + struct ps2mouse_softc *sc = arg; + + pthread_mutex_lock(&sc->mtx); + movement_update(sc, x, y); + + sc->status &= ~(PS2M_STS_LEFT_BUTTON | + PS2M_STS_RIGHT_BUTTON | PS2M_STS_MID_BUTTON); + if (button & (1 << 0)) + sc->status |= PS2M_STS_LEFT_BUTTON; + if (button & (1 << 1)) + sc->status |= PS2M_STS_MID_BUTTON; + if (button & (1 << 2)) + sc->status |= PS2M_STS_RIGHT_BUTTON; + + if ((sc->status & PS2M_STS_ENABLE_DEV) == 0 || !sc->ctrlenable) { + /* no data reporting */ + pthread_mutex_unlock(&sc->mtx); + return; + } + + movement_get(sc); + pthread_mutex_unlock(&sc->mtx); + + if (sc->fifo.num > 0) + atkbdc_event(sc->atkbdc_sc, 0); +} + +struct ps2mouse_softc * +ps2mouse_init(struct atkbdc_softc *atkbdc_sc) +{ + struct ps2mouse_softc *sc; + + sc = calloc(1, sizeof (struct ps2mouse_softc)); + pthread_mutex_init(&sc->mtx, NULL); + fifo_init(sc); + sc->atkbdc_sc = atkbdc_sc; + + pthread_mutex_lock(&sc->mtx); + ps2mouse_reset(sc); + pthread_mutex_unlock(&sc->mtx); + + console_ptr_register(ps2mouse_event, sc, 1); + + return (sc); +} + + diff --git a/usr/src/cmd/bhyve/ps2mouse.h b/usr/src/cmd/bhyve/ps2mouse.h new file mode 100644 index 0000000000..59430b01e2 --- /dev/null +++ b/usr/src/cmd/bhyve/ps2mouse.h @@ -0,0 +1,43 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _PS2MOUSE_H_ +#define _PS2MOUSE_H_ + +struct atkbdc_softc; + +struct ps2mouse_softc *ps2mouse_init(struct atkbdc_softc *sc); + +int ps2mouse_read(struct ps2mouse_softc *sc, uint8_t *val); +void ps2mouse_write(struct ps2mouse_softc *sc, uint8_t val, int insert); +void ps2mouse_toggle(struct ps2mouse_softc *sc, int enable); +int ps2mouse_fifocnt(struct ps2mouse_softc *sc); + +#endif /* _PS2MOUSE_H_ */ diff --git a/usr/src/cmd/bhyve/rfb.c b/usr/src/cmd/bhyve/rfb.c new file mode 100644 index 0000000000..39ea1611f9 --- /dev/null +++ b/usr/src/cmd/bhyve/rfb.c @@ -0,0 +1,1148 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * Copyright (c) 2015 Leon Dang + * Copyright 2018 Joyent, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#endif +#include <sys/endian.h> +#include <sys/socket.h> +#include <sys/select.h> +#include <sys/time.h> +#include <arpa/inet.h> +#include <machine/cpufunc.h> +#include <machine/specialreg.h> +#include <netinet/in.h> +#include <netdb.h> + +#include <assert.h> +#ifndef WITHOUT_CAPSICUM +#include <capsicum_helpers.h> +#endif +#include <err.h> +#include <errno.h> +#include <pthread.h> +#include <pthread_np.h> +#include <signal.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sysexits.h> +#include <unistd.h> + +#include <zlib.h> + +#ifndef __FreeBSD__ +#include <sys/debug.h> +#endif + +#include "bhyvegc.h" +#include "console.h" +#include "rfb.h" +#include "sockstream.h" + +#ifndef NO_OPENSSL +#include <openssl/des.h> +#endif + +static int rfb_debug = 0; +#define DPRINTF(params) if (rfb_debug) printf params +#define WPRINTF(params) printf params + +#define AUTH_LENGTH 16 +#define PASSWD_LENGTH 8 + +#define SECURITY_TYPE_NONE 1 +#define SECURITY_TYPE_VNC_AUTH 2 + +#define AUTH_FAILED_UNAUTH 1 +#define AUTH_FAILED_ERROR 2 + +struct rfb_softc { + int sfd; + pthread_t tid; + + int cfd; + + int width, height; + + char *password; + + bool enc_raw_ok; + bool enc_zlib_ok; + bool enc_resize_ok; + + z_stream zstream; + uint8_t *zbuf; + int zbuflen; + + int conn_wait; + int sending; + pthread_mutex_t mtx; + pthread_cond_t cond; + + int hw_crc; + uint32_t *crc; /* WxH crc cells */ + uint32_t *crc_tmp; /* buffer to store single crc row */ + int crc_width, crc_height; +}; + +struct rfb_pixfmt { + uint8_t bpp; + uint8_t depth; + uint8_t bigendian; + uint8_t truecolor; + uint16_t red_max; + uint16_t green_max; + uint16_t blue_max; + uint8_t red_shift; + uint8_t green_shift; + uint8_t blue_shift; + uint8_t pad[3]; +}; + +struct rfb_srvr_info { + uint16_t width; + uint16_t height; + struct rfb_pixfmt pixfmt; + uint32_t namelen; +}; + +struct rfb_pixfmt_msg { + uint8_t type; + uint8_t pad[3]; + struct rfb_pixfmt pixfmt; +}; + +#define RFB_ENCODING_RAW 0 +#define RFB_ENCODING_ZLIB 6 +#define RFB_ENCODING_RESIZE -223 + +#define RFB_MAX_WIDTH 2000 +#define RFB_MAX_HEIGHT 1200 +#define RFB_ZLIB_BUFSZ RFB_MAX_WIDTH*RFB_MAX_HEIGHT*4 + +/* percentage changes to screen before sending the entire screen */ +#define RFB_SEND_ALL_THRESH 25 + +struct rfb_enc_msg { + uint8_t type; + uint8_t pad; + uint16_t numencs; +}; + +struct rfb_updt_msg { + uint8_t type; + uint8_t incremental; + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; +}; + +struct rfb_key_msg { + uint8_t type; + uint8_t down; + uint16_t pad; + uint32_t code; +}; + +struct rfb_ptr_msg { + uint8_t type; + uint8_t button; + uint16_t x; + uint16_t y; +}; + +struct rfb_srvr_updt_msg { + uint8_t type; + uint8_t pad; + uint16_t numrects; +}; + +struct rfb_srvr_rect_hdr { + uint16_t x; + uint16_t y; + uint16_t width; + uint16_t height; + uint32_t encoding; +}; + +struct rfb_cuttext_msg { + uint8_t type; + uint8_t padding[3]; + uint32_t length; +}; + + +static void +rfb_send_server_init_msg(int cfd) +{ + struct bhyvegc_image *gc_image; + struct rfb_srvr_info sinfo; + + gc_image = console_get_image(); + + sinfo.width = htons(gc_image->width); + sinfo.height = htons(gc_image->height); + sinfo.pixfmt.bpp = 32; + sinfo.pixfmt.depth = 32; + sinfo.pixfmt.bigendian = 0; + sinfo.pixfmt.truecolor = 1; + sinfo.pixfmt.red_max = htons(255); + sinfo.pixfmt.green_max = htons(255); + sinfo.pixfmt.blue_max = htons(255); + sinfo.pixfmt.red_shift = 16; + sinfo.pixfmt.green_shift = 8; + sinfo.pixfmt.blue_shift = 0; + sinfo.namelen = htonl(strlen("bhyve")); + (void)stream_write(cfd, &sinfo, sizeof(sinfo)); + (void)stream_write(cfd, "bhyve", strlen("bhyve")); +} + +static void +rfb_send_resize_update_msg(struct rfb_softc *rc, int cfd) +{ + struct rfb_srvr_updt_msg supdt_msg; + struct rfb_srvr_rect_hdr srect_hdr; + + /* Number of rectangles: 1 */ + supdt_msg.type = 0; + supdt_msg.pad = 0; + supdt_msg.numrects = htons(1); + stream_write(cfd, &supdt_msg, sizeof(struct rfb_srvr_updt_msg)); + + /* Rectangle header */ + srect_hdr.x = htons(0); + srect_hdr.y = htons(0); + srect_hdr.width = htons(rc->width); + srect_hdr.height = htons(rc->height); + srect_hdr.encoding = htonl(RFB_ENCODING_RESIZE); + stream_write(cfd, &srect_hdr, sizeof(struct rfb_srvr_rect_hdr)); +} + +static void +rfb_recv_set_pixfmt_msg(struct rfb_softc *rc, int cfd) +{ + struct rfb_pixfmt_msg pixfmt_msg; + + (void)stream_read(cfd, ((void *)&pixfmt_msg)+1, sizeof(pixfmt_msg)-1); +} + + +static void +rfb_recv_set_encodings_msg(struct rfb_softc *rc, int cfd) +{ + struct rfb_enc_msg enc_msg; + int i; + uint32_t encoding; + + assert((sizeof(enc_msg) - 1) == 3); + (void)stream_read(cfd, ((void *)&enc_msg)+1, sizeof(enc_msg)-1); + + for (i = 0; i < htons(enc_msg.numencs); i++) { + (void)stream_read(cfd, &encoding, sizeof(encoding)); + switch (htonl(encoding)) { + case RFB_ENCODING_RAW: + rc->enc_raw_ok = true; + break; + case RFB_ENCODING_ZLIB: + rc->enc_zlib_ok = true; + deflateInit(&rc->zstream, Z_BEST_SPEED); + break; + case RFB_ENCODING_RESIZE: + rc->enc_resize_ok = true; + break; + } + } +} + +/* + * Calculate CRC32 using SSE4.2; Intel or AMD Bulldozer+ CPUs only + */ +static __inline uint32_t +fast_crc32(void *buf, int len, uint32_t crcval) +{ + uint32_t q = len / sizeof(uint32_t); + uint32_t *p = (uint32_t *)buf; + + while (q--) { + asm volatile ( + ".byte 0xf2, 0xf, 0x38, 0xf1, 0xf1;" + :"=S" (crcval) + :"0" (crcval), "c" (*p) + ); + p++; + } + + return (crcval); +} + + +static int +rfb_send_rect(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc, + int x, int y, int w, int h) +{ + struct rfb_srvr_updt_msg supdt_msg; + struct rfb_srvr_rect_hdr srect_hdr; + unsigned long zlen; + ssize_t nwrite, total; + int err; + uint32_t *p; + uint8_t *zbufp; + + /* + * Send a single rectangle of the given x, y, w h dimensions. + */ + + /* Number of rectangles: 1 */ + supdt_msg.type = 0; + supdt_msg.pad = 0; + supdt_msg.numrects = htons(1); + nwrite = stream_write(cfd, &supdt_msg, + sizeof(struct rfb_srvr_updt_msg)); + if (nwrite <= 0) + return (nwrite); + + + /* Rectangle header */ + srect_hdr.x = htons(x); + srect_hdr.y = htons(y); + srect_hdr.width = htons(w); + srect_hdr.height = htons(h); + + h = y + h; + w *= sizeof(uint32_t); + if (rc->enc_zlib_ok) { + zbufp = rc->zbuf; + rc->zstream.total_in = 0; + rc->zstream.total_out = 0; + for (p = &gc->data[y * gc->width + x]; y < h; y++) { + rc->zstream.next_in = (Bytef *)p; + rc->zstream.avail_in = w; + rc->zstream.next_out = (Bytef *)zbufp; + rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16 - + rc->zstream.total_out; + rc->zstream.data_type = Z_BINARY; + + /* Compress with zlib */ + err = deflate(&rc->zstream, Z_SYNC_FLUSH); + if (err != Z_OK) { + WPRINTF(("zlib[rect] deflate err: %d\n", err)); + rc->enc_zlib_ok = false; + deflateEnd(&rc->zstream); + goto doraw; + } + zbufp = rc->zbuf + rc->zstream.total_out; + p += gc->width; + } + srect_hdr.encoding = htonl(RFB_ENCODING_ZLIB); + nwrite = stream_write(cfd, &srect_hdr, + sizeof(struct rfb_srvr_rect_hdr)); + if (nwrite <= 0) + return (nwrite); + + zlen = htonl(rc->zstream.total_out); + nwrite = stream_write(cfd, &zlen, sizeof(uint32_t)); + if (nwrite <= 0) + return (nwrite); + return (stream_write(cfd, rc->zbuf, rc->zstream.total_out)); + } + +doraw: + + total = 0; + zbufp = rc->zbuf; + for (p = &gc->data[y * gc->width + x]; y < h; y++) { + memcpy(zbufp, p, w); + zbufp += w; + total += w; + p += gc->width; + } + + srect_hdr.encoding = htonl(RFB_ENCODING_RAW); + nwrite = stream_write(cfd, &srect_hdr, + sizeof(struct rfb_srvr_rect_hdr)); + if (nwrite <= 0) + return (nwrite); + + total = stream_write(cfd, rc->zbuf, total); + + return (total); +} + +static int +rfb_send_all(struct rfb_softc *rc, int cfd, struct bhyvegc_image *gc) +{ + struct rfb_srvr_updt_msg supdt_msg; + struct rfb_srvr_rect_hdr srect_hdr; + ssize_t nwrite; + unsigned long zlen; + int err; + + /* + * Send the whole thing + */ + + /* Number of rectangles: 1 */ + supdt_msg.type = 0; + supdt_msg.pad = 0; + supdt_msg.numrects = htons(1); + nwrite = stream_write(cfd, &supdt_msg, + sizeof(struct rfb_srvr_updt_msg)); + if (nwrite <= 0) + return (nwrite); + + /* Rectangle header */ + srect_hdr.x = 0; + srect_hdr.y = 0; + srect_hdr.width = htons(gc->width); + srect_hdr.height = htons(gc->height); + if (rc->enc_zlib_ok) { + rc->zstream.next_in = (Bytef *)gc->data; + rc->zstream.avail_in = gc->width * gc->height * + sizeof(uint32_t); + rc->zstream.next_out = (Bytef *)rc->zbuf; + rc->zstream.avail_out = RFB_ZLIB_BUFSZ + 16; + rc->zstream.data_type = Z_BINARY; + + rc->zstream.total_in = 0; + rc->zstream.total_out = 0; + + /* Compress with zlib */ + err = deflate(&rc->zstream, Z_SYNC_FLUSH); + if (err != Z_OK) { + WPRINTF(("zlib deflate err: %d\n", err)); + rc->enc_zlib_ok = false; + deflateEnd(&rc->zstream); + goto doraw; + } + + srect_hdr.encoding = htonl(RFB_ENCODING_ZLIB); + nwrite = stream_write(cfd, &srect_hdr, + sizeof(struct rfb_srvr_rect_hdr)); + if (nwrite <= 0) + return (nwrite); + + zlen = htonl(rc->zstream.total_out); + nwrite = stream_write(cfd, &zlen, sizeof(uint32_t)); + if (nwrite <= 0) + return (nwrite); + return (stream_write(cfd, rc->zbuf, rc->zstream.total_out)); + } + +doraw: + srect_hdr.encoding = htonl(RFB_ENCODING_RAW); + nwrite = stream_write(cfd, &srect_hdr, + sizeof(struct rfb_srvr_rect_hdr)); + if (nwrite <= 0) + return (nwrite); + + nwrite = stream_write(cfd, gc->data, + gc->width * gc->height * sizeof(uint32_t)); + + return (nwrite); +} + +#define PIX_PER_CELL 32 +#define PIXCELL_SHIFT 5 +#define PIXCELL_MASK 0x1F + +static int +rfb_send_screen(struct rfb_softc *rc, int cfd, int all) +{ + struct bhyvegc_image *gc_image; + ssize_t nwrite; + int x, y; + int celly, cellwidth; + int xcells, ycells; + int w, h; + uint32_t *p; + int rem_x, rem_y; /* remainder for resolutions not x32 pixels ratio */ + int retval; + uint32_t *crc_p, *orig_crc; + int changes; + + console_refresh(); + gc_image = console_get_image(); + + pthread_mutex_lock(&rc->mtx); + if (rc->sending) { + pthread_mutex_unlock(&rc->mtx); + return (1); + } + rc->sending = 1; + pthread_mutex_unlock(&rc->mtx); + + retval = 0; + + if (all) { + retval = rfb_send_all(rc, cfd, gc_image); + goto done; + } + + /* + * Calculate the checksum for each 32x32 cell. Send each that + * has changed since the last scan. + */ + + /* Resolution changed */ + + rc->crc_width = gc_image->width; + rc->crc_height = gc_image->height; + + w = rc->crc_width; + h = rc->crc_height; + xcells = howmany(rc->crc_width, PIX_PER_CELL); + ycells = howmany(rc->crc_height, PIX_PER_CELL); + + rem_x = w & PIXCELL_MASK; + + rem_y = h & PIXCELL_MASK; + if (!rem_y) + rem_y = PIX_PER_CELL; + + p = gc_image->data; + + /* + * Go through all cells and calculate crc. If significant number + * of changes, then send entire screen. + * crc_tmp is dual purpose: to store the new crc and to flag as + * a cell that has changed. + */ + crc_p = rc->crc_tmp - xcells; + orig_crc = rc->crc - xcells; + changes = 0; + memset(rc->crc_tmp, 0, sizeof(uint32_t) * xcells * ycells); + for (y = 0; y < h; y++) { + if ((y & PIXCELL_MASK) == 0) { + crc_p += xcells; + orig_crc += xcells; + } + + for (x = 0; x < xcells; x++) { + if (x == (xcells - 1) && rem_x > 0) + cellwidth = rem_x; + else + cellwidth = PIX_PER_CELL; + + if (rc->hw_crc) + crc_p[x] = fast_crc32(p, + cellwidth * sizeof(uint32_t), + crc_p[x]); + else + crc_p[x] = (uint32_t)crc32(crc_p[x], + (Bytef *)p, + cellwidth * sizeof(uint32_t)); + + p += cellwidth; + + /* check for crc delta if last row in cell */ + if ((y & PIXCELL_MASK) == PIXCELL_MASK || y == (h-1)) { + if (orig_crc[x] != crc_p[x]) { + orig_crc[x] = crc_p[x]; + crc_p[x] = 1; + changes++; + } else { + crc_p[x] = 0; + } + } + } + } + + /* If number of changes is > THRESH percent, send the whole screen */ + if (((changes * 100) / (xcells * ycells)) >= RFB_SEND_ALL_THRESH) { + retval = rfb_send_all(rc, cfd, gc_image); + goto done; + } + + /* Go through all cells, and send only changed ones */ + crc_p = rc->crc_tmp; + for (y = 0; y < h; y += PIX_PER_CELL) { + /* previous cell's row */ + celly = (y >> PIXCELL_SHIFT); + + /* Delta check crc to previous set */ + for (x = 0; x < xcells; x++) { + if (*crc_p++ == 0) + continue; + + if (x == (xcells - 1) && rem_x > 0) + cellwidth = rem_x; + else + cellwidth = PIX_PER_CELL; + nwrite = rfb_send_rect(rc, cfd, + gc_image, + x * PIX_PER_CELL, + celly * PIX_PER_CELL, + cellwidth, + y + PIX_PER_CELL >= h ? rem_y : PIX_PER_CELL); + if (nwrite <= 0) { + retval = nwrite; + goto done; + } + } + } + retval = 1; + +done: + pthread_mutex_lock(&rc->mtx); + rc->sending = 0; + pthread_mutex_unlock(&rc->mtx); + + return (retval); +} + + +static void +rfb_recv_update_msg(struct rfb_softc *rc, int cfd, int discardonly) +{ + struct rfb_updt_msg updt_msg; + struct bhyvegc_image *gc_image; + + (void)stream_read(cfd, ((void *)&updt_msg) + 1 , sizeof(updt_msg) - 1); + + console_refresh(); + gc_image = console_get_image(); + + updt_msg.x = htons(updt_msg.x); + updt_msg.y = htons(updt_msg.y); + updt_msg.width = htons(updt_msg.width); + updt_msg.height = htons(updt_msg.height); + + if (updt_msg.width != gc_image->width || + updt_msg.height != gc_image->height) { + rc->width = gc_image->width; + rc->height = gc_image->height; + if (rc->enc_resize_ok) + rfb_send_resize_update_msg(rc, cfd); + } + + if (discardonly) + return; + + rfb_send_screen(rc, cfd, 1); +} + +static void +rfb_recv_key_msg(struct rfb_softc *rc, int cfd) +{ + struct rfb_key_msg key_msg; + + (void)stream_read(cfd, ((void *)&key_msg) + 1, sizeof(key_msg) - 1); + + console_key_event(key_msg.down, htonl(key_msg.code)); +} + +static void +rfb_recv_ptr_msg(struct rfb_softc *rc, int cfd) +{ + struct rfb_ptr_msg ptr_msg; + + (void)stream_read(cfd, ((void *)&ptr_msg) + 1, sizeof(ptr_msg) - 1); + + console_ptr_event(ptr_msg.button, htons(ptr_msg.x), htons(ptr_msg.y)); +} + +static void +rfb_recv_cuttext_msg(struct rfb_softc *rc, int cfd) +{ + struct rfb_cuttext_msg ct_msg; + unsigned char buf[32]; + int len; + + len = stream_read(cfd, ((void *)&ct_msg) + 1, sizeof(ct_msg) - 1); + ct_msg.length = htonl(ct_msg.length); + while (ct_msg.length > 0) { + len = stream_read(cfd, buf, ct_msg.length > sizeof(buf) ? + sizeof(buf) : ct_msg.length); + ct_msg.length -= len; + } +} + +static int64_t +timeval_delta(struct timeval *prev, struct timeval *now) +{ + int64_t n1, n2; + n1 = now->tv_sec * 1000000 + now->tv_usec; + n2 = prev->tv_sec * 1000000 + prev->tv_usec; + return (n1 - n2); +} + +static void * +rfb_wr_thr(void *arg) +{ + struct rfb_softc *rc; + fd_set rfds; + struct timeval tv; + struct timeval prev_tv; + int64_t tdiff; + int cfd; + int err; + + rc = arg; + cfd = rc->cfd; + + prev_tv.tv_sec = 0; + prev_tv.tv_usec = 0; + while (rc->cfd >= 0) { + FD_ZERO(&rfds); + FD_SET(cfd, &rfds); + tv.tv_sec = 0; + tv.tv_usec = 10000; + + err = select(cfd+1, &rfds, NULL, NULL, &tv); + if (err < 0) + return (NULL); + + /* Determine if its time to push screen; ~24hz */ + gettimeofday(&tv, NULL); + tdiff = timeval_delta(&prev_tv, &tv); + if (tdiff > 40000) { + prev_tv.tv_sec = tv.tv_sec; + prev_tv.tv_usec = tv.tv_usec; + if (rfb_send_screen(rc, cfd, 0) <= 0) { + return (NULL); + } + } else { + /* sleep */ + usleep(40000 - tdiff); + } + } + + return (NULL); +} + +void +rfb_handle(struct rfb_softc *rc, int cfd) +{ + const char *vbuf = "RFB 003.008\n"; + unsigned char buf[80]; + unsigned char *message = NULL; + +#ifndef NO_OPENSSL + unsigned char challenge[AUTH_LENGTH]; + unsigned char keystr[PASSWD_LENGTH]; + unsigned char crypt_expected[AUTH_LENGTH]; + + DES_key_schedule ks; + int i; +#endif + + pthread_t tid; + uint32_t sres = 0; + int len; + int perror = 1; + + rc->cfd = cfd; + + /* 1a. Send server version */ + stream_write(cfd, vbuf, strlen(vbuf)); + + /* 1b. Read client version */ + len = read(cfd, buf, sizeof(buf)); + + /* 2a. Send security type */ + buf[0] = 1; +#ifndef NO_OPENSSL + if (rc->password) + buf[1] = SECURITY_TYPE_VNC_AUTH; + else + buf[1] = SECURITY_TYPE_NONE; +#else + buf[1] = SECURITY_TYPE_NONE; +#endif + + stream_write(cfd, buf, 2); + + /* 2b. Read agreed security type */ + len = stream_read(cfd, buf, 1); + + /* 2c. Do VNC authentication */ + switch (buf[0]) { + case SECURITY_TYPE_NONE: + sres = 0; + break; + case SECURITY_TYPE_VNC_AUTH: + /* + * The client encrypts the challenge with DES, using a password + * supplied by the user as the key. + * To form the key, the password is truncated to + * eight characters, or padded with null bytes on the right. + * The client then sends the resulting 16-bytes response. + */ +#ifndef NO_OPENSSL + strncpy(keystr, rc->password, PASSWD_LENGTH); + + /* VNC clients encrypts the challenge with all the bit fields + * in each byte of the password mirrored. + * Here we flip each byte of the keystr. + */ + for (i = 0; i < PASSWD_LENGTH; i++) { + keystr[i] = (keystr[i] & 0xF0) >> 4 + | (keystr[i] & 0x0F) << 4; + keystr[i] = (keystr[i] & 0xCC) >> 2 + | (keystr[i] & 0x33) << 2; + keystr[i] = (keystr[i] & 0xAA) >> 1 + | (keystr[i] & 0x55) << 1; + } + + /* Initialize a 16-byte random challenge */ + arc4random_buf(challenge, sizeof(challenge)); + stream_write(cfd, challenge, AUTH_LENGTH); + + /* Receive the 16-byte challenge response */ + stream_read(cfd, buf, AUTH_LENGTH); + + memcpy(crypt_expected, challenge, AUTH_LENGTH); + + /* Encrypt the Challenge with DES */ + DES_set_key((const_DES_cblock *)keystr, &ks); + DES_ecb_encrypt((const_DES_cblock *)challenge, + (const_DES_cblock *)crypt_expected, + &ks, DES_ENCRYPT); + DES_ecb_encrypt((const_DES_cblock *)(challenge + PASSWD_LENGTH), + (const_DES_cblock *)(crypt_expected + + PASSWD_LENGTH), + &ks, DES_ENCRYPT); + + if (memcmp(crypt_expected, buf, AUTH_LENGTH) != 0) { + message = "Auth Failed: Invalid Password."; + sres = htonl(1); + } else + sres = 0; +#else + sres = 0; + WPRINTF(("Auth not supported, no OpenSSL in your system")); +#endif + + break; + } + + /* 2d. Write back a status */ + stream_write(cfd, &sres, 4); + + if (sres) { +#ifdef __FreeBSD__ + be32enc(buf, strlen(message)); + stream_write(cfd, buf, 4); + stream_write(cfd, message, strlen(message)); +#else + be32enc(buf, strlen((char *)message)); + stream_write(cfd, buf, 4); + stream_write(cfd, message, strlen((char *)message)); +#endif + goto done; + } + + /* 3a. Read client shared-flag byte */ + len = stream_read(cfd, buf, 1); + + /* 4a. Write server-init info */ + rfb_send_server_init_msg(cfd); + + if (!rc->zbuf) { + rc->zbuf = malloc(RFB_ZLIB_BUFSZ + 16); + assert(rc->zbuf != NULL); + } + + rfb_send_screen(rc, cfd, 1); + + perror = pthread_create(&tid, NULL, rfb_wr_thr, rc); + if (perror == 0) + pthread_set_name_np(tid, "rfbout"); + + /* Now read in client requests. 1st byte identifies type */ + for (;;) { + len = read(cfd, buf, 1); + if (len <= 0) { + DPRINTF(("rfb client exiting\r\n")); + break; + } + + switch (buf[0]) { + case 0: + rfb_recv_set_pixfmt_msg(rc, cfd); + break; + case 2: + rfb_recv_set_encodings_msg(rc, cfd); + break; + case 3: + rfb_recv_update_msg(rc, cfd, 1); + break; + case 4: + rfb_recv_key_msg(rc, cfd); + break; + case 5: + rfb_recv_ptr_msg(rc, cfd); + break; + case 6: + rfb_recv_cuttext_msg(rc, cfd); + break; + default: + WPRINTF(("rfb unknown cli-code %d!\n", buf[0] & 0xff)); + goto done; + } + } +done: + rc->cfd = -1; + if (perror == 0) + pthread_join(tid, NULL); + if (rc->enc_zlib_ok) + deflateEnd(&rc->zstream); +} + +static void * +rfb_thr(void *arg) +{ + struct rfb_softc *rc; + sigset_t set; + + int cfd; + + rc = arg; + + sigemptyset(&set); + sigaddset(&set, SIGPIPE); + if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0) { + perror("pthread_sigmask"); + return (NULL); + } + + for (;;) { + rc->enc_raw_ok = false; + rc->enc_zlib_ok = false; + rc->enc_resize_ok = false; + + cfd = accept(rc->sfd, NULL, NULL); + if (rc->conn_wait) { + pthread_mutex_lock(&rc->mtx); + pthread_cond_signal(&rc->cond); + pthread_mutex_unlock(&rc->mtx); + rc->conn_wait = 0; + } + rfb_handle(rc, cfd); + close(cfd); + } + + /* NOTREACHED */ + return (NULL); +} + +static int +sse42_supported(void) +{ + u_int cpu_registers[4], ecx; + + do_cpuid(1, cpu_registers); + + ecx = cpu_registers[2]; + + return ((ecx & CPUID2_SSE42) != 0); +} + +int +rfb_init(char *hostname, int port, int wait, char *password) +{ + int e; + char servname[6]; + struct rfb_softc *rc; + struct addrinfo *ai; + struct addrinfo hints; + int on = 1; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; +#endif + + rc = calloc(1, sizeof(struct rfb_softc)); + + rc->crc = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32), + sizeof(uint32_t)); + rc->crc_tmp = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32), + sizeof(uint32_t)); + rc->crc_width = RFB_MAX_WIDTH; + rc->crc_height = RFB_MAX_HEIGHT; + + rc->password = password; + + snprintf(servname, sizeof(servname), "%d", port ? port : 5900); + + if (!hostname || strlen(hostname) == 0) +#if defined(INET) + hostname = "127.0.0.1"; +#elif defined(INET6) + hostname = "[::1]"; +#endif + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_NUMERICHOST | AI_NUMERICSERV | AI_PASSIVE; + + if ((e = getaddrinfo(hostname, servname, &hints, &ai)) != 0) { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(e)); + return(-1); + } + + rc->sfd = socket(ai->ai_family, ai->ai_socktype, 0); + if (rc->sfd < 0) { + perror("socket"); + freeaddrinfo(ai); + return (-1); + } + + setsockopt(rc->sfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); + + if (bind(rc->sfd, ai->ai_addr, ai->ai_addrlen) < 0) { + perror("bind"); + freeaddrinfo(ai); + return (-1); + } + + if (listen(rc->sfd, 1) < 0) { + perror("listen"); + freeaddrinfo(ai); + return (-1); + } + +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_ACCEPT, CAP_EVENT, CAP_READ, CAP_WRITE); + if (caph_rights_limit(rc->sfd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); +#endif + + rc->hw_crc = sse42_supported(); + + rc->conn_wait = wait; + if (wait) { + pthread_mutex_init(&rc->mtx, NULL); + pthread_cond_init(&rc->cond, NULL); + } + + pthread_create(&rc->tid, NULL, rfb_thr, rc); + pthread_set_name_np(rc->tid, "rfb"); + + if (wait) { + DPRINTF(("Waiting for rfb client...\n")); + pthread_mutex_lock(&rc->mtx); + pthread_cond_wait(&rc->cond, &rc->mtx); + pthread_mutex_unlock(&rc->mtx); + } + + freeaddrinfo(ai); + return (0); +} + +#ifndef __FreeBSD__ +int +rfb_init_unix(char *path, int wait, char *password) +{ + struct rfb_softc *rc; + struct sockaddr_un sock; + + if ((rc = calloc(1, sizeof (struct rfb_softc))) == NULL) { + perror("calloc"); + return (-1); + } + rc->sfd = -1; + + if ((rc->crc = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32), + sizeof (uint32_t))) == NULL) { + perror("calloc"); + goto fail; + } + if ((rc->crc_tmp = calloc(howmany(RFB_MAX_WIDTH * RFB_MAX_HEIGHT, 32), + sizeof (uint32_t))) == NULL) { + perror("calloc"); + goto fail; + } + rc->crc_width = RFB_MAX_WIDTH; + rc->crc_height = RFB_MAX_HEIGHT; + + rc->password = password; + + rc->sfd = socket(PF_UNIX, SOCK_STREAM, 0); + if (rc->sfd < 0) { + perror("socket"); + goto fail; + } + + sock.sun_family = AF_UNIX; + if (strlcpy(sock.sun_path, path, sizeof (sock.sun_path)) >= + sizeof (sock.sun_path)) { + (void) fprintf(stderr, "socket path '%s' too long\n", path); + goto fail; + } + + (void) unlink(path); + if (bind(rc->sfd, (struct sockaddr *)&sock, sizeof (sock)) < 0) { + perror("bind"); + goto fail; + } + + if (listen(rc->sfd, 1) < 0) { + perror("listen"); + goto fail; + } + + rc->hw_crc = sse42_supported(); + + rc->conn_wait = wait; + if (wait) { + VERIFY3S(pthread_mutex_init(&rc->mtx, NULL), ==, 0); + VERIFY3S(pthread_cond_init(&rc->cond, NULL), ==, 0); + } + + VERIFY3S(pthread_create(&rc->tid, NULL, rfb_thr, rc), ==, 0); + pthread_set_name_np(rc->tid, "rfb"); + + if (wait) { + DPRINTF(("Waiting for rfb client...\n")); + VERIFY3S(pthread_mutex_lock(&rc->mtx), ==, 0); + VERIFY3S(pthread_cond_wait(&rc->cond, &rc->mtx), ==, 0); + VERIFY3S(pthread_mutex_unlock(&rc->mtx), ==, 0); + } + + return (0); + +fail: + if (rc->sfd != -1) { + VERIFY3S(close(rc->sfd), ==, 0); + } + free(rc->crc); + free(rc->crc_tmp); + free(rc); + return (-1); +} +#endif diff --git a/usr/src/cmd/bhyve/rfb.h b/usr/src/cmd/bhyve/rfb.h new file mode 100644 index 0000000000..990e2075ac --- /dev/null +++ b/usr/src/cmd/bhyve/rfb.h @@ -0,0 +1,42 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * Copyright 2018 Joyent, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _RFB_H_ +#define _RFB_H_ + +#define RFB_PORT 5900 + +int rfb_init(char *hostname, int port, int wait, char *password); +#ifndef __FreeBSD__ +int rfb_init_unix(char *path, int wait, char *password); +#endif + +#endif /* _RFB_H_ */ diff --git a/usr/src/cmd/bhyve/rtc.c b/usr/src/cmd/bhyve/rtc.c new file mode 100644 index 0000000000..09ca3f61ae --- /dev/null +++ b/usr/src/cmd/bhyve/rtc.c @@ -0,0 +1,131 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> + +#include <time.h> +#include <assert.h> + +#include <machine/vmm.h> +#include <vmmapi.h> + +#include "acpi.h" +#include "pci_lpc.h" +#include "rtc.h" + +#define IO_RTC 0x70 + +#define RTC_LMEM_LSB 0x34 +#define RTC_LMEM_MSB 0x35 +#define RTC_HMEM_LSB 0x5b +#define RTC_HMEM_SB 0x5c +#define RTC_HMEM_MSB 0x5d + +#define m_64KB (64*1024) +#define m_16MB (16*1024*1024) +#define m_4GB (4ULL*1024*1024*1024) + +/* + * Returns the current RTC time as number of seconds since 00:00:00 Jan 1, 1970 + */ +static time_t +rtc_time(struct vmctx *ctx, int use_localtime) +{ + struct tm tm; + time_t t; + + time(&t); + if (use_localtime) { + localtime_r(&t, &tm); + t = timegm(&tm); + } + return (t); +} + +void +rtc_init(struct vmctx *ctx, int use_localtime) +{ + size_t himem; + size_t lomem; + int err; + + /* XXX init diag/reset code/equipment/checksum ? */ + + /* + * Report guest memory size in nvram cells as required by UEFI. + * Little-endian encoding. + * 0x34/0x35 - 64KB chunks above 16MB, below 4GB + * 0x5b/0x5c/0x5d - 64KB chunks above 4GB + */ + lomem = (vm_get_lowmem_size(ctx) - m_16MB) / m_64KB; + err = vm_rtc_write(ctx, RTC_LMEM_LSB, lomem); + assert(err == 0); + err = vm_rtc_write(ctx, RTC_LMEM_MSB, lomem >> 8); + assert(err == 0); + + himem = vm_get_highmem_size(ctx) / m_64KB; + err = vm_rtc_write(ctx, RTC_HMEM_LSB, himem); + assert(err == 0); + err = vm_rtc_write(ctx, RTC_HMEM_SB, himem >> 8); + assert(err == 0); + err = vm_rtc_write(ctx, RTC_HMEM_MSB, himem >> 16); + assert(err == 0); + + err = vm_rtc_settime(ctx, rtc_time(ctx, use_localtime)); + assert(err == 0); +} + +static void +rtc_dsdt(void) +{ + + dsdt_line(""); + dsdt_line("Device (RTC)"); + dsdt_line("{"); + dsdt_line(" Name (_HID, EisaId (\"PNP0B00\"))"); + dsdt_line(" Name (_CRS, ResourceTemplate ()"); + dsdt_line(" {"); + dsdt_indent(2); + dsdt_fixed_ioport(IO_RTC, 2); + dsdt_fixed_irq(8); + dsdt_unindent(2); + dsdt_line(" })"); + dsdt_line("}"); +} +LPC_DSDT(rtc_dsdt); + +/* + * Reserve the extended RTC I/O ports although they are not emulated at this + * time. + */ +SYSRES_IO(0x72, 6); diff --git a/usr/src/cmd/bhyve/rtc.h b/usr/src/cmd/bhyve/rtc.h new file mode 100644 index 0000000000..1c108eed99 --- /dev/null +++ b/usr/src/cmd/bhyve/rtc.h @@ -0,0 +1,36 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Peter Grehan <grehan@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _RTC_H_ +#define _RTC_H_ + +void rtc_init(struct vmctx *ctx, int use_localtime); + +#endif /* _RTC_H_ */ diff --git a/usr/src/cmd/bhyve/smbiostbl.c b/usr/src/cmd/bhyve/smbiostbl.c new file mode 100644 index 0000000000..35a41a0855 --- /dev/null +++ b/usr/src/cmd/bhyve/smbiostbl.c @@ -0,0 +1,907 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> + +#include <assert.h> +#include <errno.h> +#include <md5.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <uuid.h> + +#include <machine/vmm.h> +#include <vmmapi.h> + +#include "bhyverun.h" +#include "smbiostbl.h" + +#define MB (1024*1024) +#define GB (1024ULL*1024*1024) + +#define SMBIOS_BASE 0xF1000 + +/* BHYVE_ACPI_BASE - SMBIOS_BASE) */ +#define SMBIOS_MAX_LENGTH (0xF2400 - 0xF1000) + +#define SMBIOS_TYPE_BIOS 0 +#define SMBIOS_TYPE_SYSTEM 1 +#define SMBIOS_TYPE_CHASSIS 3 +#define SMBIOS_TYPE_PROCESSOR 4 +#define SMBIOS_TYPE_MEMARRAY 16 +#define SMBIOS_TYPE_MEMDEVICE 17 +#define SMBIOS_TYPE_MEMARRAYMAP 19 +#define SMBIOS_TYPE_BOOT 32 +#define SMBIOS_TYPE_EOT 127 + +struct smbios_structure { + uint8_t type; + uint8_t length; + uint16_t handle; +} __packed; + +typedef int (*initializer_func_t)(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size); + +struct smbios_template_entry { + struct smbios_structure *entry; + const char **strings; + initializer_func_t initializer; +}; + +/* + * SMBIOS Structure Table Entry Point + */ +#define SMBIOS_ENTRY_EANCHOR "_SM_" +#define SMBIOS_ENTRY_EANCHORLEN 4 +#define SMBIOS_ENTRY_IANCHOR "_DMI_" +#define SMBIOS_ENTRY_IANCHORLEN 5 + +struct smbios_entry_point { + char eanchor[4]; /* anchor tag */ + uint8_t echecksum; /* checksum of entry point structure */ + uint8_t eplen; /* length in bytes of entry point */ + uint8_t major; /* major version of the SMBIOS spec */ + uint8_t minor; /* minor version of the SMBIOS spec */ + uint16_t maxssize; /* maximum size in bytes of a struct */ + uint8_t revision; /* entry point structure revision */ + uint8_t format[5]; /* entry point rev-specific data */ + char ianchor[5]; /* intermediate anchor tag */ + uint8_t ichecksum; /* intermediate checksum */ + uint16_t stlen; /* len in bytes of structure table */ + uint32_t staddr; /* physical addr of structure table */ + uint16_t stnum; /* number of structure table entries */ + uint8_t bcdrev; /* BCD value representing DMI ver */ +} __packed; + +/* + * BIOS Information + */ +#define SMBIOS_FL_ISA 0x00000010 /* ISA is supported */ +#define SMBIOS_FL_PCI 0x00000080 /* PCI is supported */ +#define SMBIOS_FL_SHADOW 0x00001000 /* BIOS shadowing is allowed */ +#define SMBIOS_FL_CDBOOT 0x00008000 /* Boot from CD is supported */ +#define SMBIOS_FL_SELBOOT 0x00010000 /* Selectable Boot supported */ +#define SMBIOS_FL_EDD 0x00080000 /* EDD Spec is supported */ + +#define SMBIOS_XB1_FL_ACPI 0x00000001 /* ACPI is supported */ + +#define SMBIOS_XB2_FL_BBS 0x00000001 /* BIOS Boot Specification */ +#define SMBIOS_XB2_FL_VM 0x00000010 /* Virtual Machine */ + +struct smbios_table_type0 { + struct smbios_structure header; + uint8_t vendor; /* vendor string */ + uint8_t version; /* version string */ + uint16_t segment; /* address segment location */ + uint8_t rel_date; /* release date */ + uint8_t size; /* rom size */ + uint64_t cflags; /* characteristics */ + uint8_t xc_bytes[2]; /* characteristics ext bytes */ + uint8_t sb_major_rel; /* system bios version */ + uint8_t sb_minor_rele; + uint8_t ecfw_major_rel; /* embedded ctrl fw version */ + uint8_t ecfw_minor_rel; +} __packed; + +/* + * System Information + */ +#define SMBIOS_WAKEUP_SWITCH 0x06 /* power switch */ + +struct smbios_table_type1 { + struct smbios_structure header; + uint8_t manufacturer; /* manufacturer string */ + uint8_t product; /* product name string */ + uint8_t version; /* version string */ + uint8_t serial; /* serial number string */ + uint8_t uuid[16]; /* uuid byte array */ + uint8_t wakeup; /* wake-up event */ + uint8_t sku; /* sku number string */ + uint8_t family; /* family name string */ +} __packed; + +/* + * System Enclosure or Chassis + */ +#define SMBIOS_CHT_UNKNOWN 0x02 /* unknown */ + +#define SMBIOS_CHST_SAFE 0x03 /* safe */ + +#define SMBIOS_CHSC_NONE 0x03 /* none */ + +struct smbios_table_type3 { + struct smbios_structure header; + uint8_t manufacturer; /* manufacturer string */ + uint8_t type; /* type */ + uint8_t version; /* version string */ + uint8_t serial; /* serial number string */ + uint8_t asset; /* asset tag string */ + uint8_t bustate; /* boot-up state */ + uint8_t psstate; /* power supply state */ + uint8_t tstate; /* thermal state */ + uint8_t security; /* security status */ + uint8_t uheight; /* height in 'u's */ + uint8_t cords; /* number of power cords */ + uint8_t elems; /* number of element records */ + uint8_t elemlen; /* length of records */ + uint8_t sku; /* sku number string */ +} __packed; + +/* + * Processor Information + */ +#define SMBIOS_PRT_CENTRAL 0x03 /* central processor */ + +#define SMBIOS_PRF_OTHER 0x01 /* other */ + +#define SMBIOS_PRS_PRESENT 0x40 /* socket is populated */ +#define SMBIOS_PRS_ENABLED 0x1 /* enabled */ + +#define SMBIOS_PRU_NONE 0x06 /* none */ + +#define SMBIOS_PFL_64B 0x04 /* 64-bit capable */ + +struct smbios_table_type4 { + struct smbios_structure header; + uint8_t socket; /* socket designation string */ + uint8_t type; /* processor type */ + uint8_t family; /* processor family */ + uint8_t manufacturer; /* manufacturer string */ + uint64_t cpuid; /* processor cpuid */ + uint8_t version; /* version string */ + uint8_t voltage; /* voltage */ + uint16_t clkspeed; /* ext clock speed in mhz */ + uint16_t maxspeed; /* maximum speed in mhz */ + uint16_t curspeed; /* current speed in mhz */ + uint8_t status; /* status */ + uint8_t upgrade; /* upgrade */ + uint16_t l1handle; /* l1 cache handle */ + uint16_t l2handle; /* l2 cache handle */ + uint16_t l3handle; /* l3 cache handle */ + uint8_t serial; /* serial number string */ + uint8_t asset; /* asset tag string */ + uint8_t part; /* part number string */ + uint8_t cores; /* cores per socket */ + uint8_t ecores; /* enabled cores */ + uint8_t threads; /* threads per socket */ + uint16_t cflags; /* processor characteristics */ + uint16_t family2; /* processor family 2 */ +} __packed; + +/* + * Physical Memory Array + */ +#define SMBIOS_MAL_SYSMB 0x03 /* system board or motherboard */ + +#define SMBIOS_MAU_SYSTEM 0x03 /* system memory */ + +#define SMBIOS_MAE_NONE 0x03 /* none */ + +struct smbios_table_type16 { + struct smbios_structure header; + uint8_t location; /* physical device location */ + uint8_t use; /* device functional purpose */ + uint8_t ecc; /* err detect/correct method */ + uint32_t size; /* max mem capacity in kb */ + uint16_t errhand; /* handle of error (if any) */ + uint16_t ndevs; /* num of slots or sockets */ + uint64_t xsize; /* max mem capacity in bytes */ +} __packed; + +/* + * Memory Device + */ +#define SMBIOS_MDFF_UNKNOWN 0x02 /* unknown */ + +#define SMBIOS_MDT_UNKNOWN 0x02 /* unknown */ + +#define SMBIOS_MDF_UNKNOWN 0x0004 /* unknown */ + +struct smbios_table_type17 { + struct smbios_structure header; + uint16_t arrayhand; /* handle of physl mem array */ + uint16_t errhand; /* handle of mem error data */ + uint16_t twidth; /* total width in bits */ + uint16_t dwidth; /* data width in bits */ + uint16_t size; /* size in bytes */ + uint8_t form; /* form factor */ + uint8_t set; /* set */ + uint8_t dloc; /* device locator string */ + uint8_t bloc; /* phys bank locator string */ + uint8_t type; /* memory type */ + uint16_t flags; /* memory characteristics */ + uint16_t maxspeed; /* maximum speed in mhz */ + uint8_t manufacturer; /* manufacturer string */ + uint8_t serial; /* serial number string */ + uint8_t asset; /* asset tag string */ + uint8_t part; /* part number string */ + uint8_t attributes; /* attributes */ + uint32_t xsize; /* extended size in mbs */ + uint16_t curspeed; /* current speed in mhz */ + uint16_t minvoltage; /* minimum voltage */ + uint16_t maxvoltage; /* maximum voltage */ + uint16_t curvoltage; /* configured voltage */ +} __packed; + +/* + * Memory Array Mapped Address + */ +struct smbios_table_type19 { + struct smbios_structure header; + uint32_t saddr; /* start phys addr in kb */ + uint32_t eaddr; /* end phys addr in kb */ + uint16_t arrayhand; /* physical mem array handle */ + uint8_t width; /* num of dev in row */ + uint64_t xsaddr; /* start phys addr in bytes */ + uint64_t xeaddr; /* end phys addr in bytes */ +} __packed; + +/* + * System Boot Information + */ +#define SMBIOS_BOOT_NORMAL 0 /* no errors detected */ + +struct smbios_table_type32 { + struct smbios_structure header; + uint8_t reserved[6]; + uint8_t status; /* boot status */ +} __packed; + +/* + * End-of-Table + */ +struct smbios_table_type127 { + struct smbios_structure header; +} __packed; + +struct smbios_table_type0 smbios_type0_template = { + { SMBIOS_TYPE_BIOS, sizeof (struct smbios_table_type0), 0 }, + 1, /* bios vendor string */ + 2, /* bios version string */ + 0xF000, /* bios address segment location */ + 3, /* bios release date */ + 0x0, /* bios size (64k * (n + 1) is the size in bytes) */ + SMBIOS_FL_ISA | SMBIOS_FL_PCI | SMBIOS_FL_SHADOW | + SMBIOS_FL_CDBOOT | SMBIOS_FL_EDD, + { SMBIOS_XB1_FL_ACPI, SMBIOS_XB2_FL_BBS | SMBIOS_XB2_FL_VM }, + 0x0, /* bios major release */ + 0x0, /* bios minor release */ + 0xff, /* embedded controller firmware major release */ + 0xff /* embedded controller firmware minor release */ +}; + +const char *smbios_type0_strings[] = { + "BHYVE", /* vendor string */ + "1.00", /* bios version string */ + "03/14/2014", /* bios release date string */ + NULL +}; + +struct smbios_table_type1 smbios_type1_template = { + { SMBIOS_TYPE_SYSTEM, sizeof (struct smbios_table_type1), 0 }, + 1, /* manufacturer string */ + 2, /* product string */ + 3, /* version string */ + 4, /* serial number string */ + { 0 }, + SMBIOS_WAKEUP_SWITCH, + 5, /* sku string */ + 6 /* family string */ +}; + +static int smbios_type1_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size); + +const char *smbios_type1_strings[] = { + " ", /* manufacturer string */ + "BHYVE", /* product name string */ + "1.0", /* version string */ + "None", /* serial number string */ + "None", /* sku string */ + " ", /* family name string */ + NULL +}; + +struct smbios_table_type3 smbios_type3_template = { + { SMBIOS_TYPE_CHASSIS, sizeof (struct smbios_table_type3), 0 }, + 1, /* manufacturer string */ + SMBIOS_CHT_UNKNOWN, + 2, /* version string */ + 3, /* serial number string */ + 4, /* asset tag string */ + SMBIOS_CHST_SAFE, + SMBIOS_CHST_SAFE, + SMBIOS_CHST_SAFE, + SMBIOS_CHSC_NONE, + 0, /* height in 'u's (0=enclosure height unspecified) */ + 0, /* number of power cords (0=number unspecified) */ + 0, /* number of contained element records */ + 0, /* length of records */ + 5 /* sku number string */ +}; + +const char *smbios_type3_strings[] = { + " ", /* manufacturer string */ + "1.0", /* version string */ + "None", /* serial number string */ + "None", /* asset tag string */ + "None", /* sku number string */ + NULL +}; + +struct smbios_table_type4 smbios_type4_template = { + { SMBIOS_TYPE_PROCESSOR, sizeof (struct smbios_table_type4), 0 }, + 1, /* socket designation string */ + SMBIOS_PRT_CENTRAL, + SMBIOS_PRF_OTHER, + 2, /* manufacturer string */ + 0, /* cpuid */ + 3, /* version string */ + 0, /* voltage */ + 0, /* external clock frequency in mhz (0=unknown) */ + 0, /* maximum frequency in mhz (0=unknown) */ + 0, /* current frequency in mhz (0=unknown) */ + SMBIOS_PRS_PRESENT | SMBIOS_PRS_ENABLED, + SMBIOS_PRU_NONE, + -1, /* l1 cache handle */ + -1, /* l2 cache handle */ + -1, /* l3 cache handle */ + 4, /* serial number string */ + 5, /* asset tag string */ + 6, /* part number string */ + 0, /* cores per socket (0=unknown) */ + 0, /* enabled cores per socket (0=unknown) */ + 0, /* threads per socket (0=unknown) */ + SMBIOS_PFL_64B, + SMBIOS_PRF_OTHER +}; + +const char *smbios_type4_strings[] = { + " ", /* socket designation string */ + " ", /* manufacturer string */ + " ", /* version string */ + "None", /* serial number string */ + "None", /* asset tag string */ + "None", /* part number string */ + NULL +}; + +static int smbios_type4_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size); + +struct smbios_table_type16 smbios_type16_template = { + { SMBIOS_TYPE_MEMARRAY, sizeof (struct smbios_table_type16), 0 }, + SMBIOS_MAL_SYSMB, + SMBIOS_MAU_SYSTEM, + SMBIOS_MAE_NONE, + 0x80000000, /* max mem capacity in kb (0x80000000=use extended) */ + -1, /* handle of error (if any) */ + 0, /* number of slots or sockets (TBD) */ + 0 /* extended maximum memory capacity in bytes (TBD) */ +}; + +static int smbios_type16_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size); + +struct smbios_table_type17 smbios_type17_template = { + { SMBIOS_TYPE_MEMDEVICE, sizeof (struct smbios_table_type17), 0 }, + -1, /* handle of physical memory array */ + -1, /* handle of memory error data */ + 64, /* total width in bits including ecc */ + 64, /* data width in bits */ + 0x7fff, /* size in bytes (0x7fff=use extended)*/ + SMBIOS_MDFF_UNKNOWN, + 0, /* set (0x00=none, 0xff=unknown) */ + 1, /* device locator string */ + 2, /* physical bank locator string */ + SMBIOS_MDT_UNKNOWN, + SMBIOS_MDF_UNKNOWN, + 0, /* maximum memory speed in mhz (0=unknown) */ + 3, /* manufacturer string */ + 4, /* serial number string */ + 5, /* asset tag string */ + 6, /* part number string */ + 0, /* attributes (0=unknown rank information) */ + 0, /* extended size in mb (TBD) */ + 0, /* current speed in mhz (0=unknown) */ + 0, /* minimum voltage in mv (0=unknown) */ + 0, /* maximum voltage in mv (0=unknown) */ + 0 /* configured voltage in mv (0=unknown) */ +}; + +const char *smbios_type17_strings[] = { + " ", /* device locator string */ + " ", /* physical bank locator string */ + " ", /* manufacturer string */ + "None", /* serial number string */ + "None", /* asset tag string */ + "None", /* part number string */ + NULL +}; + +static int smbios_type17_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size); + +struct smbios_table_type19 smbios_type19_template = { + { SMBIOS_TYPE_MEMARRAYMAP, sizeof (struct smbios_table_type19), 0 }, + 0xffffffff, /* starting phys addr in kb (0xffffffff=use ext) */ + 0xffffffff, /* ending phys addr in kb (0xffffffff=use ext) */ + -1, /* physical memory array handle */ + 1, /* number of devices that form a row */ + 0, /* extended starting phys addr in bytes (TDB) */ + 0 /* extended ending phys addr in bytes (TDB) */ +}; + +static int smbios_type19_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size); + +struct smbios_table_type32 smbios_type32_template = { + { SMBIOS_TYPE_BOOT, sizeof (struct smbios_table_type32), 0 }, + { 0, 0, 0, 0, 0, 0 }, + SMBIOS_BOOT_NORMAL +}; + +struct smbios_table_type127 smbios_type127_template = { + { SMBIOS_TYPE_EOT, sizeof (struct smbios_table_type127), 0 } +}; + +static int smbios_generic_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size); + +static struct smbios_template_entry smbios_template[] = { + { (struct smbios_structure *)&smbios_type0_template, + smbios_type0_strings, + smbios_generic_initializer }, + { (struct smbios_structure *)&smbios_type1_template, + smbios_type1_strings, + smbios_type1_initializer }, + { (struct smbios_structure *)&smbios_type3_template, + smbios_type3_strings, + smbios_generic_initializer }, + { (struct smbios_structure *)&smbios_type4_template, + smbios_type4_strings, + smbios_type4_initializer }, + { (struct smbios_structure *)&smbios_type16_template, + NULL, + smbios_type16_initializer }, + { (struct smbios_structure *)&smbios_type17_template, + smbios_type17_strings, + smbios_type17_initializer }, + { (struct smbios_structure *)&smbios_type19_template, + NULL, + smbios_type19_initializer }, + { (struct smbios_structure *)&smbios_type32_template, + NULL, + smbios_generic_initializer }, + { (struct smbios_structure *)&smbios_type127_template, + NULL, + smbios_generic_initializer }, + { NULL,NULL, NULL } +}; + +static uint64_t guest_lomem, guest_himem; +static uint16_t type16_handle; + +static int +smbios_generic_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size) +{ + struct smbios_structure *entry; + + memcpy(curaddr, template_entry, template_entry->length); + entry = (struct smbios_structure *)curaddr; + entry->handle = *n + 1; + curaddr += entry->length; + if (template_strings != NULL) { + int i; + + for (i = 0; template_strings[i] != NULL; i++) { + const char *string; + int len; + + string = template_strings[i]; + len = strlen(string) + 1; + memcpy(curaddr, string, len); + curaddr += len; + } + *curaddr = '\0'; + curaddr++; + } else { + /* Minimum string section is double nul */ + *curaddr = '\0'; + curaddr++; + *curaddr = '\0'; + curaddr++; + } + (*n)++; + *endaddr = curaddr; + + return (0); +} + +static int +smbios_type1_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size) +{ + struct smbios_table_type1 *type1; + + smbios_generic_initializer(template_entry, template_strings, + curaddr, endaddr, n, size); + type1 = (struct smbios_table_type1 *)curaddr; + + if (guest_uuid_str != NULL) { + uuid_t uuid; + uint32_t status; + + uuid_from_string(guest_uuid_str, &uuid, &status); + if (status != uuid_s_ok) + return (-1); + + uuid_enc_le(&type1->uuid, &uuid); + } else { + MD5_CTX mdctx; + u_char digest[16]; + char hostname[MAXHOSTNAMELEN]; + + /* + * Universally unique and yet reproducible are an + * oxymoron, however reproducible is desirable in + * this case. + */ + if (gethostname(hostname, sizeof(hostname))) + return (-1); + + MD5Init(&mdctx); + MD5Update(&mdctx, vmname, strlen(vmname)); + MD5Update(&mdctx, hostname, sizeof(hostname)); + MD5Final(digest, &mdctx); + + /* + * Set the variant and version number. + */ + digest[6] &= 0x0F; + digest[6] |= 0x30; /* version 3 */ + digest[8] &= 0x3F; + digest[8] |= 0x80; + + memcpy(&type1->uuid, digest, sizeof (digest)); + } + + return (0); +} + +static int +smbios_type4_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size) +{ + int i; + + for (i = 0; i < guest_ncpus; i++) { + struct smbios_table_type4 *type4; + char *p; + int nstrings, len; + + smbios_generic_initializer(template_entry, template_strings, + curaddr, endaddr, n, size); + type4 = (struct smbios_table_type4 *)curaddr; + p = curaddr + sizeof (struct smbios_table_type4); + nstrings = 0; + while (p < *endaddr - 1) { + if (*p++ == '\0') + nstrings++; + } + len = sprintf(*endaddr - 1, "CPU #%d", i) + 1; + *endaddr += len - 1; + *(*endaddr) = '\0'; + (*endaddr)++; + type4->socket = nstrings + 1; + curaddr = *endaddr; + } + + return (0); +} + +static int +smbios_type16_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size) +{ + struct smbios_table_type16 *type16; + + type16_handle = *n; + smbios_generic_initializer(template_entry, template_strings, + curaddr, endaddr, n, size); + type16 = (struct smbios_table_type16 *)curaddr; + type16->xsize = guest_lomem + guest_himem; + type16->ndevs = guest_himem > 0 ? 2 : 1; + + return (0); +} + +static int +smbios_type17_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size) +{ + struct smbios_table_type17 *type17; + + smbios_generic_initializer(template_entry, template_strings, + curaddr, endaddr, n, size); + type17 = (struct smbios_table_type17 *)curaddr; + type17->arrayhand = type16_handle; + type17->xsize = guest_lomem; + + if (guest_himem > 0) { + curaddr = *endaddr; + smbios_generic_initializer(template_entry, template_strings, + curaddr, endaddr, n, size); + type17 = (struct smbios_table_type17 *)curaddr; + type17->arrayhand = type16_handle; + type17->xsize = guest_himem; + } + + return (0); +} + +static int +smbios_type19_initializer(struct smbios_structure *template_entry, + const char **template_strings, char *curaddr, char **endaddr, + uint16_t *n, uint16_t *size) +{ + struct smbios_table_type19 *type19; + + smbios_generic_initializer(template_entry, template_strings, + curaddr, endaddr, n, size); + type19 = (struct smbios_table_type19 *)curaddr; + type19->arrayhand = type16_handle; + type19->xsaddr = 0; + type19->xeaddr = guest_lomem; + + if (guest_himem > 0) { + curaddr = *endaddr; + smbios_generic_initializer(template_entry, template_strings, + curaddr, endaddr, n, size); + type19 = (struct smbios_table_type19 *)curaddr; + type19->arrayhand = type16_handle; + type19->xsaddr = 4*GB; + type19->xeaddr = guest_himem; + } + + return (0); +} + +static void +smbios_ep_initializer(struct smbios_entry_point *smbios_ep, uint32_t staddr) +{ + memset(smbios_ep, 0, sizeof(*smbios_ep)); + memcpy(smbios_ep->eanchor, SMBIOS_ENTRY_EANCHOR, + SMBIOS_ENTRY_EANCHORLEN); + smbios_ep->eplen = 0x1F; + assert(sizeof (struct smbios_entry_point) == smbios_ep->eplen); + smbios_ep->major = 2; + smbios_ep->minor = 6; + smbios_ep->revision = 0; + memcpy(smbios_ep->ianchor, SMBIOS_ENTRY_IANCHOR, + SMBIOS_ENTRY_IANCHORLEN); + smbios_ep->staddr = staddr; + smbios_ep->bcdrev = 0x24; +} + +static void +smbios_ep_finalizer(struct smbios_entry_point *smbios_ep, uint16_t len, + uint16_t num, uint16_t maxssize) +{ + uint8_t checksum; + int i; + + smbios_ep->maxssize = maxssize; + smbios_ep->stlen = len; + smbios_ep->stnum = num; + + checksum = 0; + for (i = 0x10; i < 0x1f; i++) { + checksum -= ((uint8_t *)smbios_ep)[i]; + } + smbios_ep->ichecksum = checksum; + + checksum = 0; + for (i = 0; i < 0x1f; i++) { + checksum -= ((uint8_t *)smbios_ep)[i]; + } + smbios_ep->echecksum = checksum; +} + +int +smbios_build(struct vmctx *ctx) +{ + struct smbios_entry_point *smbios_ep; + uint16_t n; + uint16_t maxssize; + char *curaddr, *startaddr, *ststartaddr; + int i; + int err; + + guest_lomem = vm_get_lowmem_size(ctx); + guest_himem = vm_get_highmem_size(ctx); + + startaddr = paddr_guest2host(ctx, SMBIOS_BASE, SMBIOS_MAX_LENGTH); + if (startaddr == NULL) { + fprintf(stderr, "smbios table requires mapped mem\n"); + return (ENOMEM); + } + + curaddr = startaddr; + + smbios_ep = (struct smbios_entry_point *)curaddr; + smbios_ep_initializer(smbios_ep, SMBIOS_BASE + + sizeof(struct smbios_entry_point)); + curaddr += sizeof(struct smbios_entry_point); + ststartaddr = curaddr; + + n = 0; + maxssize = 0; + for (i = 0; smbios_template[i].entry != NULL; i++) { + struct smbios_structure *entry; + const char **strings; + initializer_func_t initializer; + char *endaddr; + uint16_t size; + + entry = smbios_template[i].entry; + strings = smbios_template[i].strings; + initializer = smbios_template[i].initializer; + + err = (*initializer)(entry, strings, curaddr, &endaddr, + &n, &size); + if (err != 0) + return (err); + + if (size > maxssize) + maxssize = size; + + curaddr = endaddr; + } + + assert(curaddr - startaddr < SMBIOS_MAX_LENGTH); + smbios_ep_finalizer(smbios_ep, curaddr - ststartaddr, n, maxssize); + + return (0); +} + +int +smbios_parse(const char *opts) +{ + char *buf; + char *lasts; + char *token; + char *end; + long type; + struct { + const char *key; + const char **targetp; + } type1_map[] = { + { "manufacturer", &smbios_type1_strings[0] }, + { "product", &smbios_type1_strings[1] }, + { "version", &smbios_type1_strings[2] }, + { "serial", &smbios_type1_strings[3] }, + { "sku", &smbios_type1_strings[4] }, + { "family", &smbios_type1_strings[5] }, + { "uuid", (const char **)&guest_uuid_str }, + { 0 } + }; + + if ((buf = strdup(opts)) == NULL) { + (void) fprintf(stderr, "out of memory\n"); + return (-1); + } + + if ((token = strtok_r(buf, ",", &lasts)) == NULL) { + (void) fprintf(stderr, "too few fields\n"); + goto fail; + } + + errno = 0; + type = strtol(token, &end, 10); + if (errno != 0 || *end != '\0') { + (void) fprintf(stderr, "first token '%s' is not an integer\n", + token); + goto fail; + } + + /* For now, only type 1 is supported. */ + if (type != 1) { + (void) fprintf(stderr, "unsupported type %d\n", type); + goto fail; + } + + while ((token = strtok_r(NULL, ",", &lasts)) != NULL) { + char *val; + int i; + + if ((val = strchr(token, '=')) == NULL) { + (void) fprintf(stderr, "invalid key=value: '%s'\n", + token); + goto fail; + } + *val = '\0'; + val++; + + for (i = 0; type1_map[i].key != NULL; i++) { + if (strcmp(token, type1_map[i].key) == 0) { + break; + } + } + if (type1_map[i].key == NULL) { + (void) fprintf(stderr, "invalid key '%s'\n", token); + goto fail; + } + *type1_map[i].targetp = val; + } + + return (0); + +fail: + free(buf); + return (-1); +} diff --git a/usr/src/cmd/bhyve/smbiostbl.h b/usr/src/cmd/bhyve/smbiostbl.h new file mode 100644 index 0000000000..81e26309e5 --- /dev/null +++ b/usr/src/cmd/bhyve/smbiostbl.h @@ -0,0 +1,43 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +#ifndef _SMBIOSTBL_H_ +#define _SMBIOSTBL_H_ + +struct vmctx; + +int smbios_build(struct vmctx *ctx); +int smbios_parse(const char *opts); + +#endif /* _SMBIOSTBL_H_ */ diff --git a/usr/src/cmd/bhyve/sockstream.c b/usr/src/cmd/bhyve/sockstream.c new file mode 100644 index 0000000000..b592bce9aa --- /dev/null +++ b/usr/src/cmd/bhyve/sockstream.c @@ -0,0 +1,86 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Nahanni Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <unistd.h> + +#include <errno.h> + +#include "sockstream.h" + +ssize_t +stream_read(int fd, void *buf, ssize_t nbytes) +{ + uint8_t *p; + ssize_t len = 0; + ssize_t n; + + p = buf; + + while (len < nbytes) { + n = read(fd, p + len, nbytes - len); + if (n == 0) + break; + + if (n < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return (n); + } + len += n; + } + return (len); +} + +ssize_t +stream_write(int fd, const void *buf, ssize_t nbytes) +{ + const uint8_t *p; + ssize_t len = 0; + ssize_t n; + + p = buf; + + while (len < nbytes) { + n = write(fd, p + len, nbytes - len); + if (n == 0) + break; + if (n < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return (n); + } + len += n; + } + return (len); +} diff --git a/usr/src/cmd/bhyve/sockstream.h b/usr/src/cmd/bhyve/sockstream.h new file mode 100644 index 0000000000..ecea849471 --- /dev/null +++ b/usr/src/cmd/bhyve/sockstream.h @@ -0,0 +1,35 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Nahanni Systems, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/types.h> +#include <unistd.h> + +ssize_t stream_read(int fd, void *buf, ssize_t nbytes); +ssize_t stream_write(int fd, const void *buf, ssize_t nbytes); diff --git a/usr/src/cmd/bhyve/spinup_ap.c b/usr/src/cmd/bhyve/spinup_ap.c new file mode 100644 index 0000000000..ecdd05694c --- /dev/null +++ b/usr/src/cmd/bhyve/spinup_ap.c @@ -0,0 +1,110 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/types.h> + +#include <machine/vmm.h> +#include <vmmapi.h> + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +#include "bhyverun.h" +#include "spinup_ap.h" + +static void +spinup_ap_realmode(struct vmctx *ctx, int newcpu, uint64_t *rip) +{ + int vector, error; + uint16_t cs; + uint64_t desc_base; + uint32_t desc_limit, desc_access; + + vector = *rip >> PAGE_SHIFT; + *rip = 0; + + /* + * Update the %cs and %rip of the guest so that it starts + * executing real mode code at at 'vector << 12'. + */ + error = vm_set_register(ctx, newcpu, VM_REG_GUEST_RIP, *rip); + assert(error == 0); + + error = vm_get_desc(ctx, newcpu, VM_REG_GUEST_CS, &desc_base, + &desc_limit, &desc_access); + assert(error == 0); + + desc_base = vector << PAGE_SHIFT; + error = vm_set_desc(ctx, newcpu, VM_REG_GUEST_CS, + desc_base, desc_limit, desc_access); + assert(error == 0); + + cs = (vector << PAGE_SHIFT) >> 4; + error = vm_set_register(ctx, newcpu, VM_REG_GUEST_CS, cs); + assert(error == 0); +} + +int +spinup_ap(struct vmctx *ctx, int vcpu, int newcpu, uint64_t rip) +{ + int error; + + assert(newcpu != 0); + assert(newcpu < guest_ncpus); + + error = vcpu_reset(ctx, newcpu); + assert(error == 0); + + fbsdrun_set_capabilities(ctx, newcpu); + + /* + * Enable the 'unrestricted guest' mode for 'newcpu'. + * + * Set up the processor state in power-on 16-bit mode, with the CS:IP + * init'd to the specified low-mem 4K page. + */ + error = vm_set_capability(ctx, newcpu, VM_CAP_UNRESTRICTED_GUEST, 1); + assert(error == 0); + + spinup_ap_realmode(ctx, newcpu, &rip); + +#ifdef __FreeBSD__ + fbsdrun_addcpu(ctx, vcpu, newcpu, rip); +#else + fbsdrun_addcpu(ctx, vcpu, newcpu, rip, false); +#endif + + return (newcpu); +} diff --git a/usr/src/cmd/bhyve/spinup_ap.h b/usr/src/cmd/bhyve/spinup_ap.h new file mode 100644 index 0000000000..226542f6c3 --- /dev/null +++ b/usr/src/cmd/bhyve/spinup_ap.h @@ -0,0 +1,36 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _SPINUP_AP_H_ +#define _SPINUP_AP_H_ + +int spinup_ap(struct vmctx *ctx, int vcpu, int newcpu, uint64_t rip); + +#endif diff --git a/usr/src/cmd/bhyve/task_switch.c b/usr/src/cmd/bhyve/task_switch.c new file mode 100644 index 0000000000..b5950a19d8 --- /dev/null +++ b/usr/src/cmd/bhyve/task_switch.c @@ -0,0 +1,941 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Neel Natu <neel@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/_iovec.h> +#include <sys/mman.h> + +#include <x86/psl.h> +#include <x86/segments.h> +#include <x86/specialreg.h> +#include <machine/vmm.h> +#include <machine/vmm_instruction_emul.h> + +#include <assert.h> +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> + +#include <vmmapi.h> + +#include "bhyverun.h" + +/* + * Using 'struct i386tss' is tempting but causes myriad sign extension + * issues because all of its fields are defined as signed integers. + */ +struct tss32 { + uint16_t tss_link; + uint16_t rsvd1; + uint32_t tss_esp0; + uint16_t tss_ss0; + uint16_t rsvd2; + uint32_t tss_esp1; + uint16_t tss_ss1; + uint16_t rsvd3; + uint32_t tss_esp2; + uint16_t tss_ss2; + uint16_t rsvd4; + uint32_t tss_cr3; + uint32_t tss_eip; + uint32_t tss_eflags; + uint32_t tss_eax; + uint32_t tss_ecx; + uint32_t tss_edx; + uint32_t tss_ebx; + uint32_t tss_esp; + uint32_t tss_ebp; + uint32_t tss_esi; + uint32_t tss_edi; + uint16_t tss_es; + uint16_t rsvd5; + uint16_t tss_cs; + uint16_t rsvd6; + uint16_t tss_ss; + uint16_t rsvd7; + uint16_t tss_ds; + uint16_t rsvd8; + uint16_t tss_fs; + uint16_t rsvd9; + uint16_t tss_gs; + uint16_t rsvd10; + uint16_t tss_ldt; + uint16_t rsvd11; + uint16_t tss_trap; + uint16_t tss_iomap; +}; +static_assert(sizeof(struct tss32) == 104, "compile-time assertion failed"); + +#define SEL_START(sel) (((sel) & ~0x7)) +#define SEL_LIMIT(sel) (((sel) | 0x7)) +#define TSS_BUSY(type) (((type) & 0x2) != 0) + +static uint64_t +GETREG(struct vmctx *ctx, int vcpu, int reg) +{ + uint64_t val; + int error; + + error = vm_get_register(ctx, vcpu, reg, &val); + assert(error == 0); + return (val); +} + +static void +SETREG(struct vmctx *ctx, int vcpu, int reg, uint64_t val) +{ + int error; + + error = vm_set_register(ctx, vcpu, reg, val); + assert(error == 0); +} + +static struct seg_desc +usd_to_seg_desc(struct user_segment_descriptor *usd) +{ + struct seg_desc seg_desc; + + seg_desc.base = (u_int)USD_GETBASE(usd); + if (usd->sd_gran) + seg_desc.limit = (u_int)(USD_GETLIMIT(usd) << 12) | 0xfff; + else + seg_desc.limit = (u_int)USD_GETLIMIT(usd); + seg_desc.access = usd->sd_type | usd->sd_dpl << 5 | usd->sd_p << 7; + seg_desc.access |= usd->sd_xx << 12; + seg_desc.access |= usd->sd_def32 << 14; + seg_desc.access |= usd->sd_gran << 15; + + return (seg_desc); +} + +/* + * Inject an exception with an error code that is a segment selector. + * The format of the error code is described in section 6.13, "Error Code", + * Intel SDM volume 3. + * + * Bit 0 (EXT) denotes whether the exception occurred during delivery + * of an external event like an interrupt. + * + * Bit 1 (IDT) indicates whether the selector points to a gate descriptor + * in the IDT. + * + * Bit 2(GDT/LDT) has the usual interpretation of Table Indicator (TI). + */ +static void +sel_exception(struct vmctx *ctx, int vcpu, int vector, uint16_t sel, int ext) +{ + /* + * Bit 2 from the selector is retained as-is in the error code. + * + * Bit 1 can be safely cleared because none of the selectors + * encountered during task switch emulation refer to a task + * gate in the IDT. + * + * Bit 0 is set depending on the value of 'ext'. + */ + sel &= ~0x3; + if (ext) + sel |= 0x1; + vm_inject_fault(ctx, vcpu, vector, 1, sel); +} + +/* + * Return 0 if the selector 'sel' in within the limits of the GDT/LDT + * and non-zero otherwise. + */ +static int +desc_table_limit_check(struct vmctx *ctx, int vcpu, uint16_t sel) +{ + uint64_t base; + uint32_t limit, access; + int error, reg; + + reg = ISLDT(sel) ? VM_REG_GUEST_LDTR : VM_REG_GUEST_GDTR; + error = vm_get_desc(ctx, vcpu, reg, &base, &limit, &access); + assert(error == 0); + + if (reg == VM_REG_GUEST_LDTR) { + if (SEG_DESC_UNUSABLE(access) || !SEG_DESC_PRESENT(access)) + return (-1); + } + + if (limit < SEL_LIMIT(sel)) + return (-1); + else + return (0); +} + +/* + * Read/write the segment descriptor 'desc' into the GDT/LDT slot referenced + * by the selector 'sel'. + * + * Returns 0 on success. + * Returns 1 if an exception was injected into the guest. + * Returns -1 otherwise. + */ +static int +desc_table_rw(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, + uint16_t sel, struct user_segment_descriptor *desc, bool doread, + int *faultptr) +{ + struct iovec iov[2]; + uint64_t base; + uint32_t limit, access; + int error, reg; + + reg = ISLDT(sel) ? VM_REG_GUEST_LDTR : VM_REG_GUEST_GDTR; + error = vm_get_desc(ctx, vcpu, reg, &base, &limit, &access); + assert(error == 0); + assert(limit >= SEL_LIMIT(sel)); + + error = vm_copy_setup(ctx, vcpu, paging, base + SEL_START(sel), + sizeof(*desc), doread ? PROT_READ : PROT_WRITE, iov, nitems(iov), + faultptr); + if (error || *faultptr) + return (error); + + if (doread) + vm_copyin(ctx, vcpu, iov, desc, sizeof(*desc)); + else + vm_copyout(ctx, vcpu, desc, iov, sizeof(*desc)); + return (0); +} + +static int +desc_table_read(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, + uint16_t sel, struct user_segment_descriptor *desc, int *faultptr) +{ + return (desc_table_rw(ctx, vcpu, paging, sel, desc, true, faultptr)); +} + +static int +desc_table_write(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, + uint16_t sel, struct user_segment_descriptor *desc, int *faultptr) +{ + return (desc_table_rw(ctx, vcpu, paging, sel, desc, false, faultptr)); +} + +/* + * Read the TSS descriptor referenced by 'sel' into 'desc'. + * + * Returns 0 on success. + * Returns 1 if an exception was injected into the guest. + * Returns -1 otherwise. + */ +static int +read_tss_descriptor(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, + uint16_t sel, struct user_segment_descriptor *desc, int *faultptr) +{ + struct vm_guest_paging sup_paging; + int error; + + assert(!ISLDT(sel)); + assert(IDXSEL(sel) != 0); + + /* Fetch the new TSS descriptor */ + if (desc_table_limit_check(ctx, vcpu, sel)) { + if (ts->reason == TSR_IRET) + sel_exception(ctx, vcpu, IDT_TS, sel, ts->ext); + else + sel_exception(ctx, vcpu, IDT_GP, sel, ts->ext); + return (1); + } + + sup_paging = ts->paging; + sup_paging.cpl = 0; /* implicit supervisor mode */ + error = desc_table_read(ctx, vcpu, &sup_paging, sel, desc, faultptr); + return (error); +} + +static bool +code_desc(int sd_type) +{ + /* code descriptor */ + return ((sd_type & 0x18) == 0x18); +} + +static bool +stack_desc(int sd_type) +{ + /* writable data descriptor */ + return ((sd_type & 0x1A) == 0x12); +} + +static bool +data_desc(int sd_type) +{ + /* data descriptor or a readable code descriptor */ + return ((sd_type & 0x18) == 0x10 || (sd_type & 0x1A) == 0x1A); +} + +static bool +ldt_desc(int sd_type) +{ + + return (sd_type == SDT_SYSLDT); +} + +/* + * Validate the descriptor 'seg_desc' associated with 'segment'. + */ +static int +validate_seg_desc(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, + int segment, struct seg_desc *seg_desc, int *faultptr) +{ + struct vm_guest_paging sup_paging; + struct user_segment_descriptor usd; + int error, idtvec; + int cpl, dpl, rpl; + uint16_t sel, cs; + bool ldtseg, codeseg, stackseg, dataseg, conforming; + + ldtseg = codeseg = stackseg = dataseg = false; + switch (segment) { + case VM_REG_GUEST_LDTR: + ldtseg = true; + break; + case VM_REG_GUEST_CS: + codeseg = true; + break; + case VM_REG_GUEST_SS: + stackseg = true; + break; + case VM_REG_GUEST_DS: + case VM_REG_GUEST_ES: + case VM_REG_GUEST_FS: + case VM_REG_GUEST_GS: + dataseg = true; + break; + default: + assert(0); + } + + /* Get the segment selector */ + sel = GETREG(ctx, vcpu, segment); + + /* LDT selector must point into the GDT */ + if (ldtseg && ISLDT(sel)) { + sel_exception(ctx, vcpu, IDT_TS, sel, ts->ext); + return (1); + } + + /* Descriptor table limit check */ + if (desc_table_limit_check(ctx, vcpu, sel)) { + sel_exception(ctx, vcpu, IDT_TS, sel, ts->ext); + return (1); + } + + /* NULL selector */ + if (IDXSEL(sel) == 0) { + /* Code and stack segment selectors cannot be NULL */ + if (codeseg || stackseg) { + sel_exception(ctx, vcpu, IDT_TS, sel, ts->ext); + return (1); + } + seg_desc->base = 0; + seg_desc->limit = 0; + seg_desc->access = 0x10000; /* unusable */ + return (0); + } + + /* Read the descriptor from the GDT/LDT */ + sup_paging = ts->paging; + sup_paging.cpl = 0; /* implicit supervisor mode */ + error = desc_table_read(ctx, vcpu, &sup_paging, sel, &usd, faultptr); + if (error || *faultptr) + return (error); + + /* Verify that the descriptor type is compatible with the segment */ + if ((ldtseg && !ldt_desc(usd.sd_type)) || + (codeseg && !code_desc(usd.sd_type)) || + (dataseg && !data_desc(usd.sd_type)) || + (stackseg && !stack_desc(usd.sd_type))) { + sel_exception(ctx, vcpu, IDT_TS, sel, ts->ext); + return (1); + } + + /* Segment must be marked present */ + if (!usd.sd_p) { + if (ldtseg) + idtvec = IDT_TS; + else if (stackseg) + idtvec = IDT_SS; + else + idtvec = IDT_NP; + sel_exception(ctx, vcpu, idtvec, sel, ts->ext); + return (1); + } + + cs = GETREG(ctx, vcpu, VM_REG_GUEST_CS); + cpl = cs & SEL_RPL_MASK; + rpl = sel & SEL_RPL_MASK; + dpl = usd.sd_dpl; + + if (stackseg && (rpl != cpl || dpl != cpl)) { + sel_exception(ctx, vcpu, IDT_TS, sel, ts->ext); + return (1); + } + + if (codeseg) { + conforming = (usd.sd_type & 0x4) ? true : false; + if ((conforming && (cpl < dpl)) || + (!conforming && (cpl != dpl))) { + sel_exception(ctx, vcpu, IDT_TS, sel, ts->ext); + return (1); + } + } + + if (dataseg) { + /* + * A data segment is always non-conforming except when it's + * descriptor is a readable, conforming code segment. + */ + if (code_desc(usd.sd_type) && (usd.sd_type & 0x4) != 0) + conforming = true; + else + conforming = false; + + if (!conforming && (rpl > dpl || cpl > dpl)) { + sel_exception(ctx, vcpu, IDT_TS, sel, ts->ext); + return (1); + } + } + *seg_desc = usd_to_seg_desc(&usd); + return (0); +} + +static void +tss32_save(struct vmctx *ctx, int vcpu, struct vm_task_switch *task_switch, + uint32_t eip, struct tss32 *tss, struct iovec *iov) +{ + + /* General purpose registers */ + tss->tss_eax = GETREG(ctx, vcpu, VM_REG_GUEST_RAX); + tss->tss_ecx = GETREG(ctx, vcpu, VM_REG_GUEST_RCX); + tss->tss_edx = GETREG(ctx, vcpu, VM_REG_GUEST_RDX); + tss->tss_ebx = GETREG(ctx, vcpu, VM_REG_GUEST_RBX); + tss->tss_esp = GETREG(ctx, vcpu, VM_REG_GUEST_RSP); + tss->tss_ebp = GETREG(ctx, vcpu, VM_REG_GUEST_RBP); + tss->tss_esi = GETREG(ctx, vcpu, VM_REG_GUEST_RSI); + tss->tss_edi = GETREG(ctx, vcpu, VM_REG_GUEST_RDI); + + /* Segment selectors */ + tss->tss_es = GETREG(ctx, vcpu, VM_REG_GUEST_ES); + tss->tss_cs = GETREG(ctx, vcpu, VM_REG_GUEST_CS); + tss->tss_ss = GETREG(ctx, vcpu, VM_REG_GUEST_SS); + tss->tss_ds = GETREG(ctx, vcpu, VM_REG_GUEST_DS); + tss->tss_fs = GETREG(ctx, vcpu, VM_REG_GUEST_FS); + tss->tss_gs = GETREG(ctx, vcpu, VM_REG_GUEST_GS); + + /* eflags and eip */ + tss->tss_eflags = GETREG(ctx, vcpu, VM_REG_GUEST_RFLAGS); + if (task_switch->reason == TSR_IRET) + tss->tss_eflags &= ~PSL_NT; + tss->tss_eip = eip; + + /* Copy updated old TSS into guest memory */ + vm_copyout(ctx, vcpu, tss, iov, sizeof(struct tss32)); +} + +static void +update_seg_desc(struct vmctx *ctx, int vcpu, int reg, struct seg_desc *sd) +{ + int error; + + error = vm_set_desc(ctx, vcpu, reg, sd->base, sd->limit, sd->access); + assert(error == 0); +} + +/* + * Update the vcpu registers to reflect the state of the new task. + */ +static int +tss32_restore(struct vmctx *ctx, int vcpu, struct vm_task_switch *ts, + uint16_t ot_sel, struct tss32 *tss, struct iovec *iov, int *faultptr) +{ + struct seg_desc seg_desc, seg_desc2; + uint64_t *pdpte, maxphyaddr, reserved; + uint32_t eflags; + int error, i; + bool nested; + + nested = false; + if (ts->reason != TSR_IRET && ts->reason != TSR_JMP) { + tss->tss_link = ot_sel; + nested = true; + } + + eflags = tss->tss_eflags; + if (nested) + eflags |= PSL_NT; + + /* LDTR */ + SETREG(ctx, vcpu, VM_REG_GUEST_LDTR, tss->tss_ldt); + + /* PBDR */ + if (ts->paging.paging_mode != PAGING_MODE_FLAT) { + if (ts->paging.paging_mode == PAGING_MODE_PAE) { + /* + * XXX Assuming 36-bit MAXPHYADDR. + */ + maxphyaddr = (1UL << 36) - 1; + pdpte = paddr_guest2host(ctx, tss->tss_cr3 & ~0x1f, 32); + for (i = 0; i < 4; i++) { + /* Check reserved bits if the PDPTE is valid */ + if (!(pdpte[i] & 0x1)) + continue; + /* + * Bits 2:1, 8:5 and bits above the processor's + * maximum physical address are reserved. + */ + reserved = ~maxphyaddr | 0x1E6; + if (pdpte[i] & reserved) { + vm_inject_gp(ctx, vcpu); + return (1); + } + } + SETREG(ctx, vcpu, VM_REG_GUEST_PDPTE0, pdpte[0]); + SETREG(ctx, vcpu, VM_REG_GUEST_PDPTE1, pdpte[1]); + SETREG(ctx, vcpu, VM_REG_GUEST_PDPTE2, pdpte[2]); + SETREG(ctx, vcpu, VM_REG_GUEST_PDPTE3, pdpte[3]); + } + SETREG(ctx, vcpu, VM_REG_GUEST_CR3, tss->tss_cr3); + ts->paging.cr3 = tss->tss_cr3; + } + + /* eflags and eip */ + SETREG(ctx, vcpu, VM_REG_GUEST_RFLAGS, eflags); + SETREG(ctx, vcpu, VM_REG_GUEST_RIP, tss->tss_eip); + + /* General purpose registers */ + SETREG(ctx, vcpu, VM_REG_GUEST_RAX, tss->tss_eax); + SETREG(ctx, vcpu, VM_REG_GUEST_RCX, tss->tss_ecx); + SETREG(ctx, vcpu, VM_REG_GUEST_RDX, tss->tss_edx); + SETREG(ctx, vcpu, VM_REG_GUEST_RBX, tss->tss_ebx); + SETREG(ctx, vcpu, VM_REG_GUEST_RSP, tss->tss_esp); + SETREG(ctx, vcpu, VM_REG_GUEST_RBP, tss->tss_ebp); + SETREG(ctx, vcpu, VM_REG_GUEST_RSI, tss->tss_esi); + SETREG(ctx, vcpu, VM_REG_GUEST_RDI, tss->tss_edi); + + /* Segment selectors */ + SETREG(ctx, vcpu, VM_REG_GUEST_ES, tss->tss_es); + SETREG(ctx, vcpu, VM_REG_GUEST_CS, tss->tss_cs); + SETREG(ctx, vcpu, VM_REG_GUEST_SS, tss->tss_ss); + SETREG(ctx, vcpu, VM_REG_GUEST_DS, tss->tss_ds); + SETREG(ctx, vcpu, VM_REG_GUEST_FS, tss->tss_fs); + SETREG(ctx, vcpu, VM_REG_GUEST_GS, tss->tss_gs); + + /* + * If this is a nested task then write out the new TSS to update + * the previous link field. + */ + if (nested) + vm_copyout(ctx, vcpu, tss, iov, sizeof(*tss)); + + /* Validate segment descriptors */ + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_LDTR, &seg_desc, + faultptr); + if (error || *faultptr) + return (error); + update_seg_desc(ctx, vcpu, VM_REG_GUEST_LDTR, &seg_desc); + + /* + * Section "Checks on Guest Segment Registers", Intel SDM, Vol 3. + * + * The SS and CS attribute checks on VM-entry are inter-dependent so + * we need to make sure that both segments are valid before updating + * either of them. This ensures that the VMCS state can pass the + * VM-entry checks so the guest can handle any exception injected + * during task switch emulation. + */ + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_CS, &seg_desc, + faultptr); + if (error || *faultptr) + return (error); + + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_SS, &seg_desc2, + faultptr); + if (error || *faultptr) + return (error); + update_seg_desc(ctx, vcpu, VM_REG_GUEST_CS, &seg_desc); + update_seg_desc(ctx, vcpu, VM_REG_GUEST_SS, &seg_desc2); + ts->paging.cpl = tss->tss_cs & SEL_RPL_MASK; + + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_DS, &seg_desc, + faultptr); + if (error || *faultptr) + return (error); + update_seg_desc(ctx, vcpu, VM_REG_GUEST_DS, &seg_desc); + + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_ES, &seg_desc, + faultptr); + if (error || *faultptr) + return (error); + update_seg_desc(ctx, vcpu, VM_REG_GUEST_ES, &seg_desc); + + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_FS, &seg_desc, + faultptr); + if (error || *faultptr) + return (error); + update_seg_desc(ctx, vcpu, VM_REG_GUEST_FS, &seg_desc); + + error = validate_seg_desc(ctx, vcpu, ts, VM_REG_GUEST_GS, &seg_desc, + faultptr); + if (error || *faultptr) + return (error); + update_seg_desc(ctx, vcpu, VM_REG_GUEST_GS, &seg_desc); + + return (0); +} + +/* + * Push an error code on the stack of the new task. This is needed if the + * task switch was triggered by a hardware exception that causes an error + * code to be saved (e.g. #PF). + */ +static int +push_errcode(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, + int task_type, uint32_t errcode, int *faultptr) +{ + struct iovec iov[2]; + struct seg_desc seg_desc; + int stacksize, bytes, error; + uint64_t gla, cr0, rflags; + uint32_t esp; + uint16_t stacksel; + + *faultptr = 0; + + cr0 = GETREG(ctx, vcpu, VM_REG_GUEST_CR0); + rflags = GETREG(ctx, vcpu, VM_REG_GUEST_RFLAGS); + stacksel = GETREG(ctx, vcpu, VM_REG_GUEST_SS); + + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_SS, &seg_desc.base, + &seg_desc.limit, &seg_desc.access); + assert(error == 0); + + /* + * Section "Error Code" in the Intel SDM vol 3: the error code is + * pushed on the stack as a doubleword or word (depending on the + * default interrupt, trap or task gate size). + */ + if (task_type == SDT_SYS386BSY || task_type == SDT_SYS386TSS) + bytes = 4; + else + bytes = 2; + + /* + * PUSH instruction from Intel SDM vol 2: the 'B' flag in the + * stack-segment descriptor determines the size of the stack + * pointer outside of 64-bit mode. + */ + if (SEG_DESC_DEF32(seg_desc.access)) + stacksize = 4; + else + stacksize = 2; + + esp = GETREG(ctx, vcpu, VM_REG_GUEST_RSP); + esp -= bytes; + + if (vie_calculate_gla(paging->cpu_mode, VM_REG_GUEST_SS, + &seg_desc, esp, bytes, stacksize, PROT_WRITE, &gla)) { + sel_exception(ctx, vcpu, IDT_SS, stacksel, 1); + *faultptr = 1; + return (0); + } + + if (vie_alignment_check(paging->cpl, bytes, cr0, rflags, gla)) { + vm_inject_ac(ctx, vcpu, 1); + *faultptr = 1; + return (0); + } + + error = vm_copy_setup(ctx, vcpu, paging, gla, bytes, PROT_WRITE, + iov, nitems(iov), faultptr); + if (error || *faultptr) + return (error); + + vm_copyout(ctx, vcpu, &errcode, iov, bytes); + SETREG(ctx, vcpu, VM_REG_GUEST_RSP, esp); + return (0); +} + +/* + * Evaluate return value from helper functions and potentially return to + * the VM run loop. + */ +#define CHKERR(error,fault) \ + do { \ + assert((error == 0) || (error == EFAULT)); \ + if (error) \ + return (VMEXIT_ABORT); \ + else if (fault) \ + return (VMEXIT_CONTINUE); \ + } while (0) + +int +vmexit_task_switch(struct vmctx *ctx, struct vm_exit *vmexit, int *pvcpu) +{ + struct seg_desc nt; + struct tss32 oldtss, newtss; + struct vm_task_switch *task_switch; + struct vm_guest_paging *paging, sup_paging; + struct user_segment_descriptor nt_desc, ot_desc; + struct iovec nt_iov[2], ot_iov[2]; + uint64_t cr0, ot_base; + uint32_t eip, ot_lim, access; + int error, ext, fault, minlimit, nt_type, ot_type, vcpu; + enum task_switch_reason reason; + uint16_t nt_sel, ot_sel; + + task_switch = &vmexit->u.task_switch; + nt_sel = task_switch->tsssel; + ext = vmexit->u.task_switch.ext; + reason = vmexit->u.task_switch.reason; + paging = &vmexit->u.task_switch.paging; + vcpu = *pvcpu; + + assert(paging->cpu_mode == CPU_MODE_PROTECTED); + + /* + * Calculate the instruction pointer to store in the old TSS. + */ + eip = vmexit->rip + vmexit->inst_length; + + /* + * Section 4.6, "Access Rights" in Intel SDM Vol 3. + * The following page table accesses are implicitly supervisor mode: + * - accesses to GDT or LDT to load segment descriptors + * - accesses to the task state segment during task switch + */ + sup_paging = *paging; + sup_paging.cpl = 0; /* implicit supervisor mode */ + + /* Fetch the new TSS descriptor */ + error = read_tss_descriptor(ctx, vcpu, task_switch, nt_sel, &nt_desc, + &fault); + CHKERR(error, fault); + + nt = usd_to_seg_desc(&nt_desc); + + /* Verify the type of the new TSS */ + nt_type = SEG_DESC_TYPE(nt.access); + if (nt_type != SDT_SYS386BSY && nt_type != SDT_SYS386TSS && + nt_type != SDT_SYS286BSY && nt_type != SDT_SYS286TSS) { + sel_exception(ctx, vcpu, IDT_TS, nt_sel, ext); + goto done; + } + + /* TSS descriptor must have present bit set */ + if (!SEG_DESC_PRESENT(nt.access)) { + sel_exception(ctx, vcpu, IDT_NP, nt_sel, ext); + goto done; + } + + /* + * TSS must have a minimum length of 104 bytes for a 32-bit TSS and + * 44 bytes for a 16-bit TSS. + */ + if (nt_type == SDT_SYS386BSY || nt_type == SDT_SYS386TSS) + minlimit = 104 - 1; + else if (nt_type == SDT_SYS286BSY || nt_type == SDT_SYS286TSS) + minlimit = 44 - 1; + else + minlimit = 0; + + assert(minlimit > 0); + if (nt.limit < minlimit) { + sel_exception(ctx, vcpu, IDT_TS, nt_sel, ext); + goto done; + } + + /* TSS must be busy if task switch is due to IRET */ + if (reason == TSR_IRET && !TSS_BUSY(nt_type)) { + sel_exception(ctx, vcpu, IDT_TS, nt_sel, ext); + goto done; + } + + /* + * TSS must be available (not busy) if task switch reason is + * CALL, JMP, exception or interrupt. + */ + if (reason != TSR_IRET && TSS_BUSY(nt_type)) { + sel_exception(ctx, vcpu, IDT_GP, nt_sel, ext); + goto done; + } + + /* Fetch the new TSS */ + error = vm_copy_setup(ctx, vcpu, &sup_paging, nt.base, minlimit + 1, + PROT_READ | PROT_WRITE, nt_iov, nitems(nt_iov), &fault); + CHKERR(error, fault); + vm_copyin(ctx, vcpu, nt_iov, &newtss, minlimit + 1); + + /* Get the old TSS selector from the guest's task register */ + ot_sel = GETREG(ctx, vcpu, VM_REG_GUEST_TR); + if (ISLDT(ot_sel) || IDXSEL(ot_sel) == 0) { + /* + * This might happen if a task switch was attempted without + * ever loading the task register with LTR. In this case the + * TR would contain the values from power-on: + * (sel = 0, base = 0, limit = 0xffff). + */ + sel_exception(ctx, vcpu, IDT_TS, ot_sel, task_switch->ext); + goto done; + } + + /* Get the old TSS base and limit from the guest's task register */ + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_TR, &ot_base, &ot_lim, + &access); + assert(error == 0); + assert(!SEG_DESC_UNUSABLE(access) && SEG_DESC_PRESENT(access)); + ot_type = SEG_DESC_TYPE(access); + assert(ot_type == SDT_SYS386BSY || ot_type == SDT_SYS286BSY); + + /* Fetch the old TSS descriptor */ + error = read_tss_descriptor(ctx, vcpu, task_switch, ot_sel, &ot_desc, + &fault); + CHKERR(error, fault); + + /* Get the old TSS */ + error = vm_copy_setup(ctx, vcpu, &sup_paging, ot_base, minlimit + 1, + PROT_READ | PROT_WRITE, ot_iov, nitems(ot_iov), &fault); + CHKERR(error, fault); + vm_copyin(ctx, vcpu, ot_iov, &oldtss, minlimit + 1); + + /* + * Clear the busy bit in the old TSS descriptor if the task switch + * due to an IRET or JMP instruction. + */ + if (reason == TSR_IRET || reason == TSR_JMP) { + ot_desc.sd_type &= ~0x2; + error = desc_table_write(ctx, vcpu, &sup_paging, ot_sel, + &ot_desc, &fault); + CHKERR(error, fault); + } + + if (nt_type == SDT_SYS286BSY || nt_type == SDT_SYS286TSS) { + fprintf(stderr, "Task switch to 16-bit TSS not supported\n"); + return (VMEXIT_ABORT); + } + + /* Save processor state in old TSS */ + tss32_save(ctx, vcpu, task_switch, eip, &oldtss, ot_iov); + + /* + * If the task switch was triggered for any reason other than IRET + * then set the busy bit in the new TSS descriptor. + */ + if (reason != TSR_IRET) { + nt_desc.sd_type |= 0x2; + error = desc_table_write(ctx, vcpu, &sup_paging, nt_sel, + &nt_desc, &fault); + CHKERR(error, fault); + } + + /* Update task register to point at the new TSS */ + SETREG(ctx, vcpu, VM_REG_GUEST_TR, nt_sel); + + /* Update the hidden descriptor state of the task register */ + nt = usd_to_seg_desc(&nt_desc); + update_seg_desc(ctx, vcpu, VM_REG_GUEST_TR, &nt); + + /* Set CR0.TS */ + cr0 = GETREG(ctx, vcpu, VM_REG_GUEST_CR0); + SETREG(ctx, vcpu, VM_REG_GUEST_CR0, cr0 | CR0_TS); + + /* + * We are now committed to the task switch. Any exceptions encountered + * after this point will be handled in the context of the new task and + * the saved instruction pointer will belong to the new task. + */ + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, newtss.tss_eip); + assert(error == 0); + + /* Load processor state from new TSS */ + error = tss32_restore(ctx, vcpu, task_switch, ot_sel, &newtss, nt_iov, + &fault); + CHKERR(error, fault); + + /* + * Section "Interrupt Tasks" in Intel SDM, Vol 3: if an exception + * caused an error code to be generated, this error code is copied + * to the stack of the new task. + */ + if (task_switch->errcode_valid) { + assert(task_switch->ext); + assert(task_switch->reason == TSR_IDT_GATE); + error = push_errcode(ctx, vcpu, &task_switch->paging, nt_type, + task_switch->errcode, &fault); + CHKERR(error, fault); + } + + /* + * Treatment of virtual-NMI blocking if NMI is delivered through + * a task gate. + * + * Section "Architectural State Before A VM Exit", Intel SDM, Vol3: + * If the virtual NMIs VM-execution control is 1, VM entry injects + * an NMI, and delivery of the NMI causes a task switch that causes + * a VM exit, virtual-NMI blocking is in effect before the VM exit + * commences. + * + * Thus, virtual-NMI blocking is in effect at the time of the task + * switch VM exit. + */ + + /* + * Treatment of virtual-NMI unblocking on IRET from NMI handler task. + * + * Section "Changes to Instruction Behavior in VMX Non-Root Operation" + * If "virtual NMIs" control is 1 IRET removes any virtual-NMI blocking. + * This unblocking of virtual-NMI occurs even if IRET causes a fault. + * + * Thus, virtual-NMI blocking is cleared at the time of the task switch + * VM exit. + */ + + /* + * If the task switch was triggered by an event delivered through + * the IDT then extinguish the pending event from the vcpu's + * exitintinfo. + */ + if (task_switch->reason == TSR_IDT_GATE) { + error = vm_set_intinfo(ctx, vcpu, 0); + assert(error == 0); + } + + /* + * XXX should inject debug exception if 'T' bit is 1 + */ +done: + return (VMEXIT_CONTINUE); +} diff --git a/usr/src/cmd/bhyve/test/Makefile b/usr/src/cmd/bhyve/test/Makefile new file mode 100644 index 0000000000..7dbee0c5f3 --- /dev/null +++ b/usr/src/cmd/bhyve/test/Makefile @@ -0,0 +1,18 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +SUBDIRS = scripts tst + +include Makefile.subdirs diff --git a/usr/src/cmd/bhyve/test/Makefile.com b/usr/src/cmd/bhyve/test/Makefile.com new file mode 100644 index 0000000000..3c719bcea7 --- /dev/null +++ b/usr/src/cmd/bhyve/test/Makefile.com @@ -0,0 +1,60 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +include $(SRC)/Makefile.master +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/cmd/Makefile.cmd.64 + +# +# Force c99 for everything +# +CSTD= $(CSTD_GNU99) +C99MODE= -xc99=%all +C99LMODE= -Xc99=%all + +CFLAGS += $(CCVERBOSE) -_gcc=-Wimplicit-function-declaration \ + -_gcc=-Wno-parentheses +CFLAGS64 += $(CCVERBOSE) -_gcc=-Wimplicit-function-declaration \ + -_gcc=-Wno-parentheses +CPPFLAGS = -I$(SRC)/cmd/bhyve \ + -I$(COMPAT)/freebsd -I$(CONTRIB)/freebsd \ + -I$(CONTRIB)/freebsd/dev/usb/controller \ + -I$(CONTRIB)/freebsd/dev/mii \ + $(CPPFLAGS.master) \ + -I$(ROOT)/usr/platform/i86pc/include \ + -I$(SRC)/uts/i86pc/io/vmm \ + -I$(SRC)/uts/common \ + -I$(SRC)/uts/i86pc \ + -I$(SRC)/lib/libdladm/common \ + -DWITHOUT_CAPSICUM +CPPFLAGS += -I$(COMPAT)/freebsd/amd64 -I$(CONTRIB)/freebsd/amd64 + +CLEANFILES += $(EXETESTS) +CLOBBERFILES += $(ROOTTESTS) + +# +# Install related definitions +# +ROOTOPTPKG = $(ROOT)/opt/bhyvetest +ROOTBIN = $(ROOTOPTPKG)/bin +ROOTTST = $(ROOTOPTPKG)/tst +ROOTTSTDIR = $(ROOTTST)/$(TSTDIR) +ROOTTSTEXES = $(EXETESTS:%=$(ROOTTSTDIR)/%) +ROOTTSTSH = $(SHTESTS:%=$(ROOTTSTDIR)/%) +ROOTOUT = $(OUTFILES:%=$(ROOTTSTDIR)/%) +ROOTTESTS = $(ROOTTSTEXES) $(ROOTTSTSH) $(ROOTOUT) +FILEMODE = 0555 +LDLIBS = $(LDLIBS.cmd) +LINTEXE = $(EXETESTS:%.exe=%.exe.ln) diff --git a/usr/src/cmd/bhyve/test/Makefile.subdirs b/usr/src/cmd/bhyve/test/Makefile.subdirs new file mode 100644 index 0000000000..45f0aa67fa --- /dev/null +++ b/usr/src/cmd/bhyve/test/Makefile.subdirs @@ -0,0 +1,29 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +.KEEP_STATE: + +all := TARGET += all +clean := TARGET += clean +clobber := TARGET += clobber +install := TARGET += install +lint := TARGET += lint + +all clean clobber install lint: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/cmd/bhyve/test/Makefile.targ b/usr/src/cmd/bhyve/test/Makefile.targ new file mode 100644 index 0000000000..e3ec55cfdb --- /dev/null +++ b/usr/src/cmd/bhyve/test/Makefile.targ @@ -0,0 +1,55 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +$(ROOTOPTPKG): + $(INS.dir) + +$(ROOTBIN): $(ROOTOPTPKG) + $(INS.dir) + +$(ROOTBIN)/%: %.ksh $(ROOTBIN) + $(INS.rename) + +$(ROOTTST): $(ROOTOPTPKG) + $(INS.dir) + +$(ROOTTSTDIR): $(ROOTTST) + $(INS.dir) + +$(ROOTTSTDIR)/%.ksh: %.ksh $(ROOTTSTDIR) + $(INS.file) + +$(ROOTTSTDIR)/%.out: %.out $(ROOTTSTDIR) + $(INS.file) + +%.exe: %.o $(SUPOBJS) + $(LINK.c) -o $@ $< $(SUPOBJS) $(LDLIBS) + $(POST_PROCESS) + +$(ROOTTSTDIR)/%.exe: %.exe $(ROOTTSTDIR) + $(INS.file) + +all: install + +%.exe.ln: %.c $(SUPOBJS) + $(LINT.c) $< $(LDLIBS) + +lint: $(LINTEXE) + +clean: + -$(RM) *.o $(CLEANFILES) + +clobber: clean + -$(RM) $(CLOBBERFILES) diff --git a/usr/src/cmd/bhyve/test/scripts/Makefile b/usr/src/cmd/bhyve/test/scripts/Makefile new file mode 100644 index 0000000000..d28a5edb8f --- /dev/null +++ b/usr/src/cmd/bhyve/test/scripts/Makefile @@ -0,0 +1,28 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +include ../Makefile.com + +SRCS = bhyvetest +SCRIPTS = $(SRCS:%=$(ROOTBIN)/%) + +SCRIPTS := FILEMODE = 0555 +CLOBBERFILES = $(SCRIPTS) + +install: $(SCRIPTS) + +lint: + +include ../Makefile.targ diff --git a/usr/src/cmd/bhyve/test/scripts/bhyvetest.ksh b/usr/src/cmd/bhyve/test/scripts/bhyvetest.ksh new file mode 100644 index 0000000000..95b7743417 --- /dev/null +++ b/usr/src/cmd/bhyve/test/scripts/bhyvetest.ksh @@ -0,0 +1,231 @@ +#!/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +# +# bhyve test suite driver +# +unalias -a + +bt_arg0=$(basename $0) +bt_root="$(cd $(dirname $0)/..; pwd -P)" +bt_ksh="/usr/bin/ksh" +bt_outdir= +bt_keep= +bt_all= +bt_tnum=0 +bt_tfail=0 +bt_tsuc=0 + +function usage +{ + typeset msg="$*" + [[ -z "$msg" ]] || echo "$msg" 2>&1 + cat <<USAGE >&2 +Usage: $bt_arg0 [ -o dir ] [ -k ] [ -a | test ... ] + + -o dir Sets 'dir' as the output directory + -a Runs all tests, ignores tests passed in + -k Keep output from all tests, not just failures + -m mdb binary to test +USAGE + exit 2 +} + +function fatal +{ + typeset msg="$*" + [[ -z "$msg" ]] && msg="failed" + echo "$bt_arg0: $msg" >&2 + exit 1 +} + +function setup_outdir +{ + bt_outdir="$bt_outdir/$bt_arg0.$$" + mkdir -p $bt_outdir || fatal "failed to make output dir $bt_outdir" +} + +function run_single +{ + typeset name=$1 + typeset expect base ext exe command odir res reason + typeset iserr + + [[ -z "$name" ]] && fail "missing test to run" + base=${name##*/} + ext=${base##*.} + expect=${base%%.*} + odir="$bt_outdir/current" + [[ -z "$ext" ]] && fatal "found test without ext: $name" + [[ -z "$expect" ]] && fatal "found test without prefix: $name" + + if [[ "$expect" == "err" || "$expect" == "ecreate" ]]; then + iserr="yup" + else + iserr="" + fi + + case "$ext" in + "ksh") + command="$bt_ksh ./$base" + ;; + "exe") + command="./$base" + ;; + "out") + # + # This is the file format for checking output against. + # + return 0 + ;; + *) + echo "skipping test $name (unknown extensino)" + return 0 + ;; + esac + + echo "Executing test $name ... \c" + mkdir -p "$odir" >/dev/null || fatal "can't make output directory" + cd $(dirname $name) || fatal "failed to enter test directory" + $command > "$odir/stdout" 2>"$odir/stderr" + res=$? + cd - > /dev/null || fatal "failed to leave test directory" + + if [[ -f "$name.out" ]] && \ + ! diff "$name.out" "$odir/stdout" >/dev/null; then + cp $name.out $odir/$base.out + reason="stdout mismatch" + elif [[ -n "$iserr" && $res -eq 0 ]]; then + reason="test exited $res, not non-zero" + elif [[ -z "$iserr" && $res -ne 0 ]]; then + reason="test exited $res, not zero" + fi + + if [[ -n "$reason" ]]; then + echo "$reason" + ((bt_tfail++)) + mv "$odir" "$bt_outdir/failure.$bt_tfail" || fatal \ + "failed to move test output directory" + cp "$name" "$bt_outdir/failure.$bt_tfail/$(basename $name)" || \ + fatal "failed to copy test into output directory" + else + echo "passed" + ((bt_tsuc++)) + mv "$odir" "$bt_outdir/success.$bt_tsuc" || fatal \ + "failed to move test directory" + fi + + ((bt_tnum++)) +} + +function run_all +{ + typeset tests t dir + + tests=$(ls -1 $bt_root/tst/*/*.@(ksh|exe)) + for t in $tests; do + run_single $t + done +} + +function welcome +{ + cat <<WELCOME +Starting tests... +output directory: $bt_outdir +WELCOME +} + +function cleanup +{ + [[ -n "$bt_keep" ]] && return + rm -rf "$bt_outdir"/success.* || fatal \ + "failed to remove successful test cases" + if [[ $bt_tfail -eq 0 ]]; then + rmdir "$bt_outdir" || fatal \ + "failed to remove test output directory" + fi +} + +function goodbye +{ + cat <<EOF + +------------- +Results +------------- + +Tests passed: $bt_tsuc +Tests failed: $bt_tfail +Tests ran: $bt_tnum + +EOF + if [[ $bt_tfail -eq 0 ]]; then + echo "Congrats, some tiny parts of bhyve aren't completely" \ + "broken, the tests pass". + else + echo "Some tests failed, you have some work to do." + fi +} + +while getopts ":ahko:m:" c $@; do + case "$c" in + a) + bt_all="y" + ;; + k) + bt_keep="y" + ;; + o) + bt_outdir="$OPTARG" + ;; + h) + usage + ;; + :) + usage "option requires an argument -- $OPTARG" + ;; + *) + usage "invalid option -- $OPTARG" + ;; + esac +done + +shift $((OPTIND-1)) + +[[ -z "$bt_all" && $# == 0 ]] && usage "no tests to run" + +[[ -z "$bt_outdir" ]] && bt_outdir="$PWD" + +setup_outdir +welcome + +if [[ ! -z "$bt_all" ]]; then + run_all +else + for t in $@; do + [[ -f $t ]] || fatal "cannot find test $t" + run_single $t + done +fi + +goodbye +cleanup + +# +# Exit 1 if we have tests that return non-zero +# +[[ $bt_tfai -eq 0 ]] diff --git a/usr/src/cmd/bhyve/test/tst/Makefile b/usr/src/cmd/bhyve/test/tst/Makefile new file mode 100644 index 0000000000..f6a6ec96fc --- /dev/null +++ b/usr/src/cmd/bhyve/test/tst/Makefile @@ -0,0 +1,18 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +SUBDIRS = mevent + +include ../Makefile.subdirs diff --git a/usr/src/cmd/bhyve/test/tst/mevent/Makefile b/usr/src/cmd/bhyve/test/tst/mevent/Makefile new file mode 100644 index 0000000000..047886bc6a --- /dev/null +++ b/usr/src/cmd/bhyve/test/tst/mevent/Makefile @@ -0,0 +1,30 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +TSTDIR = mevent +EXETESTS = \ + lists.delete.exe \ + read.disable.exe \ + read.pause.exe \ + read.requeue.exe \ + +SHTESTS = +SUPOBJS = mevent.o testlib.o + +include ../../Makefile.com + +install: $(ROOTTESTS) + +include ../../Makefile.targ diff --git a/usr/src/cmd/bhyve/test/tst/mevent/lists.delete.c b/usr/src/cmd/bhyve/test/tst/mevent/lists.delete.c new file mode 100644 index 0000000000..d09ac133a3 --- /dev/null +++ b/usr/src/cmd/bhyve/test/tst/mevent/lists.delete.c @@ -0,0 +1,172 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +/* + * Test: lists.delete + * Assertion: mevent_delete() causes the total number of events to decrease + * + * Strategy: 1. Create a pipe. + * 2. Call mevent_add() to be notified of writes to the pipe. The + * callback will do nothing other than generate an error if it + * is called. + * 3. Create another pipe and add a read event watcher to it. The + * callback will signal a cv when called. A write to the pipe + * followed by a wait on the cv will ensure that async + * operations in mevent.c are complete. See flush_and_wait(). + * 4. Call flush_and_wait(), then get event count. + * 5. Delete the event created in step 2. + * 6. Call flush_and_wait(), then get event count. + * 7. Verify result in step 6 is one less than result in step 4. + */ + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include "testlib.h" +#include "mevent.h" + +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; + +static int +get_count(void) +{ + int global = -1, change = -1, del_pending = -1; + int total; + + test_mevent_count_lists(&global, &change, &del_pending); + ASSERT_INT_NEQ(("count not set"), global, -1); + ASSERT_INT_NEQ(("count not set"), change, -1); + ASSERT_INT_NEQ(("count not set"), change, -1); + ASSERT_INT_EQ(("pending delete not processed"), del_pending, 0); + + total = global + change + del_pending; + + VERBOSE(("count = %d (%d + %d + %d)", total, global, change, + del_pending)); + + return (total); +} + +static void +not_called_cb(int fd, enum ev_type ev, void *arg) +{ + FAIL(("this callback should never be called")); +} + +static void +flush_cb(int fd, enum ev_type ev, void *arg) +{ + char buf[32]; + + /* Drain the pipe */ + while (read(fd, buf, sizeof (buf)) > 0) + ; + + pthread_mutex_lock(&mtx); + pthread_cond_signal(&cv); + pthread_mutex_unlock(&mtx); +} + +void +flush_and_wait(int fd) +{ + uint8_t msg = 42; + + /* + * Lock taken ahead of waking flush_cb so this thread doesn't race + * with the event thread. + */ + pthread_mutex_lock(&mtx); + if (write(fd, &msg, sizeof (msg)) != sizeof (msg)) { + FAIL(("bad write")); + } + + /* Wait for it to be read */ + pthread_cond_wait(&cv, &mtx); + pthread_mutex_unlock(&mtx); +} + +int +main(int argc, const char *argv[]) +{ + int unused_pipe[2]; + int flush_pipe[2]; + struct mevent *unused_evp, *flush_evp; + int count1, count2; + + start_test(argv[0], 5); + start_event_thread(); + + /* + * Create first pipe and related event + */ + if (pipe(unused_pipe) != 0) { + FAIL_ERRNO("pipe"); + } + VERBOSE(("unused_pipe[] = { %d, %d }", unused_pipe[0], unused_pipe[1])); + if (fcntl(unused_pipe[0], F_SETFL, O_NONBLOCK) != 0) { + FAIL_ERRNO("set pipe nonblocking"); + } + unused_evp = mevent_add(unused_pipe[0], EVF_READ, not_called_cb, NULL); + ASSERT_PTR_NEQ(("mevent_add"), unused_evp, NULL); + + /* + * Create flush pipe and related event + */ + if (pipe(flush_pipe) != 0) { + FAIL_ERRNO("pipe"); + } + VERBOSE(("flush_pipe[] = { %d, %d }", flush_pipe[0], + flush_pipe[1])); + if (fcntl(flush_pipe[0], F_SETFL, O_NONBLOCK) != 0) { + FAIL_ERRNO("set pipe nonblocking"); + } + flush_evp = mevent_add(flush_pipe[0], EVF_READ, flush_cb, NULL); + ASSERT_PTR_NEQ(("mevent_add"), flush_evp, NULL); + + /* Get count before delete. */ + flush_and_wait(flush_pipe[1]); + count1 = get_count(); + + /* + * Delete the first event and flush a read after the delete is + * complete. + */ + if (mevent_delete(unused_evp) != 0) { + FAIL_ERRNO("mevent_delete"); + } + + /* + * Verify count decreased. + */ + flush_and_wait(flush_pipe[1]); + count2 = get_count(); + if (count1 - 1 != count2 ) { + FAIL(("mevent_delete() did not decrease count by 1: " + "was %d, now %d", count1, count2)); + } + + PASS(); +} diff --git a/usr/src/cmd/bhyve/test/tst/mevent/mevent.c b/usr/src/cmd/bhyve/test/tst/mevent/mevent.c new file mode 100644 index 0000000000..17b6546847 --- /dev/null +++ b/usr/src/cmd/bhyve/test/tst/mevent/mevent.c @@ -0,0 +1,57 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +#include "../../../mevent.c" +#include "testlib.h" + +/* + * Returns by reference the number of events on the global and change lists. + * + * Used by tests that wish to ensure that the event count changes as suggested + * by mevent_add() and mevent_delete(). Note that a delete does not immediately + * delete an event. Events that are pending delete are included in the change + * list until the next pass through the change list to process pending changes. + */ +void +test_mevent_count_lists(int *ret_global, int *ret_change, int *ret_del_pending) +{ + struct mevent *mevp; + int global = 0; + int change = 0; + int del_pending = 0; + + mevent_qlock(); + + LIST_FOREACH(mevp, &global_head, me_list) { + global++; + VERBOSE(("on global: type %d fd %d state %d", mevp->me_type, + mevp->me_fd, mevp->me_state)); + } + + LIST_FOREACH(mevp, &change_head, me_list) { + change++; + if (mevp->me_state == MEV_DEL_PENDING) { + del_pending++; + } + VERBOSE(("on change: type %d fd %d state %d", mevp->me_type, + mevp->me_fd, mevp->me_state)); + } + + mevent_qunlock(); + + *ret_global = global; + *ret_change = change; + *ret_del_pending = del_pending; +} diff --git a/usr/src/cmd/bhyve/test/tst/mevent/read.disable.c b/usr/src/cmd/bhyve/test/tst/mevent/read.disable.c new file mode 100644 index 0000000000..d23b1af96c --- /dev/null +++ b/usr/src/cmd/bhyve/test/tst/mevent/read.disable.c @@ -0,0 +1,163 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +/* + * Test: read.cancel + * Assertion: A read is not requeued if mevent_disable() is called while it is + * being handled. + * + * Strategy: 1. Create a pipe + * 2. Call mevent_add() to be notified of writes to the pipe. The + * callback will signal a cv. + * 3. Write to the pipe then wait for a wakeup. + * 4. From the read event callback, disable the event then awaken + * the main thread. + * 5. In the main thread, add a timer event that will awaken the + * main thread after a short delay. + * 5. Write to the pipe and wait to be awoken. The wakeup should + * come from the timer event, not the read event. + */ + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include "testlib.h" +#include "mevent.h" + +typedef enum { + CB_NONE, + CB_READ, + CB_TIMER, +} lastwake_t; + +static lastwake_t lastwake = CB_NONE; + +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; + +static struct mevent *read_event; + +static void +munch(int fd, enum ev_type ev, void *arg) +{ + ssize_t nbytes; + char buf[32] = { 0 }; + int err; + + if ((nbytes = read(fd, buf, sizeof (buf))) < 0) { + FAIL_ERRNO("bad read"); + } + VERBOSE(("read %ld bytes '%s'", nbytes, buf)); + + err = mevent_disable(read_event); + ASSERT_INT_EQ(("mevent_disable: ", strerror(err)), err, 0); + + pthread_mutex_lock(&mtx); + + ASSERT_INT_EQ(("wrong lastwake"), lastwake, CB_NONE); + lastwake = CB_READ; + + pthread_cond_signal(&cv); + VERBOSE(("wakeup")); + + pthread_mutex_unlock(&mtx); +} + +static void +tick(int ms, enum ev_type ev, void *arg) +{ + pthread_mutex_lock(&mtx); + + ASSERT_INT_EQ(("wrong lastwake"), lastwake, CB_READ); + lastwake = CB_TIMER; + + pthread_cond_signal(&cv); + VERBOSE(("wakeup")); + + pthread_mutex_unlock(&mtx); +} + +int +main(int argc, const char *argv[]) +{ + int pipefds[2]; + struct mevent *timer; + ssize_t written; + char *msgs[] = { "first", "second" }; + char *msg; + + start_test(argv[0], 5); + start_event_thread(); + + if (pipe(pipefds) != 0) { + FAIL_ERRNO("pipe"); + } + if (fcntl(pipefds[0], F_SETFL, O_NONBLOCK) != 0) { + FAIL_ERRNO("set pipe nonblocking"); + } + + /* + * First write + */ + msg = msgs[0]; + read_event = mevent_add(pipefds[0], EVF_READ, munch, msg); + ASSERT_PTR_NEQ(("mevent_add pipefd"), read_event, NULL); + + pthread_mutex_lock(&mtx); + written = write(pipefds[1], msg, strlen(msg)); + if (written < 0) { + FAIL_ERRNO("bad write"); + } + ASSERT_INT64_EQ(("write '%s' failed", msg), written, strlen(msg)); + + /* + * Wait for it to be read + */ + pthread_cond_wait(&cv, &mtx); + ASSERT_INT_EQ(("wrong lastwake"), lastwake, CB_READ); + pthread_mutex_unlock(&mtx); + + /* + * Add timer, second write. + */ + msg = msgs[1]; + timer = mevent_add(50, EVF_TIMER, tick, msg); + ASSERT_PTR_NEQ(("mevent_add timer"), timer, NULL); + + pthread_mutex_lock(&mtx); + written = write(pipefds[1], msg, strlen(msg)); + if (written < 0) { + FAIL_ERRNO("bad write"); + } + ASSERT_INT64_EQ(("write '%s' failed", msg), written, strlen(msg)); + + /* + * Wait for timer to expire + */ + pthread_cond_wait(&cv, &mtx); + ASSERT_INT_EQ(("wrong lastwake"), lastwake, CB_TIMER); + pthread_mutex_unlock(&mtx); + + PASS(); +} diff --git a/usr/src/cmd/bhyve/test/tst/mevent/read.pause.c b/usr/src/cmd/bhyve/test/tst/mevent/read.pause.c new file mode 100644 index 0000000000..c877f014f6 --- /dev/null +++ b/usr/src/cmd/bhyve/test/tst/mevent/read.pause.c @@ -0,0 +1,152 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +/* + * Test: read.pause + * Assertion: mevent_disable() can be used to pause reads. + * + * Strategy: 1. Create a pipe + * 2. Call mevent_add() to be notified of writes to the pipe. The + * callback will signal a cv. + * 3. In a loop, write to the pipe then wait on the cv. + */ + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include "testlib.h" +#include "mevent.h" + +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; + +static char cookie[] = "Chocolate chip with fudge stripes"; + +/* + * After this many bytes are sent, writes will get batched up, progress will be + * made on the write side via an interval timer + */ +const int pauseat = 8; + +static void +munch(int fd, enum ev_type ev, void *arg) +{ + static int i = 0; + char buf[sizeof (cookie)] = { 0 }; + ssize_t nbytes; + ssize_t expected; + + ASSERT_INT_EQ(("bad event"), ev, EVF_READ); + ASSERT_PTR_EQ(("bad cookie"), arg, cookie); + + /* + * For the first while, expect data to come a byte at a time. After the + * pause, we should get a burst with the rest of the data. + */ + if (i > pauseat) { + expected = strlen(cookie) - pauseat - 1; + } else { + expected = 1; + } + + if ((nbytes = read(fd, buf, sizeof (buf))) < 0) { + FAIL_ERRNO("bad read"); + } + VERBOSE(("read %ld bytes '%s'", nbytes, buf)); + + ASSERT_INT64_EQ(("wanted a byte of cookie"), nbytes, expected); + + if (expected == 1) { + ASSERT_CHAR_EQ(("bad byte %d of cookie", i), buf[0], cookie[i]); + } else { + ASSERT_STR_EQ(("bad last half of cookie"), buf, &cookie[i]); + } + + pthread_mutex_lock(&mtx); + pthread_cond_signal(&cv); + VERBOSE(("wakeup")); + pthread_mutex_unlock(&mtx); + + i++; +} + +static void +tick(int ms, enum ev_type ev, void *arg) +{ + pthread_mutex_lock(&mtx); + pthread_cond_signal(&cv); + VERBOSE(("wakeup")); + pthread_mutex_unlock(&mtx); +} + +int +main(int argc, const char *argv[]) +{ + int pipefds[2]; + struct mevent *evp, *timer; + ssize_t written; + + start_test(argv[0], 5); + start_event_thread(); + + if (pipe(pipefds) != 0) { + FAIL_ERRNO("pipe"); + } + if (fcntl(pipefds[0], F_SETFL, O_NONBLOCK) != 0) { + FAIL_ERRNO("set pipe nonblocking"); + } + + evp = mevent_add(pipefds[0], EVF_READ, munch, cookie); + ASSERT_PTR_NEQ(("mevent_add pipefd"), evp, NULL); + + for (int i = 0; cookie[i] != 0; i++) { + pthread_mutex_lock(&mtx); + written = write(pipefds[1], cookie + i, 1); + if (written < 0) { + FAIL_ERRNO("bad write"); + } + ASSERT_INT64_EQ(("write byte %d of cookie", i), written, 1); + + /* Wait for it to be read */ + pthread_cond_wait(&cv, &mtx); + pthread_mutex_unlock(&mtx); + + if (i == pauseat) { + timer = mevent_add(10, EVF_TIMER, tick, + &cookie[pauseat]); + ASSERT_PTR_NEQ(("mevent_add timer"), timer, NULL); + VERBOSE(("disable munch")); + mevent_disable(evp); + } + } + + pthread_mutex_lock(&mtx); + + mevent_enable(evp); + + pthread_cond_wait(&cv, &mtx); + pthread_mutex_unlock(&mtx); + + PASS(); +} diff --git a/usr/src/cmd/bhyve/test/tst/mevent/read.requeue.c b/usr/src/cmd/bhyve/test/tst/mevent/read.requeue.c new file mode 100644 index 0000000000..ddc3e27235 --- /dev/null +++ b/usr/src/cmd/bhyve/test/tst/mevent/read.requeue.c @@ -0,0 +1,108 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +/* + * Test: read.requeue + * Assertion: A sequence of writes turns into a sequence of events. + * + * Strategy: 1. Create a pipe + * 2. Call mevent_add() to be notified of writes to the pipe. The + * callback will signal a cv. + * 3. In a loop, write to the pipe then wait on the cv. + */ + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <unistd.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include "testlib.h" +#include "mevent.h" + +static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; + +static char *cookie = "Chocolate chip with fudge stripes"; + +static void +munch(int fd, enum ev_type ev, void *arg) +{ + static int i = 0; + char buf[8] = { 0 }; + ssize_t nbytes; + + ASSERT_INT_EQ(("bad event"), ev, EVF_READ); + ASSERT_PTR_EQ(("bad cookie"), arg, cookie); + + if ((nbytes = read(fd, buf, sizeof (buf))) < 0) { + ASSERT_INT64_EQ(("bad read: %s", strerror(errno)), nbytes, 1); + } + VERBOSE(("read %ld bytes '%s'", nbytes, buf)); + + ASSERT_INT64_EQ(("wanted a byte of cookie"), nbytes, 1); + + ASSERT_CHAR_EQ(("bad byte %d of cookie", i), buf[0], cookie[i]); + + pthread_mutex_lock(&mtx); + pthread_cond_signal(&cv); + VERBOSE(("wakeup")); + pthread_mutex_unlock(&mtx); + + i++; +} + +int +main(int argc, const char *argv[]) +{ + int pipefds[2]; + struct mevent *evp; + + start_test(argv[0], 5); + start_event_thread(); + + if (pipe(pipefds) != 0) { + FAIL_ERRNO("pipe"); + } + if (fcntl(pipefds[0], F_SETFL, O_NONBLOCK) != 0) { + FAIL_ERRNO("set pipe nonblocking"); + } + + evp = mevent_add(pipefds[0], EVF_READ, munch, cookie); + ASSERT_PTR_NEQ(("mevent_add"), evp, NULL); + + for (int i = 0; cookie[i] != '\0'; i++) { + ssize_t written; + + pthread_mutex_lock(&mtx); + written = write(pipefds[1], cookie + i, 1); + if (written < 0) { + FAIL_ERRNO("bad write"); + } + ASSERT_INT64_EQ(("write byte %d of cookie", i), written, 1); + + /* Wait for it to be read */ + pthread_cond_wait(&cv, &mtx); + pthread_mutex_unlock(&mtx); + } + + PASS(); +} diff --git a/usr/src/cmd/bhyve/test/tst/mevent/testlib.c b/usr/src/cmd/bhyve/test/tst/mevent/testlib.c new file mode 100644 index 0000000000..af756d1509 --- /dev/null +++ b/usr/src/cmd/bhyve/test/tst/mevent/testlib.c @@ -0,0 +1,69 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +#include <pthread.h> +#include <signal.h> +#include <strings.h> +#include <unistd.h> + +#include "testlib.h" +#include "mevent.h" + +const char *testlib_prog; +boolean_t testlib_verbose; + +static void +timed_out(int signo) { + ASSERT_INT_EQ(("timeout signal"), signo, SIGALRM); + + FAIL(("Timed out")); +} + +void +start_test(const char *argv0, uint32_t timeout) +{ + char *val; + + testlib_prog = strrchr(argv0, '/'); + if (testlib_prog == NULL) { + testlib_prog = argv0; + } else { + testlib_prog++; + } + + testlib_verbose = ((val = getenv("TEST_VERBOSE")) != NULL) && + val[0] != '\0'; + + signal(SIGALRM, timed_out); + alarm(timeout); +} + +/* ARGSUSED */ +static void * +event_thread(void *arg) +{ + mevent_dispatch(); + return (NULL); +} + +void +start_event_thread(void) +{ + pthread_t tid; + + if (pthread_create(&tid, NULL, event_thread, NULL) != 0) { + FAIL_ERRNO("pthread_create"); + } +} diff --git a/usr/src/cmd/bhyve/test/tst/mevent/testlib.h b/usr/src/cmd/bhyve/test/tst/mevent/testlib.h new file mode 100644 index 0000000000..80949f3cc7 --- /dev/null +++ b/usr/src/cmd/bhyve/test/tst/mevent/testlib.h @@ -0,0 +1,88 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +#include <assert.h> +#include <errno.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> + +#include <sys/types.h> +#include <sys/stat.h> + +#include "mevent.h" + +#define EXIT_PASS 0 +#define EXIT_FAIL 1 + +#define VERBOSE(msg) \ + if (testlib_verbose) { \ + (void) printf("VERBOSE %s: %s:%d %s: ", testlib_prog, \ + __FILE__, __LINE__, __func__); \ + (void) printf msg; \ + (void) printf("\n"); \ + } + +#define FAIL_PROLOGUE() \ + (void) printf("FAIL %s: %s:%d: ", testlib_prog, __FILE__, __LINE__) + +#define FAIL(msg) \ + { \ + FAIL_PROLOGUE(); \ + (void) printf msg; \ + (void) printf("\n"); \ + exit(EXIT_FAIL); \ + } + +#define FAIL_ERRNO(msg) FAIL((msg ": %s", strerror(errno))) + +#define PASS() \ + { \ + (void) printf("PASS %s\n", testlib_prog); \ + exit(EXIT_PASS); \ + } + +#define ASSERT_CMP(msg, got, cmp, exp, nfmt) \ + if (!(got cmp exp)) { \ + FAIL_PROLOGUE(); \ + (void) printf msg; \ + (void) printf(": %s=" nfmt " %s %s=" nfmt "\n", \ + #got, got, #cmp, #exp, exp); \ + exit(EXIT_FAIL); \ + } + +#define ASSERT_CHAR_EQ(msg, got, exp) ASSERT_CMP(msg, got, ==, exp, "%c") +#define ASSERT_INT_EQ(msg, got, exp) ASSERT_CMP(msg, got, ==, exp, "%d") +#define ASSERT_INT_NEQ(msg, got, exp) ASSERT_CMP(msg, got, !=, exp, "%d") +#define ASSERT_INT64_EQ(msg, got, exp) ASSERT_CMP(msg, got, ==, exp, "%ld") +#define ASSERT_PTR_EQ(msg, got, exp) ASSERT_CMP(msg, got, ==, exp, "%p") +#define ASSERT_PTR_NEQ(msg, got, exp) ASSERT_CMP(msg, got, !=, exp, "%p") + +#define ASSERT_STR_EQ(msg, got, exp) \ + if (strcmp(got, exp) != 0) { \ + FAIL_PROLOGUE(); \ + (void) printf msg; \ + (void) printf(": %s='%s' != %s='%s'\n", \ + #got, got, #exp, exp); \ + exit(EXIT_FAIL); \ + } + +extern const char *testlib_prog; +extern boolean_t testlib_verbose; + +extern void start_test(const char *, uint32_t); +extern void start_event_thread(void); +extern void test_mevent_count_lists(int *, int *, int *); diff --git a/usr/src/cmd/bhyve/uart_emul.c b/usr/src/cmd/bhyve/uart_emul.c new file mode 100644 index 0000000000..1027d0b0f6 --- /dev/null +++ b/usr/src/cmd/bhyve/uart_emul.c @@ -0,0 +1,955 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2012 NetApp, Inc. + * Copyright (c) 2013 Neel Natu <neel@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + * + */ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2015 Pluribus Networks Inc. + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <dev/ic/ns16550.h> +#ifndef WITHOUT_CAPSICUM +#include <sys/capsicum.h> +#include <capsicum_helpers.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <termios.h> +#include <unistd.h> +#include <stdbool.h> +#include <string.h> +#include <pthread.h> +#include <sysexits.h> +#ifndef __FreeBSD__ +#include <sys/socket.h> +#endif + +#include "mevent.h" +#include "uart_emul.h" + +#define COM1_BASE 0x3F8 +#define COM1_IRQ 4 +#define COM2_BASE 0x2F8 +#define COM2_IRQ 3 + +#define DEFAULT_RCLK 1843200 +#define DEFAULT_BAUD 9600 + +#define FCR_RX_MASK 0xC0 + +#define MCR_OUT1 0x04 +#define MCR_OUT2 0x08 + +#define MSR_DELTA_MASK 0x0f + +#ifndef REG_SCR +#define REG_SCR com_scr +#endif + +#define FIFOSZ 16 + +static bool uart_stdio; /* stdio in use for i/o */ +static struct termios tio_stdio_orig; + +static struct { + int baseaddr; + int irq; + bool inuse; +} uart_lres[] = { + { COM1_BASE, COM1_IRQ, false}, + { COM2_BASE, COM2_IRQ, false}, +}; + +#define UART_NLDEVS (sizeof(uart_lres) / sizeof(uart_lres[0])) + +struct fifo { + uint8_t buf[FIFOSZ]; + int rindex; /* index to read from */ + int windex; /* index to write to */ + int num; /* number of characters in the fifo */ + int size; /* size of the fifo */ +}; + +struct ttyfd { + bool opened; + int fd; /* tty device file descriptor */ + struct termios tio_orig, tio_new; /* I/O Terminals */ +}; + +struct uart_softc { + pthread_mutex_t mtx; /* protects all softc elements */ + uint8_t data; /* Data register (R/W) */ + uint8_t ier; /* Interrupt enable register (R/W) */ + uint8_t lcr; /* Line control register (R/W) */ + uint8_t mcr; /* Modem control register (R/W) */ + uint8_t lsr; /* Line status register (R/W) */ + uint8_t msr; /* Modem status register (R/W) */ + uint8_t fcr; /* FIFO control register (W) */ + uint8_t scr; /* Scratch register (R/W) */ + + uint8_t dll; /* Baudrate divisor latch LSB */ + uint8_t dlh; /* Baudrate divisor latch MSB */ + + struct fifo rxfifo; + struct mevent *mev; + + struct ttyfd tty; +#ifndef __FreeBSD__ + bool sock; + struct { + int clifd; /* console client unix domain socket */ + int servfd; /* console server unix domain socket */ + struct mevent *servmev; /* mevent for server socket */ + } usc_sock; +#endif + + bool thre_int_pending; /* THRE interrupt pending */ + + void *arg; + uart_intr_func_t intr_assert; + uart_intr_func_t intr_deassert; +}; + +static void uart_drain(int fd, enum ev_type ev, void *arg); + +static void +ttyclose(void) +{ + + tcsetattr(STDIN_FILENO, TCSANOW, &tio_stdio_orig); +} + +static void +ttyopen(struct ttyfd *tf) +{ + + tcgetattr(tf->fd, &tf->tio_orig); + + tf->tio_new = tf->tio_orig; + cfmakeraw(&tf->tio_new); + tf->tio_new.c_cflag |= CLOCAL; + tcsetattr(tf->fd, TCSANOW, &tf->tio_new); + + if (tf->fd == STDIN_FILENO) { + tio_stdio_orig = tf->tio_orig; + atexit(ttyclose); + } +} + +static int +ttyread(struct ttyfd *tf) +{ + unsigned char rb; + + if (read(tf->fd, &rb, 1) == 1) + return (rb); + else + return (-1); +} + +static void +ttywrite(struct ttyfd *tf, unsigned char wb) +{ + + (void)write(tf->fd, &wb, 1); +} + +#ifndef __FreeBSD__ +static void +sockwrite(struct uart_softc *sc, unsigned char wb) +{ + (void) write(sc->usc_sock.clifd, &wb, 1); +} +#endif + +static void +rxfifo_reset(struct uart_softc *sc, int size) +{ + char flushbuf[32]; + struct fifo *fifo; + ssize_t nread; + int error; + + fifo = &sc->rxfifo; + bzero(fifo, sizeof(struct fifo)); + fifo->size = size; + + if (sc->tty.opened) { + /* + * Flush any unread input from the tty buffer. + */ + while (1) { + nread = read(sc->tty.fd, flushbuf, sizeof(flushbuf)); + if (nread != sizeof(flushbuf)) + break; + } + + /* + * Enable mevent to trigger when new characters are available + * on the tty fd. + */ + error = mevent_enable(sc->mev); + assert(error == 0); + } +#ifndef __FreeBSD__ + if (sc->sock && sc->usc_sock.clifd != -1) { + /* Flush any unread input from the socket buffer. */ + do { + nread = read(sc->usc_sock.clifd, flushbuf, + sizeof (flushbuf)); + } while (nread == sizeof (flushbuf)); + + /* Enable mevent to trigger when new data available on sock */ + error = mevent_enable(sc->mev); + assert(error == 0); + } +#endif /* __FreeBSD__ */ +} + +static int +rxfifo_available(struct uart_softc *sc) +{ + struct fifo *fifo; + + fifo = &sc->rxfifo; + return (fifo->num < fifo->size); +} + +static int +rxfifo_putchar(struct uart_softc *sc, uint8_t ch) +{ + struct fifo *fifo; + int error; + + fifo = &sc->rxfifo; + + if (fifo->num < fifo->size) { + fifo->buf[fifo->windex] = ch; + fifo->windex = (fifo->windex + 1) % fifo->size; + fifo->num++; + if (!rxfifo_available(sc)) { + if (sc->tty.opened) { + /* + * Disable mevent callback if the FIFO is full. + */ + error = mevent_disable(sc->mev); + assert(error == 0); + } +#ifndef __FreeBSD__ + if (sc->sock && sc->usc_sock.clifd != -1) { + /* + * Disable mevent callback if the FIFO is full. + */ + error = mevent_disable(sc->mev); + assert(error == 0); + } +#endif /* __FreeBSD__ */ + } + return (0); + } else + return (-1); +} + +static int +rxfifo_getchar(struct uart_softc *sc) +{ + struct fifo *fifo; + int c, error, wasfull; + + wasfull = 0; + fifo = &sc->rxfifo; + if (fifo->num > 0) { + if (!rxfifo_available(sc)) + wasfull = 1; + c = fifo->buf[fifo->rindex]; + fifo->rindex = (fifo->rindex + 1) % fifo->size; + fifo->num--; + if (wasfull) { + if (sc->tty.opened) { + error = mevent_enable(sc->mev); + assert(error == 0); + } +#ifndef __FreeBSD__ + if (sc->sock && sc->usc_sock.clifd != -1) { + error = mevent_enable(sc->mev); + assert(error == 0); + } +#endif /* __FreeBSD__ */ + } + return (c); + } else + return (-1); +} + +static int +rxfifo_numchars(struct uart_softc *sc) +{ + struct fifo *fifo = &sc->rxfifo; + + return (fifo->num); +} + +static void +uart_opentty(struct uart_softc *sc) +{ + ttyopen(&sc->tty); + sc->mev = mevent_add(sc->tty.fd, EVF_READ, uart_drain, sc); + assert(sc->mev != NULL); +} + +static uint8_t +modem_status(uint8_t mcr) +{ + uint8_t msr; + + if (mcr & MCR_LOOPBACK) { + /* + * In the loopback mode certain bits from the MCR are + * reflected back into MSR. + */ + msr = 0; + if (mcr & MCR_RTS) + msr |= MSR_CTS; + if (mcr & MCR_DTR) + msr |= MSR_DSR; + if (mcr & MCR_OUT1) + msr |= MSR_RI; + if (mcr & MCR_OUT2) + msr |= MSR_DCD; + } else { + /* + * Always assert DCD and DSR so tty open doesn't block + * even if CLOCAL is turned off. + */ + msr = MSR_DCD | MSR_DSR; + } + assert((msr & MSR_DELTA_MASK) == 0); + + return (msr); +} + +/* + * The IIR returns a prioritized interrupt reason: + * - receive data available + * - transmit holding register empty + * - modem status change + * + * Return an interrupt reason if one is available. + */ +static int +uart_intr_reason(struct uart_softc *sc) +{ + + if ((sc->lsr & LSR_OE) != 0 && (sc->ier & IER_ERLS) != 0) + return (IIR_RLS); + else if (rxfifo_numchars(sc) > 0 && (sc->ier & IER_ERXRDY) != 0) + return (IIR_RXTOUT); + else if (sc->thre_int_pending && (sc->ier & IER_ETXRDY) != 0) + return (IIR_TXRDY); + else if ((sc->msr & MSR_DELTA_MASK) != 0 && (sc->ier & IER_EMSC) != 0) + return (IIR_MLSC); + else + return (IIR_NOPEND); +} + +static void +uart_reset(struct uart_softc *sc) +{ + uint16_t divisor; + + divisor = DEFAULT_RCLK / DEFAULT_BAUD / 16; + sc->dll = divisor; + sc->dlh = divisor >> 16; + sc->msr = modem_status(sc->mcr); + + rxfifo_reset(sc, 1); /* no fifo until enabled by software */ +} + +/* + * Toggle the COM port's intr pin depending on whether or not we have an + * interrupt condition to report to the processor. + */ +static void +uart_toggle_intr(struct uart_softc *sc) +{ + uint8_t intr_reason; + + intr_reason = uart_intr_reason(sc); + + if (intr_reason == IIR_NOPEND) + (*sc->intr_deassert)(sc->arg); + else + (*sc->intr_assert)(sc->arg); +} + +static void +uart_drain(int fd, enum ev_type ev, void *arg) +{ + struct uart_softc *sc; + int ch; + + sc = arg; + + assert(fd == sc->tty.fd); + assert(ev == EVF_READ); + + /* + * This routine is called in the context of the mevent thread + * to take out the softc lock to protect against concurrent + * access from a vCPU i/o exit + */ + pthread_mutex_lock(&sc->mtx); + + if ((sc->mcr & MCR_LOOPBACK) != 0) { + (void) ttyread(&sc->tty); + } else { + while (rxfifo_available(sc) && + ((ch = ttyread(&sc->tty)) != -1)) { + rxfifo_putchar(sc, ch); + } + uart_toggle_intr(sc); + } + + pthread_mutex_unlock(&sc->mtx); +} + +void +uart_write(struct uart_softc *sc, int offset, uint8_t value) +{ + int fifosz; + uint8_t msr; + + pthread_mutex_lock(&sc->mtx); + + /* + * Take care of the special case DLAB accesses first + */ + if ((sc->lcr & LCR_DLAB) != 0) { + if (offset == REG_DLL) { + sc->dll = value; + goto done; + } + + if (offset == REG_DLH) { + sc->dlh = value; + goto done; + } + } + + switch (offset) { + case REG_DATA: + if (sc->mcr & MCR_LOOPBACK) { + if (rxfifo_putchar(sc, value) != 0) + sc->lsr |= LSR_OE; + } else if (sc->tty.opened) { + ttywrite(&sc->tty, value); +#ifndef __FreeBSD__ + } else if (sc->sock) { + sockwrite(sc, value); +#endif + } /* else drop on floor */ + sc->thre_int_pending = true; + break; + case REG_IER: +#ifndef __FreeBSD__ + /* + * Assert an interrupt if re-enabling the THRE intr, since we + * always report THRE as active in the status register. + */ + if ((sc->ier & IER_ETXRDY) == 0 && + (value & IER_ETXRDY) != 0) { + sc->thre_int_pending = true; + } +#endif + /* + * Apply mask so that bits 4-7 are 0 + * Also enables bits 0-3 only if they're 1 + */ + sc->ier = value & 0x0F; + break; + case REG_FCR: + /* + * When moving from FIFO and 16450 mode and vice versa, + * the FIFO contents are reset. + */ + if ((sc->fcr & FCR_ENABLE) ^ (value & FCR_ENABLE)) { + fifosz = (value & FCR_ENABLE) ? FIFOSZ : 1; + rxfifo_reset(sc, fifosz); + } + + /* + * The FCR_ENABLE bit must be '1' for the programming + * of other FCR bits to be effective. + */ + if ((value & FCR_ENABLE) == 0) { + sc->fcr = 0; + } else { + if ((value & FCR_RCV_RST) != 0) + rxfifo_reset(sc, FIFOSZ); + + sc->fcr = value & + (FCR_ENABLE | FCR_DMA | FCR_RX_MASK); + } + break; + case REG_LCR: + sc->lcr = value; + break; + case REG_MCR: + /* Apply mask so that bits 5-7 are 0 */ + sc->mcr = value & 0x1F; + msr = modem_status(sc->mcr); + + /* + * Detect if there has been any change between the + * previous and the new value of MSR. If there is + * then assert the appropriate MSR delta bit. + */ + if ((msr & MSR_CTS) ^ (sc->msr & MSR_CTS)) + sc->msr |= MSR_DCTS; + if ((msr & MSR_DSR) ^ (sc->msr & MSR_DSR)) + sc->msr |= MSR_DDSR; + if ((msr & MSR_DCD) ^ (sc->msr & MSR_DCD)) + sc->msr |= MSR_DDCD; + if ((sc->msr & MSR_RI) != 0 && (msr & MSR_RI) == 0) + sc->msr |= MSR_TERI; + + /* + * Update the value of MSR while retaining the delta + * bits. + */ + sc->msr &= MSR_DELTA_MASK; + sc->msr |= msr; + break; + case REG_LSR: + /* + * Line status register is not meant to be written to + * during normal operation. + */ + break; + case REG_MSR: + /* + * As far as I can tell MSR is a read-only register. + */ + break; + case REG_SCR: + sc->scr = value; + break; + default: + break; + } + +done: + uart_toggle_intr(sc); + pthread_mutex_unlock(&sc->mtx); +} + +uint8_t +uart_read(struct uart_softc *sc, int offset) +{ + uint8_t iir, intr_reason, reg; + + pthread_mutex_lock(&sc->mtx); + + /* + * Take care of the special case DLAB accesses first + */ + if ((sc->lcr & LCR_DLAB) != 0) { + if (offset == REG_DLL) { + reg = sc->dll; + goto done; + } + + if (offset == REG_DLH) { + reg = sc->dlh; + goto done; + } + } + + switch (offset) { + case REG_DATA: + reg = rxfifo_getchar(sc); + break; + case REG_IER: + reg = sc->ier; + break; + case REG_IIR: + iir = (sc->fcr & FCR_ENABLE) ? IIR_FIFO_MASK : 0; + + intr_reason = uart_intr_reason(sc); + + /* + * Deal with side effects of reading the IIR register + */ + if (intr_reason == IIR_TXRDY) + sc->thre_int_pending = false; + + iir |= intr_reason; + + reg = iir; + break; + case REG_LCR: + reg = sc->lcr; + break; + case REG_MCR: + reg = sc->mcr; + break; + case REG_LSR: + /* Transmitter is always ready for more data */ + sc->lsr |= LSR_TEMT | LSR_THRE; + + /* Check for new receive data */ + if (rxfifo_numchars(sc) > 0) + sc->lsr |= LSR_RXRDY; + else + sc->lsr &= ~LSR_RXRDY; + + reg = sc->lsr; + + /* The LSR_OE bit is cleared on LSR read */ + sc->lsr &= ~LSR_OE; + break; + case REG_MSR: + /* + * MSR delta bits are cleared on read + */ + reg = sc->msr; + sc->msr &= ~MSR_DELTA_MASK; + break; + case REG_SCR: + reg = sc->scr; + break; + default: + reg = 0xFF; + break; + } + +done: + uart_toggle_intr(sc); + pthread_mutex_unlock(&sc->mtx); + + return (reg); +} + +#ifndef __FreeBSD__ +static void +uart_sock_drain(int fd, enum ev_type ev, void *arg) +{ + struct uart_softc *sc = arg; + char ch; + + /* + * Take the softc lock to protect against concurrent + * access from a vCPU i/o exit + */ + pthread_mutex_lock(&sc->mtx); + + if ((sc->mcr & MCR_LOOPBACK) != 0) { + (void) read(sc->usc_sock.clifd, &ch, 1); + } else { + bool err_close = false; + + while (rxfifo_available(sc)) { + int res; + + res = read(sc->usc_sock.clifd, &ch, 1); + if (res == 0) { + err_close = true; + break; + } else if (res == -1) { + if (errno != EAGAIN && errno != EINTR) { + err_close = true; + } + break; + } + + rxfifo_putchar(sc, ch); + } + uart_toggle_intr(sc); + + if (err_close) { + (void) fprintf(stderr, "uart: closing client conn\n"); + (void) shutdown(sc->usc_sock.clifd, SHUT_RDWR); + mevent_delete_close(sc->mev); + sc->mev = NULL; + sc->usc_sock.clifd = -1; + } + } + + pthread_mutex_unlock(&sc->mtx); +} + +static void +uart_sock_accept(int fd, enum ev_type ev, void *arg) +{ + struct uart_softc *sc = arg; + int connfd; + + connfd = accept(sc->usc_sock.servfd, NULL, NULL); + if (connfd == -1) { + return; + } + + /* + * Do client connection management under protection of the softc lock + * to avoid racing with concurrent UART events. + */ + pthread_mutex_lock(&sc->mtx); + + if (sc->usc_sock.clifd != -1) { + /* we're already handling a client */ + (void) fprintf(stderr, "uart: unexpected client conn\n"); + (void) shutdown(connfd, SHUT_RDWR); + (void) close(connfd); + } else { + if (fcntl(connfd, F_SETFL, O_NONBLOCK) < 0) { + perror("uart: fcntl(O_NONBLOCK)"); + (void) shutdown(connfd, SHUT_RDWR); + (void) close(connfd); + } else { + sc->usc_sock.clifd = connfd; + sc->mev = mevent_add(sc->usc_sock.clifd, EVF_READ, + uart_sock_drain, sc); + } + } + + pthread_mutex_unlock(&sc->mtx); +} + +static int +init_sock(const char *path) +{ + int servfd; + struct sockaddr_un servaddr; + + bzero(&servaddr, sizeof (servaddr)); + servaddr.sun_family = AF_UNIX; + + if (strlcpy(servaddr.sun_path, path, sizeof (servaddr.sun_path)) >= + sizeof (servaddr.sun_path)) { + (void) fprintf(stderr, "uart: path '%s' too long\n", + path); + return (-1); + } + + if ((servfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + (void) fprintf(stderr, "uart: socket() error - %s\n", + strerror(errno)); + return (-1); + } + (void) unlink(servaddr.sun_path); + + if (bind(servfd, (struct sockaddr *)&servaddr, + sizeof (servaddr)) == -1) { + (void) fprintf(stderr, "uart: bind() error - %s\n", + strerror(errno)); + goto out; + } + + if (listen(servfd, 1) == -1) { + (void) fprintf(stderr, "uart: listen() error - %s\n", + strerror(errno)); + goto out; + } + return (servfd); + +out: + (void) unlink(servaddr.sun_path); + (void) close(servfd); + return (-1); +} +#endif /* not __FreeBSD__ */ + +int +uart_legacy_alloc(int which, int *baseaddr, int *irq) +{ + + if (which < 0 || which >= UART_NLDEVS || uart_lres[which].inuse) + return (-1); + + uart_lres[which].inuse = true; + *baseaddr = uart_lres[which].baseaddr; + *irq = uart_lres[which].irq; + + return (0); +} + +struct uart_softc * +uart_init(uart_intr_func_t intr_assert, uart_intr_func_t intr_deassert, + void *arg) +{ + struct uart_softc *sc; + + sc = calloc(1, sizeof(struct uart_softc)); + + sc->arg = arg; + sc->intr_assert = intr_assert; + sc->intr_deassert = intr_deassert; + + pthread_mutex_init(&sc->mtx, NULL); + + uart_reset(sc); + + return (sc); +} + +static int +uart_tty_backend(struct uart_softc *sc, const char *opts) +{ + int fd; + int retval; + + retval = -1; + + fd = open(opts, O_RDWR | O_NONBLOCK); + if (fd > 0 && isatty(fd)) { + sc->tty.fd = fd; + sc->tty.opened = true; + retval = 0; + } + + return (retval); +} + +#ifndef __FreeBSD__ +static int +uart_sock_backend(struct uart_softc *sc, const char *inopts) +{ + char *opts; + char *opt; + char *nextopt; + char *path = NULL; + + if (strncmp(inopts, "socket,", 7) != 0) { + return (-1); + } + if ((opts = strdup(inopts + 7)) == NULL) { + return (-1); + } + + nextopt = opts; + for (opt = strsep(&nextopt, ","); opt != NULL; + opt = strsep(&nextopt, ",")) { + if (path == NULL && *opt == '/') { + path = opt; + continue; + } + /* + * XXX check for server and client options here. For now, + * everything is a server + */ + free(opts); + return (-1); + } + + sc->usc_sock.clifd = -1; + if ((sc->usc_sock.servfd = init_sock(path)) == -1) { + free(opts); + return (-1); + } + sc->sock = true; + sc->tty.fd = -1; + sc->usc_sock.servmev = mevent_add(sc->usc_sock.servfd, EVF_READ, + uart_sock_accept, sc); + assert(sc->usc_sock.servmev != NULL); + + return (0); +} +#endif /* not __FreeBSD__ */ + +int +uart_set_backend(struct uart_softc *sc, const char *opts) +{ + int retval; +#ifndef WITHOUT_CAPSICUM + cap_rights_t rights; + cap_ioctl_t cmds[] = { TIOCGETA, TIOCSETA, TIOCGWINSZ }; +#endif + + retval = -1; + + if (opts == NULL) + return (0); + + if (strcmp("stdio", opts) == 0) { + if (!uart_stdio) { + sc->tty.fd = STDIN_FILENO; + sc->tty.opened = true; + uart_stdio = true; + retval = 0; + } +#ifndef __FreeBSD__ + } else if (strncmp("socket,", opts, 7) == 0) { + return (uart_sock_backend(sc, opts)); +#endif + } else if (uart_tty_backend(sc, opts) == 0) { + retval = 0; + } + + /* Make the backend file descriptor non-blocking */ + if (retval == 0 && sc->tty.fd != -1) + retval = fcntl(sc->tty.fd, F_SETFL, O_NONBLOCK); + + if (retval == 0) { +#ifndef WITHOUT_CAPSICUM + cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, + CAP_WRITE); + if (caph_rights_limit(sc->tty.fd, &rights) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (caph_ioctls_limit(sc->tty.fd, cmds, nitems(cmds)) == -1) + errx(EX_OSERR, "Unable to apply rights for sandbox"); + if (!uart_stdio) { + if (caph_limit_stdin() == -1) + errx(EX_OSERR, + "Unable to apply rights for sandbox"); + } +#endif + uart_opentty(sc); + } + + return (retval); +} diff --git a/usr/src/cmd/bhyve/uart_emul.h b/usr/src/cmd/bhyve/uart_emul.h new file mode 100644 index 0000000000..a87202df1f --- /dev/null +++ b/usr/src/cmd/bhyve/uart_emul.h @@ -0,0 +1,47 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Neel Natu <neel@freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _UART_EMUL_H_ +#define _UART_EMUL_H_ + + +#define UART_IO_BAR_SIZE 8 + +struct uart_softc; + +typedef void (*uart_intr_func_t)(void *arg); +struct uart_softc *uart_init(uart_intr_func_t intr_assert, + uart_intr_func_t intr_deassert, void *arg); + +int uart_legacy_alloc(int unit, int *ioaddr, int *irq); +uint8_t uart_read(struct uart_softc *sc, int offset); +void uart_write(struct uart_softc *sc, int offset, uint8_t value); +int uart_set_backend(struct uart_softc *sc, const char *opt); +#endif diff --git a/usr/src/cmd/bhyve/usb_emul.c b/usr/src/cmd/bhyve/usb_emul.c new file mode 100644 index 0000000000..6ecdd9530e --- /dev/null +++ b/usr/src/cmd/bhyve/usb_emul.c @@ -0,0 +1,78 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Nahanni Systems Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/queue.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pthread.h> + +#include "usb_emul.h" + +SET_DECLARE(usb_emu_set, struct usb_devemu); + +struct usb_devemu * +usb_emu_finddev(char *name) +{ + struct usb_devemu **udpp, *udp; + + SET_FOREACH(udpp, usb_emu_set) { + udp = *udpp; + if (!strcmp(udp->ue_emu, name)) + return (udp); + } + + return (NULL); +} + +struct usb_data_xfer_block * +usb_data_xfer_append(struct usb_data_xfer *xfer, void *buf, int blen, + void *hci_data, int ccs) +{ + struct usb_data_xfer_block *xb; + + if (xfer->ndata >= USB_MAX_XFER_BLOCKS) + return (NULL); + + xb = &xfer->data[xfer->tail]; + xb->buf = buf; + xb->blen = blen; + xb->hci_data = hci_data; + xb->ccs = ccs; + xb->processed = 0; + xb->bdone = 0; + xfer->ndata++; + xfer->tail = (xfer->tail + 1) % USB_MAX_XFER_BLOCKS; + return (xb); +} diff --git a/usr/src/cmd/bhyve/usb_emul.h b/usr/src/cmd/bhyve/usb_emul.h new file mode 100644 index 0000000000..e55a421b6f --- /dev/null +++ b/usr/src/cmd/bhyve/usb_emul.h @@ -0,0 +1,164 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Leon Dang <ldang@nahannisys.com> + * Copyright 2018 Joyent, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _USB_EMUL_H_ +#define _USB_EMUL_H_ + +#include <stdlib.h> +#include <sys/linker_set.h> +#include <pthread.h> +#ifndef __FreeBSD__ +#include <synch.h> +#endif + +#define USB_MAX_XFER_BLOCKS 8 + +#define USB_XFER_OUT 0 +#define USB_XFER_IN 1 + + + +struct usb_hci; +struct usb_device_request; +struct usb_data_xfer; + +/* Device emulation handlers */ +struct usb_devemu { + char *ue_emu; /* name of device emulation */ + int ue_usbver; /* usb version: 2 or 3 */ + int ue_usbspeed; /* usb device speed */ + + /* instance creation */ + void *(*ue_init)(struct usb_hci *hci, char *opt); + + /* handlers */ + int (*ue_request)(void *sc, struct usb_data_xfer *xfer); + int (*ue_data)(void *sc, struct usb_data_xfer *xfer, int dir, + int epctx); + int (*ue_reset)(void *sc); + int (*ue_remove)(void *sc); + int (*ue_stop)(void *sc); +}; +#define USB_EMUL_SET(x) DATA_SET(usb_emu_set, x); + +/* + * USB device events to notify HCI when state changes + */ +enum hci_usbev { + USBDEV_ATTACH, + USBDEV_RESET, + USBDEV_STOP, + USBDEV_REMOVE, +}; + +/* usb controller, ie xhci, ehci */ +struct usb_hci { + int (*hci_intr)(struct usb_hci *hci, int epctx); + int (*hci_event)(struct usb_hci *hci, enum hci_usbev evid, + void *param); + void *hci_sc; /* private softc for hci */ + + /* controller managed fields */ + int hci_address; + int hci_port; +}; + +/* + * Each xfer block is mapped to the hci transfer block. + * On input into the device handler, blen is set to the lenght of buf. + * The device handler is to update blen to reflect on the residual size + * of the buffer, i.e. len(buf) - len(consumed). + */ +struct usb_data_xfer_block { + void *buf; /* IN or OUT pointer */ + int blen; /* in:len(buf), out:len(remaining) */ + int bdone; /* bytes transferred */ + uint32_t processed; /* device processed this + errcode */ + void *hci_data; /* HCI private reference */ + int ccs; + uint32_t streamid; + uint64_t trbnext; /* next TRB guest address */ +}; + +struct usb_data_xfer { + struct usb_data_xfer_block data[USB_MAX_XFER_BLOCKS]; + struct usb_device_request *ureq; /* setup ctl request */ + int ndata; /* # of data items */ + int head; + int tail; + pthread_mutex_t mtx; +}; + +enum USB_ERRCODE { + USB_ACK, + USB_NAK, + USB_STALL, + USB_NYET, + USB_ERR, + USB_SHORT +}; + +#define USB_DATA_GET_ERRCODE(x) (x)->processed >> 8 +#define USB_DATA_SET_ERRCODE(x,e) do { \ + (x)->processed = ((x)->processed & 0xFF) | (e << 8); \ + } while (0) + +#define USB_DATA_OK(x,i) ((x)->data[(i)].buf != NULL) + +#define USB_DATA_XFER_INIT(x) do { \ + memset((x), 0, sizeof(*(x))); \ + pthread_mutex_init(&((x)->mtx), NULL); \ + } while (0) + +#define USB_DATA_XFER_RESET(x) do { \ + memset((x)->data, 0, sizeof((x)->data)); \ + (x)->ndata = 0; \ + (x)->head = (x)->tail = 0; \ + } while (0) + +#define USB_DATA_XFER_LOCK(x) do { \ + pthread_mutex_lock(&((x)->mtx)); \ + } while (0) + +#define USB_DATA_XFER_UNLOCK(x) do { \ + pthread_mutex_unlock(&((x)->mtx)); \ + } while (0) +#ifndef __FreeBSD__ +#define USB_DATA_XFER_LOCK_HELD(x) MUTEX_HELD(&((x)->mtx)) +#endif + +struct usb_devemu *usb_emu_finddev(char *name); + +struct usb_data_xfer_block *usb_data_xfer_append(struct usb_data_xfer *xfer, + void *buf, int blen, void *hci_data, int ccs); + + +#endif /* _USB_EMUL_H_ */ diff --git a/usr/src/cmd/bhyve/usb_mouse.c b/usr/src/cmd/bhyve/usb_mouse.c new file mode 100644 index 0000000000..e613012071 --- /dev/null +++ b/usr/src/cmd/bhyve/usb_mouse.c @@ -0,0 +1,802 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2014 Leon Dang <ldang@nahannisys.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/time.h> + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <dev/usb/usb.h> +#include <dev/usb/usbdi.h> + +#include "usb_emul.h" +#include "console.h" +#include "bhyvegc.h" + +static int umouse_debug = 0; +#define DPRINTF(params) if (umouse_debug) printf params +#define WPRINTF(params) printf params + +/* USB endpoint context (1-15) for reporting mouse data events*/ +#define UMOUSE_INTR_ENDPT 1 + +#define UMOUSE_REPORT_DESC_TYPE 0x22 + +#define UMOUSE_GET_REPORT 0x01 +#define UMOUSE_GET_IDLE 0x02 +#define UMOUSE_GET_PROTOCOL 0x03 +#define UMOUSE_SET_REPORT 0x09 +#define UMOUSE_SET_IDLE 0x0A +#define UMOUSE_SET_PROTOCOL 0x0B + +#define HSETW(ptr, val) ptr = { (uint8_t)(val), (uint8_t)((val) >> 8) } + +enum { + UMSTR_LANG, + UMSTR_MANUFACTURER, + UMSTR_PRODUCT, + UMSTR_SERIAL, + UMSTR_CONFIG, + UMSTR_MAX +}; + +static const char *umouse_desc_strings[] = { + "\x04\x09", + "BHYVE", + "HID Tablet", + "01", + "HID Tablet Device", +}; + +struct umouse_hid_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bcdHID[2]; + uint8_t bCountryCode; + uint8_t bNumDescriptors; + uint8_t bReportDescriptorType; + uint8_t wItemLength[2]; +} __packed; + +struct umouse_config_desc { + struct usb_config_descriptor confd; + struct usb_interface_descriptor ifcd; + struct umouse_hid_descriptor hidd; + struct usb_endpoint_descriptor endpd; + struct usb_endpoint_ss_comp_descriptor sscompd; +} __packed; + +#define MOUSE_MAX_X 0x8000 +#define MOUSE_MAX_Y 0x8000 + +static const uint8_t umouse_report_desc[] = { + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x02, /* USAGE (Mouse) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x09, 0x01, /* USAGE (Pointer) */ + 0xa1, 0x00, /* COLLECTION (Physical) */ + 0x05, 0x09, /* USAGE_PAGE (Button) */ + 0x19, 0x01, /* USAGE_MINIMUM (Button 1) */ + 0x29, 0x03, /* USAGE_MAXIMUM (Button 3) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x95, 0x03, /* REPORT_COUNT (3) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs); 3 buttons */ + 0x75, 0x05, /* REPORT_SIZE (5) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x81, 0x03, /* INPUT (Cnst,Var,Abs); padding */ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x30, /* USAGE (X) */ + 0x09, 0x31, /* USAGE (Y) */ + 0x35, 0x00, /* PHYSICAL_MINIMUM (0) */ + 0x46, 0xff, 0x7f, /* PHYSICAL_MAXIMUM (0x7fff) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x26, 0xff, 0x7f, /* LOGICAL_MAXIMUM (0x7fff) */ + 0x75, 0x10, /* REPORT_SIZE (16) */ + 0x95, 0x02, /* REPORT_COUNT (2) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0x05, 0x01, /* USAGE Page (Generic Desktop) */ + 0x09, 0x38, /* USAGE (Wheel) */ + 0x35, 0x00, /* PHYSICAL_MINIMUM (0) */ + 0x45, 0x00, /* PHYSICAL_MAXIMUM (0) */ + 0x15, 0x81, /* LOGICAL_MINIMUM (-127) */ + 0x25, 0x7f, /* LOGICAL_MAXIMUM (127) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x81, 0x06, /* INPUT (Data,Var,Rel) */ + 0xc0, /* END_COLLECTION */ + 0xc0 /* END_COLLECTION */ +}; + +struct umouse_report { + uint8_t buttons; /* bits: 0 left, 1 right, 2 middle */ + int16_t x; /* x position */ + int16_t y; /* y position */ + int8_t z; /* z wheel position */ +} __packed; + + +#define MSETW(ptr, val) ptr = { (uint8_t)(val), (uint8_t)((val) >> 8) } + +static struct usb_device_descriptor umouse_dev_desc = { + .bLength = sizeof(umouse_dev_desc), + .bDescriptorType = UDESC_DEVICE, + MSETW(.bcdUSB, UD_USB_3_0), + .bMaxPacketSize = 8, /* max packet size */ + MSETW(.idVendor, 0xFB5D), /* vendor */ + MSETW(.idProduct, 0x0001), /* product */ + MSETW(.bcdDevice, 0), /* device version */ + .iManufacturer = UMSTR_MANUFACTURER, + .iProduct = UMSTR_PRODUCT, + .iSerialNumber = UMSTR_SERIAL, + .bNumConfigurations = 1, +}; + +static struct umouse_config_desc umouse_confd = { + .confd = { + .bLength = sizeof(umouse_confd.confd), + .bDescriptorType = UDESC_CONFIG, + .wTotalLength[0] = sizeof(umouse_confd), + .bNumInterface = 1, + .bConfigurationValue = 1, + .iConfiguration = UMSTR_CONFIG, + .bmAttributes = UC_BUS_POWERED | UC_REMOTE_WAKEUP, + .bMaxPower = 0, + }, + .ifcd = { + .bLength = sizeof(umouse_confd.ifcd), + .bDescriptorType = UDESC_INTERFACE, + .bNumEndpoints = 1, + .bInterfaceClass = UICLASS_HID, + .bInterfaceSubClass = UISUBCLASS_BOOT, + .bInterfaceProtocol = UIPROTO_MOUSE, + }, + .hidd = { + .bLength = sizeof(umouse_confd.hidd), + .bDescriptorType = 0x21, + .bcdHID = { 0x01, 0x10 }, + .bCountryCode = 0, + .bNumDescriptors = 1, + .bReportDescriptorType = UMOUSE_REPORT_DESC_TYPE, + .wItemLength = { sizeof(umouse_report_desc), 0 }, + }, + .endpd = { + .bLength = sizeof(umouse_confd.endpd), + .bDescriptorType = UDESC_ENDPOINT, + .bEndpointAddress = UE_DIR_IN | UMOUSE_INTR_ENDPT, + .bmAttributes = UE_INTERRUPT, + .wMaxPacketSize[0] = 8, + .bInterval = 0xA, + }, + .sscompd = { + .bLength = sizeof(umouse_confd.sscompd), + .bDescriptorType = UDESC_ENDPOINT_SS_COMP, + .bMaxBurst = 0, + .bmAttributes = 0, + MSETW(.wBytesPerInterval, 0), + }, +}; + + +struct umouse_bos_desc { + struct usb_bos_descriptor bosd; + struct usb_devcap_ss_descriptor usbssd; +} __packed; + + +struct umouse_bos_desc umouse_bosd = { + .bosd = { + .bLength = sizeof(umouse_bosd.bosd), + .bDescriptorType = UDESC_BOS, + HSETW(.wTotalLength, sizeof(umouse_bosd)), + .bNumDeviceCaps = 1, + }, + .usbssd = { + .bLength = sizeof(umouse_bosd.usbssd), + .bDescriptorType = UDESC_DEVICE_CAPABILITY, + .bDevCapabilityType = 3, + .bmAttributes = 0, + HSETW(.wSpeedsSupported, 0x08), + .bFunctionalitySupport = 3, + .bU1DevExitLat = 0xa, /* dummy - not used */ + .wU2DevExitLat = { 0x20, 0x00 }, + } +}; + + +struct umouse_softc { + struct usb_hci *hci; + + char *opt; + + struct umouse_report um_report; + int newdata; + struct { + uint8_t idle; + uint8_t protocol; + uint8_t feature; + } hid; + + pthread_mutex_t mtx; + pthread_mutex_t ev_mtx; + int polling; + struct timeval prev_evt; +}; + +static void +umouse_event(uint8_t button, int x, int y, void *arg) +{ + struct umouse_softc *sc; + struct bhyvegc_image *gc; + + gc = console_get_image(); + if (gc == NULL) { + /* not ready */ + return; + } + + sc = arg; + + pthread_mutex_lock(&sc->mtx); + + sc->um_report.buttons = 0; + sc->um_report.z = 0; + + if (button & 0x01) + sc->um_report.buttons |= 0x01; /* left */ + if (button & 0x02) + sc->um_report.buttons |= 0x04; /* middle */ + if (button & 0x04) + sc->um_report.buttons |= 0x02; /* right */ + if (button & 0x8) + sc->um_report.z = 1; + if (button & 0x10) + sc->um_report.z = -1; + + /* scale coords to mouse resolution */ + sc->um_report.x = MOUSE_MAX_X * x / gc->width; + sc->um_report.y = MOUSE_MAX_Y * y / gc->height; + sc->newdata = 1; + pthread_mutex_unlock(&sc->mtx); + + pthread_mutex_lock(&sc->ev_mtx); + sc->hci->hci_intr(sc->hci, UE_DIR_IN | UMOUSE_INTR_ENDPT); + pthread_mutex_unlock(&sc->ev_mtx); +} + +static void * +umouse_init(struct usb_hci *hci, char *opt) +{ + struct umouse_softc *sc; + + sc = calloc(1, sizeof(struct umouse_softc)); + sc->hci = hci; + + sc->hid.protocol = 1; /* REPORT protocol */ + sc->opt = strdup(opt); + pthread_mutex_init(&sc->mtx, NULL); + pthread_mutex_init(&sc->ev_mtx, NULL); + + console_ptr_register(umouse_event, sc, 10); + + return (sc); +} + +#define UREQ(x,y) ((x) | ((y) << 8)) + +static int +umouse_request(void *scarg, struct usb_data_xfer *xfer) +{ + struct umouse_softc *sc; + struct usb_data_xfer_block *data; + const char *str; + uint16_t value; + uint16_t index; + uint16_t len; + uint16_t slen; + uint8_t *udata; + int err; + int i, idx; + int eshort; + + sc = scarg; + + data = NULL; + udata = NULL; + idx = xfer->head; + for (i = 0; i < xfer->ndata; i++) { + xfer->data[idx].bdone = 0; + if (data == NULL && USB_DATA_OK(xfer,i)) { + data = &xfer->data[idx]; + udata = data->buf; + } + + xfer->data[idx].processed = 1; + idx = (idx + 1) % USB_MAX_XFER_BLOCKS; + } + + err = USB_ERR_NORMAL_COMPLETION; + eshort = 0; + + if (!xfer->ureq) { + DPRINTF(("umouse_request: port %d\r\n", sc->hci->hci_port)); + goto done; + } + + value = UGETW(xfer->ureq->wValue); + index = UGETW(xfer->ureq->wIndex); + len = UGETW(xfer->ureq->wLength); + + DPRINTF(("umouse_request: port %d, type 0x%x, req 0x%x, val 0x%x, " + "idx 0x%x, len %u\r\n", + sc->hci->hci_port, xfer->ureq->bmRequestType, + xfer->ureq->bRequest, value, index, len)); + + switch (UREQ(xfer->ureq->bRequest, xfer->ureq->bmRequestType)) { + case UREQ(UR_GET_CONFIG, UT_READ_DEVICE): + DPRINTF(("umouse: (UR_GET_CONFIG, UT_READ_DEVICE)\r\n")); + if (!data) + break; + + *udata = umouse_confd.confd.bConfigurationValue; + data->blen = len > 0 ? len - 1 : 0; + eshort = data->blen > 0; + data->bdone += 1; + break; + + case UREQ(UR_GET_DESCRIPTOR, UT_READ_DEVICE): + DPRINTF(("umouse: (UR_GET_DESCRIPTOR, UT_READ_DEVICE) val %x\r\n", + value >> 8)); + if (!data) + break; + + switch (value >> 8) { + case UDESC_DEVICE: + DPRINTF(("umouse: (->UDESC_DEVICE) len %u ?= " + "sizeof(umouse_dev_desc) %lu\r\n", + len, sizeof(umouse_dev_desc))); + if ((value & 0xFF) != 0) { + err = USB_ERR_IOERROR; + goto done; + } + if (len > sizeof(umouse_dev_desc)) { + data->blen = len - sizeof(umouse_dev_desc); + len = sizeof(umouse_dev_desc); + } else + data->blen = 0; + memcpy(data->buf, &umouse_dev_desc, len); + data->bdone += len; + break; + + case UDESC_CONFIG: + DPRINTF(("umouse: (->UDESC_CONFIG)\r\n")); + if ((value & 0xFF) != 0) { + err = USB_ERR_IOERROR; + goto done; + } + if (len > sizeof(umouse_confd)) { + data->blen = len - sizeof(umouse_confd); + len = sizeof(umouse_confd); + } else + data->blen = 0; + + memcpy(data->buf, &umouse_confd, len); + data->bdone += len; + break; + + case UDESC_STRING: + DPRINTF(("umouse: (->UDESC_STRING)\r\n")); + str = NULL; + if ((value & 0xFF) < UMSTR_MAX) + str = umouse_desc_strings[value & 0xFF]; + else + goto done; + + if ((value & 0xFF) == UMSTR_LANG) { + udata[0] = 4; + udata[1] = UDESC_STRING; + data->blen = len - 2; + len -= 2; + data->bdone += 2; + + if (len >= 2) { + udata[2] = str[0]; + udata[3] = str[1]; + data->blen -= 2; + data->bdone += 2; + } else + data->blen = 0; + + goto done; + } + + slen = 2 + strlen(str) * 2; + udata[0] = slen; + udata[1] = UDESC_STRING; + + if (len > slen) { + data->blen = len - slen; + len = slen; + } else + data->blen = 0; + for (i = 2; i < len; i += 2) { + udata[i] = *str++; + udata[i+1] = '\0'; + } + data->bdone += slen; + + break; + + case UDESC_BOS: + DPRINTF(("umouse: USB3 BOS\r\n")); + if (len > sizeof(umouse_bosd)) { + data->blen = len - sizeof(umouse_bosd); + len = sizeof(umouse_bosd); + } else + data->blen = 0; + memcpy(udata, &umouse_bosd, len); + data->bdone += len; + break; + + default: + DPRINTF(("umouse: unknown(%d)->ERROR\r\n", value >> 8)); + err = USB_ERR_IOERROR; + goto done; + } + eshort = data->blen > 0; + break; + + case UREQ(UR_GET_DESCRIPTOR, UT_READ_INTERFACE): + DPRINTF(("umouse: (UR_GET_DESCRIPTOR, UT_READ_INTERFACE) " + "0x%x\r\n", (value >> 8))); + if (!data) + break; + + switch (value >> 8) { + case UMOUSE_REPORT_DESC_TYPE: + if (len > sizeof(umouse_report_desc)) { + data->blen = len - sizeof(umouse_report_desc); + len = sizeof(umouse_report_desc); + } else + data->blen = 0; + memcpy(data->buf, umouse_report_desc, len); + data->bdone += len; + break; + default: + DPRINTF(("umouse: IO ERROR\r\n")); + err = USB_ERR_IOERROR; + goto done; + } + eshort = data->blen > 0; + break; + + case UREQ(UR_GET_INTERFACE, UT_READ_INTERFACE): + DPRINTF(("umouse: (UR_GET_INTERFACE, UT_READ_INTERFACE)\r\n")); + if (index != 0) { + DPRINTF(("umouse get_interface, invalid index %d\r\n", + index)); + err = USB_ERR_IOERROR; + goto done; + } + + if (!data) + break; + + if (len > 0) { + *udata = 0; + data->blen = len - 1; + } + eshort = data->blen > 0; + data->bdone += 1; + break; + + case UREQ(UR_GET_STATUS, UT_READ_DEVICE): + DPRINTF(("umouse: (UR_GET_STATUS, UT_READ_DEVICE)\r\n")); + if (data != NULL && len > 1) { + if (sc->hid.feature == UF_DEVICE_REMOTE_WAKEUP) + USETW(udata, UDS_REMOTE_WAKEUP); + else + USETW(udata, 0); + data->blen = len - 2; + data->bdone += 2; + } + + eshort = data->blen > 0; + break; + + case UREQ(UR_GET_STATUS, UT_READ_INTERFACE): + case UREQ(UR_GET_STATUS, UT_READ_ENDPOINT): + DPRINTF(("umouse: (UR_GET_STATUS, UT_READ_INTERFACE)\r\n")); + if (data != NULL && len > 1) { + USETW(udata, 0); + data->blen = len - 2; + data->bdone += 2; + } + eshort = data->blen > 0; + break; + + case UREQ(UR_SET_ADDRESS, UT_WRITE_DEVICE): + /* XXX Controller should've handled this */ + DPRINTF(("umouse set address %u\r\n", value)); + break; + + case UREQ(UR_SET_CONFIG, UT_WRITE_DEVICE): + DPRINTF(("umouse set config %u\r\n", value)); + break; + + case UREQ(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): + DPRINTF(("umouse set descriptor %u\r\n", value)); + break; + + + case UREQ(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): + DPRINTF(("umouse: (UR_SET_FEATURE, UT_WRITE_DEVICE) %x\r\n", value)); + if (value == UF_DEVICE_REMOTE_WAKEUP) + sc->hid.feature = 0; + break; + + case UREQ(UR_SET_FEATURE, UT_WRITE_DEVICE): + DPRINTF(("umouse: (UR_SET_FEATURE, UT_WRITE_DEVICE) %x\r\n", value)); + if (value == UF_DEVICE_REMOTE_WAKEUP) + sc->hid.feature = UF_DEVICE_REMOTE_WAKEUP; + break; + + case UREQ(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): + case UREQ(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): + case UREQ(UR_SET_FEATURE, UT_WRITE_INTERFACE): + case UREQ(UR_SET_FEATURE, UT_WRITE_ENDPOINT): + DPRINTF(("umouse: (UR_CLEAR_FEATURE, UT_WRITE_INTERFACE)\r\n")); + err = USB_ERR_IOERROR; + goto done; + + case UREQ(UR_SET_INTERFACE, UT_WRITE_INTERFACE): + DPRINTF(("umouse set interface %u\r\n", value)); + break; + + case UREQ(UR_ISOCH_DELAY, UT_WRITE_DEVICE): + DPRINTF(("umouse set isoch delay %u\r\n", value)); + break; + + case UREQ(UR_SET_SEL, 0): + DPRINTF(("umouse set sel\r\n")); + break; + + case UREQ(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): + DPRINTF(("umouse synch frame\r\n")); + break; + + /* HID device requests */ + + case UREQ(UMOUSE_GET_REPORT, UT_READ_CLASS_INTERFACE): + DPRINTF(("umouse: (UMOUSE_GET_REPORT, UT_READ_CLASS_INTERFACE) " + "0x%x\r\n", (value >> 8))); + if (!data) + break; + + if ((value >> 8) == 0x01 && len >= sizeof(sc->um_report)) { + /* TODO read from backend */ + + if (len > sizeof(sc->um_report)) { + data->blen = len - sizeof(sc->um_report); + len = sizeof(sc->um_report); + } else + data->blen = 0; + + memcpy(data->buf, &sc->um_report, len); + data->bdone += len; + } else { + err = USB_ERR_IOERROR; + goto done; + } + eshort = data->blen > 0; + break; + + case UREQ(UMOUSE_GET_IDLE, UT_READ_CLASS_INTERFACE): + if (data != NULL && len > 0) { + *udata = sc->hid.idle; + data->blen = len - 1; + data->bdone += 1; + } + eshort = data->blen > 0; + break; + + case UREQ(UMOUSE_GET_PROTOCOL, UT_READ_CLASS_INTERFACE): + if (data != NULL && len > 0) { + *udata = sc->hid.protocol; + data->blen = len - 1; + data->bdone += 1; + } + eshort = data->blen > 0; + break; + + case UREQ(UMOUSE_SET_REPORT, UT_WRITE_CLASS_INTERFACE): + DPRINTF(("umouse: (UMOUSE_SET_REPORT, UT_WRITE_CLASS_INTERFACE) ignored\r\n")); + break; + + case UREQ(UMOUSE_SET_IDLE, UT_WRITE_CLASS_INTERFACE): + sc->hid.idle = UGETW(xfer->ureq->wValue) >> 8; + DPRINTF(("umouse: (UMOUSE_SET_IDLE, UT_WRITE_CLASS_INTERFACE) %x\r\n", + sc->hid.idle)); + break; + + case UREQ(UMOUSE_SET_PROTOCOL, UT_WRITE_CLASS_INTERFACE): + sc->hid.protocol = UGETW(xfer->ureq->wValue) >> 8; + DPRINTF(("umouse: (UR_CLEAR_FEATURE, UT_WRITE_CLASS_INTERFACE) %x\r\n", + sc->hid.protocol)); + break; + + default: + DPRINTF(("**** umouse request unhandled\r\n")); + err = USB_ERR_IOERROR; + break; + } + +done: + if (xfer->ureq && (xfer->ureq->bmRequestType & UT_WRITE) && + (err == USB_ERR_NORMAL_COMPLETION) && (data != NULL)) + data->blen = 0; + else if (eshort) + err = USB_ERR_SHORT_XFER; + + DPRINTF(("umouse request error code %d (0=ok), blen %u txlen %u\r\n", + err, (data ? data->blen : 0), (data ? data->bdone : 0))); + + return (err); +} + +static int +umouse_data_handler(void *scarg, struct usb_data_xfer *xfer, int dir, + int epctx) +{ + struct umouse_softc *sc; + struct usb_data_xfer_block *data; + uint8_t *udata; + int len, i, idx; + int err; + + DPRINTF(("umouse handle data - DIR=%s|EP=%d, blen %d\r\n", + dir ? "IN" : "OUT", epctx, xfer->data[0].blen)); + + + /* find buffer to add data */ + udata = NULL; + err = USB_ERR_NORMAL_COMPLETION; + + /* handle xfer at first unprocessed item with buffer */ + data = NULL; + idx = xfer->head; + for (i = 0; i < xfer->ndata; i++) { + data = &xfer->data[idx]; + if (data->buf != NULL && data->blen != 0) { + break; + } else { + data->processed = 1; + data = NULL; + } + idx = (idx + 1) % USB_MAX_XFER_BLOCKS; + } + if (!data) + goto done; + + udata = data->buf; + len = data->blen; + + if (udata == NULL) { + DPRINTF(("umouse no buffer provided for input\r\n")); + err = USB_ERR_NOMEM; + goto done; + } + + sc = scarg; + + if (dir) { + + pthread_mutex_lock(&sc->mtx); + + if (!sc->newdata) { + err = USB_ERR_CANCELLED; + USB_DATA_SET_ERRCODE(&xfer->data[xfer->head], USB_NAK); + pthread_mutex_unlock(&sc->mtx); + goto done; + } + + if (sc->polling) { + err = USB_ERR_STALLED; + USB_DATA_SET_ERRCODE(data, USB_STALL); + pthread_mutex_unlock(&sc->mtx); + goto done; + } + sc->polling = 1; + + if (len > 0) { + sc->newdata = 0; + + data->processed = 1; + data->bdone += 6; + memcpy(udata, &sc->um_report, 6); + data->blen = len - 6; + if (data->blen > 0) + err = USB_ERR_SHORT_XFER; + } + + sc->polling = 0; + pthread_mutex_unlock(&sc->mtx); + } else { + USB_DATA_SET_ERRCODE(data, USB_STALL); + err = USB_ERR_STALLED; + } + +done: + return (err); +} + +static int +umouse_reset(void *scarg) +{ + struct umouse_softc *sc; + + sc = scarg; + + sc->newdata = 0; + + return (0); +} + +static int +umouse_remove(void *scarg) +{ + + return (0); +} + +static int +umouse_stop(void *scarg) +{ + + return (0); +} + + +struct usb_devemu ue_mouse = { + .ue_emu = "tablet", + .ue_usbver = 3, + .ue_usbspeed = USB_SPEED_HIGH, + .ue_init = umouse_init, + .ue_request = umouse_request, + .ue_data = umouse_data_handler, + .ue_reset = umouse_reset, + .ue_remove = umouse_remove, + .ue_stop = umouse_stop +}; +USB_EMUL_SET(ue_mouse); diff --git a/usr/src/cmd/bhyve/vga.c b/usr/src/cmd/bhyve/vga.c new file mode 100644 index 0000000000..314ddeb1e8 --- /dev/null +++ b/usr/src/cmd/bhyve/vga.c @@ -0,0 +1,1357 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +/* + * Copyright 2018 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> + +#include <assert.h> +#include <pthread.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <machine/vmm.h> + +#include "bhyvegc.h" +#include "console.h" +#include "inout.h" +#include "mem.h" +#include "vga.h" + +#define KB (1024UL) +#define MB (1024 * 1024UL) + +struct vga_softc { + struct mem_range mr; + + struct bhyvegc *gc; + int gc_width; + int gc_height; + struct bhyvegc_image *gc_image; + + uint8_t *vga_ram; + + /* + * General registers + */ + uint8_t vga_misc; + uint8_t vga_sts1; + + /* + * Sequencer + */ + struct { + int seq_index; + uint8_t seq_reset; + uint8_t seq_clock_mode; + int seq_cm_dots; + uint8_t seq_map_mask; + uint8_t seq_cmap_sel; + int seq_cmap_pri_off; + int seq_cmap_sec_off; + uint8_t seq_mm; + } vga_seq; + + /* + * CRT Controller + */ + struct { + int crtc_index; + uint8_t crtc_mode_ctrl; + uint8_t crtc_horiz_total; + uint8_t crtc_horiz_disp_end; + uint8_t crtc_start_horiz_blank; + uint8_t crtc_end_horiz_blank; + uint8_t crtc_start_horiz_retrace; + uint8_t crtc_end_horiz_retrace; + uint8_t crtc_vert_total; + uint8_t crtc_overflow; + uint8_t crtc_present_row_scan; + uint8_t crtc_max_scan_line; + uint8_t crtc_cursor_start; + uint8_t crtc_cursor_on; + uint8_t crtc_cursor_end; + uint8_t crtc_start_addr_high; + uint8_t crtc_start_addr_low; + uint16_t crtc_start_addr; + uint8_t crtc_cursor_loc_low; + uint8_t crtc_cursor_loc_high; + uint16_t crtc_cursor_loc; + uint8_t crtc_vert_retrace_start; + uint8_t crtc_vert_retrace_end; + uint8_t crtc_vert_disp_end; + uint8_t crtc_offset; + uint8_t crtc_underline_loc; + uint8_t crtc_start_vert_blank; + uint8_t crtc_end_vert_blank; + uint8_t crtc_line_compare; + } vga_crtc; + + /* + * Graphics Controller + */ + struct { + int gc_index; + uint8_t gc_set_reset; + uint8_t gc_enb_set_reset; + uint8_t gc_color_compare; + uint8_t gc_rotate; + uint8_t gc_op; + uint8_t gc_read_map_sel; + uint8_t gc_mode; + bool gc_mode_c4; /* chain 4 */ + bool gc_mode_oe; /* odd/even */ + uint8_t gc_mode_rm; /* read mode */ + uint8_t gc_mode_wm; /* write mode */ + uint8_t gc_misc; + uint8_t gc_misc_gm; /* graphics mode */ + uint8_t gc_misc_mm; /* memory map */ + uint8_t gc_color_dont_care; + uint8_t gc_bit_mask; + uint8_t gc_latch0; + uint8_t gc_latch1; + uint8_t gc_latch2; + uint8_t gc_latch3; + } vga_gc; + + /* + * Attribute Controller + */ + struct { + int atc_flipflop; + int atc_index; + uint8_t atc_palette[16]; + uint8_t atc_mode; + uint8_t atc_overscan_color; + uint8_t atc_color_plane_enb; + uint8_t atc_horiz_pixel_panning; + uint8_t atc_color_select; + uint8_t atc_color_select_45; + uint8_t atc_color_select_67; + } vga_atc; + + /* + * DAC + */ + struct { + uint8_t dac_state; + uint8_t dac_rd_index; + uint8_t dac_rd_subindex; + uint8_t dac_wr_index; + uint8_t dac_wr_subindex; + uint8_t dac_palette[3 * 256]; + uint32_t dac_palette_rgb[256]; + } vga_dac; +}; + +static bool +vga_in_reset(struct vga_softc *sc) +{ + return (((sc->vga_seq.seq_clock_mode & SEQ_CM_SO) != 0) || + ((sc->vga_seq.seq_reset & SEQ_RESET_ASYNC) == 0) || + ((sc->vga_seq.seq_reset & SEQ_RESET_SYNC) == 0) || + ((sc->vga_crtc.crtc_mode_ctrl & CRTC_MC_TE) == 0)); +} + +static void +vga_check_size(struct bhyvegc *gc, struct vga_softc *sc) +{ + int old_width, old_height; + + if (vga_in_reset(sc)) + return; + + //old_width = sc->gc_width; + //old_height = sc->gc_height; + old_width = sc->gc_image->width; + old_height = sc->gc_image->height; + + /* + * Horizontal Display End: For text modes this is the number + * of characters. For graphics modes this is the number of + * pixels per scanlines divided by the number of pixels per + * character clock. + */ + sc->gc_width = (sc->vga_crtc.crtc_horiz_disp_end + 1) * + sc->vga_seq.seq_cm_dots; + + sc->gc_height = (sc->vga_crtc.crtc_vert_disp_end | + (((sc->vga_crtc.crtc_overflow & CRTC_OF_VDE8) >> CRTC_OF_VDE8_SHIFT) << 8) | + (((sc->vga_crtc.crtc_overflow & CRTC_OF_VDE9) >> CRTC_OF_VDE9_SHIFT) << 9)) + 1; + + if (old_width != sc->gc_width || old_height != sc->gc_height) + bhyvegc_resize(gc, sc->gc_width, sc->gc_height); +} + +static uint32_t +vga_get_pixel(struct vga_softc *sc, int x, int y) +{ + int offset; + int bit; + uint8_t data; + uint8_t idx; + + offset = (y * sc->gc_width / 8) + (x / 8); + bit = 7 - (x % 8); + + data = (((sc->vga_ram[offset + 0 * 64*KB] >> bit) & 0x1) << 0) | + (((sc->vga_ram[offset + 1 * 64*KB] >> bit) & 0x1) << 1) | + (((sc->vga_ram[offset + 2 * 64*KB] >> bit) & 0x1) << 2) | + (((sc->vga_ram[offset + 3 * 64*KB] >> bit) & 0x1) << 3); + + data &= sc->vga_atc.atc_color_plane_enb; + + if (sc->vga_atc.atc_mode & ATC_MC_IPS) { + idx = sc->vga_atc.atc_palette[data] & 0x0f; + idx |= sc->vga_atc.atc_color_select_45; + } else { + idx = sc->vga_atc.atc_palette[data]; + } + idx |= sc->vga_atc.atc_color_select_67; + + return (sc->vga_dac.dac_palette_rgb[idx]); +} + +static void +vga_render_graphics(struct vga_softc *sc) +{ + int x, y; + + for (y = 0; y < sc->gc_height; y++) { + for (x = 0; x < sc->gc_width; x++) { + int offset; + + offset = y * sc->gc_width + x; + sc->gc_image->data[offset] = vga_get_pixel(sc, x, y); + } + } +} + +static uint32_t +vga_get_text_pixel(struct vga_softc *sc, int x, int y) +{ + int dots, offset, bit, font_offset; + uint8_t ch, attr, font; + uint8_t idx; + + dots = sc->vga_seq.seq_cm_dots; + + offset = 2 * sc->vga_crtc.crtc_start_addr; + offset += (y / 16 * sc->gc_width / dots) * 2 + (x / dots) * 2; + + bit = 7 - (x % dots > 7 ? 7 : x % dots); + + ch = sc->vga_ram[offset + 0 * 64*KB]; + attr = sc->vga_ram[offset + 1 * 64*KB]; + + if (sc->vga_crtc.crtc_cursor_on && + (offset == (sc->vga_crtc.crtc_cursor_loc * 2)) && + ((y % 16) >= (sc->vga_crtc.crtc_cursor_start & CRTC_CS_CS)) && + ((y % 16) <= (sc->vga_crtc.crtc_cursor_end & CRTC_CE_CE))) { + idx = sc->vga_atc.atc_palette[attr & 0xf]; + return (sc->vga_dac.dac_palette_rgb[idx]); + } + + if ((sc->vga_seq.seq_mm & SEQ_MM_EM) && + sc->vga_seq.seq_cmap_pri_off != sc->vga_seq.seq_cmap_sec_off) { + if (attr & 0x8) + font_offset = sc->vga_seq.seq_cmap_pri_off + + (ch << 5) + y % 16; + else + font_offset = sc->vga_seq.seq_cmap_sec_off + + (ch << 5) + y % 16; + attr &= ~0x8; + } else { + font_offset = (ch << 5) + y % 16; + } + + font = sc->vga_ram[font_offset + 2 * 64*KB]; + + if (font & (1 << bit)) + idx = sc->vga_atc.atc_palette[attr & 0xf]; + else + idx = sc->vga_atc.atc_palette[attr >> 4]; + + return (sc->vga_dac.dac_palette_rgb[idx]); +} + +static void +vga_render_text(struct vga_softc *sc) +{ + int x, y; + + for (y = 0; y < sc->gc_height; y++) { + for (x = 0; x < sc->gc_width; x++) { + int offset; + + offset = y * sc->gc_width + x; + sc->gc_image->data[offset] = vga_get_text_pixel(sc, x, y); + } + } +} + +void +vga_render(struct bhyvegc *gc, void *arg) +{ + struct vga_softc *sc = arg; + + vga_check_size(gc, sc); + + if (vga_in_reset(sc)) { + memset(sc->gc_image->data, 0, + sc->gc_image->width * sc->gc_image->height * + sizeof (uint32_t)); + return; + } + + if (sc->vga_gc.gc_misc_gm && (sc->vga_atc.atc_mode & ATC_MC_GA)) + vga_render_graphics(sc); + else + vga_render_text(sc); +} + +static uint64_t +vga_mem_rd_handler(struct vmctx *ctx, uint64_t addr, void *arg1) +{ + struct vga_softc *sc = arg1; + uint8_t map_sel; + int offset; + + offset = addr; + switch (sc->vga_gc.gc_misc_mm) { + case 0x0: + /* + * extended mode: base 0xa0000 size 128k + */ + offset -=0xa0000; + offset &= (128 * KB - 1); + break; + case 0x1: + /* + * EGA/VGA mode: base 0xa0000 size 64k + */ + offset -=0xa0000; + offset &= (64 * KB - 1); + break; + case 0x2: + /* + * monochrome text mode: base 0xb0000 size 32kb + */ +#ifdef __FreeBSD__ + assert(0); +#else + abort(); +#endif + case 0x3: + /* + * color text mode and CGA: base 0xb8000 size 32kb + */ + offset -=0xb8000; + offset &= (32 * KB - 1); + break; + } + + /* Fill latches. */ + sc->vga_gc.gc_latch0 = sc->vga_ram[offset + 0*64*KB]; + sc->vga_gc.gc_latch1 = sc->vga_ram[offset + 1*64*KB]; + sc->vga_gc.gc_latch2 = sc->vga_ram[offset + 2*64*KB]; + sc->vga_gc.gc_latch3 = sc->vga_ram[offset + 3*64*KB]; + + if (sc->vga_gc.gc_mode_rm) { + /* read mode 1 */ + assert(0); + } + + map_sel = sc->vga_gc.gc_read_map_sel; + if (sc->vga_gc.gc_mode_oe) { + map_sel |= (offset & 1); + offset &= ~1; + } + + /* read mode 0: return the byte from the selected plane. */ + offset += map_sel * 64*KB; + + return (sc->vga_ram[offset]); +} + +static void +vga_mem_wr_handler(struct vmctx *ctx, uint64_t addr, uint8_t val, void *arg1) +{ + struct vga_softc *sc = arg1; + uint8_t c0, c1, c2, c3; + uint8_t m0, m1, m2, m3; + uint8_t set_reset; + uint8_t enb_set_reset; + uint8_t mask; + int offset; + + offset = addr; + switch (sc->vga_gc.gc_misc_mm) { + case 0x0: + /* + * extended mode: base 0xa0000 size 128kb + */ + offset -=0xa0000; + offset &= (128 * KB - 1); + break; + case 0x1: + /* + * EGA/VGA mode: base 0xa0000 size 64kb + */ + offset -=0xa0000; + offset &= (64 * KB - 1); + break; + case 0x2: + /* + * monochrome text mode: base 0xb0000 size 32kb + */ +#ifdef __FreeBSD__ + assert(0); +#else + abort(); +#endif + case 0x3: + /* + * color text mode and CGA: base 0xb8000 size 32kb + */ + offset -=0xb8000; + offset &= (32 * KB - 1); + break; + } + + set_reset = sc->vga_gc.gc_set_reset; + enb_set_reset = sc->vga_gc.gc_enb_set_reset; + + c0 = sc->vga_gc.gc_latch0; + c1 = sc->vga_gc.gc_latch1; + c2 = sc->vga_gc.gc_latch2; + c3 = sc->vga_gc.gc_latch3; + + switch (sc->vga_gc.gc_mode_wm) { + case 0: + /* write mode 0 */ + mask = sc->vga_gc.gc_bit_mask; + + val = (val >> sc->vga_gc.gc_rotate) | + (val << (8 - sc->vga_gc.gc_rotate)); + + switch (sc->vga_gc.gc_op) { + case 0x00: /* replace */ + m0 = (set_reset & 1) ? mask : 0x00; + m1 = (set_reset & 2) ? mask : 0x00; + m2 = (set_reset & 4) ? mask : 0x00; + m3 = (set_reset & 8) ? mask : 0x00; + + c0 = (enb_set_reset & 1) ? (c0 & ~mask) : (val & mask); + c1 = (enb_set_reset & 2) ? (c1 & ~mask) : (val & mask); + c2 = (enb_set_reset & 4) ? (c2 & ~mask) : (val & mask); + c3 = (enb_set_reset & 8) ? (c3 & ~mask) : (val & mask); + + c0 |= m0; + c1 |= m1; + c2 |= m2; + c3 |= m3; + break; + case 0x08: /* AND */ + m0 = set_reset & 1 ? 0xff : ~mask; + m1 = set_reset & 2 ? 0xff : ~mask; + m2 = set_reset & 4 ? 0xff : ~mask; + m3 = set_reset & 8 ? 0xff : ~mask; + + c0 = enb_set_reset & 1 ? c0 & m0 : val & m0; + c1 = enb_set_reset & 2 ? c1 & m1 : val & m1; + c2 = enb_set_reset & 4 ? c2 & m2 : val & m2; + c3 = enb_set_reset & 8 ? c3 & m3 : val & m3; + break; + case 0x10: /* OR */ + m0 = set_reset & 1 ? mask : 0x00; + m1 = set_reset & 2 ? mask : 0x00; + m2 = set_reset & 4 ? mask : 0x00; + m3 = set_reset & 8 ? mask : 0x00; + + c0 = enb_set_reset & 1 ? c0 | m0 : val | m0; + c1 = enb_set_reset & 2 ? c1 | m1 : val | m1; + c2 = enb_set_reset & 4 ? c2 | m2 : val | m2; + c3 = enb_set_reset & 8 ? c3 | m3 : val | m3; + break; + case 0x18: /* XOR */ + m0 = set_reset & 1 ? mask : 0x00; + m1 = set_reset & 2 ? mask : 0x00; + m2 = set_reset & 4 ? mask : 0x00; + m3 = set_reset & 8 ? mask : 0x00; + + c0 = enb_set_reset & 1 ? c0 ^ m0 : val ^ m0; + c1 = enb_set_reset & 2 ? c1 ^ m1 : val ^ m1; + c2 = enb_set_reset & 4 ? c2 ^ m2 : val ^ m2; + c3 = enb_set_reset & 8 ? c3 ^ m3 : val ^ m3; + break; + } + break; + case 1: + /* write mode 1 */ + break; + case 2: + /* write mode 2 */ + mask = sc->vga_gc.gc_bit_mask; + + switch (sc->vga_gc.gc_op) { + case 0x00: /* replace */ + m0 = (val & 1 ? 0xff : 0x00) & mask; + m1 = (val & 2 ? 0xff : 0x00) & mask; + m2 = (val & 4 ? 0xff : 0x00) & mask; + m3 = (val & 8 ? 0xff : 0x00) & mask; + + c0 &= ~mask; + c1 &= ~mask; + c2 &= ~mask; + c3 &= ~mask; + + c0 |= m0; + c1 |= m1; + c2 |= m2; + c3 |= m3; + break; + case 0x08: /* AND */ + m0 = (val & 1 ? 0xff : 0x00) | ~mask; + m1 = (val & 2 ? 0xff : 0x00) | ~mask; + m2 = (val & 4 ? 0xff : 0x00) | ~mask; + m3 = (val & 8 ? 0xff : 0x00) | ~mask; + + c0 &= m0; + c1 &= m1; + c2 &= m2; + c3 &= m3; + break; + case 0x10: /* OR */ + m0 = (val & 1 ? 0xff : 0x00) & mask; + m1 = (val & 2 ? 0xff : 0x00) & mask; + m2 = (val & 4 ? 0xff : 0x00) & mask; + m3 = (val & 8 ? 0xff : 0x00) & mask; + + c0 |= m0; + c1 |= m1; + c2 |= m2; + c3 |= m3; + break; + case 0x18: /* XOR */ + m0 = (val & 1 ? 0xff : 0x00) & mask; + m1 = (val & 2 ? 0xff : 0x00) & mask; + m2 = (val & 4 ? 0xff : 0x00) & mask; + m3 = (val & 8 ? 0xff : 0x00) & mask; + + c0 ^= m0; + c1 ^= m1; + c2 ^= m2; + c3 ^= m3; + break; + } + break; + case 3: + /* write mode 3 */ + mask = sc->vga_gc.gc_bit_mask & val; + + val = (val >> sc->vga_gc.gc_rotate) | + (val << (8 - sc->vga_gc.gc_rotate)); + + switch (sc->vga_gc.gc_op) { + case 0x00: /* replace */ + m0 = (set_reset & 1 ? 0xff : 0x00) & mask; + m1 = (set_reset & 2 ? 0xff : 0x00) & mask; + m2 = (set_reset & 4 ? 0xff : 0x00) & mask; + m3 = (set_reset & 8 ? 0xff : 0x00) & mask; + + c0 &= ~mask; + c1 &= ~mask; + c2 &= ~mask; + c3 &= ~mask; + + c0 |= m0; + c1 |= m1; + c2 |= m2; + c3 |= m3; + break; + case 0x08: /* AND */ + m0 = (set_reset & 1 ? 0xff : 0x00) | ~mask; + m1 = (set_reset & 2 ? 0xff : 0x00) | ~mask; + m2 = (set_reset & 4 ? 0xff : 0x00) | ~mask; + m3 = (set_reset & 8 ? 0xff : 0x00) | ~mask; + + c0 &= m0; + c1 &= m1; + c2 &= m2; + c3 &= m3; + break; + case 0x10: /* OR */ + m0 = (set_reset & 1 ? 0xff : 0x00) & mask; + m1 = (set_reset & 2 ? 0xff : 0x00) & mask; + m2 = (set_reset & 4 ? 0xff : 0x00) & mask; + m3 = (set_reset & 8 ? 0xff : 0x00) & mask; + + c0 |= m0; + c1 |= m1; + c2 |= m2; + c3 |= m3; + break; + case 0x18: /* XOR */ + m0 = (set_reset & 1 ? 0xff : 0x00) & mask; + m1 = (set_reset & 2 ? 0xff : 0x00) & mask; + m2 = (set_reset & 4 ? 0xff : 0x00) & mask; + m3 = (set_reset & 8 ? 0xff : 0x00) & mask; + + c0 ^= m0; + c1 ^= m1; + c2 ^= m2; + c3 ^= m3; + break; + } + break; + } + + if (sc->vga_gc.gc_mode_oe) { + if (offset & 1) { + offset &= ~1; + if (sc->vga_seq.seq_map_mask & 2) + sc->vga_ram[offset + 1*64*KB] = c1; + if (sc->vga_seq.seq_map_mask & 8) + sc->vga_ram[offset + 3*64*KB] = c3; + } else { + if (sc->vga_seq.seq_map_mask & 1) + sc->vga_ram[offset + 0*64*KB] = c0; + if (sc->vga_seq.seq_map_mask & 4) + sc->vga_ram[offset + 2*64*KB] = c2; + } + } else { + if (sc->vga_seq.seq_map_mask & 1) + sc->vga_ram[offset + 0*64*KB] = c0; + if (sc->vga_seq.seq_map_mask & 2) + sc->vga_ram[offset + 1*64*KB] = c1; + if (sc->vga_seq.seq_map_mask & 4) + sc->vga_ram[offset + 2*64*KB] = c2; + if (sc->vga_seq.seq_map_mask & 8) + sc->vga_ram[offset + 3*64*KB] = c3; + } +} + +static int +vga_mem_handler(struct vmctx *ctx, int vcpu, int dir, uint64_t addr, + int size, uint64_t *val, void *arg1, long arg2) +{ + if (dir == MEM_F_WRITE) { + switch (size) { + case 1: + vga_mem_wr_handler(ctx, addr, *val, arg1); + break; + case 2: + vga_mem_wr_handler(ctx, addr, *val, arg1); + vga_mem_wr_handler(ctx, addr + 1, *val >> 8, arg1); + break; + case 4: + vga_mem_wr_handler(ctx, addr, *val, arg1); + vga_mem_wr_handler(ctx, addr + 1, *val >> 8, arg1); + vga_mem_wr_handler(ctx, addr + 2, *val >> 16, arg1); + vga_mem_wr_handler(ctx, addr + 3, *val >> 24, arg1); + break; + case 8: + vga_mem_wr_handler(ctx, addr, *val, arg1); + vga_mem_wr_handler(ctx, addr + 1, *val >> 8, arg1); + vga_mem_wr_handler(ctx, addr + 2, *val >> 16, arg1); + vga_mem_wr_handler(ctx, addr + 3, *val >> 24, arg1); + vga_mem_wr_handler(ctx, addr + 4, *val >> 32, arg1); + vga_mem_wr_handler(ctx, addr + 5, *val >> 40, arg1); + vga_mem_wr_handler(ctx, addr + 6, *val >> 48, arg1); + vga_mem_wr_handler(ctx, addr + 7, *val >> 56, arg1); + break; + } + } else { + switch (size) { + case 1: + *val = vga_mem_rd_handler(ctx, addr, arg1); + break; + case 2: + *val = vga_mem_rd_handler(ctx, addr, arg1); + *val |= vga_mem_rd_handler(ctx, addr + 1, arg1) << 8; + break; + case 4: + *val = vga_mem_rd_handler(ctx, addr, arg1); + *val |= vga_mem_rd_handler(ctx, addr + 1, arg1) << 8; + *val |= vga_mem_rd_handler(ctx, addr + 2, arg1) << 16; + *val |= vga_mem_rd_handler(ctx, addr + 3, arg1) << 24; + break; + case 8: + *val = vga_mem_rd_handler(ctx, addr, arg1); + *val |= vga_mem_rd_handler(ctx, addr + 1, arg1) << 8; + *val |= vga_mem_rd_handler(ctx, addr + 2, arg1) << 16; + *val |= vga_mem_rd_handler(ctx, addr + 3, arg1) << 24; + *val |= vga_mem_rd_handler(ctx, addr + 4, arg1) << 32; + *val |= vga_mem_rd_handler(ctx, addr + 5, arg1) << 40; + *val |= vga_mem_rd_handler(ctx, addr + 6, arg1) << 48; + *val |= vga_mem_rd_handler(ctx, addr + 7, arg1) << 56; + break; + } + } + + return (0); +} + +static int +vga_port_in_handler(struct vmctx *ctx, int in, int port, int bytes, + uint8_t *val, void *arg) +{ + struct vga_softc *sc = arg; + + switch (port) { + case CRTC_IDX_MONO_PORT: + case CRTC_IDX_COLOR_PORT: + *val = sc->vga_crtc.crtc_index; + break; + case CRTC_DATA_MONO_PORT: + case CRTC_DATA_COLOR_PORT: + switch (sc->vga_crtc.crtc_index) { + case CRTC_HORIZ_TOTAL: + *val = sc->vga_crtc.crtc_horiz_total; + break; + case CRTC_HORIZ_DISP_END: + *val = sc->vga_crtc.crtc_horiz_disp_end; + break; + case CRTC_START_HORIZ_BLANK: + *val = sc->vga_crtc.crtc_start_horiz_blank; + break; + case CRTC_END_HORIZ_BLANK: + *val = sc->vga_crtc.crtc_end_horiz_blank; + break; + case CRTC_START_HORIZ_RETRACE: + *val = sc->vga_crtc.crtc_start_horiz_retrace; + break; + case CRTC_END_HORIZ_RETRACE: + *val = sc->vga_crtc.crtc_end_horiz_retrace; + break; + case CRTC_VERT_TOTAL: + *val = sc->vga_crtc.crtc_vert_total; + break; + case CRTC_OVERFLOW: + *val = sc->vga_crtc.crtc_overflow; + break; + case CRTC_PRESET_ROW_SCAN: + *val = sc->vga_crtc.crtc_present_row_scan; + break; + case CRTC_MAX_SCAN_LINE: + *val = sc->vga_crtc.crtc_max_scan_line; + break; + case CRTC_CURSOR_START: + *val = sc->vga_crtc.crtc_cursor_start; + break; + case CRTC_CURSOR_END: + *val = sc->vga_crtc.crtc_cursor_end; + break; + case CRTC_START_ADDR_HIGH: + *val = sc->vga_crtc.crtc_start_addr_high; + break; + case CRTC_START_ADDR_LOW: + *val = sc->vga_crtc.crtc_start_addr_low; + break; + case CRTC_CURSOR_LOC_HIGH: + *val = sc->vga_crtc.crtc_cursor_loc_high; + break; + case CRTC_CURSOR_LOC_LOW: + *val = sc->vga_crtc.crtc_cursor_loc_low; + break; + case CRTC_VERT_RETRACE_START: + *val = sc->vga_crtc.crtc_vert_retrace_start; + break; + case CRTC_VERT_RETRACE_END: + *val = sc->vga_crtc.crtc_vert_retrace_end; + break; + case CRTC_VERT_DISP_END: + *val = sc->vga_crtc.crtc_vert_disp_end; + break; + case CRTC_OFFSET: + *val = sc->vga_crtc.crtc_offset; + break; + case CRTC_UNDERLINE_LOC: + *val = sc->vga_crtc.crtc_underline_loc; + break; + case CRTC_START_VERT_BLANK: + *val = sc->vga_crtc.crtc_start_vert_blank; + break; + case CRTC_END_VERT_BLANK: + *val = sc->vga_crtc.crtc_end_vert_blank; + break; + case CRTC_MODE_CONTROL: + *val = sc->vga_crtc.crtc_mode_ctrl; + break; + case CRTC_LINE_COMPARE: + *val = sc->vga_crtc.crtc_line_compare; + break; + default: + //printf("XXX VGA CRTC: inb 0x%04x at index %d\n", port, sc->vga_crtc.crtc_index); + assert(0); + break; + } + break; + case ATC_IDX_PORT: + *val = sc->vga_atc.atc_index; + break; + case ATC_DATA_PORT: + switch (sc->vga_atc.atc_index) { + case ATC_PALETTE0 ... ATC_PALETTE15: + *val = sc->vga_atc.atc_palette[sc->vga_atc.atc_index]; + break; + case ATC_MODE_CONTROL: + *val = sc->vga_atc.atc_mode; + break; + case ATC_OVERSCAN_COLOR: + *val = sc->vga_atc.atc_overscan_color; + break; + case ATC_COLOR_PLANE_ENABLE: + *val = sc->vga_atc.atc_color_plane_enb; + break; + case ATC_HORIZ_PIXEL_PANNING: + *val = sc->vga_atc.atc_horiz_pixel_panning; + break; + case ATC_COLOR_SELECT: + *val = sc->vga_atc.atc_color_select; + break; + default: + //printf("XXX VGA ATC inb 0x%04x at index %d\n", port , sc->vga_atc.atc_index); + assert(0); + break; + } + break; + case SEQ_IDX_PORT: + *val = sc->vga_seq.seq_index; + break; + case SEQ_DATA_PORT: + switch (sc->vga_seq.seq_index) { + case SEQ_RESET: + *val = sc->vga_seq.seq_reset; + break; + case SEQ_CLOCKING_MODE: + *val = sc->vga_seq.seq_clock_mode; + break; + case SEQ_MAP_MASK: + *val = sc->vga_seq.seq_map_mask; + break; + case SEQ_CHAR_MAP_SELECT: + *val = sc->vga_seq.seq_cmap_sel; + break; + case SEQ_MEMORY_MODE: + *val = sc->vga_seq.seq_mm; + break; + default: + //printf("XXX VGA SEQ: inb 0x%04x at index %d\n", port, sc->vga_seq.seq_index); + assert(0); + break; + } + break; + case DAC_DATA_PORT: + *val = sc->vga_dac.dac_palette[3 * sc->vga_dac.dac_rd_index + + sc->vga_dac.dac_rd_subindex]; + sc->vga_dac.dac_rd_subindex++; + if (sc->vga_dac.dac_rd_subindex == 3) { + sc->vga_dac.dac_rd_index++; + sc->vga_dac.dac_rd_subindex = 0; + } + break; + case GC_IDX_PORT: + *val = sc->vga_gc.gc_index; + break; + case GC_DATA_PORT: + switch (sc->vga_gc.gc_index) { + case GC_SET_RESET: + *val = sc->vga_gc.gc_set_reset; + break; + case GC_ENABLE_SET_RESET: + *val = sc->vga_gc.gc_enb_set_reset; + break; + case GC_COLOR_COMPARE: + *val = sc->vga_gc.gc_color_compare; + break; + case GC_DATA_ROTATE: + *val = sc->vga_gc.gc_rotate; + break; + case GC_READ_MAP_SELECT: + *val = sc->vga_gc.gc_read_map_sel; + break; + case GC_MODE: + *val = sc->vga_gc.gc_mode; + break; + case GC_MISCELLANEOUS: + *val = sc->vga_gc.gc_misc; + break; + case GC_COLOR_DONT_CARE: + *val = sc->vga_gc.gc_color_dont_care; + break; + case GC_BIT_MASK: + *val = sc->vga_gc.gc_bit_mask; + break; + default: + //printf("XXX VGA GC: inb 0x%04x at index %d\n", port, sc->vga_crtc.crtc_index); + assert(0); + break; + } + break; + case GEN_MISC_OUTPUT_PORT: + *val = sc->vga_misc; + break; + case GEN_INPUT_STS0_PORT: + assert(0); + break; + case GEN_INPUT_STS1_MONO_PORT: + case GEN_INPUT_STS1_COLOR_PORT: + sc->vga_atc.atc_flipflop = 0; +#ifdef __FreeBSD__ + sc->vga_sts1 = GEN_IS1_VR | GEN_IS1_DE; + //sc->vga_sts1 ^= (GEN_IS1_VR | GEN_IS1_DE); +#else + /* + * During the bhyve bring-up process, a guest image was failing + * to successfully boot. It appeared to be spinning, waiting + * for this value to be toggled. Until it can be ruled out + * that this is unnecessary (and documentation seems to + * indicate that it should be present), the toggle should + * remain. + */ + sc->vga_sts1 ^= (GEN_IS1_VR | GEN_IS1_DE); +#endif + *val = sc->vga_sts1; + break; + case GEN_FEATURE_CTRL_PORT: + // OpenBSD calls this with bytes = 1 + //assert(0); + *val = 0; + break; + case 0x3c3: + *val = 0; + break; + default: + printf("XXX vga_port_in_handler() unhandled port 0x%x\n", port); + //assert(0); + return (-1); + } + + return (0); +} + +static int +vga_port_out_handler(struct vmctx *ctx, int in, int port, int bytes, + uint8_t val, void *arg) +{ + struct vga_softc *sc = arg; + + switch (port) { + case CRTC_IDX_MONO_PORT: + case CRTC_IDX_COLOR_PORT: + sc->vga_crtc.crtc_index = val; + break; + case CRTC_DATA_MONO_PORT: + case CRTC_DATA_COLOR_PORT: + switch (sc->vga_crtc.crtc_index) { + case CRTC_HORIZ_TOTAL: + sc->vga_crtc.crtc_horiz_total = val; + break; + case CRTC_HORIZ_DISP_END: + sc->vga_crtc.crtc_horiz_disp_end = val; + break; + case CRTC_START_HORIZ_BLANK: + sc->vga_crtc.crtc_start_horiz_blank = val; + break; + case CRTC_END_HORIZ_BLANK: + sc->vga_crtc.crtc_end_horiz_blank = val; + break; + case CRTC_START_HORIZ_RETRACE: + sc->vga_crtc.crtc_start_horiz_retrace = val; + break; + case CRTC_END_HORIZ_RETRACE: + sc->vga_crtc.crtc_end_horiz_retrace = val; + break; + case CRTC_VERT_TOTAL: + sc->vga_crtc.crtc_vert_total = val; + break; + case CRTC_OVERFLOW: + sc->vga_crtc.crtc_overflow = val; + break; + case CRTC_PRESET_ROW_SCAN: + sc->vga_crtc.crtc_present_row_scan = val; + break; + case CRTC_MAX_SCAN_LINE: + sc->vga_crtc.crtc_max_scan_line = val; + break; + case CRTC_CURSOR_START: + sc->vga_crtc.crtc_cursor_start = val; + sc->vga_crtc.crtc_cursor_on = (val & CRTC_CS_CO) == 0; + break; + case CRTC_CURSOR_END: + sc->vga_crtc.crtc_cursor_end = val; + break; + case CRTC_START_ADDR_HIGH: + sc->vga_crtc.crtc_start_addr_high = val; + sc->vga_crtc.crtc_start_addr &= 0x00ff; + sc->vga_crtc.crtc_start_addr |= (val << 8); + break; + case CRTC_START_ADDR_LOW: + sc->vga_crtc.crtc_start_addr_low = val; + sc->vga_crtc.crtc_start_addr &= 0xff00; + sc->vga_crtc.crtc_start_addr |= (val & 0xff); + break; + case CRTC_CURSOR_LOC_HIGH: + sc->vga_crtc.crtc_cursor_loc_high = val; + sc->vga_crtc.crtc_cursor_loc &= 0x00ff; + sc->vga_crtc.crtc_cursor_loc |= (val << 8); + break; + case CRTC_CURSOR_LOC_LOW: + sc->vga_crtc.crtc_cursor_loc_low = val; + sc->vga_crtc.crtc_cursor_loc &= 0xff00; + sc->vga_crtc.crtc_cursor_loc |= (val & 0xff); + break; + case CRTC_VERT_RETRACE_START: + sc->vga_crtc.crtc_vert_retrace_start = val; + break; + case CRTC_VERT_RETRACE_END: + sc->vga_crtc.crtc_vert_retrace_end = val; + break; + case CRTC_VERT_DISP_END: + sc->vga_crtc.crtc_vert_disp_end = val; + break; + case CRTC_OFFSET: + sc->vga_crtc.crtc_offset = val; + break; + case CRTC_UNDERLINE_LOC: + sc->vga_crtc.crtc_underline_loc = val; + break; + case CRTC_START_VERT_BLANK: + sc->vga_crtc.crtc_start_vert_blank = val; + break; + case CRTC_END_VERT_BLANK: + sc->vga_crtc.crtc_end_vert_blank = val; + break; + case CRTC_MODE_CONTROL: + sc->vga_crtc.crtc_mode_ctrl = val; + break; + case CRTC_LINE_COMPARE: + sc->vga_crtc.crtc_line_compare = val; + break; + default: + //printf("XXX VGA CRTC: outb 0x%04x, 0x%02x at index %d\n", port, val, sc->vga_crtc.crtc_index); + assert(0); + break; + } + break; + case ATC_IDX_PORT: + if (sc->vga_atc.atc_flipflop == 0) { + if (sc->vga_atc.atc_index & 0x20) + assert(0); + sc->vga_atc.atc_index = val & ATC_IDX_MASK; + } else { + switch (sc->vga_atc.atc_index) { + case ATC_PALETTE0 ... ATC_PALETTE15: + sc->vga_atc.atc_palette[sc->vga_atc.atc_index] = val & 0x3f; + break; + case ATC_MODE_CONTROL: + sc->vga_atc.atc_mode = val; + break; + case ATC_OVERSCAN_COLOR: + sc->vga_atc.atc_overscan_color = val; + break; + case ATC_COLOR_PLANE_ENABLE: + sc->vga_atc.atc_color_plane_enb = val; + break; + case ATC_HORIZ_PIXEL_PANNING: + sc->vga_atc.atc_horiz_pixel_panning = val; + break; + case ATC_COLOR_SELECT: + sc->vga_atc.atc_color_select = val; + sc->vga_atc.atc_color_select_45 = + (val & ATC_CS_C45) << 4; + sc->vga_atc.atc_color_select_67 = + ((val & ATC_CS_C67) >> 2) << 6; + break; + default: + //printf("XXX VGA ATC: outb 0x%04x, 0x%02x at index %d\n", port, val, sc->vga_atc.atc_index); + assert(0); + break; + } + } + sc->vga_atc.atc_flipflop ^= 1; + break; + case ATC_DATA_PORT: + break; + case SEQ_IDX_PORT: + sc->vga_seq.seq_index = val & 0x1f; + break; + case SEQ_DATA_PORT: + switch (sc->vga_seq.seq_index) { + case SEQ_RESET: + sc->vga_seq.seq_reset = val; + break; + case SEQ_CLOCKING_MODE: + sc->vga_seq.seq_clock_mode = val; + sc->vga_seq.seq_cm_dots = (val & SEQ_CM_89) ? 8 : 9; + break; + case SEQ_MAP_MASK: + sc->vga_seq.seq_map_mask = val; + break; + case SEQ_CHAR_MAP_SELECT: + sc->vga_seq.seq_cmap_sel = val; + + sc->vga_seq.seq_cmap_pri_off = ((((val & SEQ_CMS_SA) >> SEQ_CMS_SA_SHIFT) * 2) + ((val & SEQ_CMS_SAH) >> SEQ_CMS_SAH_SHIFT)) * 8 * KB; + sc->vga_seq.seq_cmap_sec_off = ((((val & SEQ_CMS_SB) >> SEQ_CMS_SB_SHIFT) * 2) + ((val & SEQ_CMS_SBH) >> SEQ_CMS_SBH_SHIFT)) * 8 * KB; + break; + case SEQ_MEMORY_MODE: + sc->vga_seq.seq_mm = val; + /* Windows queries Chain4 */ + //assert((sc->vga_seq.seq_mm & SEQ_MM_C4) == 0); + break; + default: + //printf("XXX VGA SEQ: outb 0x%04x, 0x%02x at index %d\n", port, val, sc->vga_seq.seq_index); + assert(0); + break; + } + break; + case DAC_MASK: + break; + case DAC_IDX_RD_PORT: + sc->vga_dac.dac_rd_index = val; + sc->vga_dac.dac_rd_subindex = 0; + break; + case DAC_IDX_WR_PORT: + sc->vga_dac.dac_wr_index = val; + sc->vga_dac.dac_wr_subindex = 0; + break; + case DAC_DATA_PORT: + sc->vga_dac.dac_palette[3 * sc->vga_dac.dac_wr_index + + sc->vga_dac.dac_wr_subindex] = val; + sc->vga_dac.dac_wr_subindex++; + if (sc->vga_dac.dac_wr_subindex == 3) { + sc->vga_dac.dac_palette_rgb[sc->vga_dac.dac_wr_index] = + ((((sc->vga_dac.dac_palette[3*sc->vga_dac.dac_wr_index + 0] << 2) | + ((sc->vga_dac.dac_palette[3*sc->vga_dac.dac_wr_index + 0] & 0x1) << 1) | + (sc->vga_dac.dac_palette[3*sc->vga_dac.dac_wr_index + 0] & 0x1)) << 16) | + (((sc->vga_dac.dac_palette[3*sc->vga_dac.dac_wr_index + 1] << 2) | + ((sc->vga_dac.dac_palette[3*sc->vga_dac.dac_wr_index + 1] & 0x1) << 1) | + (sc->vga_dac.dac_palette[3*sc->vga_dac.dac_wr_index + 1] & 0x1)) << 8) | + (((sc->vga_dac.dac_palette[3*sc->vga_dac.dac_wr_index + 2] << 2) | + ((sc->vga_dac.dac_palette[3*sc->vga_dac.dac_wr_index + 2] & 0x1) << 1) | + (sc->vga_dac.dac_palette[3*sc->vga_dac.dac_wr_index + 2] & 0x1)) << 0)); + + sc->vga_dac.dac_wr_index++; + sc->vga_dac.dac_wr_subindex = 0; + } + break; + case GC_IDX_PORT: + sc->vga_gc.gc_index = val; + break; + case GC_DATA_PORT: + switch (sc->vga_gc.gc_index) { + case GC_SET_RESET: + sc->vga_gc.gc_set_reset = val; + break; + case GC_ENABLE_SET_RESET: + sc->vga_gc.gc_enb_set_reset = val; + break; + case GC_COLOR_COMPARE: + sc->vga_gc.gc_color_compare = val; + break; + case GC_DATA_ROTATE: + sc->vga_gc.gc_rotate = val; + sc->vga_gc.gc_op = (val >> 3) & 0x3; + break; + case GC_READ_MAP_SELECT: + sc->vga_gc.gc_read_map_sel = val; + break; + case GC_MODE: + sc->vga_gc.gc_mode = val; + sc->vga_gc.gc_mode_c4 = (val & GC_MODE_C4) != 0; + assert(!sc->vga_gc.gc_mode_c4); + sc->vga_gc.gc_mode_oe = (val & GC_MODE_OE) != 0; + sc->vga_gc.gc_mode_rm = (val >> 3) & 0x1; + sc->vga_gc.gc_mode_wm = val & 0x3; + + if (sc->gc_image) + sc->gc_image->vgamode = 1; + break; + case GC_MISCELLANEOUS: + sc->vga_gc.gc_misc = val; + sc->vga_gc.gc_misc_gm = val & GC_MISC_GM; + sc->vga_gc.gc_misc_mm = (val & GC_MISC_MM) >> + GC_MISC_MM_SHIFT; + break; + case GC_COLOR_DONT_CARE: + sc->vga_gc.gc_color_dont_care = val; + break; + case GC_BIT_MASK: + sc->vga_gc.gc_bit_mask = val; + break; + default: + //printf("XXX VGA GC: outb 0x%04x, 0x%02x at index %d\n", port, val, sc->vga_gc.gc_index); + assert(0); + break; + } + break; + case GEN_INPUT_STS0_PORT: + /* write to Miscellaneous Output Register */ + sc->vga_misc = val; + break; + case GEN_INPUT_STS1_MONO_PORT: + case GEN_INPUT_STS1_COLOR_PORT: + /* write to Feature Control Register */ + break; +// case 0x3c3: +// break; + default: + printf("XXX vga_port_out_handler() unhandled port 0x%x, val 0x%x\n", port, val); + //assert(0); + return (-1); + } + return (0); +} + +static int +vga_port_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, + uint32_t *eax, void *arg) +{ + uint8_t val; + int error; + + switch (bytes) { + case 1: + if (in) { + *eax &= ~0xff; + error = vga_port_in_handler(ctx, in, port, 1, + &val, arg); + if (!error) { + *eax |= val & 0xff; + } + } else { + val = *eax & 0xff; + error = vga_port_out_handler(ctx, in, port, 1, + val, arg); + } + break; + case 2: + if (in) { + *eax &= ~0xffff; + error = vga_port_in_handler(ctx, in, port, 1, + &val, arg); + if (!error) { + *eax |= val & 0xff; + } + error = vga_port_in_handler(ctx, in, port + 1, 1, + &val, arg); + if (!error) { + *eax |= (val & 0xff) << 8; + } + } else { + val = *eax & 0xff; + error = vga_port_out_handler(ctx, in, port, 1, + val, arg); + val = (*eax >> 8) & 0xff; + error =vga_port_out_handler(ctx, in, port + 1, 1, + val, arg); + } + break; + default: + assert(0); + return (-1); + } + + return (error); +} + +void * +vga_init(int io_only) +{ + struct inout_port iop; + struct vga_softc *sc; + int port, error; + + sc = calloc(1, sizeof(struct vga_softc)); + + bzero(&iop, sizeof(struct inout_port)); + iop.name = "VGA"; + for (port = VGA_IOPORT_START; port <= VGA_IOPORT_END; port++) { + iop.port = port; + iop.size = 1; + iop.flags = IOPORT_F_INOUT; + iop.handler = vga_port_handler; + iop.arg = sc; + + error = register_inout(&iop); + assert(error == 0); + } + + sc->gc_image = console_get_image(); + + /* only handle io ports; vga graphics is disabled */ + if (io_only) + return(sc); + + sc->mr.name = "VGA memory"; + sc->mr.flags = MEM_F_RW; + sc->mr.base = 640 * KB; + sc->mr.size = 128 * KB; + sc->mr.handler = vga_mem_handler; + sc->mr.arg1 = sc; + error = register_mem_fallback(&sc->mr); + assert(error == 0); + + sc->vga_ram = malloc(256 * KB); + memset(sc->vga_ram, 0, 256 * KB); + + { + static uint8_t palette[] = { + 0x00,0x00,0x00, 0x00,0x00,0x2a, 0x00,0x2a,0x00, 0x00,0x2a,0x2a, + 0x2a,0x00,0x00, 0x2a,0x00,0x2a, 0x2a,0x2a,0x00, 0x2a,0x2a,0x2a, + 0x00,0x00,0x15, 0x00,0x00,0x3f, 0x00,0x2a,0x15, 0x00,0x2a,0x3f, + 0x2a,0x00,0x15, 0x2a,0x00,0x3f, 0x2a,0x2a,0x15, 0x2a,0x2a,0x3f, + }; + int i; + + memcpy(sc->vga_dac.dac_palette, palette, 16 * 3 * sizeof (uint8_t)); + for (i = 0; i < 16; i++) { + sc->vga_dac.dac_palette_rgb[i] = + ((((sc->vga_dac.dac_palette[3*i + 0] << 2) | + ((sc->vga_dac.dac_palette[3*i + 0] & 0x1) << 1) | + (sc->vga_dac.dac_palette[3*i + 0] & 0x1)) << 16) | + (((sc->vga_dac.dac_palette[3*i + 1] << 2) | + ((sc->vga_dac.dac_palette[3*i + 1] & 0x1) << 1) | + (sc->vga_dac.dac_palette[3*i + 1] & 0x1)) << 8) | + (((sc->vga_dac.dac_palette[3*i + 2] << 2) | + ((sc->vga_dac.dac_palette[3*i + 2] & 0x1) << 1) | + (sc->vga_dac.dac_palette[3*i + 2] & 0x1)) << 0)); + } + } + + return (sc); +} diff --git a/usr/src/cmd/bhyve/vga.h b/usr/src/cmd/bhyve/vga.h new file mode 100644 index 0000000000..36c6dc15fa --- /dev/null +++ b/usr/src/cmd/bhyve/vga.h @@ -0,0 +1,162 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2015 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _VGA_H_ +#define _VGA_H_ + +#define VGA_IOPORT_START 0x3c0 +#define VGA_IOPORT_END 0x3df + +/* General registers */ +#define GEN_INPUT_STS0_PORT 0x3c2 +#define GEN_FEATURE_CTRL_PORT 0x3ca +#define GEN_MISC_OUTPUT_PORT 0x3cc +#define GEN_INPUT_STS1_MONO_PORT 0x3ba +#define GEN_INPUT_STS1_COLOR_PORT 0x3da +#define GEN_IS1_VR 0x08 /* Vertical retrace */ +#define GEN_IS1_DE 0x01 /* Display enable not */ + +/* Attribute controller registers. */ +#define ATC_IDX_PORT 0x3c0 +#define ATC_DATA_PORT 0x3c1 + +#define ATC_IDX_MASK 0x1f +#define ATC_PALETTE0 0 +#define ATC_PALETTE15 15 +#define ATC_MODE_CONTROL 16 +#define ATC_MC_IPS 0x80 /* Internal palette size */ +#define ATC_MC_GA 0x01 /* Graphics/alphanumeric */ +#define ATC_OVERSCAN_COLOR 17 +#define ATC_COLOR_PLANE_ENABLE 18 +#define ATC_HORIZ_PIXEL_PANNING 19 +#define ATC_COLOR_SELECT 20 +#define ATC_CS_C67 0x0c /* Color select bits 6+7 */ +#define ATC_CS_C45 0x03 /* Color select bits 4+5 */ + +/* Sequencer registers. */ +#define SEQ_IDX_PORT 0x3c4 +#define SEQ_DATA_PORT 0x3c5 + +#define SEQ_RESET 0 +#define SEQ_RESET_ASYNC 0x1 +#define SEQ_RESET_SYNC 0x2 +#define SEQ_CLOCKING_MODE 1 +#define SEQ_CM_SO 0x20 /* Screen off */ +#define SEQ_CM_89 0x01 /* 8/9 dot clock */ +#define SEQ_MAP_MASK 2 +#define SEQ_CHAR_MAP_SELECT 3 +#define SEQ_CMS_SAH 0x20 /* Char map A bit 2 */ +#define SEQ_CMS_SAH_SHIFT 5 +#define SEQ_CMS_SA 0x0c /* Char map A bits 0+1 */ +#define SEQ_CMS_SA_SHIFT 2 +#define SEQ_CMS_SBH 0x10 /* Char map B bit 2 */ +#define SEQ_CMS_SBH_SHIFT 4 +#define SEQ_CMS_SB 0x03 /* Char map B bits 0+1 */ +#define SEQ_CMS_SB_SHIFT 0 +#define SEQ_MEMORY_MODE 4 +#define SEQ_MM_C4 0x08 /* Chain 4 */ +#define SEQ_MM_OE 0x04 /* Odd/even */ +#define SEQ_MM_EM 0x02 /* Extended memory */ + +/* Graphics controller registers. */ +#define GC_IDX_PORT 0x3ce +#define GC_DATA_PORT 0x3cf + +#define GC_SET_RESET 0 +#define GC_ENABLE_SET_RESET 1 +#define GC_COLOR_COMPARE 2 +#define GC_DATA_ROTATE 3 +#define GC_READ_MAP_SELECT 4 +#define GC_MODE 5 +#define GC_MODE_OE 0x10 /* Odd/even */ +#define GC_MODE_C4 0x04 /* Chain 4 */ + +#define GC_MISCELLANEOUS 6 +#define GC_MISC_GM 0x01 /* Graphics/alphanumeric */ +#define GC_MISC_MM 0x0c /* memory map */ +#define GC_MISC_MM_SHIFT 2 +#define GC_COLOR_DONT_CARE 7 +#define GC_BIT_MASK 8 + +/* CRT controller registers. */ +#define CRTC_IDX_MONO_PORT 0x3b4 +#define CRTC_DATA_MONO_PORT 0x3b5 +#define CRTC_IDX_COLOR_PORT 0x3d4 +#define CRTC_DATA_COLOR_PORT 0x3d5 + +#define CRTC_HORIZ_TOTAL 0 +#define CRTC_HORIZ_DISP_END 1 +#define CRTC_START_HORIZ_BLANK 2 +#define CRTC_END_HORIZ_BLANK 3 +#define CRTC_START_HORIZ_RETRACE 4 +#define CRTC_END_HORIZ_RETRACE 5 +#define CRTC_VERT_TOTAL 6 +#define CRTC_OVERFLOW 7 +#define CRTC_OF_VRS9 0x80 /* VRS bit 9 */ +#define CRTC_OF_VRS9_SHIFT 7 +#define CRTC_OF_VDE9 0x40 /* VDE bit 9 */ +#define CRTC_OF_VDE9_SHIFT 6 +#define CRTC_OF_VRS8 0x04 /* VRS bit 8 */ +#define CRTC_OF_VRS8_SHIFT 2 +#define CRTC_OF_VDE8 0x02 /* VDE bit 8 */ +#define CRTC_OF_VDE8_SHIFT 1 +#define CRTC_PRESET_ROW_SCAN 8 +#define CRTC_MAX_SCAN_LINE 9 +#define CRTC_MSL_MSL 0x1f +#define CRTC_CURSOR_START 10 +#define CRTC_CS_CO 0x20 /* Cursor off */ +#define CRTC_CS_CS 0x1f /* Cursor start */ +#define CRTC_CURSOR_END 11 +#define CRTC_CE_CE 0x1f /* Cursor end */ +#define CRTC_START_ADDR_HIGH 12 +#define CRTC_START_ADDR_LOW 13 +#define CRTC_CURSOR_LOC_HIGH 14 +#define CRTC_CURSOR_LOC_LOW 15 +#define CRTC_VERT_RETRACE_START 16 +#define CRTC_VERT_RETRACE_END 17 +#define CRTC_VRE_MASK 0xf +#define CRTC_VERT_DISP_END 18 +#define CRTC_OFFSET 19 +#define CRTC_UNDERLINE_LOC 20 +#define CRTC_START_VERT_BLANK 21 +#define CRTC_END_VERT_BLANK 22 +#define CRTC_MODE_CONTROL 23 +#define CRTC_MC_TE 0x80 /* Timing enable */ +#define CRTC_LINE_COMPARE 24 + +/* DAC registers */ +#define DAC_MASK 0x3c6 +#define DAC_IDX_RD_PORT 0x3c7 +#define DAC_IDX_WR_PORT 0x3c8 +#define DAC_DATA_PORT 0x3c9 + +void *vga_init(int io_only); + +#endif /* _VGA_H_ */ diff --git a/usr/src/cmd/bhyve/virtio.c b/usr/src/cmd/bhyve/virtio.c new file mode 100644 index 0000000000..d3ff5e3951 --- /dev/null +++ b/usr/src/cmd/bhyve/virtio.c @@ -0,0 +1,794 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Chris Torek <torek @ torek net> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/uio.h> + +#include <stdio.h> +#include <stdint.h> +#include <pthread.h> +#include <pthread_np.h> + +#include "bhyverun.h" +#include "pci_emul.h" +#include "virtio.h" + +/* + * Functions for dealing with generalized "virtual devices" as + * defined by <https://www.google.com/#output=search&q=virtio+spec> + */ + +/* + * In case we decide to relax the "virtio softc comes at the + * front of virtio-based device softc" constraint, let's use + * this to convert. + */ +#define DEV_SOFTC(vs) ((void *)(vs)) + +/* + * Link a virtio_softc to its constants, the device softc, and + * the PCI emulation. + */ +void +vi_softc_linkup(struct virtio_softc *vs, struct virtio_consts *vc, + void *dev_softc, struct pci_devinst *pi, + struct vqueue_info *queues) +{ + int i; + + /* vs and dev_softc addresses must match */ + assert((void *)vs == dev_softc); + vs->vs_vc = vc; + vs->vs_pi = pi; + pi->pi_arg = vs; + + vs->vs_queues = queues; + for (i = 0; i < vc->vc_nvq; i++) { + queues[i].vq_vs = vs; + queues[i].vq_num = i; + } +} + +/* + * Reset device (device-wide). This erases all queues, i.e., + * all the queues become invalid (though we don't wipe out the + * internal pointers, we just clear the VQ_ALLOC flag). + * + * It resets negotiated features to "none". + * + * If MSI-X is enabled, this also resets all the vectors to NO_VECTOR. + */ +void +vi_reset_dev(struct virtio_softc *vs) +{ + struct vqueue_info *vq; + int i, nvq; + + if (vs->vs_mtx) + assert(pthread_mutex_isowned_np(vs->vs_mtx)); + + nvq = vs->vs_vc->vc_nvq; + for (vq = vs->vs_queues, i = 0; i < nvq; vq++, i++) { + vq->vq_flags = 0; + vq->vq_last_avail = 0; + vq->vq_save_used = 0; + vq->vq_pfn = 0; + vq->vq_msix_idx = VIRTIO_MSI_NO_VECTOR; + } + vs->vs_negotiated_caps = 0; + vs->vs_curq = 0; + /* vs->vs_status = 0; -- redundant */ + if (vs->vs_isr) + pci_lintr_deassert(vs->vs_pi); + vs->vs_isr = 0; + vs->vs_msix_cfg_idx = VIRTIO_MSI_NO_VECTOR; +} + +/* + * Set I/O BAR (usually 0) to map PCI config registers. + */ +void +vi_set_io_bar(struct virtio_softc *vs, int barnum) +{ + size_t size; + + /* + * ??? should we use CFG0 if MSI-X is disabled? + * Existing code did not... + */ + size = VTCFG_R_CFG1 + vs->vs_vc->vc_cfgsize; + pci_emul_alloc_bar(vs->vs_pi, barnum, PCIBAR_IO, size); +} + +/* + * Initialize MSI-X vector capabilities if we're to use MSI-X, + * or MSI capabilities if not. + * + * We assume we want one MSI-X vector per queue, here, plus one + * for the config vec. + */ +int +vi_intr_init(struct virtio_softc *vs, int barnum, int use_msix) +{ + int nvec; + + if (use_msix) { + vs->vs_flags |= VIRTIO_USE_MSIX; + VS_LOCK(vs); + vi_reset_dev(vs); /* set all vectors to NO_VECTOR */ + VS_UNLOCK(vs); + nvec = vs->vs_vc->vc_nvq + 1; + if (pci_emul_add_msixcap(vs->vs_pi, nvec, barnum)) + return (1); + } else + vs->vs_flags &= ~VIRTIO_USE_MSIX; + + /* Only 1 MSI vector for bhyve */ + pci_emul_add_msicap(vs->vs_pi, 1); + + /* Legacy interrupts are mandatory for virtio devices */ + pci_lintr_request(vs->vs_pi); + + return (0); +} + +/* + * Initialize the currently-selected virtio queue (vs->vs_curq). + * The guest just gave us a page frame number, from which we can + * calculate the addresses of the queue. + */ +void +vi_vq_init(struct virtio_softc *vs, uint32_t pfn) +{ + struct vqueue_info *vq; + uint64_t phys; + size_t size; + char *base; + + vq = &vs->vs_queues[vs->vs_curq]; + vq->vq_pfn = pfn; + phys = (uint64_t)pfn << VRING_PFN; + size = vring_size(vq->vq_qsize); + base = paddr_guest2host(vs->vs_pi->pi_vmctx, phys, size); + + /* First page(s) are descriptors... */ + vq->vq_desc = (struct virtio_desc *)base; + base += vq->vq_qsize * sizeof(struct virtio_desc); + + /* ... immediately followed by "avail" ring (entirely uint16_t's) */ + vq->vq_avail = (struct vring_avail *)base; + base += (2 + vq->vq_qsize + 1) * sizeof(uint16_t); + + /* Then it's rounded up to the next page... */ + base = (char *)roundup2((uintptr_t)base, VRING_ALIGN); + + /* ... and the last page(s) are the used ring. */ + vq->vq_used = (struct vring_used *)base; + + /* Mark queue as allocated, and start at 0 when we use it. */ + vq->vq_flags = VQ_ALLOC; + vq->vq_last_avail = 0; + vq->vq_save_used = 0; +} + +/* + * Helper inline for vq_getchain(): record the i'th "real" + * descriptor. + */ +static inline void +_vq_record(int i, volatile struct virtio_desc *vd, struct vmctx *ctx, + struct iovec *iov, int n_iov, uint16_t *flags) { + + if (i >= n_iov) + return; + iov[i].iov_base = paddr_guest2host(ctx, vd->vd_addr, vd->vd_len); + iov[i].iov_len = vd->vd_len; + if (flags != NULL) + flags[i] = vd->vd_flags; +} +#define VQ_MAX_DESCRIPTORS 512 /* see below */ + +/* + * Examine the chain of descriptors starting at the "next one" to + * make sure that they describe a sensible request. If so, return + * the number of "real" descriptors that would be needed/used in + * acting on this request. This may be smaller than the number of + * available descriptors, e.g., if there are two available but + * they are two separate requests, this just returns 1. Or, it + * may be larger: if there are indirect descriptors involved, + * there may only be one descriptor available but it may be an + * indirect pointing to eight more. We return 8 in this case, + * i.e., we do not count the indirect descriptors, only the "real" + * ones. + * + * Basically, this vets the vd_flags and vd_next field of each + * descriptor and tells you how many are involved. Since some may + * be indirect, this also needs the vmctx (in the pci_devinst + * at vs->vs_pi) so that it can find indirect descriptors. + * + * As we process each descriptor, we copy and adjust it (guest to + * host address wise, also using the vmtctx) into the given iov[] + * array (of the given size). If the array overflows, we stop + * placing values into the array but keep processing descriptors, + * up to VQ_MAX_DESCRIPTORS, before giving up and returning -1. + * So you, the caller, must not assume that iov[] is as big as the + * return value (you can process the same thing twice to allocate + * a larger iov array if needed, or supply a zero length to find + * out how much space is needed). + * + * If you want to verify the WRITE flag on each descriptor, pass a + * non-NULL "flags" pointer to an array of "uint16_t" of the same size + * as n_iov and we'll copy each vd_flags field after unwinding any + * indirects. + * + * If some descriptor(s) are invalid, this prints a diagnostic message + * and returns -1. If no descriptors are ready now it simply returns 0. + * + * You are assumed to have done a vq_ring_ready() if needed (note + * that vq_has_descs() does one). + */ +int +vq_getchain(struct vqueue_info *vq, uint16_t *pidx, + struct iovec *iov, int n_iov, uint16_t *flags) +{ + int i; + u_int ndesc, n_indir; + u_int idx, next; + volatile struct virtio_desc *vdir, *vindir, *vp; + struct vmctx *ctx; + struct virtio_softc *vs; + const char *name; + + vs = vq->vq_vs; + name = vs->vs_vc->vc_name; + + /* + * Note: it's the responsibility of the guest not to + * update vq->vq_avail->va_idx until all of the descriptors + * the guest has written are valid (including all their + * vd_next fields and vd_flags). + * + * Compute (last_avail - va_idx) in integers mod 2**16. This is + * the number of descriptors the device has made available + * since the last time we updated vq->vq_last_avail. + * + * We just need to do the subtraction as an unsigned int, + * then trim off excess bits. + */ + idx = vq->vq_last_avail; + ndesc = (uint16_t)((u_int)vq->vq_avail->va_idx - idx); + if (ndesc == 0) + return (0); + if (ndesc > vq->vq_qsize) { + /* XXX need better way to diagnose issues */ + fprintf(stderr, + "%s: ndesc (%u) out of range, driver confused?\r\n", + name, (u_int)ndesc); + return (-1); + } + + /* + * Now count/parse "involved" descriptors starting from + * the head of the chain. + * + * To prevent loops, we could be more complicated and + * check whether we're re-visiting a previously visited + * index, but we just abort if the count gets excessive. + */ + ctx = vs->vs_pi->pi_vmctx; + *pidx = next = vq->vq_avail->va_ring[idx & (vq->vq_qsize - 1)]; + vq->vq_last_avail++; + for (i = 0; i < VQ_MAX_DESCRIPTORS; next = vdir->vd_next) { + if (next >= vq->vq_qsize) { + fprintf(stderr, + "%s: descriptor index %u out of range, " + "driver confused?\r\n", + name, next); + return (-1); + } + vdir = &vq->vq_desc[next]; + if ((vdir->vd_flags & VRING_DESC_F_INDIRECT) == 0) { + _vq_record(i, vdir, ctx, iov, n_iov, flags); + i++; + } else if ((vs->vs_vc->vc_hv_caps & + VIRTIO_RING_F_INDIRECT_DESC) == 0) { + fprintf(stderr, + "%s: descriptor has forbidden INDIRECT flag, " + "driver confused?\r\n", + name); + return (-1); + } else { + n_indir = vdir->vd_len / 16; + if ((vdir->vd_len & 0xf) || n_indir == 0) { + fprintf(stderr, + "%s: invalid indir len 0x%x, " + "driver confused?\r\n", + name, (u_int)vdir->vd_len); + return (-1); + } + vindir = paddr_guest2host(ctx, + vdir->vd_addr, vdir->vd_len); + /* + * Indirects start at the 0th, then follow + * their own embedded "next"s until those run + * out. Each one's indirect flag must be off + * (we don't really have to check, could just + * ignore errors...). + */ + next = 0; + for (;;) { + vp = &vindir[next]; + if (vp->vd_flags & VRING_DESC_F_INDIRECT) { + fprintf(stderr, + "%s: indirect desc has INDIR flag," + " driver confused?\r\n", + name); + return (-1); + } + _vq_record(i, vp, ctx, iov, n_iov, flags); + if (++i > VQ_MAX_DESCRIPTORS) + goto loopy; + if ((vp->vd_flags & VRING_DESC_F_NEXT) == 0) + break; + next = vp->vd_next; + if (next >= n_indir) { + fprintf(stderr, + "%s: invalid next %u > %u, " + "driver confused?\r\n", + name, (u_int)next, n_indir); + return (-1); + } + } + } + if ((vdir->vd_flags & VRING_DESC_F_NEXT) == 0) + return (i); + } +loopy: + fprintf(stderr, + "%s: descriptor loop? count > %d - driver confused?\r\n", + name, i); + return (-1); +} + +/* + * Return the currently-first request chain back to the available queue. + * + * (This chain is the one you handled when you called vq_getchain() + * and used its positive return value.) + */ +void +vq_retchain(struct vqueue_info *vq) +{ + + vq->vq_last_avail--; +} + +/* + * Return specified request chain to the guest, setting its I/O length + * to the provided value. + * + * (This chain is the one you handled when you called vq_getchain() + * and used its positive return value.) + */ +void +vq_relchain(struct vqueue_info *vq, uint16_t idx, uint32_t iolen) +{ + uint16_t uidx, mask; + volatile struct vring_used *vuh; + volatile struct virtio_used *vue; + + /* + * Notes: + * - mask is N-1 where N is a power of 2 so computes x % N + * - vuh points to the "used" data shared with guest + * - vue points to the "used" ring entry we want to update + * - head is the same value we compute in vq_iovecs(). + * + * (I apologize for the two fields named vu_idx; the + * virtio spec calls the one that vue points to, "id"...) + */ + mask = vq->vq_qsize - 1; + vuh = vq->vq_used; + + uidx = vuh->vu_idx; + vue = &vuh->vu_ring[uidx++ & mask]; + vue->vu_idx = idx; + vue->vu_tlen = iolen; +#ifndef __FreeBSD__ + /* + * Ensure the used descriptor is visible before updating the index. + * This is necessary on ISAs with memory ordering less strict than x86. + */ + wmb(); +#endif + vuh->vu_idx = uidx; +} + +/* + * Driver has finished processing "available" chains and calling + * vq_relchain on each one. If driver used all the available + * chains, used_all should be set. + * + * If the "used" index moved we may need to inform the guest, i.e., + * deliver an interrupt. Even if the used index did NOT move we + * may need to deliver an interrupt, if the avail ring is empty and + * we are supposed to interrupt on empty. + * + * Note that used_all_avail is provided by the caller because it's + * a snapshot of the ring state when he decided to finish interrupt + * processing -- it's possible that descriptors became available after + * that point. (It's also typically a constant 1/True as well.) + */ +void +vq_endchains(struct vqueue_info *vq, int used_all_avail) +{ + struct virtio_softc *vs; + uint16_t event_idx, new_idx, old_idx; + int intr; + + /* + * Interrupt generation: if we're using EVENT_IDX, + * interrupt if we've crossed the event threshold. + * Otherwise interrupt is generated if we added "used" entries, + * but suppressed by VRING_AVAIL_F_NO_INTERRUPT. + * + * In any case, though, if NOTIFY_ON_EMPTY is set and the + * entire avail was processed, we need to interrupt always. + */ + vs = vq->vq_vs; + old_idx = vq->vq_save_used; + vq->vq_save_used = new_idx = vq->vq_used->vu_idx; +#ifndef __FreeBSD__ + /* + * Use full memory barrier between vu_idx store from preceding + * vq_relchain() call and the loads from VQ_USED_EVENT_IDX() or + * va_flags below. + */ + mb(); +#endif + if (used_all_avail && + (vs->vs_negotiated_caps & VIRTIO_F_NOTIFY_ON_EMPTY)) + intr = 1; + else if (vs->vs_negotiated_caps & VIRTIO_RING_F_EVENT_IDX) { + event_idx = VQ_USED_EVENT_IDX(vq); + /* + * This calculation is per docs and the kernel + * (see src/sys/dev/virtio/virtio_ring.h). + */ + intr = (uint16_t)(new_idx - event_idx - 1) < + (uint16_t)(new_idx - old_idx); + } else { + intr = new_idx != old_idx && + !(vq->vq_avail->va_flags & VRING_AVAIL_F_NO_INTERRUPT); + } + if (intr) + vq_interrupt(vs, vq); +} + +/* Note: these are in sorted order to make for a fast search */ +static struct config_reg { + uint16_t cr_offset; /* register offset */ + uint8_t cr_size; /* size (bytes) */ + uint8_t cr_ro; /* true => reg is read only */ + const char *cr_name; /* name of reg */ +} config_regs[] = { + { VTCFG_R_HOSTCAP, 4, 1, "HOSTCAP" }, + { VTCFG_R_GUESTCAP, 4, 0, "GUESTCAP" }, + { VTCFG_R_PFN, 4, 0, "PFN" }, + { VTCFG_R_QNUM, 2, 1, "QNUM" }, + { VTCFG_R_QSEL, 2, 0, "QSEL" }, + { VTCFG_R_QNOTIFY, 2, 0, "QNOTIFY" }, + { VTCFG_R_STATUS, 1, 0, "STATUS" }, + { VTCFG_R_ISR, 1, 0, "ISR" }, + { VTCFG_R_CFGVEC, 2, 0, "CFGVEC" }, + { VTCFG_R_QVEC, 2, 0, "QVEC" }, +}; + +static inline struct config_reg * +vi_find_cr(int offset) { + u_int hi, lo, mid; + struct config_reg *cr; + + lo = 0; + hi = sizeof(config_regs) / sizeof(*config_regs) - 1; + while (hi >= lo) { + mid = (hi + lo) >> 1; + cr = &config_regs[mid]; + if (cr->cr_offset == offset) + return (cr); + if (cr->cr_offset < offset) + lo = mid + 1; + else + hi = mid - 1; + } + return (NULL); +} + +/* + * Handle pci config space reads. + * If it's to the MSI-X info, do that. + * If it's part of the virtio standard stuff, do that. + * Otherwise dispatch to the actual driver. + */ +uint64_t +vi_pci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size) +{ + struct virtio_softc *vs = pi->pi_arg; + struct virtio_consts *vc; + struct config_reg *cr; + uint64_t virtio_config_size, max; + const char *name; + uint32_t newoff; + uint32_t value; + int error; + + if (vs->vs_flags & VIRTIO_USE_MSIX) { + if (baridx == pci_msix_table_bar(pi) || + baridx == pci_msix_pba_bar(pi)) { + return (pci_emul_msix_tread(pi, offset, size)); + } + } + + /* XXX probably should do something better than just assert() */ + assert(baridx == 0); + + if (vs->vs_mtx) + pthread_mutex_lock(vs->vs_mtx); + + vc = vs->vs_vc; + name = vc->vc_name; + value = size == 1 ? 0xff : size == 2 ? 0xffff : 0xffffffff; + + if (size != 1 && size != 2 && size != 4) + goto bad; + + if (pci_msix_enabled(pi)) + virtio_config_size = VTCFG_R_CFG1; + else + virtio_config_size = VTCFG_R_CFG0; + + if (offset >= virtio_config_size) { + /* + * Subtract off the standard size (including MSI-X + * registers if enabled) and dispatch to underlying driver. + * If that fails, fall into general code. + */ + newoff = offset - virtio_config_size; + max = vc->vc_cfgsize ? vc->vc_cfgsize : 0x100000000; + if (newoff + size > max) + goto bad; + error = (*vc->vc_cfgread)(DEV_SOFTC(vs), newoff, size, &value); + if (!error) + goto done; + } + +bad: + cr = vi_find_cr(offset); + if (cr == NULL || cr->cr_size != size) { + if (cr != NULL) { + /* offset must be OK, so size must be bad */ + fprintf(stderr, + "%s: read from %s: bad size %d\r\n", + name, cr->cr_name, size); + } else { + fprintf(stderr, + "%s: read from bad offset/size %jd/%d\r\n", + name, (uintmax_t)offset, size); + } + goto done; + } + + switch (offset) { + case VTCFG_R_HOSTCAP: + value = vc->vc_hv_caps; + break; + case VTCFG_R_GUESTCAP: + value = vs->vs_negotiated_caps; + break; + case VTCFG_R_PFN: + if (vs->vs_curq < vc->vc_nvq) + value = vs->vs_queues[vs->vs_curq].vq_pfn; + break; + case VTCFG_R_QNUM: + value = vs->vs_curq < vc->vc_nvq ? + vs->vs_queues[vs->vs_curq].vq_qsize : 0; + break; + case VTCFG_R_QSEL: + value = vs->vs_curq; + break; + case VTCFG_R_QNOTIFY: + value = 0; /* XXX */ + break; + case VTCFG_R_STATUS: + value = vs->vs_status; + break; + case VTCFG_R_ISR: + value = vs->vs_isr; + vs->vs_isr = 0; /* a read clears this flag */ + if (value) + pci_lintr_deassert(pi); + break; + case VTCFG_R_CFGVEC: + value = vs->vs_msix_cfg_idx; + break; + case VTCFG_R_QVEC: + value = vs->vs_curq < vc->vc_nvq ? + vs->vs_queues[vs->vs_curq].vq_msix_idx : + VIRTIO_MSI_NO_VECTOR; + break; + } +done: + if (vs->vs_mtx) + pthread_mutex_unlock(vs->vs_mtx); + return (value); +} + +/* + * Handle pci config space writes. + * If it's to the MSI-X info, do that. + * If it's part of the virtio standard stuff, do that. + * Otherwise dispatch to the actual driver. + */ +void +vi_pci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value) +{ + struct virtio_softc *vs = pi->pi_arg; + struct vqueue_info *vq; + struct virtio_consts *vc; + struct config_reg *cr; + uint64_t virtio_config_size, max; + const char *name; + uint32_t newoff; + int error; + + if (vs->vs_flags & VIRTIO_USE_MSIX) { + if (baridx == pci_msix_table_bar(pi) || + baridx == pci_msix_pba_bar(pi)) { + pci_emul_msix_twrite(pi, offset, size, value); + return; + } + } + + /* XXX probably should do something better than just assert() */ + assert(baridx == 0); + + if (vs->vs_mtx) + pthread_mutex_lock(vs->vs_mtx); + + vc = vs->vs_vc; + name = vc->vc_name; + + if (size != 1 && size != 2 && size != 4) + goto bad; + + if (pci_msix_enabled(pi)) + virtio_config_size = VTCFG_R_CFG1; + else + virtio_config_size = VTCFG_R_CFG0; + + if (offset >= virtio_config_size) { + /* + * Subtract off the standard size (including MSI-X + * registers if enabled) and dispatch to underlying driver. + */ + newoff = offset - virtio_config_size; + max = vc->vc_cfgsize ? vc->vc_cfgsize : 0x100000000; + if (newoff + size > max) + goto bad; + error = (*vc->vc_cfgwrite)(DEV_SOFTC(vs), newoff, size, value); + if (!error) + goto done; + } + +bad: + cr = vi_find_cr(offset); + if (cr == NULL || cr->cr_size != size || cr->cr_ro) { + if (cr != NULL) { + /* offset must be OK, wrong size and/or reg is R/O */ + if (cr->cr_size != size) + fprintf(stderr, + "%s: write to %s: bad size %d\r\n", + name, cr->cr_name, size); + if (cr->cr_ro) + fprintf(stderr, + "%s: write to read-only reg %s\r\n", + name, cr->cr_name); + } else { + fprintf(stderr, + "%s: write to bad offset/size %jd/%d\r\n", + name, (uintmax_t)offset, size); + } + goto done; + } + + switch (offset) { + case VTCFG_R_GUESTCAP: + vs->vs_negotiated_caps = value & vc->vc_hv_caps; + if (vc->vc_apply_features) + (*vc->vc_apply_features)(DEV_SOFTC(vs), + vs->vs_negotiated_caps); + break; + case VTCFG_R_PFN: + if (vs->vs_curq >= vc->vc_nvq) + goto bad_qindex; + vi_vq_init(vs, value); + break; + case VTCFG_R_QSEL: + /* + * Note that the guest is allowed to select an + * invalid queue; we just need to return a QNUM + * of 0 while the bad queue is selected. + */ + vs->vs_curq = value; + break; + case VTCFG_R_QNOTIFY: + if (value >= vc->vc_nvq) { + fprintf(stderr, "%s: queue %d notify out of range\r\n", + name, (int)value); + goto done; + } + vq = &vs->vs_queues[value]; + if (vq->vq_notify) + (*vq->vq_notify)(DEV_SOFTC(vs), vq); + else if (vc->vc_qnotify) + (*vc->vc_qnotify)(DEV_SOFTC(vs), vq); + else + fprintf(stderr, + "%s: qnotify queue %d: missing vq/vc notify\r\n", + name, (int)value); + break; + case VTCFG_R_STATUS: + vs->vs_status = value; + if (value == 0) + (*vc->vc_reset)(DEV_SOFTC(vs)); + break; + case VTCFG_R_CFGVEC: + vs->vs_msix_cfg_idx = value; + break; + case VTCFG_R_QVEC: + if (vs->vs_curq >= vc->vc_nvq) + goto bad_qindex; + vq = &vs->vs_queues[vs->vs_curq]; + vq->vq_msix_idx = value; + break; + } + goto done; + +bad_qindex: + fprintf(stderr, + "%s: write config reg %s: curq %d >= max %d\r\n", + name, cr->cr_name, vs->vs_curq, vc->vc_nvq); +done: + if (vs->vs_mtx) + pthread_mutex_unlock(vs->vs_mtx); +} diff --git a/usr/src/cmd/bhyve/virtio.h b/usr/src/cmd/bhyve/virtio.h new file mode 100644 index 0000000000..a2c3362ec2 --- /dev/null +++ b/usr/src/cmd/bhyve/virtio.h @@ -0,0 +1,484 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2013 Chris Torek <torek @ torek net> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _VIRTIO_H_ +#define _VIRTIO_H_ + +#include <pthread_np.h> + +/* + * These are derived from several virtio specifications. + * + * Some useful links: + * https://github.com/rustyrussell/virtio-spec + * http://people.redhat.com/pbonzini/virtio-spec.pdf + */ + +/* + * A virtual device has zero or more "virtual queues" (virtqueue). + * Each virtqueue uses at least two 4096-byte pages, laid out thus: + * + * +-----------------------------------------------+ + * | "desc": <N> descriptors, 16 bytes each | + * | ----------------------------------------- | + * | "avail": 2 uint16; <N> uint16; 1 uint16 | + * | ----------------------------------------- | + * | pad to 4k boundary | + * +-----------------------------------------------+ + * | "used": 2 x uint16; <N> elems; 1 uint16 | + * | ----------------------------------------- | + * | pad to 4k boundary | + * +-----------------------------------------------+ + * + * The number <N> that appears here is always a power of two and is + * limited to no more than 32768 (as it must fit in a 16-bit field). + * If <N> is sufficiently large, the above will occupy more than + * two pages. In any case, all pages must be physically contiguous + * within the guest's physical address space. + * + * The <N> 16-byte "desc" descriptors consist of a 64-bit guest + * physical address <addr>, a 32-bit length <len>, a 16-bit + * <flags>, and a 16-bit <next> field (all in guest byte order). + * + * There are three flags that may be set : + * NEXT descriptor is chained, so use its "next" field + * WRITE descriptor is for host to write into guest RAM + * (else host is to read from guest RAM) + * INDIRECT descriptor address field is (guest physical) + * address of a linear array of descriptors + * + * Unless INDIRECT is set, <len> is the number of bytes that may + * be read/written from guest physical address <addr>. If + * INDIRECT is set, WRITE is ignored and <len> provides the length + * of the indirect descriptors (and <len> must be a multiple of + * 16). Note that NEXT may still be set in the main descriptor + * pointing to the indirect, and should be set in each indirect + * descriptor that uses the next descriptor (these should generally + * be numbered sequentially). However, INDIRECT must not be set + * in the indirect descriptors. Upon reaching an indirect descriptor + * without a NEXT bit, control returns to the direct descriptors. + * + * Except inside an indirect, each <next> value must be in the + * range [0 .. N) (i.e., the half-open interval). (Inside an + * indirect, each <next> must be in the range [0 .. <len>/16).) + * + * The "avail" data structures reside in the same pages as the + * "desc" structures since both together are used by the device to + * pass information to the hypervisor's virtual driver. These + * begin with a 16-bit <flags> field and 16-bit index <idx>, then + * have <N> 16-bit <ring> values, followed by one final 16-bit + * field <used_event>. The <N> <ring> entries are simply indices + * indices into the descriptor ring (and thus must meet the same + * constraints as each <next> value). However, <idx> is counted + * up from 0 (initially) and simply wraps around after 65535; it + * is taken mod <N> to find the next available entry. + * + * The "used" ring occupies a separate page or pages, and contains + * values written from the virtual driver back to the guest OS. + * This begins with a 16-bit <flags> and 16-bit <idx>, then there + * are <N> "vring_used" elements, followed by a 16-bit <avail_event>. + * The <N> "vring_used" elements consist of a 32-bit <id> and a + * 32-bit <len> (vu_tlen below). The <id> is simply the index of + * the head of a descriptor chain the guest made available + * earlier, and the <len> is the number of bytes actually written, + * e.g., in the case of a network driver that provided a large + * receive buffer but received only a small amount of data. + * + * The two event fields, <used_event> and <avail_event>, in the + * avail and used rings (respectively -- note the reversal!), are + * always provided, but are used only if the virtual device + * negotiates the VIRTIO_RING_F_EVENT_IDX feature during feature + * negotiation. Similarly, both rings provide a flag -- + * VRING_AVAIL_F_NO_INTERRUPT and VRING_USED_F_NO_NOTIFY -- in + * their <flags> field, indicating that the guest does not need an + * interrupt, or that the hypervisor driver does not need a + * notify, when descriptors are added to the corresponding ring. + * (These are provided only for interrupt optimization and need + * not be implemented.) + */ +#define VRING_ALIGN 4096 + +#define VRING_DESC_F_NEXT (1 << 0) +#define VRING_DESC_F_WRITE (1 << 1) +#define VRING_DESC_F_INDIRECT (1 << 2) + +struct virtio_desc { /* AKA vring_desc */ + uint64_t vd_addr; /* guest physical address */ + uint32_t vd_len; /* length of scatter/gather seg */ + uint16_t vd_flags; /* VRING_F_DESC_* */ + uint16_t vd_next; /* next desc if F_NEXT */ +} __packed; + +struct virtio_used { /* AKA vring_used_elem */ + uint32_t vu_idx; /* head of used descriptor chain */ + uint32_t vu_tlen; /* length written-to */ +} __packed; + +#define VRING_AVAIL_F_NO_INTERRUPT 1 + +struct vring_avail { + uint16_t va_flags; /* VRING_AVAIL_F_* */ + uint16_t va_idx; /* counts to 65535, then cycles */ + uint16_t va_ring[]; /* size N, reported in QNUM value */ +/* uint16_t va_used_event; -- after N ring entries */ +} __packed; + +#define VRING_USED_F_NO_NOTIFY 1 +struct vring_used { + uint16_t vu_flags; /* VRING_USED_F_* */ + uint16_t vu_idx; /* counts to 65535, then cycles */ + struct virtio_used vu_ring[]; /* size N */ +/* uint16_t vu_avail_event; -- after N ring entries */ +} __packed; + +/* + * The address of any given virtual queue is determined by a single + * Page Frame Number register. The guest writes the PFN into the + * PCI config space. However, a device that has two or more + * virtqueues can have a different PFN, and size, for each queue. + * The number of queues is determinable via the PCI config space + * VTCFG_R_QSEL register. Writes to QSEL select the queue: 0 means + * queue #0, 1 means queue#1, etc. Once a queue is selected, the + * remaining PFN and QNUM registers refer to that queue. + * + * QNUM is a read-only register containing a nonzero power of two + * that indicates the (hypervisor's) queue size. Or, if reading it + * produces zero, the hypervisor does not have a corresponding + * queue. (The number of possible queues depends on the virtual + * device. The block device has just one; the network device + * provides either two -- 0 = receive, 1 = transmit -- or three, + * with 2 = control.) + * + * PFN is a read/write register giving the physical page address of + * the virtqueue in guest memory (the guest must allocate enough space + * based on the hypervisor's provided QNUM). + * + * QNOTIFY is effectively write-only: when the guest writes a queue + * number to the register, the hypervisor should scan the specified + * virtqueue. (Reading QNOTIFY currently always gets 0). + */ + +/* + * PFN register shift amount + */ +#define VRING_PFN 12 + +/* + * Virtio device types + * + * XXX Should really be merged with <dev/virtio/virtio.h> defines + */ +#define VIRTIO_TYPE_NET 1 +#define VIRTIO_TYPE_BLOCK 2 +#define VIRTIO_TYPE_CONSOLE 3 +#define VIRTIO_TYPE_ENTROPY 4 +#define VIRTIO_TYPE_BALLOON 5 +#define VIRTIO_TYPE_IOMEMORY 6 +#define VIRTIO_TYPE_RPMSG 7 +#define VIRTIO_TYPE_SCSI 8 +#define VIRTIO_TYPE_9P 9 + +/* experimental IDs start at 65535 and work down */ + +/* + * PCI vendor/device IDs + */ +#define VIRTIO_VENDOR 0x1AF4 +#define VIRTIO_DEV_NET 0x1000 +#define VIRTIO_DEV_BLOCK 0x1001 +#define VIRTIO_DEV_CONSOLE 0x1003 +#define VIRTIO_DEV_RANDOM 0x1005 +#define VIRTIO_DEV_SCSI 0x1008 + +/* + * PCI config space constants. + * + * If MSI-X is enabled, the ISR register is generally not used, + * and the configuration vector and queue vector appear at offsets + * 20 and 22 with the remaining configuration registers at 24. + * If MSI-X is not enabled, those two registers disappear and + * the remaining configuration registers start at offset 20. + */ +#define VTCFG_R_HOSTCAP 0 +#define VTCFG_R_GUESTCAP 4 +#define VTCFG_R_PFN 8 +#define VTCFG_R_QNUM 12 +#define VTCFG_R_QSEL 14 +#define VTCFG_R_QNOTIFY 16 +#define VTCFG_R_STATUS 18 +#define VTCFG_R_ISR 19 +#define VTCFG_R_CFGVEC 20 +#define VTCFG_R_QVEC 22 +#define VTCFG_R_CFG0 20 /* No MSI-X */ +#define VTCFG_R_CFG1 24 /* With MSI-X */ +#define VTCFG_R_MSIX 20 + +/* + * Bits in VTCFG_R_STATUS. Guests need not actually set any of these, + * but a guest writing 0 to this register means "please reset". + */ +#define VTCFG_STATUS_ACK 0x01 /* guest OS has acknowledged dev */ +#define VTCFG_STATUS_DRIVER 0x02 /* guest OS driver is loaded */ +#define VTCFG_STATUS_DRIVER_OK 0x04 /* guest OS driver ready */ +#define VTCFG_STATUS_FAILED 0x80 /* guest has given up on this dev */ + +/* + * Bits in VTCFG_R_ISR. These apply only if not using MSI-X. + * + * (We don't [yet?] ever use CONF_CHANGED.) + */ +#define VTCFG_ISR_QUEUES 0x01 /* re-scan queues */ +#define VTCFG_ISR_CONF_CHANGED 0x80 /* configuration changed */ + +#define VIRTIO_MSI_NO_VECTOR 0xFFFF + +/* + * Feature flags. + * Note: bits 0 through 23 are reserved to each device type. + */ +#define VIRTIO_F_NOTIFY_ON_EMPTY (1 << 24) +#define VIRTIO_RING_F_INDIRECT_DESC (1 << 28) +#define VIRTIO_RING_F_EVENT_IDX (1 << 29) + +/* From section 2.3, "Virtqueue Configuration", of the virtio specification */ +static inline size_t +vring_size(u_int qsz) +{ + size_t size; + + /* constant 3 below = va_flags, va_idx, va_used_event */ + size = sizeof(struct virtio_desc) * qsz + sizeof(uint16_t) * (3 + qsz); + size = roundup2(size, VRING_ALIGN); + + /* constant 3 below = vu_flags, vu_idx, vu_avail_event */ + size += sizeof(uint16_t) * 3 + sizeof(struct virtio_used) * qsz; + size = roundup2(size, VRING_ALIGN); + + return (size); +} + +struct vmctx; +struct pci_devinst; +struct vqueue_info; + +/* + * A virtual device, with some number (possibly 0) of virtual + * queues and some size (possibly 0) of configuration-space + * registers private to the device. The virtio_softc should come + * at the front of each "derived class", so that a pointer to the + * virtio_softc is also a pointer to the more specific, derived- + * from-virtio driver's softc. + * + * Note: inside each hypervisor virtio driver, changes to these + * data structures must be locked against other threads, if any. + * Except for PCI config space register read/write, we assume each + * driver does the required locking, but we need a pointer to the + * lock (if there is one) for PCI config space read/write ops. + * + * When the guest reads or writes the device's config space, the + * generic layer checks for operations on the special registers + * described above. If the offset of the register(s) being read + * or written is past the CFG area (CFG0 or CFG1), the request is + * passed on to the virtual device, after subtracting off the + * generic-layer size. (So, drivers can just use the offset as + * an offset into "struct config", for instance.) + * + * (The virtio layer also makes sure that the read or write is to/ + * from a "good" config offset, hence vc_cfgsize, and on BAR #0. + * However, the driver must verify the read or write size and offset + * and that no one is writing a readonly register.) + * + * The BROKED flag ("this thing done gone and broked") is for future + * use. + */ +#define VIRTIO_USE_MSIX 0x01 +#define VIRTIO_EVENT_IDX 0x02 /* use the event-index values */ +#define VIRTIO_BROKED 0x08 /* ??? */ + +struct virtio_softc { + struct virtio_consts *vs_vc; /* constants (see below) */ + int vs_flags; /* VIRTIO_* flags from above */ + pthread_mutex_t *vs_mtx; /* POSIX mutex, if any */ + struct pci_devinst *vs_pi; /* PCI device instance */ + uint32_t vs_negotiated_caps; /* negotiated capabilities */ + struct vqueue_info *vs_queues; /* one per vc_nvq */ + int vs_curq; /* current queue */ + uint8_t vs_status; /* value from last status write */ + uint8_t vs_isr; /* ISR flags, if not MSI-X */ + uint16_t vs_msix_cfg_idx; /* MSI-X vector for config event */ +}; + +#define VS_LOCK(vs) \ +do { \ + if (vs->vs_mtx) \ + pthread_mutex_lock(vs->vs_mtx); \ +} while (0) + +#define VS_UNLOCK(vs) \ +do { \ + if (vs->vs_mtx) \ + pthread_mutex_unlock(vs->vs_mtx); \ +} while (0) + +struct virtio_consts { + const char *vc_name; /* name of driver (for diagnostics) */ + int vc_nvq; /* number of virtual queues */ + size_t vc_cfgsize; /* size of dev-specific config regs */ + void (*vc_reset)(void *); /* called on virtual device reset */ + void (*vc_qnotify)(void *, struct vqueue_info *); + /* called on QNOTIFY if no VQ notify */ + int (*vc_cfgread)(void *, int, int, uint32_t *); + /* called to read config regs */ + int (*vc_cfgwrite)(void *, int, int, uint32_t); + /* called to write config regs */ + void (*vc_apply_features)(void *, uint64_t); + /* called to apply negotiated features */ + uint64_t vc_hv_caps; /* hypervisor-provided capabilities */ +}; + +/* + * Data structure allocated (statically) per virtual queue. + * + * Drivers may change vq_qsize after a reset. When the guest OS + * requests a device reset, the hypervisor first calls + * vs->vs_vc->vc_reset(); then the data structure below is + * reinitialized (for each virtqueue: vs->vs_vc->vc_nvq). + * + * The remaining fields should only be fussed-with by the generic + * code. + * + * Note: the addresses of vq_desc, vq_avail, and vq_used are all + * computable from each other, but it's a lot simpler if we just + * keep a pointer to each one. The event indices are similarly + * (but more easily) computable, and this time we'll compute them: + * they're just XX_ring[N]. + */ +#define VQ_ALLOC 0x01 /* set once we have a pfn */ +#define VQ_BROKED 0x02 /* ??? */ +struct vqueue_info { + uint16_t vq_qsize; /* size of this queue (a power of 2) */ + void (*vq_notify)(void *, struct vqueue_info *); + /* called instead of vc_notify, if not NULL */ + + struct virtio_softc *vq_vs; /* backpointer to softc */ + uint16_t vq_num; /* we're the num'th queue in the softc */ + + uint16_t vq_flags; /* flags (see above) */ + uint16_t vq_last_avail; /* a recent value of vq_avail->va_idx */ + uint16_t vq_save_used; /* saved vq_used->vu_idx; see vq_endchains */ + uint16_t vq_msix_idx; /* MSI-X index, or VIRTIO_MSI_NO_VECTOR */ + + uint32_t vq_pfn; /* PFN of virt queue (not shifted!) */ + + volatile struct virtio_desc *vq_desc; /* descriptor array */ + volatile struct vring_avail *vq_avail; /* the "avail" ring */ + volatile struct vring_used *vq_used; /* the "used" ring */ + +}; +/* as noted above, these are sort of backwards, name-wise */ +#define VQ_AVAIL_EVENT_IDX(vq) \ + (*(volatile uint16_t *)&(vq)->vq_used->vu_ring[(vq)->vq_qsize]) +#define VQ_USED_EVENT_IDX(vq) \ + ((vq)->vq_avail->va_ring[(vq)->vq_qsize]) + +/* + * Is this ring ready for I/O? + */ +static inline int +vq_ring_ready(struct vqueue_info *vq) +{ + + return (vq->vq_flags & VQ_ALLOC); +} + +/* + * Are there "available" descriptors? (This does not count + * how many, just returns True if there are some.) + */ +static inline int +vq_has_descs(struct vqueue_info *vq) +{ + + return (vq_ring_ready(vq) && vq->vq_last_avail != + vq->vq_avail->va_idx); +} + +/* + * Deliver an interrupt to guest on the given virtual queue + * (if possible, or a generic MSI interrupt if not using MSI-X). + */ +static inline void +vq_interrupt(struct virtio_softc *vs, struct vqueue_info *vq) +{ + + if (pci_msix_enabled(vs->vs_pi)) + pci_generate_msix(vs->vs_pi, vq->vq_msix_idx); + else { +#ifndef __FreeBSD__ + boolean_t unlock = B_FALSE; + + if (vs->vs_mtx && !pthread_mutex_isowned_np(vs->vs_mtx)) { + unlock = B_TRUE; + pthread_mutex_lock(vs->vs_mtx); + } +#else + VS_LOCK(vs); +#endif + vs->vs_isr |= VTCFG_ISR_QUEUES; + pci_generate_msi(vs->vs_pi, 0); + pci_lintr_assert(vs->vs_pi); +#ifndef __FreeBSD__ + if (unlock) + pthread_mutex_unlock(vs->vs_mtx); +#else + VS_UNLOCK(vs); +#endif + } +} + +struct iovec; +void vi_softc_linkup(struct virtio_softc *vs, struct virtio_consts *vc, + void *dev_softc, struct pci_devinst *pi, + struct vqueue_info *queues); +int vi_intr_init(struct virtio_softc *vs, int barnum, int use_msix); +void vi_reset_dev(struct virtio_softc *); +void vi_set_io_bar(struct virtio_softc *, int); + +int vq_getchain(struct vqueue_info *vq, uint16_t *pidx, + struct iovec *iov, int n_iov, uint16_t *flags); +void vq_retchain(struct vqueue_info *vq); +void vq_relchain(struct vqueue_info *vq, uint16_t idx, uint32_t iolen); +void vq_endchains(struct vqueue_info *vq, int used_all_avail); + +uint64_t vi_pci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size); +void vi_pci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value); +#endif /* _VIRTIO_H_ */ diff --git a/usr/src/cmd/bhyve/xmsr.c b/usr/src/cmd/bhyve/xmsr.c new file mode 100644 index 0000000000..3278ea591c --- /dev/null +++ b/usr/src/cmd/bhyve/xmsr.c @@ -0,0 +1,239 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> + +#include <machine/cpufunc.h> +#include <machine/vmm.h> +#include <machine/specialreg.h> + +#include <vmmapi.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xmsr.h" + +static int cpu_vendor_intel, cpu_vendor_amd; + +int +emulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t val) +{ + + if (cpu_vendor_intel) { + switch (num) { +#ifndef __FreeBSD__ + case MSR_PERFCTR0: + case MSR_PERFCTR1: + case MSR_EVNTSEL0: + case MSR_EVNTSEL1: + return (0); +#endif + case 0xd04: /* Sandy Bridge uncore PMCs */ + case 0xc24: + return (0); + case MSR_BIOS_UPDT_TRIG: + return (0); + case MSR_BIOS_SIGN: + return (0); + default: + break; + } + } else if (cpu_vendor_amd) { + switch (num) { + case MSR_HWCR: + /* + * Ignore writes to hardware configuration MSR. + */ + return (0); + + case MSR_NB_CFG1: + case MSR_IC_CFG: + return (0); /* Ignore writes */ + + case MSR_PERFEVSEL0: + case MSR_PERFEVSEL1: + case MSR_PERFEVSEL2: + case MSR_PERFEVSEL3: + /* Ignore writes to the PerfEvtSel MSRs */ + return (0); + + case MSR_K7_PERFCTR0: + case MSR_K7_PERFCTR1: + case MSR_K7_PERFCTR2: + case MSR_K7_PERFCTR3: + /* Ignore writes to the PerfCtr MSRs */ + return (0); + + case MSR_P_STATE_CONTROL: + /* Ignore write to change the P-state */ + return (0); + + default: + break; + } + } + return (-1); +} + +int +emulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t num, uint64_t *val) +{ + int error = 0; + + if (cpu_vendor_intel) { + switch (num) { + case MSR_BIOS_SIGN: + case MSR_IA32_PLATFORM_ID: + case MSR_PKG_ENERGY_STATUS: + case MSR_PP0_ENERGY_STATUS: + case MSR_PP1_ENERGY_STATUS: + case MSR_DRAM_ENERGY_STATUS: + *val = 0; + break; + case MSR_RAPL_POWER_UNIT: + /* + * Use the default value documented in section + * "RAPL Interfaces" in Intel SDM vol3. + */ + *val = 0x000a1003; + break; + default: + error = -1; + break; + } + } else if (cpu_vendor_amd) { + switch (num) { + case MSR_BIOS_SIGN: + *val = 0; + break; + case MSR_HWCR: + /* + * Bios and Kernel Developer's Guides for AMD Families + * 12H, 14H, 15H and 16H. + */ + *val = 0x01000010; /* Reset value */ + *val |= 1 << 9; /* MONITOR/MWAIT disable */ + break; + + case MSR_NB_CFG1: + case MSR_IC_CFG: + /* + * The reset value is processor family dependent so + * just return 0. + */ + *val = 0; + break; + + case MSR_PERFEVSEL0: + case MSR_PERFEVSEL1: + case MSR_PERFEVSEL2: + case MSR_PERFEVSEL3: + /* + * PerfEvtSel MSRs are not properly virtualized so just + * return zero. + */ + *val = 0; + break; + + case MSR_K7_PERFCTR0: + case MSR_K7_PERFCTR1: + case MSR_K7_PERFCTR2: + case MSR_K7_PERFCTR3: + /* + * PerfCtr MSRs are not properly virtualized so just + * return zero. + */ + *val = 0; + break; + + case MSR_SMM_ADDR: + case MSR_SMM_MASK: + /* + * Return the reset value defined in the AMD Bios and + * Kernel Developer's Guide. + */ + *val = 0; + break; + + case MSR_P_STATE_LIMIT: + case MSR_P_STATE_CONTROL: + case MSR_P_STATE_STATUS: + case MSR_P_STATE_CONFIG(0): /* P0 configuration */ + *val = 0; + break; + + /* + * OpenBSD guests test bit 0 of this MSR to detect if the + * workaround for erratum 721 is already applied. + * https://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf + */ + case 0xC0011029: + *val = 1; + break; + + default: + error = -1; + break; + } + } else { + error = -1; + } + return (error); +} + +int +init_msr(void) +{ + int error; + u_int regs[4]; + char cpu_vendor[13]; + + do_cpuid(0, regs); + ((u_int *)&cpu_vendor)[0] = regs[1]; + ((u_int *)&cpu_vendor)[1] = regs[3]; + ((u_int *)&cpu_vendor)[2] = regs[2]; + cpu_vendor[12] = '\0'; + + error = 0; + if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { + cpu_vendor_amd = 1; + } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) { + cpu_vendor_intel = 1; + } else { + fprintf(stderr, "Unknown cpu vendor \"%s\"\n", cpu_vendor); + error = -1; + } + return (error); +} diff --git a/usr/src/cmd/bhyve/xmsr.h b/usr/src/cmd/bhyve/xmsr.h new file mode 100644 index 0000000000..1fb47c3ae2 --- /dev/null +++ b/usr/src/cmd/bhyve/xmsr.h @@ -0,0 +1,38 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ + +#ifndef _XMSR_H_ +#define _XMSR_H_ + +int init_msr(void); +int emulate_wrmsr(struct vmctx *ctx, int vcpu, uint32_t code, uint64_t val); +int emulate_rdmsr(struct vmctx *ctx, int vcpu, uint32_t code, uint64_t *val); + +#endif diff --git a/usr/src/cmd/bhyve/zhyve.c b/usr/src/cmd/bhyve/zhyve.c new file mode 100644 index 0000000000..d3e764b14d --- /dev/null +++ b/usr/src/cmd/bhyve/zhyve.c @@ -0,0 +1,167 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2018, Joyent, Inc. + */ + +/* + * This small 'zhyve' stub is init for the zone: we therefore need to pick up + * our command-line arguments placed in ZHYVE_CMD_FILE by the boot stub, do a + * little administration, and exec the real bhyve binary. + */ + +#include <assert.h> +#include <errno.h> +#include <fcntl.h> +#include <libnvpair.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <sys/corectl.h> + +#define ZHYVE_CMD_FILE "/var/run/bhyve/zhyve.cmd" + +/* + * Do a read of the specified size or return an error. Returns 0 on success + * and -1 on error. Sets errno to EINVAL if EOF is encountered. For other + * errors, see read(2). + */ +static int +full_read(int fd, char *buf, size_t len) +{ + ssize_t nread = 0; + size_t totread = 0; + + while (totread < len) { + nread = read(fd, buf + totread, len - totread); + if (nread == 0) { + errno = EINVAL; + return (-1); + } + if (nread < 0) { + if (errno == EINTR || errno == EAGAIN) { + continue; + } + return (-1); + } + totread += nread; + } + assert(totread == len); + + return (0); +} + +/* + * Reads the command line options from the packed nvlist in the file referenced + * by path. On success, 0 is returned and the members of *argv reference memory + * allocated from an nvlist. On failure, -1 is returned. + */ + +static int +parse_options_file(const char *path, uint_t *argcp, char ***argvp) +{ + int fd = -1; + struct stat stbuf; + char *buf = NULL; + nvlist_t *nvl = NULL; + int ret; + + if ((fd = open(path, O_RDONLY)) < 0 || + fstat(fd, &stbuf) != 0 || + (buf = malloc(stbuf.st_size)) == NULL || + full_read(fd, buf, stbuf.st_size) != 0 || + nvlist_unpack(buf, stbuf.st_size, &nvl, 0) != 0 || + nvlist_lookup_string_array(nvl, "bhyve_args", argvp, argcp) != 0) { + nvlist_free(nvl); + ret = -1; + } else { + ret = 0; + } + + free(buf); + (void) close(fd); + + (void) printf("Configuration from %s:\n", path); + nvlist_print(stdout, nvl); + + return (ret); +} + +/* + * Setup to suppress core dumps within the zone. + */ +static void +config_core_dumps() +{ + (void) core_set_options(0x0); +} + +int +main(int argc, char **argv) +{ + char **tmpargs; + uint_t zargc; + char **zargv; + int fd; + + config_core_dumps(); + + fd = open("/dev/null", O_WRONLY); + assert(fd >= 0); + if (fd != STDIN_FILENO) { + (void) dup2(fd, STDIN_FILENO); + (void) close(fd); + } + + fd = open("/dev/zfd/1", O_WRONLY); + assert(fd >= 0); + if (fd != STDOUT_FILENO) { + (void) dup2(fd, STDOUT_FILENO); + (void) close(fd); + } + setvbuf(stdout, NULL, _IONBF, 0); + + fd = open("/dev/zfd/2", O_WRONLY); + assert(fd >= 0); + if (fd != STDERR_FILENO) { + (void) dup2(fd, STDERR_FILENO); + (void) close(fd); + } + setvbuf(stderr, NULL, _IONBF, 0); + + if (parse_options_file(ZHYVE_CMD_FILE, &zargc, &zargv) != 0) { + (void) fprintf(stderr, "%s: failed to parse %s: %s\n", + argv[0], ZHYVE_CMD_FILE, strerror(errno)); + return (EXIT_FAILURE); + } + + /* + * Annoyingly, we need a NULL at the end. + */ + + if ((tmpargs = malloc(sizeof (*zargv) * (zargc + 1))) == NULL) { + perror("malloc failed"); + return (EXIT_FAILURE); + } + + memcpy(tmpargs, zargv, sizeof (*zargv) * zargc); + tmpargs[zargc] = NULL; + + (void) execv("/usr/sbin/bhyve", tmpargs); + + perror("execv failed"); + return (EXIT_FAILURE); +} diff --git a/usr/src/cmd/bhyvectl/Makefile b/usr/src/cmd/bhyvectl/Makefile new file mode 100644 index 0000000000..11b16ca4df --- /dev/null +++ b/usr/src/cmd/bhyvectl/Makefile @@ -0,0 +1,57 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2013 Pluribus Networks Inc. +# Copyright 2018 Joyent, Inc. +# + +PROG = bhyvectl + +include ../Makefile.cmd +include ../Makefile.cmd.64 + +SRCS = bhyvectl.c +OBJS = $(SRCS:.c=.o) humanize_number.o + +CLEANFILES = $(PROG) +CLOBBERFILES += $(ROOTUSRSBINPROG) + +.KEEP_STATE: + +CFLAGS += $(CCVERBOSE) +CPPFLAGS = -I$(COMPAT)/freebsd -I$(CONTRIB)/freebsd \ + -I$(COMPAT)/freebsd/amd64 -I$(CONTRIB)/freebsd/amd64 \ + $(CPPFLAGS.master) \ + -I$(ROOT)/usr/platform/i86pc/include \ + -I$(SRC)/uts/i86pc/io/vmm +LDLIBS += -lvmmapi + +CERRWARN += -_gcc=-Wno-uninitialized + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS) + $(POST_PROCESS) + +install: all $(ROOTUSRSBINPROG) + +clean: + $(RM) $(OBJS) $(CLEANFILES) + +lint: lint_SRCS + +include ../Makefile.targ + +%.o: $(CONTRIB)/freebsd/lib/libutil/%.c + $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) diff --git a/usr/src/cmd/bhyvectl/bhyvectl.c b/usr/src/cmd/bhyvectl/bhyvectl.c new file mode 100644 index 0000000000..d7179d5874 --- /dev/null +++ b/usr/src/cmd/bhyvectl/bhyvectl.c @@ -0,0 +1,2372 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + * + * $FreeBSD$ + */ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Pluribus Networks Inc. + * Copyright 2017 Joyent, Inc. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/sysctl.h> +#include <sys/errno.h> +#include <sys/mman.h> +#include <sys/cpuset.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <unistd.h> +#include <libgen.h> +#include <libutil.h> +#include <fcntl.h> +#include <getopt.h> +#include <time.h> +#include <assert.h> +#include <libutil.h> + +#include <machine/cpufunc.h> +#include <machine/specialreg.h> +#include <machine/vmm.h> +#include <machine/vmm_dev.h> +#include <vmmapi.h> + +#include "amd/vmcb.h" +#include "intel/vmcs.h" + +#define MB (1UL << 20) +#define GB (1UL << 30) + +#define REQ_ARG required_argument +#define NO_ARG no_argument +#define OPT_ARG optional_argument + +static const char *progname; + +static void +usage(bool cpu_intel) +{ + + (void)fprintf(stderr, + "Usage: %s --vm=<vmname>\n" + " [--cpu=<vcpu_number>]\n" + " [--create]\n" + " [--destroy]\n" + " [--get-all]\n" + " [--get-stats]\n" + " [--set-desc-ds]\n" + " [--get-desc-ds]\n" + " [--set-desc-es]\n" + " [--get-desc-es]\n" + " [--set-desc-gs]\n" + " [--get-desc-gs]\n" + " [--set-desc-fs]\n" + " [--get-desc-fs]\n" + " [--set-desc-cs]\n" + " [--get-desc-cs]\n" + " [--set-desc-ss]\n" + " [--get-desc-ss]\n" + " [--set-desc-tr]\n" + " [--get-desc-tr]\n" + " [--set-desc-ldtr]\n" + " [--get-desc-ldtr]\n" + " [--set-desc-gdtr]\n" + " [--get-desc-gdtr]\n" + " [--set-desc-idtr]\n" + " [--get-desc-idtr]\n" + " [--run]\n" + " [--capname=<capname>]\n" + " [--getcap]\n" + " [--setcap=<0|1>]\n" + " [--desc-base=<BASE>]\n" + " [--desc-limit=<LIMIT>]\n" + " [--desc-access=<ACCESS>]\n" + " [--set-cr0=<CR0>]\n" + " [--get-cr0]\n" + " [--set-cr2=<CR2>]\n" + " [--get-cr2]\n" + " [--set-cr3=<CR3>]\n" + " [--get-cr3]\n" + " [--set-cr4=<CR4>]\n" + " [--get-cr4]\n" + " [--set-dr0=<DR0>]\n" + " [--get-dr0]\n" + " [--set-dr1=<DR1>]\n" + " [--get-dr1]\n" + " [--set-dr2=<DR2>]\n" + " [--get-dr2]\n" + " [--set-dr3=<DR3>]\n" + " [--get-dr3]\n" + " [--set-dr6=<DR6>]\n" + " [--get-dr6]\n" + " [--set-dr7=<DR7>]\n" + " [--get-dr7]\n" + " [--set-rsp=<RSP>]\n" + " [--get-rsp]\n" + " [--set-rip=<RIP>]\n" + " [--get-rip]\n" + " [--get-rax]\n" + " [--set-rax=<RAX>]\n" + " [--get-rbx]\n" + " [--get-rcx]\n" + " [--get-rdx]\n" + " [--get-rsi]\n" + " [--get-rdi]\n" + " [--get-rbp]\n" + " [--get-r8]\n" + " [--get-r9]\n" + " [--get-r10]\n" + " [--get-r11]\n" + " [--get-r12]\n" + " [--get-r13]\n" + " [--get-r14]\n" + " [--get-r15]\n" + " [--set-rflags=<RFLAGS>]\n" + " [--get-rflags]\n" + " [--set-cs]\n" + " [--get-cs]\n" + " [--set-ds]\n" + " [--get-ds]\n" + " [--set-es]\n" + " [--get-es]\n" + " [--set-fs]\n" + " [--get-fs]\n" + " [--set-gs]\n" + " [--get-gs]\n" + " [--set-ss]\n" + " [--get-ss]\n" + " [--get-tr]\n" + " [--get-ldtr]\n" + " [--set-x2apic-state=<state>]\n" + " [--get-x2apic-state]\n" +#ifdef __FreeBSD__ + " [--unassign-pptdev=<bus/slot/func>]\n" +#endif + " [--set-mem=<memory in units of MB>]\n" + " [--get-lowmem]\n" + " [--get-highmem]\n" + " [--get-gpa-pmap]\n" + " [--assert-lapic-lvt=<pin>]\n" + " [--inject-nmi]\n" + " [--force-reset]\n" + " [--force-poweroff]\n" + " [--get-rtc-time]\n" + " [--set-rtc-time=<secs>]\n" + " [--get-rtc-nvram]\n" + " [--set-rtc-nvram=<val>]\n" + " [--rtc-nvram-offset=<offset>]\n" + " [--get-active-cpus]\n" + " [--get-suspended-cpus]\n" + " [--get-intinfo]\n" + " [--get-eptp]\n" + " [--set-exception-bitmap]\n" + " [--get-exception-bitmap]\n" + " [--get-tsc-offset]\n" + " [--get-guest-pat]\n" + " [--get-io-bitmap-address]\n" + " [--get-msr-bitmap]\n" + " [--get-msr-bitmap-address]\n" + " [--get-guest-sysenter]\n" + " [--get-exit-reason]\n" + " [--get-cpu-topology]\n", + progname); + + if (cpu_intel) { + (void)fprintf(stderr, + " [--get-vmcs-pinbased-ctls]\n" + " [--get-vmcs-procbased-ctls]\n" + " [--get-vmcs-procbased-ctls2]\n" + " [--get-vmcs-entry-interruption-info]\n" + " [--set-vmcs-entry-interruption-info=<info>]\n" + " [--get-vmcs-guest-physical-address\n" + " [--get-vmcs-guest-linear-address\n" + " [--get-vmcs-host-pat]\n" + " [--get-vmcs-host-cr0]\n" + " [--get-vmcs-host-cr3]\n" + " [--get-vmcs-host-cr4]\n" + " [--get-vmcs-host-rip]\n" + " [--get-vmcs-host-rsp]\n" + " [--get-vmcs-cr0-mask]\n" + " [--get-vmcs-cr0-shadow]\n" + " [--get-vmcs-cr4-mask]\n" + " [--get-vmcs-cr4-shadow]\n" + " [--get-vmcs-cr3-targets]\n" + " [--get-vmcs-apic-access-address]\n" + " [--get-vmcs-virtual-apic-address]\n" + " [--get-vmcs-tpr-threshold]\n" + " [--get-vmcs-vpid]\n" + " [--get-vmcs-instruction-error]\n" + " [--get-vmcs-exit-ctls]\n" + " [--get-vmcs-entry-ctls]\n" + " [--get-vmcs-link]\n" + " [--get-vmcs-exit-qualification]\n" + " [--get-vmcs-exit-interruption-info]\n" + " [--get-vmcs-exit-interruption-error]\n" + " [--get-vmcs-interruptibility]\n" + ); + } else { + (void)fprintf(stderr, + " [--get-vmcb-intercepts]\n" + " [--get-vmcb-asid]\n" + " [--get-vmcb-exit-details]\n" + " [--get-vmcb-tlb-ctrl]\n" + " [--get-vmcb-virq]\n" + " [--get-avic-apic-bar]\n" + " [--get-avic-backing-page]\n" + " [--get-avic-table]\n" + ); + } + exit(1); +} + +static int get_rtc_time, set_rtc_time; +static int get_rtc_nvram, set_rtc_nvram; +static int rtc_nvram_offset; +static uint8_t rtc_nvram_value; +static time_t rtc_secs; + +static int get_stats, getcap, setcap, capval, get_gpa_pmap; +static int inject_nmi, assert_lapic_lvt; +static int force_reset, force_poweroff; +static const char *capname; +static int create, destroy, get_memmap, get_memseg; +static int get_intinfo; +static int get_active_cpus, get_suspended_cpus; +static uint64_t memsize; +static int set_cr0, get_cr0, set_cr2, get_cr2, set_cr3, get_cr3; +static int set_cr4, get_cr4; +static int set_efer, get_efer; +static int set_dr0, get_dr0; +static int set_dr1, get_dr1; +static int set_dr2, get_dr2; +static int set_dr3, get_dr3; +static int set_dr6, get_dr6; +static int set_dr7, get_dr7; +static int set_rsp, get_rsp, set_rip, get_rip, set_rflags, get_rflags; +static int set_rax, get_rax; +static int get_rbx, get_rcx, get_rdx, get_rsi, get_rdi, get_rbp; +static int get_r8, get_r9, get_r10, get_r11, get_r12, get_r13, get_r14, get_r15; +static int set_desc_ds, get_desc_ds; +static int set_desc_es, get_desc_es; +static int set_desc_fs, get_desc_fs; +static int set_desc_gs, get_desc_gs; +static int set_desc_cs, get_desc_cs; +static int set_desc_ss, get_desc_ss; +static int set_desc_gdtr, get_desc_gdtr; +static int set_desc_idtr, get_desc_idtr; +static int set_desc_tr, get_desc_tr; +static int set_desc_ldtr, get_desc_ldtr; +static int set_cs, set_ds, set_es, set_fs, set_gs, set_ss, set_tr, set_ldtr; +static int get_cs, get_ds, get_es, get_fs, get_gs, get_ss, get_tr, get_ldtr; +static int set_x2apic_state, get_x2apic_state; +enum x2apic_state x2apic_state; +#ifdef __FreeBSD__ +static int unassign_pptdev, bus, slot, func; +#endif +static int run; +static int get_cpu_topology; + +/* + * VMCB specific. + */ +static int get_vmcb_intercept, get_vmcb_exit_details, get_vmcb_tlb_ctrl; +static int get_vmcb_virq, get_avic_table; + +/* + * VMCS-specific fields + */ +static int get_pinbased_ctls, get_procbased_ctls, get_procbased_ctls2; +static int get_eptp, get_io_bitmap, get_tsc_offset; +static int get_vmcs_entry_interruption_info, set_vmcs_entry_interruption_info; +static int get_vmcs_interruptibility; +uint32_t vmcs_entry_interruption_info; +static int get_vmcs_gpa, get_vmcs_gla; +static int get_exception_bitmap, set_exception_bitmap, exception_bitmap; +static int get_cr0_mask, get_cr0_shadow; +static int get_cr4_mask, get_cr4_shadow; +static int get_cr3_targets; +static int get_apic_access_addr, get_virtual_apic_addr, get_tpr_threshold; +static int get_msr_bitmap, get_msr_bitmap_address; +static int get_vpid_asid; +static int get_inst_err, get_exit_ctls, get_entry_ctls; +static int get_host_cr0, get_host_cr3, get_host_cr4; +static int get_host_rip, get_host_rsp; +static int get_guest_pat, get_host_pat; +static int get_guest_sysenter, get_vmcs_link; +static int get_exit_reason, get_vmcs_exit_qualification; +static int get_vmcs_exit_interruption_info, get_vmcs_exit_interruption_error; +static int get_vmcs_exit_inst_length; + +static uint64_t desc_base; +static uint32_t desc_limit, desc_access; + +static int get_all; + +static void +dump_vm_run_exitcode(struct vm_exit *vmexit, int vcpu) +{ + printf("vm exit[%d]\n", vcpu); + printf("\trip\t\t0x%016lx\n", vmexit->rip); + printf("\tinst_length\t%d\n", vmexit->inst_length); + switch (vmexit->exitcode) { + case VM_EXITCODE_INOUT: + printf("\treason\t\tINOUT\n"); + printf("\tdirection\t%s\n", vmexit->u.inout.in ? "IN" : "OUT"); + printf("\tbytes\t\t%d\n", vmexit->u.inout.bytes); + printf("\tflags\t\t%s%s\n", + vmexit->u.inout.string ? "STRING " : "", + vmexit->u.inout.rep ? "REP " : ""); + printf("\tport\t\t0x%04x\n", vmexit->u.inout.port); + printf("\teax\t\t0x%08x\n", vmexit->u.inout.eax); + break; + case VM_EXITCODE_VMX: + printf("\treason\t\tVMX\n"); + printf("\tstatus\t\t%d\n", vmexit->u.vmx.status); + printf("\texit_reason\t0x%08x (%u)\n", + vmexit->u.vmx.exit_reason, vmexit->u.vmx.exit_reason); + printf("\tqualification\t0x%016lx\n", + vmexit->u.vmx.exit_qualification); + printf("\tinst_type\t\t%d\n", vmexit->u.vmx.inst_type); + printf("\tinst_error\t\t%d\n", vmexit->u.vmx.inst_error); + break; + case VM_EXITCODE_SVM: + printf("\treason\t\tSVM\n"); + printf("\texit_reason\t\t%#lx\n", vmexit->u.svm.exitcode); + printf("\texitinfo1\t\t%#lx\n", vmexit->u.svm.exitinfo1); + printf("\texitinfo2\t\t%#lx\n", vmexit->u.svm.exitinfo2); + break; + default: + printf("*** unknown vm run exitcode %d\n", vmexit->exitcode); + break; + } +} + +/* AMD 6th generation and Intel compatible MSRs */ +#define MSR_AMD6TH_START 0xC0000000 +#define MSR_AMD6TH_END 0xC0001FFF +/* AMD 7th and 8th generation compatible MSRs */ +#define MSR_AMD7TH_START 0xC0010000 +#define MSR_AMD7TH_END 0xC0011FFF + +static const char * +msr_name(uint32_t msr) +{ + static char buf[32]; + + switch(msr) { + case MSR_TSC: + return ("MSR_TSC"); + case MSR_EFER: + return ("MSR_EFER"); + case MSR_STAR: + return ("MSR_STAR"); + case MSR_LSTAR: + return ("MSR_LSTAR"); + case MSR_CSTAR: + return ("MSR_CSTAR"); + case MSR_SF_MASK: + return ("MSR_SF_MASK"); + case MSR_FSBASE: + return ("MSR_FSBASE"); + case MSR_GSBASE: + return ("MSR_GSBASE"); + case MSR_KGSBASE: + return ("MSR_KGSBASE"); + case MSR_SYSENTER_CS_MSR: + return ("MSR_SYSENTER_CS_MSR"); + case MSR_SYSENTER_ESP_MSR: + return ("MSR_SYSENTER_ESP_MSR"); + case MSR_SYSENTER_EIP_MSR: + return ("MSR_SYSENTER_EIP_MSR"); + case MSR_PAT: + return ("MSR_PAT"); + } + snprintf(buf, sizeof(buf), "MSR %#08x", msr); + + return (buf); +} + +static inline void +print_msr_pm(uint64_t msr, int vcpu, int readable, int writeable) +{ + + if (readable || writeable) { + printf("%-20s[%d]\t\t%c%c\n", msr_name(msr), vcpu, + readable ? 'R' : '-', writeable ? 'W' : '-'); + } +} + +/* + * Reference APM vol2, section 15.11 MSR Intercepts. + */ +static void +dump_amd_msr_pm(const char *bitmap, int vcpu) +{ + int byte, bit, readable, writeable; + uint32_t msr; + + for (msr = 0; msr < 0x2000; msr++) { + byte = msr / 4; + bit = (msr % 4) * 2; + + /* Look at MSRs in the range 0x00000000 to 0x00001FFF */ + readable = (bitmap[byte] & (1 << bit)) ? 0 : 1; + writeable = (bitmap[byte] & (2 << bit)) ? 0 : 1; + print_msr_pm(msr, vcpu, readable, writeable); + + /* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */ + byte += 2048; + readable = (bitmap[byte] & (1 << bit)) ? 0 : 1; + writeable = (bitmap[byte] & (2 << bit)) ? 0 : 1; + print_msr_pm(msr + MSR_AMD6TH_START, vcpu, readable, + writeable); + + /* MSR 0xC0010000 to 0xC0011FF is only for AMD */ + byte += 4096; + readable = (bitmap[byte] & (1 << bit)) ? 0 : 1; + writeable = (bitmap[byte] & (2 << bit)) ? 0 : 1; + print_msr_pm(msr + MSR_AMD7TH_START, vcpu, readable, + writeable); + } +} + +/* + * Reference Intel SDM Vol3 Section 24.6.9 MSR-Bitmap Address + */ +static void +dump_intel_msr_pm(const char *bitmap, int vcpu) +{ + int byte, bit, readable, writeable; + uint32_t msr; + + for (msr = 0; msr < 0x2000; msr++) { + byte = msr / 8; + bit = msr & 0x7; + + /* Look at MSRs in the range 0x00000000 to 0x00001FFF */ + readable = (bitmap[byte] & (1 << bit)) ? 0 : 1; + writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1; + print_msr_pm(msr, vcpu, readable, writeable); + + /* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */ + byte += 1024; + readable = (bitmap[byte] & (1 << bit)) ? 0 : 1; + writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1; + print_msr_pm(msr + MSR_AMD6TH_START, vcpu, readable, + writeable); + } +} + +static int +dump_msr_bitmap(int vcpu, uint64_t addr, bool cpu_intel) +{ + int error, fd, map_size; + const char *bitmap; + + error = -1; + bitmap = MAP_FAILED; + + fd = open("/dev/mem", O_RDONLY, 0); + if (fd < 0) { + perror("Couldn't open /dev/mem"); + goto done; + } + + if (cpu_intel) + map_size = PAGE_SIZE; + else + map_size = 2 * PAGE_SIZE; + + bitmap = mmap(NULL, map_size, PROT_READ, MAP_SHARED, fd, addr); + if (bitmap == MAP_FAILED) { + perror("mmap failed"); + goto done; + } + + if (cpu_intel) + dump_intel_msr_pm(bitmap, vcpu); + else + dump_amd_msr_pm(bitmap, vcpu); + + error = 0; +done: + if (bitmap != MAP_FAILED) + munmap((void *)bitmap, map_size); + if (fd >= 0) + close(fd); + + return (error); +} + +static int +vm_get_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t *ret_val) +{ + + return (vm_get_register(ctx, vcpu, VMCS_IDENT(field), ret_val)); +} + +static int +vm_set_vmcs_field(struct vmctx *ctx, int vcpu, int field, uint64_t val) +{ + + return (vm_set_register(ctx, vcpu, VMCS_IDENT(field), val)); +} + +static int +vm_get_vmcb_field(struct vmctx *ctx, int vcpu, int off, int bytes, + uint64_t *ret_val) +{ + + return (vm_get_register(ctx, vcpu, VMCB_ACCESS(off, bytes), ret_val)); +} + +static int +vm_set_vmcb_field(struct vmctx *ctx, int vcpu, int off, int bytes, + uint64_t val) +{ + + return (vm_set_register(ctx, vcpu, VMCB_ACCESS(off, bytes), val)); +} + +enum { + VMNAME = 1000, /* avoid collision with return values from getopt */ + VCPU, + SET_MEM, + SET_EFER, + SET_CR0, + SET_CR2, + SET_CR3, + SET_CR4, + SET_DR0, + SET_DR1, + SET_DR2, + SET_DR3, + SET_DR6, + SET_DR7, + SET_RSP, + SET_RIP, + SET_RAX, + SET_RFLAGS, + DESC_BASE, + DESC_LIMIT, + DESC_ACCESS, + SET_CS, + SET_DS, + SET_ES, + SET_FS, + SET_GS, + SET_SS, + SET_TR, + SET_LDTR, + SET_X2APIC_STATE, + SET_EXCEPTION_BITMAP, + SET_VMCS_ENTRY_INTERRUPTION_INFO, + SET_CAP, + CAPNAME, + UNASSIGN_PPTDEV, + GET_GPA_PMAP, + ASSERT_LAPIC_LVT, + SET_RTC_TIME, + SET_RTC_NVRAM, + RTC_NVRAM_OFFSET, +}; + +static void +print_cpus(const char *banner, const cpuset_t *cpus) +{ + int i; + int first; + + first = 1; + printf("%s:\t", banner); + if (!CPU_EMPTY(cpus)) { + for (i = 0; i < CPU_SETSIZE; i++) { + if (CPU_ISSET(i, cpus)) { + printf("%s%d", first ? " " : ", ", i); + first = 0; + } + } + } else + printf(" (none)"); + printf("\n"); +} + +static void +print_intinfo(const char *banner, uint64_t info) +{ + int type; + + printf("%s:\t", banner); + if (info & VM_INTINFO_VALID) { + type = info & VM_INTINFO_TYPE; + switch (type) { + case VM_INTINFO_HWINTR: + printf("extint"); + break; + case VM_INTINFO_NMI: + printf("nmi"); + break; + case VM_INTINFO_SWINTR: + printf("swint"); + break; + default: + printf("exception"); + break; + } + printf(" vector %d", (int)VM_INTINFO_VECTOR(info)); + if (info & VM_INTINFO_DEL_ERRCODE) + printf(" errcode %#x", (u_int)(info >> 32)); + } else { + printf("n/a"); + } + printf("\n"); +} + +static bool +cpu_vendor_intel(void) +{ + u_int regs[4]; + char cpu_vendor[13]; + + do_cpuid(0, regs); + ((u_int *)&cpu_vendor)[0] = regs[1]; + ((u_int *)&cpu_vendor)[1] = regs[3]; + ((u_int *)&cpu_vendor)[2] = regs[2]; + cpu_vendor[12] = '\0'; + + if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { + return (false); + } else if (strcmp(cpu_vendor, "GenuineIntel") == 0) { + return (true); + } else { + fprintf(stderr, "Unknown cpu vendor \"%s\"\n", cpu_vendor); + exit(1); + } +} + +static int +get_all_registers(struct vmctx *ctx, int vcpu) +{ + uint64_t cr0, cr2, cr3, cr4, dr0, dr1, dr2, dr3, dr6, dr7; + uint64_t rsp, rip, rflags, efer; + uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp; + uint64_t r8, r9, r10, r11, r12, r13, r14, r15; + int error = 0; + + if (!error && (get_efer || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_EFER, &efer); + if (error == 0) + printf("efer[%d]\t\t0x%016lx\n", vcpu, efer); + } + + if (!error && (get_cr0 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR0, &cr0); + if (error == 0) + printf("cr0[%d]\t\t0x%016lx\n", vcpu, cr0); + } + + if (!error && (get_cr2 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR2, &cr2); + if (error == 0) + printf("cr2[%d]\t\t0x%016lx\n", vcpu, cr2); + } + + if (!error && (get_cr3 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR3, &cr3); + if (error == 0) + printf("cr3[%d]\t\t0x%016lx\n", vcpu, cr3); + } + + if (!error && (get_cr4 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CR4, &cr4); + if (error == 0) + printf("cr4[%d]\t\t0x%016lx\n", vcpu, cr4); + } + + if (!error && (get_dr0 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR0, &dr0); + if (error == 0) + printf("dr0[%d]\t\t0x%016lx\n", vcpu, dr0); + } + + if (!error && (get_dr1 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR1, &dr1); + if (error == 0) + printf("dr1[%d]\t\t0x%016lx\n", vcpu, dr1); + } + + if (!error && (get_dr2 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR2, &dr2); + if (error == 0) + printf("dr2[%d]\t\t0x%016lx\n", vcpu, dr2); + } + + if (!error && (get_dr3 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR3, &dr3); + if (error == 0) + printf("dr3[%d]\t\t0x%016lx\n", vcpu, dr3); + } + + if (!error && (get_dr6 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR6, &dr6); + if (error == 0) + printf("dr6[%d]\t\t0x%016lx\n", vcpu, dr6); + } + + if (!error && (get_dr7 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DR7, &dr7); + if (error == 0) + printf("dr7[%d]\t\t0x%016lx\n", vcpu, dr7); + } + + if (!error && (get_rsp || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSP, &rsp); + if (error == 0) + printf("rsp[%d]\t\t0x%016lx\n", vcpu, rsp); + } + + if (!error && (get_rip || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RIP, &rip); + if (error == 0) + printf("rip[%d]\t\t0x%016lx\n", vcpu, rip); + } + + if (!error && (get_rax || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RAX, &rax); + if (error == 0) + printf("rax[%d]\t\t0x%016lx\n", vcpu, rax); + } + + if (!error && (get_rbx || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBX, &rbx); + if (error == 0) + printf("rbx[%d]\t\t0x%016lx\n", vcpu, rbx); + } + + if (!error && (get_rcx || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RCX, &rcx); + if (error == 0) + printf("rcx[%d]\t\t0x%016lx\n", vcpu, rcx); + } + + if (!error && (get_rdx || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDX, &rdx); + if (error == 0) + printf("rdx[%d]\t\t0x%016lx\n", vcpu, rdx); + } + + if (!error && (get_rsi || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RSI, &rsi); + if (error == 0) + printf("rsi[%d]\t\t0x%016lx\n", vcpu, rsi); + } + + if (!error && (get_rdi || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RDI, &rdi); + if (error == 0) + printf("rdi[%d]\t\t0x%016lx\n", vcpu, rdi); + } + + if (!error && (get_rbp || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RBP, &rbp); + if (error == 0) + printf("rbp[%d]\t\t0x%016lx\n", vcpu, rbp); + } + + if (!error && (get_r8 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R8, &r8); + if (error == 0) + printf("r8[%d]\t\t0x%016lx\n", vcpu, r8); + } + + if (!error && (get_r9 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R9, &r9); + if (error == 0) + printf("r9[%d]\t\t0x%016lx\n", vcpu, r9); + } + + if (!error && (get_r10 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R10, &r10); + if (error == 0) + printf("r10[%d]\t\t0x%016lx\n", vcpu, r10); + } + + if (!error && (get_r11 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R11, &r11); + if (error == 0) + printf("r11[%d]\t\t0x%016lx\n", vcpu, r11); + } + + if (!error && (get_r12 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R12, &r12); + if (error == 0) + printf("r12[%d]\t\t0x%016lx\n", vcpu, r12); + } + + if (!error && (get_r13 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R13, &r13); + if (error == 0) + printf("r13[%d]\t\t0x%016lx\n", vcpu, r13); + } + + if (!error && (get_r14 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R14, &r14); + if (error == 0) + printf("r14[%d]\t\t0x%016lx\n", vcpu, r14); + } + + if (!error && (get_r15 || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_R15, &r15); + if (error == 0) + printf("r15[%d]\t\t0x%016lx\n", vcpu, r15); + } + + if (!error && (get_rflags || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_RFLAGS, + &rflags); + if (error == 0) + printf("rflags[%d]\t0x%016lx\n", vcpu, rflags); + } + + return (error); +} + +static int +get_all_segments(struct vmctx *ctx, int vcpu) +{ + uint64_t cs, ds, es, fs, gs, ss, tr, ldtr; + int error = 0; + + if (!error && (get_desc_ds || get_all)) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_DS, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("ds desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && (get_desc_es || get_all)) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_ES, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("es desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && (get_desc_fs || get_all)) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_FS, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("fs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && (get_desc_gs || get_all)) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GS, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("gs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && (get_desc_ss || get_all)) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_SS, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("ss desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && (get_desc_cs || get_all)) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_CS, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("cs desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && (get_desc_tr || get_all)) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_TR, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("tr desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && (get_desc_ldtr || get_all)) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_LDTR, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("ldtr desc[%d]\t0x%016lx/0x%08x/0x%08x\n", + vcpu, desc_base, desc_limit, desc_access); + } + } + + if (!error && (get_desc_gdtr || get_all)) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_GDTR, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("gdtr[%d]\t\t0x%016lx/0x%08x\n", + vcpu, desc_base, desc_limit); + } + } + + if (!error && (get_desc_idtr || get_all)) { + error = vm_get_desc(ctx, vcpu, VM_REG_GUEST_IDTR, + &desc_base, &desc_limit, &desc_access); + if (error == 0) { + printf("idtr[%d]\t\t0x%016lx/0x%08x\n", + vcpu, desc_base, desc_limit); + } + } + + if (!error && (get_cs || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_CS, &cs); + if (error == 0) + printf("cs[%d]\t\t0x%04lx\n", vcpu, cs); + } + + if (!error && (get_ds || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_DS, &ds); + if (error == 0) + printf("ds[%d]\t\t0x%04lx\n", vcpu, ds); + } + + if (!error && (get_es || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_ES, &es); + if (error == 0) + printf("es[%d]\t\t0x%04lx\n", vcpu, es); + } + + if (!error && (get_fs || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_FS, &fs); + if (error == 0) + printf("fs[%d]\t\t0x%04lx\n", vcpu, fs); + } + + if (!error && (get_gs || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_GS, &gs); + if (error == 0) + printf("gs[%d]\t\t0x%04lx\n", vcpu, gs); + } + + if (!error && (get_ss || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_SS, &ss); + if (error == 0) + printf("ss[%d]\t\t0x%04lx\n", vcpu, ss); + } + + if (!error && (get_tr || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_TR, &tr); + if (error == 0) + printf("tr[%d]\t\t0x%04lx\n", vcpu, tr); + } + + if (!error && (get_ldtr || get_all)) { + error = vm_get_register(ctx, vcpu, VM_REG_GUEST_LDTR, &ldtr); + if (error == 0) + printf("ldtr[%d]\t\t0x%04lx\n", vcpu, ldtr); + } + + return (error); +} + +static int +get_misc_vmcs(struct vmctx *ctx, int vcpu) +{ + uint64_t ctl, cr0, cr3, cr4, rsp, rip, pat, addr, u64; + int error = 0; + + if (!error && (get_cr0_mask || get_all)) { + uint64_t cr0mask; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_MASK, &cr0mask); + if (error == 0) + printf("cr0_mask[%d]\t\t0x%016lx\n", vcpu, cr0mask); + } + + if (!error && (get_cr0_shadow || get_all)) { + uint64_t cr0shadow; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR0_SHADOW, + &cr0shadow); + if (error == 0) + printf("cr0_shadow[%d]\t\t0x%016lx\n", vcpu, cr0shadow); + } + + if (!error && (get_cr4_mask || get_all)) { + uint64_t cr4mask; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_MASK, &cr4mask); + if (error == 0) + printf("cr4_mask[%d]\t\t0x%016lx\n", vcpu, cr4mask); + } + + if (!error && (get_cr4_shadow || get_all)) { + uint64_t cr4shadow; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR4_SHADOW, + &cr4shadow); + if (error == 0) + printf("cr4_shadow[%d]\t\t0x%016lx\n", vcpu, cr4shadow); + } + + if (!error && (get_cr3_targets || get_all)) { + uint64_t target_count, target_addr; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET_COUNT, + &target_count); + if (error == 0) { + printf("cr3_target_count[%d]\t0x%016lx\n", + vcpu, target_count); + } + + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET0, + &target_addr); + if (error == 0) { + printf("cr3_target0[%d]\t\t0x%016lx\n", + vcpu, target_addr); + } + + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET1, + &target_addr); + if (error == 0) { + printf("cr3_target1[%d]\t\t0x%016lx\n", + vcpu, target_addr); + } + + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET2, + &target_addr); + if (error == 0) { + printf("cr3_target2[%d]\t\t0x%016lx\n", + vcpu, target_addr); + } + + error = vm_get_vmcs_field(ctx, vcpu, VMCS_CR3_TARGET3, + &target_addr); + if (error == 0) { + printf("cr3_target3[%d]\t\t0x%016lx\n", + vcpu, target_addr); + } + } + + if (!error && (get_pinbased_ctls || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_PIN_BASED_CTLS, &ctl); + if (error == 0) + printf("pinbased_ctls[%d]\t0x%016lx\n", vcpu, ctl); + } + + if (!error && (get_procbased_ctls || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_PRI_PROC_BASED_CTLS, &ctl); + if (error == 0) + printf("procbased_ctls[%d]\t0x%016lx\n", vcpu, ctl); + } + + if (!error && (get_procbased_ctls2 || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_SEC_PROC_BASED_CTLS, &ctl); + if (error == 0) + printf("procbased_ctls2[%d]\t0x%016lx\n", vcpu, ctl); + } + + if (!error && (get_vmcs_gla || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_LINEAR_ADDRESS, &u64); + if (error == 0) + printf("gla[%d]\t\t0x%016lx\n", vcpu, u64); + } + + if (!error && (get_vmcs_gpa || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_PHYSICAL_ADDRESS, &u64); + if (error == 0) + printf("gpa[%d]\t\t0x%016lx\n", vcpu, u64); + } + + if (!error && (get_vmcs_entry_interruption_info || + get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO,&u64); + if (error == 0) { + printf("entry_interruption_info[%d]\t0x%016lx\n", + vcpu, u64); + } + } + + if (!error && (get_tpr_threshold || get_all)) { + uint64_t threshold; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_TPR_THRESHOLD, + &threshold); + if (error == 0) + printf("tpr_threshold[%d]\t0x%016lx\n", vcpu, threshold); + } + + if (!error && (get_inst_err || get_all)) { + uint64_t insterr; + error = vm_get_vmcs_field(ctx, vcpu, VMCS_INSTRUCTION_ERROR, + &insterr); + if (error == 0) { + printf("instruction_error[%d]\t0x%016lx\n", + vcpu, insterr); + } + } + + if (!error && (get_exit_ctls || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_CTLS, &ctl); + if (error == 0) + printf("exit_ctls[%d]\t\t0x%016lx\n", vcpu, ctl); + } + + if (!error && (get_entry_ctls || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_ENTRY_CTLS, &ctl); + if (error == 0) + printf("entry_ctls[%d]\t\t0x%016lx\n", vcpu, ctl); + } + + if (!error && (get_host_pat || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_IA32_PAT, &pat); + if (error == 0) + printf("host_pat[%d]\t\t0x%016lx\n", vcpu, pat); + } + + if (!error && (get_host_cr0 || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR0, &cr0); + if (error == 0) + printf("host_cr0[%d]\t\t0x%016lx\n", vcpu, cr0); + } + + if (!error && (get_host_cr3 || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR3, &cr3); + if (error == 0) + printf("host_cr3[%d]\t\t0x%016lx\n", vcpu, cr3); + } + + if (!error && (get_host_cr4 || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_CR4, &cr4); + if (error == 0) + printf("host_cr4[%d]\t\t0x%016lx\n", vcpu, cr4); + } + + if (!error && (get_host_rip || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RIP, &rip); + if (error == 0) + printf("host_rip[%d]\t\t0x%016lx\n", vcpu, rip); + } + + if (!error && (get_host_rsp || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_HOST_RSP, &rsp); + if (error == 0) + printf("host_rsp[%d]\t\t0x%016lx\n", vcpu, rsp); + } + + if (!error && (get_vmcs_link || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_LINK_POINTER, &addr); + if (error == 0) + printf("vmcs_pointer[%d]\t0x%016lx\n", vcpu, addr); + } + + if (!error && (get_vmcs_exit_interruption_info || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_INTR_INFO, &u64); + if (error == 0) { + printf("vmcs_exit_interruption_info[%d]\t0x%016lx\n", + vcpu, u64); + } + } + + if (!error && (get_vmcs_exit_interruption_error || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_INTR_ERRCODE, + &u64); + if (error == 0) { + printf("vmcs_exit_interruption_error[%d]\t0x%016lx\n", + vcpu, u64); + } + } + + if (!error && (get_vmcs_interruptibility || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_INTERRUPTIBILITY, &u64); + if (error == 0) { + printf("vmcs_guest_interruptibility[%d]\t0x%016lx\n", + vcpu, u64); + } + } + + if (!error && (get_vmcs_exit_inst_length || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_EXIT_INSTRUCTION_LENGTH, &u64); + if (error == 0) + printf("vmcs_exit_inst_length[%d]\t0x%08x\n", vcpu, + (uint32_t)u64); + } + + if (!error && (get_vmcs_exit_qualification || get_all)) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_QUALIFICATION, + &u64); + if (error == 0) + printf("vmcs_exit_qualification[%d]\t0x%016lx\n", + vcpu, u64); + } + + return (error); +} + +static int +get_misc_vmcb(struct vmctx *ctx, int vcpu) +{ + uint64_t ctl, addr; + int error = 0; + + if (!error && (get_vmcb_intercept || get_all)) { + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_CR_INTERCEPT, 4, + &ctl); + if (error == 0) + printf("cr_intercept[%d]\t0x%08x\n", vcpu, (int)ctl); + + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_DR_INTERCEPT, 4, + &ctl); + if (error == 0) + printf("dr_intercept[%d]\t0x%08x\n", vcpu, (int)ctl); + + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXC_INTERCEPT, 4, + &ctl); + if (error == 0) + printf("exc_intercept[%d]\t0x%08x\n", vcpu, (int)ctl); + + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_INST1_INTERCEPT, + 4, &ctl); + if (error == 0) + printf("inst1_intercept[%d]\t0x%08x\n", vcpu, (int)ctl); + + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_INST2_INTERCEPT, + 4, &ctl); + if (error == 0) + printf("inst2_intercept[%d]\t0x%08x\n", vcpu, (int)ctl); + } + + if (!error && (get_vmcb_tlb_ctrl || get_all)) { + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_TLB_CTRL, + 4, &ctl); + if (error == 0) + printf("TLB ctrl[%d]\t0x%016lx\n", vcpu, ctl); + } + + if (!error && (get_vmcb_exit_details || get_all)) { + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXITINFO1, + 8, &ctl); + if (error == 0) + printf("exitinfo1[%d]\t0x%016lx\n", vcpu, ctl); + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXITINFO2, + 8, &ctl); + if (error == 0) + printf("exitinfo2[%d]\t0x%016lx\n", vcpu, ctl); + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_EXITINTINFO, + 8, &ctl); + if (error == 0) + printf("exitintinfo[%d]\t0x%016lx\n", vcpu, ctl); + } + + if (!error && (get_vmcb_virq || get_all)) { + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_VIRQ, + 8, &ctl); + if (error == 0) + printf("v_irq/tpr[%d]\t0x%016lx\n", vcpu, ctl); + } + + if (!error && (get_apic_access_addr || get_all)) { + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_BAR, 8, + &addr); + if (error == 0) + printf("AVIC apic_bar[%d]\t0x%016lx\n", vcpu, addr); + } + + if (!error && (get_virtual_apic_addr || get_all)) { + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_PAGE, 8, + &addr); + if (error == 0) + printf("AVIC backing page[%d]\t0x%016lx\n", vcpu, addr); + } + + if (!error && (get_avic_table || get_all)) { + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_LT, 8, + &addr); + if (error == 0) + printf("AVIC logical table[%d]\t0x%016lx\n", + vcpu, addr); + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_AVIC_PT, 8, + &addr); + if (error == 0) + printf("AVIC physical table[%d]\t0x%016lx\n", + vcpu, addr); + } + + return (error); +} + +static struct option * +setup_options(bool cpu_intel) +{ + const struct option common_opts[] = { + { "vm", REQ_ARG, 0, VMNAME }, + { "cpu", REQ_ARG, 0, VCPU }, + { "set-mem", REQ_ARG, 0, SET_MEM }, + { "set-efer", REQ_ARG, 0, SET_EFER }, + { "set-cr0", REQ_ARG, 0, SET_CR0 }, + { "set-cr2", REQ_ARG, 0, SET_CR2 }, + { "set-cr3", REQ_ARG, 0, SET_CR3 }, + { "set-cr4", REQ_ARG, 0, SET_CR4 }, + { "set-dr0", REQ_ARG, 0, SET_DR0 }, + { "set-dr1", REQ_ARG, 0, SET_DR1 }, + { "set-dr2", REQ_ARG, 0, SET_DR2 }, + { "set-dr3", REQ_ARG, 0, SET_DR3 }, + { "set-dr6", REQ_ARG, 0, SET_DR6 }, + { "set-dr7", REQ_ARG, 0, SET_DR7 }, + { "set-rsp", REQ_ARG, 0, SET_RSP }, + { "set-rip", REQ_ARG, 0, SET_RIP }, + { "set-rax", REQ_ARG, 0, SET_RAX }, + { "set-rflags", REQ_ARG, 0, SET_RFLAGS }, + { "desc-base", REQ_ARG, 0, DESC_BASE }, + { "desc-limit", REQ_ARG, 0, DESC_LIMIT }, + { "desc-access",REQ_ARG, 0, DESC_ACCESS }, + { "set-cs", REQ_ARG, 0, SET_CS }, + { "set-ds", REQ_ARG, 0, SET_DS }, + { "set-es", REQ_ARG, 0, SET_ES }, + { "set-fs", REQ_ARG, 0, SET_FS }, + { "set-gs", REQ_ARG, 0, SET_GS }, + { "set-ss", REQ_ARG, 0, SET_SS }, + { "set-tr", REQ_ARG, 0, SET_TR }, + { "set-ldtr", REQ_ARG, 0, SET_LDTR }, + { "set-x2apic-state",REQ_ARG, 0, SET_X2APIC_STATE }, + { "set-exception-bitmap", + REQ_ARG, 0, SET_EXCEPTION_BITMAP }, + { "capname", REQ_ARG, 0, CAPNAME }, + { "unassign-pptdev", REQ_ARG, 0, UNASSIGN_PPTDEV }, + { "setcap", REQ_ARG, 0, SET_CAP }, + { "get-gpa-pmap", REQ_ARG, 0, GET_GPA_PMAP }, + { "assert-lapic-lvt", REQ_ARG, 0, ASSERT_LAPIC_LVT }, + { "get-rtc-time", NO_ARG, &get_rtc_time, 1 }, + { "set-rtc-time", REQ_ARG, 0, SET_RTC_TIME }, + { "rtc-nvram-offset", REQ_ARG, 0, RTC_NVRAM_OFFSET }, + { "get-rtc-nvram", NO_ARG, &get_rtc_nvram, 1 }, + { "set-rtc-nvram", REQ_ARG, 0, SET_RTC_NVRAM }, + { "getcap", NO_ARG, &getcap, 1 }, + { "get-stats", NO_ARG, &get_stats, 1 }, + { "get-desc-ds",NO_ARG, &get_desc_ds, 1 }, + { "set-desc-ds",NO_ARG, &set_desc_ds, 1 }, + { "get-desc-es",NO_ARG, &get_desc_es, 1 }, + { "set-desc-es",NO_ARG, &set_desc_es, 1 }, + { "get-desc-ss",NO_ARG, &get_desc_ss, 1 }, + { "set-desc-ss",NO_ARG, &set_desc_ss, 1 }, + { "get-desc-cs",NO_ARG, &get_desc_cs, 1 }, + { "set-desc-cs",NO_ARG, &set_desc_cs, 1 }, + { "get-desc-fs",NO_ARG, &get_desc_fs, 1 }, + { "set-desc-fs",NO_ARG, &set_desc_fs, 1 }, + { "get-desc-gs",NO_ARG, &get_desc_gs, 1 }, + { "set-desc-gs",NO_ARG, &set_desc_gs, 1 }, + { "get-desc-tr",NO_ARG, &get_desc_tr, 1 }, + { "set-desc-tr",NO_ARG, &set_desc_tr, 1 }, + { "set-desc-ldtr", NO_ARG, &set_desc_ldtr, 1 }, + { "get-desc-ldtr", NO_ARG, &get_desc_ldtr, 1 }, + { "set-desc-gdtr", NO_ARG, &set_desc_gdtr, 1 }, + { "get-desc-gdtr", NO_ARG, &get_desc_gdtr, 1 }, + { "set-desc-idtr", NO_ARG, &set_desc_idtr, 1 }, + { "get-desc-idtr", NO_ARG, &get_desc_idtr, 1 }, + { "get-memmap", NO_ARG, &get_memmap, 1 }, + { "get-memseg", NO_ARG, &get_memseg, 1 }, + { "get-efer", NO_ARG, &get_efer, 1 }, + { "get-cr0", NO_ARG, &get_cr0, 1 }, + { "get-cr2", NO_ARG, &get_cr2, 1 }, + { "get-cr3", NO_ARG, &get_cr3, 1 }, + { "get-cr4", NO_ARG, &get_cr4, 1 }, + { "get-dr0", NO_ARG, &get_dr0, 1 }, + { "get-dr1", NO_ARG, &get_dr1, 1 }, + { "get-dr2", NO_ARG, &get_dr2, 1 }, + { "get-dr3", NO_ARG, &get_dr3, 1 }, + { "get-dr6", NO_ARG, &get_dr6, 1 }, + { "get-dr7", NO_ARG, &get_dr7, 1 }, + { "get-rsp", NO_ARG, &get_rsp, 1 }, + { "get-rip", NO_ARG, &get_rip, 1 }, + { "get-rax", NO_ARG, &get_rax, 1 }, + { "get-rbx", NO_ARG, &get_rbx, 1 }, + { "get-rcx", NO_ARG, &get_rcx, 1 }, + { "get-rdx", NO_ARG, &get_rdx, 1 }, + { "get-rsi", NO_ARG, &get_rsi, 1 }, + { "get-rdi", NO_ARG, &get_rdi, 1 }, + { "get-rbp", NO_ARG, &get_rbp, 1 }, + { "get-r8", NO_ARG, &get_r8, 1 }, + { "get-r9", NO_ARG, &get_r9, 1 }, + { "get-r10", NO_ARG, &get_r10, 1 }, + { "get-r11", NO_ARG, &get_r11, 1 }, + { "get-r12", NO_ARG, &get_r12, 1 }, + { "get-r13", NO_ARG, &get_r13, 1 }, + { "get-r14", NO_ARG, &get_r14, 1 }, + { "get-r15", NO_ARG, &get_r15, 1 }, + { "get-rflags", NO_ARG, &get_rflags, 1 }, + { "get-cs", NO_ARG, &get_cs, 1 }, + { "get-ds", NO_ARG, &get_ds, 1 }, + { "get-es", NO_ARG, &get_es, 1 }, + { "get-fs", NO_ARG, &get_fs, 1 }, + { "get-gs", NO_ARG, &get_gs, 1 }, + { "get-ss", NO_ARG, &get_ss, 1 }, + { "get-tr", NO_ARG, &get_tr, 1 }, + { "get-ldtr", NO_ARG, &get_ldtr, 1 }, + { "get-eptp", NO_ARG, &get_eptp, 1 }, + { "get-exception-bitmap", + NO_ARG, &get_exception_bitmap, 1 }, + { "get-io-bitmap-address", + NO_ARG, &get_io_bitmap, 1 }, + { "get-tsc-offset", NO_ARG, &get_tsc_offset, 1 }, + { "get-msr-bitmap", + NO_ARG, &get_msr_bitmap, 1 }, + { "get-msr-bitmap-address", + NO_ARG, &get_msr_bitmap_address, 1 }, + { "get-guest-pat", NO_ARG, &get_guest_pat, 1 }, + { "get-guest-sysenter", + NO_ARG, &get_guest_sysenter, 1 }, + { "get-exit-reason", + NO_ARG, &get_exit_reason, 1 }, + { "get-x2apic-state", NO_ARG, &get_x2apic_state, 1 }, + { "get-all", NO_ARG, &get_all, 1 }, + { "run", NO_ARG, &run, 1 }, + { "create", NO_ARG, &create, 1 }, + { "destroy", NO_ARG, &destroy, 1 }, + { "inject-nmi", NO_ARG, &inject_nmi, 1 }, + { "force-reset", NO_ARG, &force_reset, 1 }, + { "force-poweroff", NO_ARG, &force_poweroff, 1 }, + { "get-active-cpus", NO_ARG, &get_active_cpus, 1 }, + { "get-suspended-cpus", NO_ARG, &get_suspended_cpus, 1 }, + { "get-intinfo", NO_ARG, &get_intinfo, 1 }, + { "get-cpu-topology", NO_ARG, &get_cpu_topology, 1 }, + }; + + const struct option intel_opts[] = { + { "get-vmcs-pinbased-ctls", + NO_ARG, &get_pinbased_ctls, 1 }, + { "get-vmcs-procbased-ctls", + NO_ARG, &get_procbased_ctls, 1 }, + { "get-vmcs-procbased-ctls2", + NO_ARG, &get_procbased_ctls2, 1 }, + { "get-vmcs-guest-linear-address", + NO_ARG, &get_vmcs_gla, 1 }, + { "get-vmcs-guest-physical-address", + NO_ARG, &get_vmcs_gpa, 1 }, + { "get-vmcs-entry-interruption-info", + NO_ARG, &get_vmcs_entry_interruption_info, 1}, + { "get-vmcs-cr0-mask", NO_ARG, &get_cr0_mask, 1 }, + { "get-vmcs-cr0-shadow", NO_ARG,&get_cr0_shadow, 1 }, + { "get-vmcs-cr4-mask", NO_ARG, &get_cr4_mask, 1 }, + { "get-vmcs-cr4-shadow", NO_ARG, &get_cr4_shadow, 1 }, + { "get-vmcs-cr3-targets", NO_ARG, &get_cr3_targets, 1 }, + { "get-vmcs-tpr-threshold", + NO_ARG, &get_tpr_threshold, 1 }, + { "get-vmcs-vpid", NO_ARG, &get_vpid_asid, 1 }, + { "get-vmcs-exit-ctls", NO_ARG, &get_exit_ctls, 1 }, + { "get-vmcs-entry-ctls", + NO_ARG, &get_entry_ctls, 1 }, + { "get-vmcs-instruction-error", + NO_ARG, &get_inst_err, 1 }, + { "get-vmcs-host-pat", NO_ARG, &get_host_pat, 1 }, + { "get-vmcs-host-cr0", + NO_ARG, &get_host_cr0, 1 }, + { "set-vmcs-entry-interruption-info", + REQ_ARG, 0, SET_VMCS_ENTRY_INTERRUPTION_INFO }, + { "get-vmcs-exit-qualification", + NO_ARG, &get_vmcs_exit_qualification, 1 }, + { "get-vmcs-exit-inst-length", + NO_ARG, &get_vmcs_exit_inst_length, 1 }, + { "get-vmcs-interruptibility", + NO_ARG, &get_vmcs_interruptibility, 1 }, + { "get-vmcs-exit-interruption-error", + NO_ARG, &get_vmcs_exit_interruption_error, 1 }, + { "get-vmcs-exit-interruption-info", + NO_ARG, &get_vmcs_exit_interruption_info, 1 }, + { "get-vmcs-link", NO_ARG, &get_vmcs_link, 1 }, + { "get-vmcs-host-cr3", + NO_ARG, &get_host_cr3, 1 }, + { "get-vmcs-host-cr4", + NO_ARG, &get_host_cr4, 1 }, + { "get-vmcs-host-rip", + NO_ARG, &get_host_rip, 1 }, + { "get-vmcs-host-rsp", + NO_ARG, &get_host_rsp, 1 }, + { "get-apic-access-address", + NO_ARG, &get_apic_access_addr, 1}, + { "get-virtual-apic-address", + NO_ARG, &get_virtual_apic_addr, 1} + }; + + const struct option amd_opts[] = { + { "get-vmcb-intercepts", + NO_ARG, &get_vmcb_intercept, 1 }, + { "get-vmcb-asid", + NO_ARG, &get_vpid_asid, 1 }, + { "get-vmcb-exit-details", + NO_ARG, &get_vmcb_exit_details, 1 }, + { "get-vmcb-tlb-ctrl", + NO_ARG, &get_vmcb_tlb_ctrl, 1 }, + { "get-vmcb-virq", + NO_ARG, &get_vmcb_virq, 1 }, + { "get-avic-apic-bar", + NO_ARG, &get_apic_access_addr, 1 }, + { "get-avic-backing-page", + NO_ARG, &get_virtual_apic_addr, 1 }, + { "get-avic-table", + NO_ARG, &get_avic_table, 1 } + }; + + const struct option null_opt = { + NULL, 0, NULL, 0 + }; + + struct option *all_opts; + char *cp; + int optlen; + + optlen = sizeof(common_opts); + + if (cpu_intel) + optlen += sizeof(intel_opts); + else + optlen += sizeof(amd_opts); + + optlen += sizeof(null_opt); + + all_opts = malloc(optlen); + + cp = (char *)all_opts; + memcpy(cp, common_opts, sizeof(common_opts)); + cp += sizeof(common_opts); + + if (cpu_intel) { + memcpy(cp, intel_opts, sizeof(intel_opts)); + cp += sizeof(intel_opts); + } else { + memcpy(cp, amd_opts, sizeof(amd_opts)); + cp += sizeof(amd_opts); + } + + memcpy(cp, &null_opt, sizeof(null_opt)); + cp += sizeof(null_opt); + + return (all_opts); +} + +static const char * +wday_str(int idx) +{ + static const char *weekdays[] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + + if (idx >= 0 && idx < 7) + return (weekdays[idx]); + else + return ("UNK"); +} + +static const char * +mon_str(int idx) +{ + static const char *months[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + + if (idx >= 0 && idx < 12) + return (months[idx]); + else + return ("UNK"); +} + +static int +show_memmap(struct vmctx *ctx) +{ + char name[SPECNAMELEN + 1], numbuf[8]; + vm_ooffset_t segoff; + vm_paddr_t gpa; + size_t maplen, seglen; + int error, flags, prot, segid, delim; + + printf("Address Length Segment Offset "); + printf("Prot Flags\n"); + + gpa = 0; + while (1) { + error = vm_mmap_getnext(ctx, &gpa, &segid, &segoff, &maplen, + &prot, &flags); + if (error) + return (errno == ENOENT ? 0 : error); + + error = vm_get_memseg(ctx, segid, &seglen, name, sizeof(name)); + if (error) + return (error); + + printf("%-12lX", gpa); + humanize_number(numbuf, sizeof(numbuf), maplen, "B", + HN_AUTOSCALE, HN_NOSPACE); + printf("%-12s", numbuf); + + printf("%-12s", name[0] ? name : "sysmem"); + printf("%-12lX", segoff); + printf("%c%c%c ", prot & PROT_READ ? 'R' : '-', + prot & PROT_WRITE ? 'W' : '-', + prot & PROT_EXEC ? 'X' : '-'); + + delim = '\0'; + if (flags & VM_MEMMAP_F_WIRED) { + printf("%cwired", delim); + delim = '/'; + } + if (flags & VM_MEMMAP_F_IOMMU) { + printf("%ciommu", delim); + delim = '/'; + } + printf("\n"); + + gpa += maplen; + } +} + +static int +show_memseg(struct vmctx *ctx) +{ + char name[SPECNAMELEN + 1], numbuf[8]; + size_t seglen; + int error, segid; + + printf("ID Length Name\n"); + + segid = 0; + while (1) { + error = vm_get_memseg(ctx, segid, &seglen, name, sizeof(name)); + if (error) + return (errno == EINVAL ? 0 : error); + + if (seglen) { + printf("%-4d", segid); + humanize_number(numbuf, sizeof(numbuf), seglen, "B", + HN_AUTOSCALE, HN_NOSPACE); + printf("%-12s", numbuf); + printf("%s", name[0] ? name : "sysmem"); + printf("\n"); + } + segid++; + } +} + +int +main(int argc, char *argv[]) +{ + char *vmname; + int error, ch, vcpu, ptenum; + vm_paddr_t gpa_pmap; + struct vm_exit vmexit; + uint64_t rax, cr0, cr2, cr3, cr4, dr0, dr1, dr2, dr3, dr6, dr7; + uint64_t rsp, rip, rflags, efer, pat; + uint64_t eptp, bm, addr, u64, pteval[4], *pte, info[2]; + struct vmctx *ctx; + cpuset_t cpus; + bool cpu_intel; + uint64_t cs, ds, es, fs, gs, ss, tr, ldtr; + struct tm tm; + struct option *opts; + + cpu_intel = cpu_vendor_intel(); + opts = setup_options(cpu_intel); + + vcpu = 0; + vmname = NULL; + assert_lapic_lvt = -1; + progname = basename(argv[0]); + + while ((ch = getopt_long(argc, argv, "", opts, NULL)) != -1) { + switch (ch) { + case 0: + break; + case VMNAME: + vmname = optarg; + break; + case VCPU: + vcpu = atoi(optarg); + break; + case SET_MEM: + memsize = atoi(optarg) * MB; + memsize = roundup(memsize, 2 * MB); + break; + case SET_EFER: + efer = strtoul(optarg, NULL, 0); + set_efer = 1; + break; + case SET_CR0: + cr0 = strtoul(optarg, NULL, 0); + set_cr0 = 1; + break; + case SET_CR2: + cr2 = strtoul(optarg, NULL, 0); + set_cr2 = 1; + break; + case SET_CR3: + cr3 = strtoul(optarg, NULL, 0); + set_cr3 = 1; + break; + case SET_CR4: + cr4 = strtoul(optarg, NULL, 0); + set_cr4 = 1; + break; + case SET_DR0: + dr0 = strtoul(optarg, NULL, 0); + set_dr0 = 1; + break; + case SET_DR1: + dr1 = strtoul(optarg, NULL, 0); + set_dr1 = 1; + break; + case SET_DR2: + dr2 = strtoul(optarg, NULL, 0); + set_dr2 = 1; + break; + case SET_DR3: + dr3 = strtoul(optarg, NULL, 0); + set_dr3 = 1; + break; + case SET_DR6: + dr6 = strtoul(optarg, NULL, 0); + set_dr6 = 1; + break; + case SET_DR7: + dr7 = strtoul(optarg, NULL, 0); + set_dr7 = 1; + break; + case SET_RSP: + rsp = strtoul(optarg, NULL, 0); + set_rsp = 1; + break; + case SET_RIP: + rip = strtoul(optarg, NULL, 0); + set_rip = 1; + break; + case SET_RAX: + rax = strtoul(optarg, NULL, 0); + set_rax = 1; + break; + case SET_RFLAGS: + rflags = strtoul(optarg, NULL, 0); + set_rflags = 1; + break; + case DESC_BASE: + desc_base = strtoul(optarg, NULL, 0); + break; + case DESC_LIMIT: + desc_limit = strtoul(optarg, NULL, 0); + break; + case DESC_ACCESS: + desc_access = strtoul(optarg, NULL, 0); + break; + case SET_CS: + cs = strtoul(optarg, NULL, 0); + set_cs = 1; + break; + case SET_DS: + ds = strtoul(optarg, NULL, 0); + set_ds = 1; + break; + case SET_ES: + es = strtoul(optarg, NULL, 0); + set_es = 1; + break; + case SET_FS: + fs = strtoul(optarg, NULL, 0); + set_fs = 1; + break; + case SET_GS: + gs = strtoul(optarg, NULL, 0); + set_gs = 1; + break; + case SET_SS: + ss = strtoul(optarg, NULL, 0); + set_ss = 1; + break; + case SET_TR: + tr = strtoul(optarg, NULL, 0); + set_tr = 1; + break; + case SET_LDTR: + ldtr = strtoul(optarg, NULL, 0); + set_ldtr = 1; + break; + case SET_X2APIC_STATE: + x2apic_state = strtol(optarg, NULL, 0); + set_x2apic_state = 1; + break; + case SET_EXCEPTION_BITMAP: + exception_bitmap = strtoul(optarg, NULL, 0); + set_exception_bitmap = 1; + break; + case SET_VMCS_ENTRY_INTERRUPTION_INFO: + vmcs_entry_interruption_info = strtoul(optarg, NULL, 0); + set_vmcs_entry_interruption_info = 1; + break; + case SET_CAP: + capval = strtoul(optarg, NULL, 0); + setcap = 1; + break; + case SET_RTC_TIME: + rtc_secs = strtoul(optarg, NULL, 0); + set_rtc_time = 1; + break; + case SET_RTC_NVRAM: + rtc_nvram_value = (uint8_t)strtoul(optarg, NULL, 0); + set_rtc_nvram = 1; + break; + case RTC_NVRAM_OFFSET: + rtc_nvram_offset = strtoul(optarg, NULL, 0); + break; + case GET_GPA_PMAP: + gpa_pmap = strtoul(optarg, NULL, 0); + get_gpa_pmap = 1; + break; + case CAPNAME: + capname = optarg; + break; +#ifdef __FreeBSD__ + case UNASSIGN_PPTDEV: + unassign_pptdev = 1; + if (sscanf(optarg, "%d/%d/%d", &bus, &slot, &func) != 3) + usage(cpu_intel); + break; +#endif + case ASSERT_LAPIC_LVT: + assert_lapic_lvt = atoi(optarg); + break; + default: + usage(cpu_intel); + } + } + argc -= optind; + argv += optind; + + if (vmname == NULL) + usage(cpu_intel); + + error = 0; + + if (!error && create) + error = vm_create(vmname); + + if (!error) { + ctx = vm_open(vmname); + if (ctx == NULL) { + printf("VM:%s is not created.\n", vmname); + exit (1); + } + } + + if (!error && memsize) + error = vm_setup_memory(ctx, memsize, VM_MMAP_ALL); + + if (!error && set_efer) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_EFER, efer); + + if (!error && set_cr0) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR0, cr0); + + if (!error && set_cr2) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR2, cr2); + + if (!error && set_cr3) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR3, cr3); + + if (!error && set_cr4) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CR4, cr4); + + if (!error && set_dr0) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR0, dr0); + + if (!error && set_dr1) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR1, dr1); + + if (!error && set_dr2) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR2, dr2); + + if (!error && set_dr3) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR3, dr3); + + if (!error && set_dr6) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR6, dr6); + + if (!error && set_dr7) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DR7, dr7); + + if (!error && set_rsp) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RSP, rsp); + + if (!error && set_rip) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RIP, rip); + + if (!error && set_rax) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RAX, rax); + + if (!error && set_rflags) { + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_RFLAGS, + rflags); + } + + if (!error && set_desc_ds) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_DS, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_es) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_ES, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_ss) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_SS, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_cs) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_CS, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_fs) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_FS, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_gs) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GS, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_tr) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_TR, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_ldtr) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_LDTR, + desc_base, desc_limit, desc_access); + } + + if (!error && set_desc_gdtr) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_GDTR, + desc_base, desc_limit, 0); + } + + if (!error && set_desc_idtr) { + error = vm_set_desc(ctx, vcpu, VM_REG_GUEST_IDTR, + desc_base, desc_limit, 0); + } + + if (!error && set_cs) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_CS, cs); + + if (!error && set_ds) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_DS, ds); + + if (!error && set_es) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_ES, es); + + if (!error && set_fs) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_FS, fs); + + if (!error && set_gs) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_GS, gs); + + if (!error && set_ss) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_SS, ss); + + if (!error && set_tr) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_TR, tr); + + if (!error && set_ldtr) + error = vm_set_register(ctx, vcpu, VM_REG_GUEST_LDTR, ldtr); + + if (!error && set_x2apic_state) + error = vm_set_x2apic_state(ctx, vcpu, x2apic_state); + +#ifdef __FreeBSD__ + if (!error && unassign_pptdev) + error = vm_unassign_pptdev(ctx, bus, slot, func); +#endif /* __FreeBSD__ */ + + if (!error && set_exception_bitmap) { + if (cpu_intel) + error = vm_set_vmcs_field(ctx, vcpu, + VMCS_EXCEPTION_BITMAP, + exception_bitmap); + else + error = vm_set_vmcb_field(ctx, vcpu, + VMCB_OFF_EXC_INTERCEPT, + 4, exception_bitmap); + } + + if (!error && cpu_intel && set_vmcs_entry_interruption_info) { + error = vm_set_vmcs_field(ctx, vcpu, VMCS_ENTRY_INTR_INFO, + vmcs_entry_interruption_info); + } + + if (!error && inject_nmi) { + error = vm_inject_nmi(ctx, vcpu); + } + + if (!error && assert_lapic_lvt != -1) { + error = vm_lapic_local_irq(ctx, vcpu, assert_lapic_lvt); + } + + if (!error && (get_memseg || get_all)) + error = show_memseg(ctx); + + if (!error && (get_memmap || get_all)) + error = show_memmap(ctx); + + if (!error) + error = get_all_registers(ctx, vcpu); + + if (!error) + error = get_all_segments(ctx, vcpu); + + if (!error) { + if (cpu_intel) + error = get_misc_vmcs(ctx, vcpu); + else + error = get_misc_vmcb(ctx, vcpu); + } + + if (!error && (get_x2apic_state || get_all)) { + error = vm_get_x2apic_state(ctx, vcpu, &x2apic_state); + if (error == 0) + printf("x2apic_state[%d]\t%d\n", vcpu, x2apic_state); + } + + if (!error && (get_eptp || get_all)) { + if (cpu_intel) + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EPTP, &eptp); + else + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_NPT_BASE, + 8, &eptp); + if (error == 0) + printf("%s[%d]\t\t0x%016lx\n", + cpu_intel ? "eptp" : "rvi/npt", vcpu, eptp); + } + + if (!error && (get_exception_bitmap || get_all)) { + if(cpu_intel) + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_EXCEPTION_BITMAP, &bm); + else + error = vm_get_vmcb_field(ctx, vcpu, + VMCB_OFF_EXC_INTERCEPT, + 4, &bm); + if (error == 0) + printf("exception_bitmap[%d]\t%#lx\n", vcpu, bm); + } + + if (!error && (get_io_bitmap || get_all)) { + if (cpu_intel) { + error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_A, + &bm); + if (error == 0) + printf("io_bitmap_a[%d]\t%#lx\n", vcpu, bm); + error = vm_get_vmcs_field(ctx, vcpu, VMCS_IO_BITMAP_B, + &bm); + if (error == 0) + printf("io_bitmap_b[%d]\t%#lx\n", vcpu, bm); + } else { + error = vm_get_vmcb_field(ctx, vcpu, + VMCB_OFF_IO_PERM, 8, &bm); + if (error == 0) + printf("io_bitmap[%d]\t%#lx\n", vcpu, bm); + } + } + + if (!error && (get_tsc_offset || get_all)) { + uint64_t tscoff; + if (cpu_intel) + error = vm_get_vmcs_field(ctx, vcpu, VMCS_TSC_OFFSET, + &tscoff); + else + error = vm_get_vmcb_field(ctx, vcpu, + VMCB_OFF_TSC_OFFSET, + 8, &tscoff); + if (error == 0) + printf("tsc_offset[%d]\t0x%016lx\n", vcpu, tscoff); + } + + if (!error && (get_msr_bitmap_address || get_all)) { + if (cpu_intel) + error = vm_get_vmcs_field(ctx, vcpu, VMCS_MSR_BITMAP, + &addr); + else + error = vm_get_vmcb_field(ctx, vcpu, + VMCB_OFF_MSR_PERM, 8, &addr); + if (error == 0) + printf("msr_bitmap[%d]\t\t%#lx\n", vcpu, addr); + } + + if (!error && (get_msr_bitmap || get_all)) { + if (cpu_intel) { + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_MSR_BITMAP, &addr); + } else { + error = vm_get_vmcb_field(ctx, vcpu, + VMCB_OFF_MSR_PERM, 8, + &addr); + } + + if (error == 0) + error = dump_msr_bitmap(vcpu, addr, cpu_intel); + } + + if (!error && (get_vpid_asid || get_all)) { + uint64_t vpid; + if (cpu_intel) + error = vm_get_vmcs_field(ctx, vcpu, VMCS_VPID, &vpid); + else + error = vm_get_vmcb_field(ctx, vcpu, VMCB_OFF_ASID, + 4, &vpid); + if (error == 0) + printf("%s[%d]\t\t0x%04lx\n", + cpu_intel ? "vpid" : "asid", vcpu, vpid); + } + + if (!error && (get_guest_pat || get_all)) { + if (cpu_intel) + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_IA32_PAT, &pat); + else + error = vm_get_vmcb_field(ctx, vcpu, + VMCB_OFF_GUEST_PAT, 8, &pat); + if (error == 0) + printf("guest_pat[%d]\t\t0x%016lx\n", vcpu, pat); + } + + if (!error && (get_guest_sysenter || get_all)) { + if (cpu_intel) + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_IA32_SYSENTER_CS, + &cs); + else + error = vm_get_vmcb_field(ctx, vcpu, + VMCB_OFF_SYSENTER_CS, 8, + &cs); + + if (error == 0) + printf("guest_sysenter_cs[%d]\t%#lx\n", vcpu, cs); + if (cpu_intel) + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_IA32_SYSENTER_ESP, + &rsp); + else + error = vm_get_vmcb_field(ctx, vcpu, + VMCB_OFF_SYSENTER_ESP, 8, + &rsp); + + if (error == 0) + printf("guest_sysenter_sp[%d]\t%#lx\n", vcpu, rsp); + if (cpu_intel) + error = vm_get_vmcs_field(ctx, vcpu, + VMCS_GUEST_IA32_SYSENTER_EIP, + &rip); + else + error = vm_get_vmcb_field(ctx, vcpu, + VMCB_OFF_SYSENTER_EIP, 8, + &rip); + if (error == 0) + printf("guest_sysenter_ip[%d]\t%#lx\n", vcpu, rip); + } + + if (!error && (get_exit_reason || get_all)) { + if (cpu_intel) + error = vm_get_vmcs_field(ctx, vcpu, VMCS_EXIT_REASON, + &u64); + else + error = vm_get_vmcb_field(ctx, vcpu, + VMCB_OFF_EXIT_REASON, 8, + &u64); + if (error == 0) + printf("exit_reason[%d]\t%#lx\n", vcpu, u64); + } + + if (!error && setcap) { + int captype; + captype = vm_capability_name2type(capname); + error = vm_set_capability(ctx, vcpu, captype, capval); + if (error != 0 && errno == ENOENT) + printf("Capability \"%s\" is not available\n", capname); + } + + if (!error && get_gpa_pmap) { + error = vm_get_gpa_pmap(ctx, gpa_pmap, pteval, &ptenum); + if (error == 0) { + printf("gpa %#lx:", gpa_pmap); + pte = &pteval[0]; + while (ptenum-- > 0) + printf(" %#lx", *pte++); + printf("\n"); + } + } + + if (!error && set_rtc_nvram) + error = vm_rtc_write(ctx, rtc_nvram_offset, rtc_nvram_value); + + if (!error && (get_rtc_nvram || get_all)) { + error = vm_rtc_read(ctx, rtc_nvram_offset, &rtc_nvram_value); + if (error == 0) { + printf("rtc nvram[%03d]: 0x%02x\n", rtc_nvram_offset, + rtc_nvram_value); + } + } + + if (!error && set_rtc_time) + error = vm_rtc_settime(ctx, rtc_secs); + + if (!error && (get_rtc_time || get_all)) { + error = vm_rtc_gettime(ctx, &rtc_secs); + if (error == 0) { + gmtime_r(&rtc_secs, &tm); + printf("rtc time %#lx: %s %s %02d %02d:%02d:%02d %d\n", + rtc_secs, wday_str(tm.tm_wday), mon_str(tm.tm_mon), + tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, + 1900 + tm.tm_year); + } + } + + if (!error && (getcap || get_all)) { + int captype, val, getcaptype; + + if (getcap && capname) + getcaptype = vm_capability_name2type(capname); + else + getcaptype = -1; + + for (captype = 0; captype < VM_CAP_MAX; captype++) { + if (getcaptype >= 0 && captype != getcaptype) + continue; + error = vm_get_capability(ctx, vcpu, captype, &val); + if (error == 0) { + printf("Capability \"%s\" is %s on vcpu %d\n", + vm_capability_type2name(captype), + val ? "set" : "not set", vcpu); + } else if (errno == ENOENT) { + error = 0; + printf("Capability \"%s\" is not available\n", + vm_capability_type2name(captype)); + } else { + break; + } + } + } + + if (!error && (get_active_cpus || get_all)) { + error = vm_active_cpus(ctx, &cpus); + if (!error) + print_cpus("active cpus", &cpus); + } + + if (!error && (get_suspended_cpus || get_all)) { + error = vm_suspended_cpus(ctx, &cpus); + if (!error) + print_cpus("suspended cpus", &cpus); + } + + if (!error && (get_intinfo || get_all)) { + error = vm_get_intinfo(ctx, vcpu, &info[0], &info[1]); + if (!error) { + print_intinfo("pending", info[0]); + print_intinfo("current", info[1]); + } + } + + if (!error && (get_stats || get_all)) { + int i, num_stats; + uint64_t *stats; + struct timeval tv; + const char *desc; + + stats = vm_get_stats(ctx, vcpu, &tv, &num_stats); + if (stats != NULL) { + printf("vcpu%d stats:\n", vcpu); + for (i = 0; i < num_stats; i++) { + desc = vm_get_stat_desc(ctx, i); + printf("%-40s\t%ld\n", desc, stats[i]); + } + } + } + + if (!error && (get_cpu_topology || get_all)) { + uint16_t sockets, cores, threads, maxcpus; + + vm_get_topology(ctx, &sockets, &cores, &threads, &maxcpus); + printf("cpu_topology:\tsockets=%hu, cores=%hu, threads=%hu, " + "maxcpus=%hu\n", sockets, cores, threads, maxcpus); + } + + if (!error && run) { + error = vm_run(ctx, vcpu, &vmexit); + if (error == 0) + dump_vm_run_exitcode(&vmexit, vcpu); + else + printf("vm_run error %d\n", error); + } + + if (!error && force_reset) + error = vm_suspend(ctx, VM_SUSPEND_RESET); + + if (!error && force_poweroff) + error = vm_suspend(ctx, VM_SUSPEND_POWEROFF); + + if (error) + printf("errno = %d\n", errno); + + if (!error && destroy) + vm_destroy(ctx); + + free (opts); + exit(error); +} diff --git a/usr/src/cmd/cmd-inet/etc/services b/usr/src/cmd/cmd-inet/etc/services index 37514ac0a7..25ccc7cc43 100644 --- a/usr/src/cmd/cmd-inet/etc/services +++ b/usr/src/cmd/cmd-inet/etc/services @@ -1,6 +1,7 @@ # # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2015 Joyent, Inc. # # CDDL HEADER START # @@ -215,6 +216,8 @@ krb5_prop 754/tcp # Kerberos V5 KDC propogation swat 901/tcp # Samba Web Adm.Tool ufsd 1008/tcp ufsd # UFS-aware server ufsd 1008/udp ufsd +portolan 1296/tcp # Portolan +svp-underlay 1339/tcp # SDC VXLAN underlay invalidation cvc 1495/tcp # Network Console ingreslock 1524/tcp www-ldap-gw 1760/tcp # HTTP to LDAP gateway diff --git a/usr/src/cmd/cmd-inet/etc/sock2path.d/system%2Fkernel b/usr/src/cmd/cmd-inet/etc/sock2path.d/system%2Fkernel index c62e339953..49151907eb 100644 --- a/usr/src/cmd/cmd-inet/etc/sock2path.d/system%2Fkernel +++ b/usr/src/cmd/cmd-inet/etc/sock2path.d/system%2Fkernel @@ -18,6 +18,7 @@ # CDDL HEADER END # # Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, Joyent, Inc. All rights reserved. # # socket configuration information # @@ -52,3 +53,6 @@ 29 4 1 /dev/spdsock 31 1 0 trill + + 33 1 0 lx_netlink + 33 4 0 lx_netlink diff --git a/usr/src/cmd/cmd-inet/lib/ipmgmtd/Makefile b/usr/src/cmd/cmd-inet/lib/ipmgmtd/Makefile index 199f92807a..f150602cc9 100644 --- a/usr/src/cmd/cmd-inet/lib/ipmgmtd/Makefile +++ b/usr/src/cmd/cmd-inet/lib/ipmgmtd/Makefile @@ -19,13 +19,15 @@ # CDDL HEADER END # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2015 Joyent, Inc. # # Needed for ROOTFS_LIBDIR definition include ../../../../lib/Makefile.lib PROG= ipmgmtd -OBJS= ipmgmt_main.o ipmgmt_door.o ipmgmt_persist.o ipmgmt_util.o +OBJS= ipmgmt_main.o ipmgmt_door.o ipmgmt_persist.o ipmgmt_util.o \ + ipmgmt_path.o SRCS= $(OBJS:.o=.c) SVCMETHOD= net-ipmgmt MANIFEST= network-ipmgmt.xml diff --git a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_door.c b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_door.c index c83c7627ad..bb4ffcbf0e 100644 --- a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_door.c +++ b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_door.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2014, Joyent, Inc. All rights reserved. * Copyright (c) 2016-2017, Chris Fraire <cfraire@me.com>. */ @@ -113,7 +114,9 @@ ipmgmt_handler(void *cookie, char *argp, size_t argsz, door_desc_t *dp, goto fail; } - /* check for solaris.network.interface.config authorization */ + /* + * if not root, check for solaris.network.interface.config authorization + */ if (infop->idi_set) { uid_t uid; struct passwd pwd; @@ -125,24 +128,32 @@ ipmgmt_handler(void *cookie, char *argp, size_t argsz, door_desc_t *dp, goto fail; } uid = ucred_getruid(cred); + ucred_free(cred); if ((int)uid < 0) { err = errno; ipmgmt_log(LOG_ERR, "Could not get user id."); goto fail; } - if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) == - NULL) { - err = errno; - ipmgmt_log(LOG_ERR, "Could not get password entry."); - goto fail; - } - if (chkauthattr(NETWORK_INTERFACE_CONFIG_AUTH, - pwd.pw_name) != 1) { - err = EPERM; - ipmgmt_log(LOG_ERR, "Not authorized for operation."); - goto fail; + + /* + * Branded zones may have different auth, but root always + * allowed. + */ + if (uid != 0) { + if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) == NULL) { + err = errno; + ipmgmt_log(LOG_ERR, + "Could not get password entry."); + goto fail; + } + if (chkauthattr(NETWORK_INTERFACE_CONFIG_AUTH, + pwd.pw_name) != 1) { + err = EPERM; + ipmgmt_log(LOG_ERR, + "Not authorized for operation."); + goto fail; + } } - ucred_free(cred); } /* individual handlers take care of calling door_return */ diff --git a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_impl.h b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_impl.h index e95e5c7e00..f4d6d30645 100644 --- a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_impl.h +++ b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_impl.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2015 Joyent, Inc. * Copyright (c) 2016, Chris Fraire <cfraire@me.com>. */ @@ -144,8 +145,6 @@ extern ipmgmt_aobjmap_list_t aobjmap; #define ADDROBJ_LOOKUPADD 0x00000004 #define ADDROBJ_SETLIFNUM 0x00000008 -/* Permanent data store for ipadm */ -#define IPADM_DB_FILE "/etc/ipadm/ipadm.conf" #define IPADM_FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) /* @@ -155,20 +154,12 @@ extern ipmgmt_aobjmap_list_t aobjmap; */ #define IPADM_DB_VERSION 1 -/* - * A temporary file created in SMF volatile filesystem. This file captures the - * in-memory copy of list `aobjmap' on disk. This is done to recover from - * daemon reboot (using svcadm) or crashes. - */ -#define IPADM_TMPFS_DIR "/etc/svc/volatile/ipadm" -#define ADDROBJ_MAPPING_DB_FILE IPADM_TMPFS_DIR"/aobjmap.conf" - -/* - * A temporary copy of the ipadm configuration file might need - * to be created if write requests are encountered during boottime - * and the root filesystem is mounted read-only. - */ -#define IPADM_VOL_DB_FILE IPADM_TMPFS_DIR"/ipadm.conf" +typedef enum ipadm_path { + IPADM_PATH_TMPFS_DIR = 1, + IPADM_PATH_ADDROBJ_MAP_DB, + IPADM_PATH_DB, + IPADM_PATH_VOL_DB +} ipadm_path_t; /* SCF resources required to interact with svc.configd */ typedef struct scf_resources { @@ -198,6 +189,8 @@ extern void ipmgmt_release_scf_resources(scf_resources_t *); extern boolean_t ipmgmt_needs_upgrade(scf_resources_t *); extern void ipmgmt_update_dbver(scf_resources_t *); +extern void ipmgmt_path(ipadm_path_t, char *, size_t); + #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_main.c b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_main.c index 5cdc0f5697..994d1b0125 100644 --- a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_main.c +++ b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_main.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2015 Joyent, Inc. */ /* @@ -105,6 +106,7 @@ ipmgmt_db_init() int fd, err, scferr; scf_resources_t res; boolean_t upgrade = B_TRUE; + char aobjpath[MAXPATHLEN]; /* * Check to see if we need to upgrade the data-store. We need to @@ -134,11 +136,11 @@ ipmgmt_db_init() ipmgmt_release_scf_resources(&res); /* creates the address object data store, if it doesn't exist */ - if ((fd = open(ADDROBJ_MAPPING_DB_FILE, O_CREAT|O_RDONLY, - IPADM_FILE_MODE)) == -1) { + ipmgmt_path(IPADM_PATH_ADDROBJ_MAP_DB, aobjpath, sizeof (aobjpath)); + if ((fd = open(aobjpath, O_CREAT|O_RDONLY, IPADM_FILE_MODE)) == -1) { err = errno; - ipmgmt_log(LOG_ERR, "could not open %s: %s", - ADDROBJ_MAPPING_DB_FILE, strerror(err)); + ipmgmt_log(LOG_ERR, "could not open %s: %s", aobjpath, + strerror(err)); return (err); } (void) close(fd); @@ -152,8 +154,8 @@ ipmgmt_db_init() * representation of the mapping. That is, build `aobjmap' structure * from address object data store. */ - if ((err = ipadm_rw_db(ipmgmt_aobjmap_init, NULL, - ADDROBJ_MAPPING_DB_FILE, 0, IPADM_DB_READ)) != 0) { + if ((err = ipadm_rw_db(ipmgmt_aobjmap_init, NULL, aobjpath, 0, + IPADM_DB_READ)) != 0) { /* if there was nothing to initialize, it's fine */ if (err != ENOENT) return (err); @@ -165,17 +167,42 @@ ipmgmt_db_init() return (err); } +static const char * +ipmgmt_door_path() +{ + static char door[MAXPATHLEN]; + static boolean_t init_done = B_FALSE; + + if (!init_done) { + const char *zroot = zone_get_nroot(); + + /* + * If this is a branded zone, make sure we use the "/native" + * prefix for the door path: + */ + (void) snprintf(door, sizeof (door), "%s%s", zroot != NULL ? + zroot : "", IPMGMT_DOOR); + + init_done = B_TRUE; + } + + return (door); +} + static int ipmgmt_door_init() { int fd; int err; + const char *door = ipmgmt_door_path(); - /* create the door file for ipmgmtd */ - if ((fd = open(IPMGMT_DOOR, O_CREAT|O_RDONLY, IPADM_FILE_MODE)) == -1) { + /* + * Create the door file for ipmgmtd. + */ + if ((fd = open(door, O_CREAT | O_RDONLY, IPADM_FILE_MODE)) == -1) { err = errno; - ipmgmt_log(LOG_ERR, "could not open %s: %s", - IPMGMT_DOOR, strerror(err)); + ipmgmt_log(LOG_ERR, "could not open %s: %s", door, + strerror(err)); return (err); } (void) close(fd); @@ -186,15 +213,16 @@ ipmgmt_door_init() ipmgmt_log(LOG_ERR, "failed to create door: %s", strerror(err)); return (err); } + /* * fdetach first in case a previous daemon instance exited * ungracefully. */ - (void) fdetach(IPMGMT_DOOR); - if (fattach(ipmgmt_door_fd, IPMGMT_DOOR) != 0) { + (void) fdetach(door); + if (fattach(ipmgmt_door_fd, door) != 0) { err = errno; - ipmgmt_log(LOG_ERR, "failed to attach door to %s: %s", - IPMGMT_DOOR, strerror(err)); + ipmgmt_log(LOG_ERR, "failed to attach door to %s: %s", door, + strerror(err)); goto fail; } return (0); @@ -207,13 +235,15 @@ fail: static void ipmgmt_door_fini() { + const char *door = ipmgmt_door_path(); + if (ipmgmt_door_fd == -1) return; - (void) fdetach(IPMGMT_DOOR); + (void) fdetach(door); if (door_revoke(ipmgmt_door_fd) == -1) { ipmgmt_log(LOG_ERR, "failed to revoke access to door %s: %s", - IPMGMT_DOOR, strerror(errno)); + door, strerror(errno)); } } @@ -350,10 +380,14 @@ ipmgmt_init_privileges() { struct stat statbuf; int err; + char tmpfsdir[MAXPATHLEN]; - /* create the IPADM_TMPFS_DIR directory */ - if (stat(IPADM_TMPFS_DIR, &statbuf) < 0) { - if (mkdir(IPADM_TMPFS_DIR, (mode_t)0755) < 0) { + /* + * Create the volatile storage directory: + */ + ipmgmt_path(IPADM_PATH_TMPFS_DIR, tmpfsdir, sizeof (tmpfsdir)); + if (stat(tmpfsdir, &statbuf) < 0) { + if (mkdir(tmpfsdir, (mode_t)0755) < 0) { err = errno; goto fail; } @@ -364,8 +398,8 @@ ipmgmt_init_privileges() } } - if ((chmod(IPADM_TMPFS_DIR, 0755) < 0) || - (chown(IPADM_TMPFS_DIR, UID_NETADM, GID_NETADM) < 0)) { + if ((chmod(tmpfsdir, 0755) < 0) || + (chown(tmpfsdir, UID_NETADM, GID_NETADM) < 0)) { err = errno; goto fail; } diff --git a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_path.c b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_path.c new file mode 100644 index 0000000000..0219ac1522 --- /dev/null +++ b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_path.c @@ -0,0 +1,84 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Joyent, Inc. + */ + +/* + * Lookup functions for various file paths used by ipmgmtd. This mechanism + * primarily exists to account for a native root prefix when run within a + * branded zone (e.g. "/native"). + */ + +#include <stdio.h> +#include <zone.h> +#include "ipmgmt_impl.h" + +#define IPADM_PERM_DIR "/etc/ipadm" +#define IPADM_TMPFS_DIR "/etc/svc/volatile/ipadm" + +typedef struct ipadm_path_ent { + ipadm_path_t ipe_id; + const char *ipe_path; +} ipadm_path_ent_t; + +static ipadm_path_ent_t ipadm_paths[] = { + /* + * A temporary directory created in the SMF volatile filesystem. + */ + { IPADM_PATH_TMPFS_DIR, IPADM_TMPFS_DIR }, + + /* + * This file captures the in-memory copy of list `aobjmap' on disk. + * This allows the system to recover in the event that the daemon + * crashes or is restarted. + */ + { IPADM_PATH_ADDROBJ_MAP_DB, IPADM_TMPFS_DIR "/aobjmap.conf" }, + + /* + * The permanent data store for ipadm. + */ + { IPADM_PATH_DB, IPADM_PERM_DIR "/ipadm.conf" }, + + /* + * A temporary copy of the ipadm configuration created, if needed, to + * service write requests early in boot. This file is merged with the + * permanent data store once it is available for writes. + */ + { IPADM_PATH_VOL_DB, IPADM_TMPFS_DIR "/ipadm.conf" }, + + { 0, NULL } +}; + +/* + * Load one of the paths used by ipadm into the provided string buffer. + * Prepends the native system prefix (e.g. "/native") if one is in effect, + * such as when running within a branded zone. + */ +void +ipmgmt_path(ipadm_path_t ip, char *buf, size_t bufsz) +{ + int i; + + for (i = 0; ipadm_paths[i].ipe_path != NULL; i++) { + if (ipadm_paths[i].ipe_id == ip) { + const char *zroot = zone_get_nroot(); + + (void) snprintf(buf, bufsz, "%s%s", zroot != NULL ? + zroot : "", ipadm_paths[i].ipe_path); + + return; + } + } + + abort(); +} diff --git a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c index c1995611e9..a185068005 100644 --- a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c +++ b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c @@ -386,13 +386,18 @@ static void * ipmgmt_db_restore_thread(void *arg) { int err; + char confpath[MAXPATHLEN]; + char tmpconfpath[MAXPATHLEN]; + + ipmgmt_path(IPADM_PATH_DB, confpath, sizeof (confpath)); + ipmgmt_path(IPADM_PATH_VOL_DB, tmpconfpath, sizeof (tmpconfpath)); for (;;) { (void) sleep(5); (void) pthread_rwlock_wrlock(&ipmgmt_dbconf_lock); if (!ipmgmt_rdonly_root) break; - err = ipmgmt_cpfile(IPADM_VOL_DB_FILE, IPADM_DB_FILE, B_FALSE); + err = ipmgmt_cpfile(tmpconfpath, confpath, B_FALSE); if (err == 0) { ipmgmt_rdonly_root = B_FALSE; break; @@ -424,6 +429,11 @@ ipmgmt_db_walk(db_wfunc_t *db_walk_func, void *db_warg, ipadm_db_op_t db_op) mode_t mode; pthread_t tid; pthread_attr_t attr; + char confpath[MAXPATHLEN]; + char tmpconfpath[MAXPATHLEN]; + + ipmgmt_path(IPADM_PATH_DB, confpath, sizeof (confpath)); + ipmgmt_path(IPADM_PATH_VOL_DB, tmpconfpath, sizeof (tmpconfpath)); writeop = (db_op != IPADM_DB_READ); if (writeop) { @@ -436,11 +446,10 @@ ipmgmt_db_walk(db_wfunc_t *db_walk_func, void *db_warg, ipadm_db_op_t db_op) /* * Did a previous write attempt fail? If so, don't even try to - * read/write to IPADM_DB_FILE. + * read/write to the permanent configuration file. */ if (!ipmgmt_rdonly_root) { - err = ipadm_rw_db(db_walk_func, db_warg, IPADM_DB_FILE, - mode, db_op); + err = ipadm_rw_db(db_walk_func, db_warg, confpath, mode, db_op); if (err != EROFS) goto done; } @@ -448,11 +457,11 @@ ipmgmt_db_walk(db_wfunc_t *db_walk_func, void *db_warg, ipadm_db_op_t db_op) /* * If we haven't already copied the file to the volatile * file system, do so. This should only happen on a failed - * writeop(i.e., we have acquired the write lock above). + * writeop (i.e., we have acquired the write lock above). */ - if (access(IPADM_VOL_DB_FILE, F_OK) != 0) { + if (access(tmpconfpath, F_OK) != 0) { assert(writeop); - err = ipmgmt_cpfile(IPADM_DB_FILE, IPADM_VOL_DB_FILE, B_TRUE); + err = ipmgmt_cpfile(confpath, tmpconfpath, B_TRUE); if (err != 0) goto done; (void) pthread_attr_init(&attr); @@ -463,7 +472,7 @@ ipmgmt_db_walk(db_wfunc_t *db_walk_func, void *db_warg, ipadm_db_op_t db_op) NULL); (void) pthread_attr_destroy(&attr); if (err != 0) { - (void) unlink(IPADM_VOL_DB_FILE); + (void) unlink(tmpconfpath); goto done; } ipmgmt_rdonly_root = B_TRUE; @@ -472,7 +481,7 @@ ipmgmt_db_walk(db_wfunc_t *db_walk_func, void *db_warg, ipadm_db_op_t db_op) /* * Read/write from the volatile copy. */ - err = ipadm_rw_db(db_walk_func, db_warg, IPADM_VOL_DB_FILE, + err = ipadm_rw_db(db_walk_func, db_warg, tmpconfpath, mode, db_op); done: (void) pthread_rwlock_unlock(&ipmgmt_dbconf_lock); @@ -1254,6 +1263,9 @@ ipmgmt_persist_aobjmap(ipmgmt_aobjmap_t *nodep, ipadm_db_op_t op) int err; ipadm_dbwrite_cbarg_t cb; nvlist_t *nvl = NULL; + char aobjpath[MAXPATHLEN]; + + ipmgmt_path(IPADM_PATH_ADDROBJ_MAP_DB, aobjpath, sizeof (aobjpath)); if (op == IPADM_DB_WRITE) { if ((err = i_ipmgmt_node2nvl(&nvl, nodep)) != 0) @@ -1264,14 +1276,14 @@ ipmgmt_persist_aobjmap(ipmgmt_aobjmap_t *nodep, ipadm_db_op_t op) else cb.dbw_flags = 0; - err = ipadm_rw_db(ipmgmt_update_aobjmap, &cb, - ADDROBJ_MAPPING_DB_FILE, IPADM_FILE_MODE, IPADM_DB_WRITE); + err = ipadm_rw_db(ipmgmt_update_aobjmap, &cb, aobjpath, + IPADM_FILE_MODE, IPADM_DB_WRITE); nvlist_free(nvl); } else { assert(op == IPADM_DB_DELETE); - err = ipadm_rw_db(ipmgmt_delete_aobjmap, nodep, - ADDROBJ_MAPPING_DB_FILE, IPADM_FILE_MODE, IPADM_DB_DELETE); + err = ipadm_rw_db(ipmgmt_delete_aobjmap, nodep, aobjpath, + IPADM_FILE_MODE, IPADM_DB_DELETE); } return (err); } diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c index 133254be4a..e6a88304a7 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c +++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/defaults.c @@ -32,6 +32,7 @@ #include <stdio.h> #include <sys/stat.h> #include <libnvpair.h> +#include <zone.h> #include "common.h" #include "defaults.h" @@ -67,6 +68,32 @@ static struct dhcp_default defaults[] = { { "ADOPT_DOMAINNAME", "0", 0, 0 }, }; + +/* + * df_find_defaults(): builds the path to the default configuration file + * + * input: void + * output: void + */ + +static const char * +df_find_defaults(void) +{ + static char agent_defaults_path[MAXPATHLEN] = { 0 }; + const char *zroot = NULL; + + if (agent_defaults_path[0] != '\0') { + return agent_defaults_path; + } + + zroot = zone_get_nroot(); + + (void) snprintf(agent_defaults_path, MAXPATHLEN, "%s%s", + zroot != NULL ? zroot : "", DHCP_AGENT_DEFAULTS); + + return agent_defaults_path; +} + /* * df_build_cache(): builds the defaults nvlist cache * @@ -77,6 +104,7 @@ static struct dhcp_default defaults[] = { static nvlist_t * df_build_cache(void) { + const char *agent_defaults_path = df_find_defaults(); char entry[1024]; int i; char *param, *pastv6, *value, *end; @@ -84,7 +112,7 @@ df_build_cache(void) nvlist_t *nvlist; struct dhcp_default *defp; - if ((fp = fopen(DHCP_AGENT_DEFAULTS, "r")) == NULL) + if ((fp = fopen(agent_defaults_path, "r")) == NULL) return (NULL); if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) { @@ -164,6 +192,7 @@ df_build_cache(void) const char * df_get_string(const char *if_name, boolean_t isv6, uint_t param) { + const char *agent_defaults_path = df_find_defaults(); char *value; char paramstr[256]; char name[256]; @@ -175,10 +204,11 @@ df_get_string(const char *if_name, boolean_t isv6, uint_t param) if (param >= (sizeof (defaults) / sizeof (*defaults))) return (NULL); - if (stat(DHCP_AGENT_DEFAULTS, &statbuf) != 0) { + + if (stat(agent_defaults_path, &statbuf) != 0) { if (!df_unavail_msg) { dhcpmsg(MSG_WARNING, "cannot access %s; using " - "built-in defaults", DHCP_AGENT_DEFAULTS); + "built-in defaults", agent_defaults_path); df_unavail_msg = B_TRUE; } return (defaults[param].df_default); diff --git a/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c b/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c index 6b5a08a51a..7517f2c094 100644 --- a/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c +++ b/usr/src/cmd/cmd-inet/sbin/dhcpagent/request.c @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2011 Joyent, Inc. All rights reserved. * Copyright (c) 2016-2017, Chris Fraire <cfraire@me.com>. * * REQUESTING state of the client state machine. @@ -39,6 +40,7 @@ #include <dhcp_hostconf.h> #include <dhcpagent_util.h> #include <dhcpmsg.h> +#include <strings.h> #include "states.h" #include "util.h" @@ -645,8 +647,24 @@ accept_v4_acknak(dhcp_smach_t *dsmp, PKT_LIST *plp) stop_pkt_retransmission(dsmp); if (*plp->opts[CD_DHCP_TYPE]->value == NAK) { - dhcpmsg(MSG_WARNING, "accept_v4_acknak: NAK on interface %s", - dsmp->dsm_name); + char saddr[18]; + + saddr[0] = '\0'; + if (plp->opts[CD_SERVER_ID] != NULL && + plp->opts[CD_SERVER_ID]->len == sizeof (struct in_addr)) { + struct in_addr t_server; + + bcopy(plp->opts[CD_SERVER_ID]->value, &t_server, + plp->opts[CD_SERVER_ID]->len); + (void) strlcpy(saddr, inet_ntoa(t_server), + sizeof (saddr)); + } + + dhcpmsg(MSG_WARNING, "accept_v4_acknak: NAK on interface %s " + "from %s %s", + dsmp->dsm_name, + inet_ntoa(plp->pktfrom.v4.sin_addr), saddr); + dsmp->dsm_bad_offers++; free_pkt_entry(plp); dhcp_restart(dsmp); diff --git a/usr/src/cmd/cmd-inet/usr.lib/wpad/Makefile b/usr/src/cmd/cmd-inet/usr.lib/wpad/Makefile index 5dcf9c3755..4957961b61 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/wpad/Makefile +++ b/usr/src/cmd/cmd-inet/usr.lib/wpad/Makefile @@ -34,7 +34,7 @@ include ../../../Makefile.cmd ROOTMANIFESTDIR = $(ROOTSVCNETWORK) LDLIBS += -ldladm -ldlpi -all install := LDLIBS += -lcrypto +all install := LDLIBS += -lsunw_crypto LINTFLAGS += -u diff --git a/usr/src/cmd/cmd-inet/usr.sbin/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/Makefile index f17a96a1ed..2b33026630 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/Makefile +++ b/usr/src/cmd/cmd-inet/usr.sbin/Makefile @@ -166,6 +166,7 @@ route := CPPFLAGS += -DNDEBUG ndd := LDLIBS += -ldladm -lipadm $(RELEASE_BUILD)ndd := CERRWARN += -_gcc=-Wno-unused in.comsat := LDFLAGS += $(MAPFILE.NGB:%=-M%) +route := LDLIBS += -lzonecfg -lcontract .KEEP_STATE: @@ -268,7 +269,7 @@ lint: $(LINTSUBDIRS) in.telnetd.c $(LDLIBS) -lbsm -lpam -lsocket -lnsl $(LINT.c) if_mpadm.c $(LDLIBS) -lsocket -lnsl -lipmp -linetutil $(LINT.c) ipaddrsel.c $(LDLIBS) -lsocket -lnsl - $(LINT.c) route.c $(LDLIBS) -lsocket -lnsl -ltsnet + $(LINT.c) route.c $(LDLIBS) -lsocket -lnsl -ltsnet -lcontract -lzonecfg $(LINT.c) syncinit.c $(LDLIBS) -ldlpi $(LINT.c) syncloop.c $(LDLIBS) -ldlpi $(LINT.c) syncstat.c $(LDLIBS) -ldlpi diff --git a/usr/src/cmd/cmd-inet/usr.sbin/arp.c b/usr/src/cmd/cmd-inet/usr.sbin/arp.c index 19ab13fd47..aa9adac6ce 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/arp.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/arp.c @@ -58,6 +58,7 @@ #include <arpa/inet.h> #include <net/if_types.h> #include <net/if_dl.h> +#include <zone.h> static int file(char *); static int set(int, char *[]); @@ -118,7 +119,11 @@ main(int argc, char *argv[]) * is to let netstat, which prints it as part of * the MIB statistics, do it. */ - (void) execl("/usr/bin/netstat", "netstat", + char netstat_path[MAXPATHLEN]; + const char *zroot = zone_get_nroot(); + (void) snprintf(netstat_path, sizeof (netstat_path), "%s%s", zroot != NULL ? + zroot : "", "/usr/bin/netstat"); + (void) execl(netstat_path, "netstat", (n_flag ? "-np" : "-p"), "-f", "inet", (char *)0); (void) fprintf(stderr, "failed to exec netstat: %s\n", diff --git a/usr/src/cmd/cmd-inet/usr.sbin/ndp.c b/usr/src/cmd/cmd-inet/usr.sbin/ndp.c index 23b940c686..2fc19775ad 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/ndp.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/ndp.c @@ -40,6 +40,7 @@ #include <inet/ip.h> #include <net/if_dl.h> #include <net/route.h> +#include <zone.h> typedef struct sockaddr_in6 sin6_t; @@ -95,7 +96,6 @@ static int ndp_set_nce(char *, char *, char *[], int); static int ndp_set_file(char *); static char *ndp_iface = NULL; -static char *netstat_path = "/usr/bin/netstat"; static pid_t ndp_pid; static boolean_t ndp_noresolve = B_FALSE; /* Don't lookup addresses */ static boolean_t ndp_run = B_TRUE; @@ -103,6 +103,7 @@ static boolean_t ndp_run = B_TRUE; #define MAX_ATTEMPTS 5 #define MAX_OPTS 5 #define WORDSEPS " \t\r\n" +#define NETSTAT_PATH "/usr/bin/netstat" /* * Macros borrowed from route(1M) for working with PF_ROUTE messages @@ -767,6 +768,12 @@ ndp_get(int fd, struct lifreq *lifrp, void *unused) static void ndp_get_all(void) { + char netstat_path[MAXPATHLEN]; + const char *zroot = zone_get_nroot(); + + (void) snprintf(netstat_path, sizeof (netstat_path), "%s%s", zroot != NULL ? + zroot : "", NETSTAT_PATH); + (void) execl(netstat_path, "netstat", (ndp_noresolve ? "-np" : "-p"), "-f", "inet6", (char *)0); diff --git a/usr/src/cmd/cmd-inet/usr.sbin/route.c b/usr/src/cmd/cmd-inet/usr.sbin/route.c index a2fd0d2d17..29ccf97bb1 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/route.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/route.c @@ -6,6 +6,7 @@ /* All Rights Reserved */ /* Copyright (c) 1990 Mentat Inc. */ +/* Copyright 2018, Joyent, Inc. */ /* * @@ -79,6 +80,13 @@ #include <assert.h> #include <strings.h> +#include <libcontract.h> +#include <sys/ctfs.h> +#include <sys/contract/process.h> +#include <sys/wait.h> +#include <libzonecfg.h> +#include <zone.h> + #include <libtsnet.h> #include <tsol/label.h> @@ -292,6 +300,7 @@ static void syntax_error(char *err, ...); static void usage(char *cp); static void write_to_rtfile(FILE *fp, int argc, char **argv); static void pmsg_secattr(const char *, size_t, const char *); +static void do_zone(char *); static pid_t pid; static int s; @@ -308,6 +317,7 @@ static char perm_file_sfx[] = "/etc/inet/static_routes"; static char *perm_file; static char temp_file_sfx[] = "/etc/inet/static_routes.tmp"; static char *temp_file; +static char *zonename; static struct in6_addr in6_host_mask = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /* @@ -354,7 +364,7 @@ usage(char *cp) cp); } (void) fprintf(stderr, gettext("usage: route [ -fnpqv ] " - "[ -R <root-dir> ] cmd [[ -<qualifers> ] args ]\n")); + "[-z <zone> ] [ -R <root-dir> ] cmd [[ -<qualifers> ] args ]\n")); exit(1); /* NOTREACHED */ } @@ -418,7 +428,7 @@ main(int argc, char **argv) if (argc < 2) usage(NULL); - while ((ch = getopt(argc, argv, "R:nqdtvfp")) != EOF) { + while ((ch = getopt(argc, argv, "R:nqdtvfpz:")) != EOF) { switch (ch) { case 'n': nflag = B_TRUE; @@ -444,6 +454,9 @@ main(int argc, char **argv) case 'R': root_dir = optarg; break; + case 'z': + zonename = optarg; + break; case '?': default: usage(NULL); @@ -453,6 +466,8 @@ main(int argc, char **argv) argc -= optind; argv += optind; + do_zone(zonename); + pid = getpid(); if (tflag) s = open("/dev/null", O_WRONLY); @@ -3252,3 +3267,74 @@ pmsg_secattr(const char *sptr, size_t msglen, const char *labelstr) sizeof (buf))); } } + +static void +do_zone(char *name) +{ + zoneid_t zoneid; + zone_state_t st; + int fd, status, rc = 0; + pid_t pid; + + if (name == NULL) + return; + + if (getzoneid() != GLOBAL_ZONEID) { + (void) fprintf(stderr, + "route: -z can only be specified from the global zone\n"); + exit(EXIT_FAILURE); + } + + if (strcmp(name, GLOBAL_ZONENAME) == 0) + return; + + if (zone_get_state(name, &st) != Z_OK) + quit("unable to get zone state", errno); + + if (st != ZONE_STATE_RUNNING) { + (void) fprintf(stderr, "route: zone must be running\n"); + exit(EXIT_FAILURE); + } + + if ((zoneid = getzoneidbyname(name)) == -1) + quit("cannot determine zone id", errno); + + if ((fd = open64(CTFS_ROOT "/process/template", O_RDWR)) == -1) + quit("cannot open ctfs template", errno); + + /* + * zone_enter() does not allow contracts to straddle zones, so we must + * create a new, though largely unused contract. Once we fork, the + * child is the only member of the new contract, so it can perform a + * zone_enter(). + */ + rc |= ct_tmpl_set_critical(fd, 0); + rc |= ct_tmpl_set_informative(fd, 0); + rc |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR); + rc |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT); + if (rc || ct_tmpl_activate(fd)) { + (void) close(fd); + quit("could not create contract", errno); + } + + switch (pid = fork1()) { + case 0: + (void) ct_tmpl_clear(fd); + (void) close(fd); + if (zone_enter(zoneid) == -1) + quit("could not enter zone", errno); + return; + + case -1: + quit("fork1 failed", errno); + + default: + (void) ct_tmpl_clear(fd); + (void) close(fd); + if (waitpid(pid, &status, 0) < 0) + quit("waitpid failed", errno); + + exit(WEXITSTATUS(status)); + } + +} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/routeadm/routeadm.c b/usr/src/cmd/cmd-inet/usr.sbin/routeadm/routeadm.c index 71a2fc9853..be826baba2 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/routeadm/routeadm.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/routeadm/routeadm.c @@ -21,10 +21,9 @@ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2012 Joyent, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -46,6 +45,7 @@ #include <libscf.h> #include <libscf_priv.h> #include <libuutil.h> +#include <ifaddrs.h> /* * This program moves routing management under SMF. We do this by giving @@ -2335,8 +2335,8 @@ out: /* * - * Return the number of IPv6 addresses configured. This answers the - * generic question, "is IPv6 configured?". We only start in.ndpd if IPv6 + * Return the number of non-loopback IPv6 addresses configured. This answers + * the generic question, "is IPv6 configured?". We only start in.ndpd if IPv6 * is configured, and we also only enable IPv6 routing daemons if IPv6 is * enabled. */ @@ -2344,28 +2344,24 @@ static int ra_numv6intfs(void) { static int num = -1; - int ipsock; - struct lifnum lifn; + int cnt; + struct ifaddrs *ifp_head, *ifp; if (num != -1) return (num); - if ((ipsock = socket(PF_INET6, SOCK_DGRAM, 0)) == -1) { - (void) fprintf(stderr, - gettext("%1$s: unable to open %2$s: %3$s\n"), - myname, IP_DEV_NAME, strerror(errno)); + if (getifaddrs(&ifp_head) < 0) return (0); - } - lifn.lifn_family = AF_INET6; - lifn.lifn_flags = 0; - if (ioctl(ipsock, SIOCGLIFNUM, &lifn) == -1) { - (void) close(ipsock); - return (0); + cnt = 0; + for (ifp = ifp_head; ifp; ifp = ifp->ifa_next) { + if (!(ifp->ifa_flags & IFF_LOOPBACK) && + (ifp->ifa_flags & IFF_IPV6)) + cnt++; } - (void) close(ipsock); - return (num = lifn.lifn_count); + freeifaddrs(ifp_head); + return (num = cnt); } /* diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile index 55327064e7..88a13c99e1 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile @@ -40,16 +40,18 @@ OBJS= nfs4_xdr.o snoop.o snoop_aarp.o snoop_adsp.o snoop_aecho.o \ snoop_pppoe.o snoop_rip.o snoop_rip6.o snoop_rpc.o snoop_rpcprint.o \ snoop_rpcsec.o snoop_rport.o snoop_rquota.o snoop_rstat.o snoop_rtmp.o \ snoop_sctp.o snoop_slp.o snoop_smb.o snoop_socks.o snoop_solarnet.o \ - snoop_tcp.o snoop_tftp.o snoop_trill.o snoop_udp.o snoop_zip.o + snoop_svp.o snoop_tcp.o snoop_tftp.o snoop_trill.o snoop_udp.o \ + snoop_vxlan.o snoop_zip.o SRCS= $(OBJS:.o=.c) HDRS= snoop.h snoop_mip.h at.h snoop_ospf.h snoop_ospf6.h include ../../../Makefile.cmd +include ../../../Makefile.ctf CPPFLAGS += -I. -I$(SRC)/common/net/dhcp \ -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -LDLIBS += -ldhcputil -ldlpi -lsocket -lnsl -ltsol +LDLIBS += -ldhcputil -ldlpi -lsocket -lnsl -ltsol -luuid LDFLAGS += $(MAPFILE.NGB:%=-M%) CERRWARN += -_gcc=-Wno-switch CERRWARN += -_gcc=-Wno-implicit-function-declaration diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c index e6a71ea602..6ee99a06c6 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.c @@ -121,6 +121,7 @@ main(int argc, char **argv) char *output_area; int nbytes; char *datalink = NULL; + char *zonename = NULL; dlpi_handle_t dh; names[0] = '\0'; @@ -227,7 +228,7 @@ main(int argc, char **argv) } (void) setvbuf(stdout, NULL, _IOLBF, BUFSIZ); - while ((c = getopt(argc, argv, "at:CPDSi:o:Nn:s:d:I:vVp:f:c:x:U?rqz")) + while ((c = getopt(argc, argv, "at:CPDSi:o:Nn:s:d:I:vVp:f:c:x:U?rqz:Z")) != EOF) { switch (c) { case 'a': @@ -348,8 +349,11 @@ main(int argc, char **argv) case 'U': Uflg = B_TRUE; break; -#ifdef DEBUG case 'z': + zonename = optarg; + break; +#ifdef DEBUG + case 'Z': zflg = B_TRUE; break; #endif /* DEBUG */ @@ -371,7 +375,7 @@ main(int argc, char **argv) * requested was chosen, but that's too hard. */ if (!icapfile) { - use_kern_pf = open_datalink(&dh, datalink); + use_kern_pf = open_datalink(&dh, datalink, zonename); } else { use_kern_pf = B_FALSE; cap_open_read(icapfile); @@ -812,6 +816,8 @@ usage(void) (void) fprintf(stderr, "\t[ -r ] # Do not resolve address to name\n"); (void) fprintf(stderr, + "\t[ -z zone ] # Open links from named zone\n"); + (void) fprintf(stderr, "\n\t[ filter expression ]\n"); (void) fprintf(stderr, "\nExample:\n"); (void) fprintf(stderr, "\tsnoop -o saved host fred\n\n"); diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h index d9c559dec1..fc63d3987f 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop.h @@ -24,6 +24,7 @@ * Use is subject to license terms. * * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. */ #ifndef _SNOOP_H @@ -195,7 +196,7 @@ extern void cap_open_read(const char *); extern void cap_open_write(const char *); extern void cap_read(int, int, int, void (*)(), int); extern void cap_close(void); -extern boolean_t open_datalink(dlpi_handle_t *, const char *); +extern boolean_t open_datalink(dlpi_handle_t *, const char *, const char *); extern void init_datalink(dlpi_handle_t, ulong_t, ulong_t, struct timeval *, struct Pf_ext_packetfilt *); extern void net_read(dlpi_handle_t, size_t, int, void (*)(), int); @@ -273,6 +274,8 @@ extern int interpret_socks_reply(int, char *, int); extern int interpret_trill(int, struct ether_header **, char *, int *); extern int interpret_isis(int, char *, int, boolean_t); extern int interpret_bpdu(int, char *, int); +extern int interpret_vxlan(int, char *, int); +extern int interpret_svp(int, char *, int); extern void init_ldap(void); extern boolean_t arp_for_ether(char *, struct ether_addr *); extern char *ether_ouiname(uint32_t); diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c index ab6bc292ac..8fbf3fc15f 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_capture.c @@ -29,6 +29,7 @@ #include <strings.h> #include <errno.h> #include <fcntl.h> +#include <limits.h> #include <setjmp.h> #include <sys/types.h> #include <sys/signal.h> @@ -114,7 +115,7 @@ select_datalink(const char *linkname, void *arg) * about the datalink useful for building the proper packet filters. */ boolean_t -open_datalink(dlpi_handle_t *dhp, const char *linkname) +open_datalink(dlpi_handle_t *dhp, const char *linkname, const char *zonename) { int retval; int flags = DLPI_PASSIVE | DLPI_RAW; @@ -122,6 +123,9 @@ open_datalink(dlpi_handle_t *dhp, const char *linkname) dlpi_info_t dlinfo; if (linkname == NULL) { + if (zonename != NULL) + pr_err("a datalink must be specified with a zone name"); + /* * Select a datalink to use by default. Prefer datalinks that * are plumbed by IP. @@ -145,7 +149,8 @@ open_datalink(dlpi_handle_t *dhp, const char *linkname) flags |= DLPI_DEVIPNET; if (Iflg || strcmp(linkname, "lo0") == 0) flags |= DLPI_IPNETINFO; - if ((retval = dlpi_open(linkname, dhp, flags)) != DLPI_SUCCESS) { + if ((retval = dlpi_open_zone(linkname, zonename, dhp, + flags)) != DLPI_SUCCESS) { pr_err("cannot open \"%s\": %s", linkname, dlpi_strerror(retval)); } @@ -614,6 +619,10 @@ cap_open_read(const char *name) if (fstat(capfile_in, &st) < 0) pr_err("couldn't stat %s: %m", name); + if (st.st_size > INT_MAX) + pr_err("input file size (%llu bytes) exceeds maximum " + "supported size (%d bytes)", + (unsigned long long)st.st_size, INT_MAX); cap_len = st.st_size; cap_buffp = mmap(0, cap_len, PROT_READ, MAP_PRIVATE, capfile_in, 0); diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ether.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ether.c index 5c6bde0cd6..029ed66116 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ether.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ether.c @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2015 Joyent, Inc. */ #include <stdio.h> @@ -54,8 +55,9 @@ static headerlen_fn_t ether_header_len, fddi_header_len, tr_header_len, ib_header_len, ipnet_header_len, ipv4_header_len, ipv6_header_len; -static interpreter_fn_t interpret_ether, interpret_fddi, interpret_tr, +static interpreter_fn_t interpret_fddi, interpret_tr, interpret_ib, interpret_ipnet, interpret_iptun; +interpreter_fn_t interpret_ether; static void addr_copy_swap(struct ether_addr *, struct ether_addr *); static int tr_machdr_len(char *, int *, int *); diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rport.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rport.c index 3f745b30eb..8e474fe470 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rport.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_rport.c @@ -21,6 +21,7 @@ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2018, Joyent, Inc. */ #include <stdio.h> @@ -76,6 +77,7 @@ static const struct porttable pt_udp[] = { { 560, "RMONITOR" }, { 561, "MONITOR" }, { IPPORT_SOCKS, "SOCKS" }, + { IPPORT_VXLAN, "VXLAN" }, { 0, NULL } }; @@ -128,6 +130,7 @@ static struct porttable pt_tcp[] = { { 540, "UUCP" }, { 600, "PCSERVER" }, { IPPORT_SOCKS, "SOCKS" }, + { 1296, "SVP" }, { 1524, "INGRESLOCK" }, { 2904, "M2UA" }, { 2905, "M3UA" }, @@ -425,6 +428,15 @@ interpret_reserved(int flags, int proto, in_port_t src, in_port_t dst, (void) interpret_socks_reply(flags, data, dlen); return (1); + case IPPORT_VXLAN: + (void) interpret_vxlan(flags, data, dlen); + return (1); + case 1296: + if (proto == IPPROTO_TCP) { + (void) interpret_svp(flags, data, dlen); + return (1); + } + break; } } diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_svp.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_svp.c new file mode 100644 index 0000000000..54f4dded8c --- /dev/null +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_svp.c @@ -0,0 +1,556 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. All rights reserved. + */ + +/* + * Decode SVP (SmartDC VxLAN Protocol) packets + */ + +#include <inttypes.h> +#include <sys/crc32.h> +#include <uuid/uuid.h> +#include <stdio.h> +#include <stdarg.h> +#include <libvarpd_svp_prot.h> +#include "snoop.h" + +/* + * String size large enough for an IPv6 address + / + a 3 digit (or less) + * prefix length + */ +#define ADDRSTR_LEN (INET6_ADDRSTRLEN + 4) + +/* + * Large enough for all currently known status strings as well as a + * 16-bit hex value. + */ +#define STATUSSTR_LEN 32 + +/* + * Large enough for all currently known op strings, as well as a + * 16-bit hex value. + */ +#define OPSTR_LEN 32 + +/* + * Large enough for VL3 types and bulk types, as well as a 32-bit + * hex value. + */ +#define TYPESTR_LEN 32 + +static uint32_t svp_crc32_tab[] = { CRC32_TABLE }; + +#define STR(_x, _buf, _len) \ + case _x: \ + (void) strlcpy(_buf, #_x, _len); \ + break + +static void +svp_op_str(uint16_t op, char *buf, size_t buflen) +{ + switch (op) { + STR(SVP_R_UNKNOWN, buf, buflen); + STR(SVP_R_PING, buf, buflen); + STR(SVP_R_PONG, buf, buflen); + STR(SVP_R_VL2_REQ, buf, buflen); + STR(SVP_R_VL2_ACK, buf, buflen); + STR(SVP_R_VL3_REQ, buf, buflen); + STR(SVP_R_VL3_ACK, buf, buflen); + STR(SVP_R_BULK_REQ, buf, buflen); + STR(SVP_R_BULK_ACK, buf, buflen); + STR(SVP_R_LOG_REQ, buf, buflen); + STR(SVP_R_LOG_ACK, buf, buflen); + STR(SVP_R_LOG_RM, buf, buflen); + STR(SVP_R_LOG_RM_ACK, buf, buflen); + STR(SVP_R_SHOOTDOWN, buf, buflen); + default: + (void) snprintf(buf, buflen, "0x%hx", op); + } +} + +static void +svp_status_str(uint16_t status, char *buf, size_t buflen) +{ + switch (status) { + STR(SVP_S_OK, buf, buflen); + STR(SVP_S_FATAL, buf, buflen); + STR(SVP_S_NOTFOUND, buf, buflen); + STR(SVP_S_BADL3TYPE, buf, buflen); + STR(SVP_S_BADBULK, buf, buflen); + default: + (void) snprintf(buf, buflen, "0x%hx", status); + } +} + +static void +svp_vl3_type_str(uint32_t type, char *buf, size_t buflen) +{ + switch (type) { + STR(SVP_VL3_IP, buf, buflen); + STR(SVP_VL3_IPV6, buf, buflen); + default: + (void) snprintf(buf, buflen, "0x%x", type); + } +} + +static void +svp_bulk_type_str(uint32_t type, char *buf, size_t buflen) +{ + switch (type) { + STR(SVP_BULK_VL2, buf, buflen); + STR(SVP_BULK_VL3, buf, buflen); + default: + (void) snprintf(buf, buflen, "0x%x", type); + } +} + +static void +svp_log_type_str(uint32_t type, char *buf, size_t buflen) +{ + switch (type) { + STR(SVP_LOG_VL2, buf, buflen); + STR(SVP_LOG_VL3, buf, buflen); + default: + (void) snprintf(buf, buflen, "0x%x", type); + } +} +#undef STR + +static void +svp_addr_str(void *addrp, uint8_t *prefixp, char *buf, size_t buflen) +{ + struct in_addr v4; + int af = AF_INET6; + + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addrp)) { + af = AF_INET; + IN6_V4MAPPED_TO_INADDR((struct in6_addr *)addrp, &v4); + addrp = &v4; + } + + if (inet_ntop(af, addrp, buf, buflen) == NULL) { + uint8_t *p = addrp; + size_t i; + + (void) strlcpy(buf, "0x", buflen); + for (i = 0; i < 16; i++) { + (void) snprintf(buf + 2 + i * 2, + sizeof (buf) - 2 - i * 2, "%02hhx", p[i]); + } + } + + if (prefixp != NULL && *prefixp != 128) { + char buf2[5]; /* / + 3 digits + NUL */ + + if (af == AF_INET) + *prefixp -= 96; + + (void) snprintf(buf2, sizeof (buf2), "/%hhu", *prefixp); + (void) strlcat(buf, buf2, buflen); + } +} + +static boolean_t +svp_check_crc(char *data, int len) +{ + svp_req_t *req = (svp_req_t *)data; + uint32_t save_crc = req->svp_crc32; + uint32_t crc = -1U; + + req->svp_crc32 = 0; + CRC32(crc, (uint8_t *)data, len, -1U, svp_crc32_tab); + crc = ~crc; + req->svp_crc32 = save_crc; + + return (ntohl(save_crc) == crc ? B_TRUE : B_FALSE); +} + +static void +do_svp_vl2_req(void *data, int len) +{ + svp_vl2_req_t *vl2 = data; + + show_printf("MAC = %s", ether_ntoa((struct ether_addr *)vl2->sl2r_mac)); + show_printf("Virtual network id = %u", ntohl(vl2->sl2r_vnetid)); +} + +static void +do_svp_vl2_ack(void *data, int len) +{ + svp_vl2_ack_t *vl2a = data; + char status[STATUSSTR_LEN]; + char addr[ADDRSTR_LEN]; + + svp_status_str(ntohs(vl2a->sl2a_status), status, sizeof (status)); + svp_addr_str(vl2a->sl2a_addr, NULL, addr, sizeof (addr)); + + show_printf("Status = %s", status); + show_printf("UL3 Address = %s", addr); + show_printf("UL3 Port = %hu", ntohs(vl2a->sl2a_port)); +} + +static void +do_svp_vl3_req(void *data, int len) +{ + svp_vl3_req_t *req = data; + char type[TYPESTR_LEN]; + char addr[ADDRSTR_LEN]; + + svp_vl3_type_str(ntohl(req->sl3r_type), type, sizeof (type)); + svp_addr_str(req->sl3r_ip, NULL, addr, sizeof (addr)); + + show_printf("Virtual network id = %u", ntohl(req->sl3r_vnetid)); + show_printf("Type = %s", type); + show_printf("VL3 Address = %s", addr); +} + +static void +do_svp_vl3_ack(void *data, int len) +{ + svp_vl3_ack_t *vl3a = data; + char status[STATUSSTR_LEN]; + char addr[ADDRSTR_LEN]; + + svp_status_str(ntohl(vl3a->sl3a_status), status, sizeof (status)); + svp_addr_str(vl3a->sl3a_uip, NULL, addr, sizeof (addr)); + + show_printf("Status = %s", status); + show_printf("MAC = %s", + ether_ntoa((struct ether_addr *)vl3a->sl3a_mac)); + show_printf("UL3 Address = %s", addr); + show_printf("UL3 Port = %hu", ntohs(vl3a->sl3a_uport)); +} + +static void +do_svp_bulk_req(void *data, int len) +{ + svp_bulk_req_t *req = data; + char type[TYPESTR_LEN]; + + if (len < sizeof (svp_bulk_req_t)) { + show_printf("SVP_R_BULK_REQ runt"); + return; + } + + svp_bulk_type_str(ntohl(req->svbr_type), type, sizeof (type)); + show_printf("Type = %s", type); +} + +static void +do_svp_bulk_ack(void *data, int len) +{ + svp_bulk_ack_t *ack = data; + char status[STATUSSTR_LEN]; + char type[TYPESTR_LEN]; + + svp_status_str(ntohl(ack->svba_status), status, sizeof (status)); + svp_bulk_type_str(ntohl(ack->svba_type), type, sizeof (type)); + + show_printf("Status = %s", status); + show_printf("Type = %s", type); + + /* + * Currently the data format is undefined (see libvarp_svp_prot.h), + * so there is nothing else we can display. + */ +} + +static void +do_svp_log_req(void *data, int len) +{ + svp_log_req_t *svlr = data; + char addr[ADDRSTR_LEN]; + + svp_addr_str(svlr->svlr_ip, NULL, addr, sizeof (addr)); + + show_printf("Count = %u", ntohl(svlr->svlr_count)); + show_printf("Address = %s", addr); +} + +static void +do_svp_log_ack(void *data, int len) +{ + svp_log_ack_t *ack = data; + union { + svp_log_vl2_t *vl2; + svp_log_vl3_t *vl3; + uint32_t *vtype; + void *vd; + } u; + size_t total = 0, rlen = 0; + uint8_t prefixlen; + boolean_t is_host; + char status[STATUSSTR_LEN]; + char typestr[TYPESTR_LEN]; + char uuid[UUID_PRINTABLE_STRING_LENGTH]; + char addr[ADDRSTR_LEN]; + + u.vd = (ack + 1); + + svp_status_str(ntohl(ack->svla_status), status, sizeof (status)); + + show_printf("Status = %s", status); + len -= sizeof (*ack); + + while (len > 0) { + uint32_t type; + + if (len < sizeof (uint32_t)) { + show_printf(" Trailing runt"); + break; + } + + type = ntohl(*u.vtype); + svp_log_type_str(type, typestr, sizeof (typestr)); + + switch (type) { + case SVP_LOG_VL2: + rlen = sizeof (svp_log_vl2_t); + break; + case SVP_LOG_VL3: + rlen = sizeof (svp_log_vl3_t); + break; + default: + /* + * If we don't know the type of log record we have, + * we cannot determine the size of the record, so we + * cannot continue past this. + */ + show_printf("Log %-4zu: Log type = %s", ++total, + typestr); + return; + } + + if (len < rlen) { + show_printf("Log %-4zu %s runt", ++total, typestr); + return; + } + + /* These are the same in SVP_LOG_VL2 and SVP_LOG_VL3 records */ + show_printf("Log %-4zu Log type = %s", ++total, typestr); + + uuid_parse(uuid, u.vl2->svl2_id); + show_printf("%8s UUID = %s", "", uuid); + + switch (type) { + case SVP_LOG_VL2: + show_printf("%8s MAC = %s", "", + ether_ntoa((struct ether_addr *)u.vl2->svl2_mac)); + show_printf("%8s Vnet = %u", "", + ntohl(u.vl2->svl2_vnetid)); + u.vl2++; + break; + case SVP_LOG_VL3: + svp_addr_str(u.vl3->svl3_ip, NULL, addr, sizeof (addr)); + + show_printf("%8s VLAN = %hu", "", + ntohs(u.vl3->svl3_vlan)); + show_printf("%8s Address = %s", "", addr); + show_printf("%8s Vnet = %u", "", + ntohl(u.vl3->svl3_vnetid)); + u.vl3++; + break; + } + + len -= rlen; + show_space(); + } + show_printf("Total log records = %zu", total); +} + +static void +do_svp_lrm_req(void *data, int len) +{ + /* + * Sized large enough to hold the expected size message + * (formatted below) if there's a length mismatch. + */ + char mismatch_str[64] = { 0 }; + svp_lrm_req_t *req = data; + size_t expected_sz = sizeof (*req); + size_t i, n; + + n = ntohl(req->svrr_count); + + /* IDs are 16-byte UUIDs */ + expected_sz += n * UUID_LEN; + if (len != expected_sz) { + (void) snprintf(mismatch_str, sizeof (mismatch_str), + " (expected %zu bytes, actual size is %d bytes)", + expected_sz, len); + } + show_printf("ID Count = %u%s", n, mismatch_str); + if (len != expected_sz) + return; + + for (i = 0; i < n; i++) { + char uuid[UUID_PRINTABLE_STRING_LENGTH]; + + uuid_parse(uuid, &req->svrr_ids[UUID_LEN * i]); + show_printf("%-4s %s", (i == 0) ? "IDs:" : "", uuid); + } +} + +static void +do_svp_lrm_ack(void *data, int len) +{ + svp_lrm_ack_t *ack = data; + char status[STATUSSTR_LEN]; + + svp_status_str(ntohl(ack->svra_status), status, sizeof (status)); + show_printf("Status = %s", status); +} + +static void +do_svp_shootdown(void *data, int len) +{ + svp_shootdown_t *sd = data; + + show_printf("Vnet = %u", ntohl(sd->svsd_vnetid)); + show_printf("MAC Address = %s", + ether_ntoa((struct ether_addr *)sd->svsd_mac)); +} + +static struct svp_len_tbl { + uint16_t slt_op; + size_t slt_len; +} svp_len_tbl[] = { + { SVP_R_UNKNOWN, 0 }, + { SVP_R_PING, 0 }, + { SVP_R_PONG, 0 }, + { SVP_R_VL2_REQ, sizeof (svp_vl2_req_t) }, + { SVP_R_VL2_ACK, sizeof (svp_vl2_ack_t) }, + { SVP_R_VL3_REQ, sizeof (svp_vl3_req_t) }, + { SVP_R_VL3_ACK, sizeof (svp_vl3_ack_t) }, + { SVP_R_BULK_REQ, sizeof (svp_bulk_req_t) }, + { SVP_R_BULK_ACK, sizeof (svp_bulk_ack_t) }, + { SVP_R_LOG_REQ, sizeof (svp_log_req_t) }, + { SVP_R_LOG_ACK, 0 }, + { SVP_R_LOG_RM, sizeof (svp_lrm_req_t) }, + { SVP_R_LOG_RM_ACK, sizeof (svp_lrm_ack_t) }, + { SVP_R_SHOOTDOWN, sizeof (svp_shootdown_t) }, +}; + +static boolean_t +svp_check_runt(uint16_t op, int len) +{ + if (op > SVP_R_SHOOTDOWN) + return (B_FALSE); + + if (len < svp_len_tbl[op].slt_len) { + char opstr[OPSTR_LEN]; + + svp_op_str(op, opstr, sizeof (opstr)); + show_printf("%s Runt", opstr); + show_space(); + return (B_TRUE); + } + return (B_FALSE); +} + +int +interpret_svp(int flags, char *data, int fraglen) +{ + svp_req_t *req = (svp_req_t *)data; + char opstr[OPSTR_LEN]; + uint16_t op; + boolean_t crc_ok; + + if (fraglen < sizeof (svp_req_t)) { + if (flags & F_SUM) + (void) snprintf(get_sum_line(), MAXLINE, + "SVP RUNT"); + if (flags & F_DTAIL) + show_header("SVP RUNT: ", "Short packet", fraglen); + + return (fraglen); + } + + op = ntohs(req->svp_op); + svp_op_str(op, opstr, sizeof (opstr)); + + crc_ok = svp_check_crc(data, fraglen); + + if (flags & F_SUM) { + (void) snprintf(get_sum_line(), MAXLINE, + "SVP V=%hu OP=%s ID=%u%s", ntohs(req->svp_ver), opstr, + ntohl(req->svp_id), crc_ok ? "" : " (BAD CRC)"); + } + + if (flags & F_DTAIL) { + show_header("SVP: ", "SVP Header", sizeof (svp_req_t)); + show_space(); + show_printf("Version = %hu", ntohs(req->svp_ver)); + show_printf("Op = %s", opstr); + show_printf("Packet length = %u bytes%s", ntohl(req->svp_size), + (ntohl(req->svp_size) == fraglen - sizeof (*req)) ? + "" : " (mismatch)"); + show_printf("Id = %u", ntohl(req->svp_id)); + show_printf("CRC = %x%s", ntohl(req->svp_crc32), + crc_ok ? "" : " (bad)"); + show_space(); + + req++; + fraglen -= sizeof (*req); + + /* + * Since we cannot know the length of an unknown op, + * svp_check_runt() returns B_TRUE for both truncated packets + * and unknown packets -- we have nothing meaningful besides + * the header we could print anyway. + */ + if (svp_check_runt(op, fraglen)) + return (fraglen); + + switch (op) { + case SVP_R_VL2_REQ: + do_svp_vl2_req(req, fraglen); + break; + case SVP_R_VL2_ACK: + do_svp_vl2_ack(req, fraglen); + break; + case SVP_R_VL3_REQ: + do_svp_vl3_req(req, fraglen); + break; + case SVP_R_VL3_ACK: + do_svp_vl3_ack(req, fraglen); + break; + case SVP_R_BULK_REQ: + do_svp_bulk_req(req, fraglen); + break; + case SVP_R_BULK_ACK: + do_svp_bulk_ack(req, fraglen); + break; + case SVP_R_LOG_REQ: + do_svp_log_req(req, fraglen); + break; + case SVP_R_LOG_ACK: + do_svp_log_ack(req, fraglen); + break; + case SVP_R_LOG_RM: + do_svp_lrm_req(req, fraglen); + break; + case SVP_R_LOG_RM_ACK: + do_svp_lrm_ack(req, fraglen); + break; + case SVP_R_SHOOTDOWN: + do_svp_shootdown(req, fraglen); + break; + } + + show_space(); + } + + return (0); +} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_vxlan.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_vxlan.c new file mode 100644 index 0000000000..36025ca8f3 --- /dev/null +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_vxlan.c @@ -0,0 +1,68 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2015 Joyent, Inc. All rights reserved. + */ + +/* + * Decode VXLAN encapsulated packets. + */ + +#include <sys/vxlan.h> +#include "snoop.h" + +int +interpret_vxlan(int flags, char *data, int fraglen) +{ + vxlan_hdr_t *vxlan = (vxlan_hdr_t *)data; + uint32_t id, vxf; + + if (fraglen < sizeof (vxlan_hdr_t)) { + if (flags & F_SUM) + (void) snprintf(get_sum_line(), MAXLINE, + "VXLAN RUNT"); + if (flags & F_DTAIL) + show_header("VXLAN RUNT: ", "Short packet", fraglen); + + return (fraglen); + } + + id = ntohl(vxlan->vxlan_id) >> VXLAN_ID_SHIFT; + vxf = ntohl(vxlan->vxlan_flags); + + if (flags & F_SUM) { + (void) snprintf(get_sum_line(), MAXLINE, + "VXLAN VNI=%d", id); + } + + if (flags & F_DTAIL) { + show_header("VXLAN: ", "VXLAN Header", sizeof (vxlan_hdr_t)); + show_space(); + (void) snprintf(get_line(0, 0), get_line_remain(), + "Flags = 0x%08x", vxf); + (void) snprintf(get_line(0, 0), get_line_remain(), " %s", + getflag(vxf >> 24, VXLAN_F_VDI >> 24, "vni present", + "vni missing")); + (void) snprintf(get_line(0, 0), get_line_remain(), + "VXLAN network id (VNI) = %d", id); + show_space(); + } + + if (flags & (F_DTAIL | F_ALLSUM)) { + fraglen -= sizeof (vxlan_hdr_t); + data += sizeof (vxlan_hdr_t); + + return (interpret_ether(flags, data, fraglen, fraglen)); + } + + return (0); +} diff --git a/usr/src/cmd/column/Makefile b/usr/src/cmd/column/Makefile new file mode 100644 index 0000000000..b9b395b384 --- /dev/null +++ b/usr/src/cmd/column/Makefile @@ -0,0 +1,34 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# Copyright 2018 Joyent, Inc. +# + +PROG=column +OBJS=column.o + +include ../Makefile.cmd + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) + +install: all $(ROOTPROG) + +clean: + $(RM) $(OBJS) + +lint: lint_PROG + +include ../Makefile.targ diff --git a/usr/src/cmd/column/THIRDPARTYLICENSE b/usr/src/cmd/column/THIRDPARTYLICENSE new file mode 100644 index 0000000000..a80f56cb43 --- /dev/null +++ b/usr/src/cmd/column/THIRDPARTYLICENSE @@ -0,0 +1,26 @@ +Copyright (c) 1989, 1993, 1994 + The Regents of the University of California. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. 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. +4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + * +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND 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. diff --git a/usr/src/cmd/column/THIRDPARTYLICENSE.descrip b/usr/src/cmd/column/THIRDPARTYLICENSE.descrip new file mode 100644 index 0000000000..42051a2982 --- /dev/null +++ b/usr/src/cmd/column/THIRDPARTYLICENSE.descrip @@ -0,0 +1 @@ +PORTIONS OF COLUMN COMMAND FUNCTIONALITY diff --git a/usr/src/cmd/column/column.c b/usr/src/cmd/column/column.c new file mode 100644 index 0000000000..5c76cb8751 --- /dev/null +++ b/usr/src/cmd/column/column.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 1989, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND 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. + */ +/* + * Portions Copyright 2018 Joyent, Inc. + */ + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/param.h> +#include <sys/termios.h> + +#include <err.h> +#include <limits.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <wchar.h> +#include <wctype.h> + +#define TAB 8 +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ + +static void c_columnate(void); +static void input(FILE *); +static void maketbl(void); +static void print(void); +static void r_columnate(void); +static void usage(void); +static int width(const wchar_t *); + +static int termwidth = 80; /* default terminal width */ + +static int entries; /* number of records */ +static int eval; /* exit value */ +static int maxlength; /* longest record */ +static wchar_t **list; /* array of pointers to records */ +static const wchar_t *separator = L"\t "; /* field separator for table option */ + +int +main(int argc, char **argv) +{ + struct winsize win; + FILE *fp; + int ch, tflag, xflag; + char *p; + const char *src; + wchar_t *newsep; + size_t seplen; + + (void) setlocale(LC_ALL, ""); + + if (ioctl(1, TIOCGWINSZ, &win) == -1 || !win.ws_col) { + if ((p = getenv("COLUMNS"))) + termwidth = atoi(p); + } else + termwidth = win.ws_col; + + tflag = xflag = 0; + while ((ch = getopt(argc, argv, "c:s:tx")) != -1) + switch (ch) { + case 'c': + termwidth = atoi(optarg); + break; + case 's': + src = optarg; + seplen = mbsrtowcs(NULL, &src, 0, NULL); + if (seplen == (size_t)-1) + err(1, "bad separator"); + newsep = malloc((seplen + 1) * sizeof (wchar_t)); + if (newsep == NULL) + err(1, NULL); + (void) mbsrtowcs(newsep, &src, seplen + 1, NULL); + separator = newsep; + break; + case 't': + tflag = 1; + break; + case 'x': + xflag = 1; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (!*argv) + input(stdin); + else for (; *argv; ++argv) + if ((fp = fopen(*argv, "rF"))) { + input(fp); + (void) fclose(fp); + } else { + warn("%s", *argv); + eval = 1; + } + + if (!entries) + exit(eval); + + maxlength = roundup(maxlength + 1, TAB); + if (tflag) + maketbl(); + else if (maxlength >= termwidth) + print(); + else if (xflag) + c_columnate(); + else + r_columnate(); + exit(eval); + + /*NOTREACHED*/ + return (eval); +} + +static void +c_columnate(void) +{ + int chcnt, col, cnt, endcol, numcols; + wchar_t **lp; + + numcols = termwidth / maxlength; + endcol = maxlength; + for (chcnt = col = 0, lp = list; ; ++lp) { + (void) wprintf(L"%ls", *lp); + chcnt += width(*lp); + if (!--entries) + break; + if (++col == numcols) { + chcnt = col = 0; + endcol = maxlength; + (void) putwchar('\n'); + } else { + while ((cnt = roundup(chcnt + 1, TAB)) <= endcol) { + (void) putwchar('\t'); + chcnt = cnt; + } + endcol += maxlength; + } + } + if (chcnt) + (void) putwchar('\n'); +} + +static void +r_columnate(void) +{ + int base, chcnt, cnt, col, endcol, numcols, numrows, row; + + numcols = termwidth / maxlength; + numrows = entries / numcols; + if (entries % numcols) + ++numrows; + + for (row = 0; row < numrows; ++row) { + endcol = maxlength; + for (base = row, chcnt = col = 0; col < numcols; ++col) { + (void) wprintf(L"%ls", list[base]); + chcnt += width(list[base]); + if ((base += numrows) >= entries) + break; + while ((cnt = roundup(chcnt + 1, TAB)) <= endcol) { + (void) putwchar('\t'); + chcnt = cnt; + } + endcol += maxlength; + } + (void) putwchar('\n'); + } +} + +static void +print(void) +{ + int cnt; + wchar_t **lp; + + for (cnt = entries, lp = list; cnt--; ++lp) + (void) wprintf(L"%ls\n", *lp); +} + +typedef struct _tbl { + wchar_t **list; + int cols, *len; +} TBL; +#define DEFCOLS 25 + +static void +maketbl(void) +{ + TBL *t; + int coloff, cnt; + wchar_t *p, **lp; + int *lens, maxcols; + TBL *tbl; + wchar_t **cols; + wchar_t *last; + + if ((t = tbl = calloc(entries, sizeof (TBL))) == NULL) + err(1, (char *)NULL); + if ((cols = calloc((maxcols = DEFCOLS), sizeof (*cols))) == NULL) + err(1, (char *)NULL); + if ((lens = calloc(maxcols, sizeof (int))) == NULL) + err(1, (char *)NULL); + for (cnt = 0, lp = list; cnt < entries; ++cnt, ++lp, ++t) { + for (coloff = 0, p = *lp; + (cols[coloff] = wcstok(p, separator, &last)); + p = NULL) + if (++coloff == maxcols) { + if (!(cols = realloc(cols, ((uint_t)maxcols + + DEFCOLS) * sizeof (char *))) || + !(lens = realloc(lens, + ((uint_t)maxcols + DEFCOLS) * + sizeof (int)))) + err(1, NULL); + (void) memset((char *)lens + maxcols * + sizeof (int), 0, DEFCOLS * sizeof (int)); + maxcols += DEFCOLS; + } + if ((t->list = calloc(coloff, sizeof (*t->list))) == NULL) + err(1, (char *)NULL); + if ((t->len = calloc(coloff, sizeof (int))) == NULL) + err(1, (char *)NULL); + for (t->cols = coloff; --coloff >= 0; ) { + t->list[coloff] = cols[coloff]; + t->len[coloff] = width(cols[coloff]); + if (t->len[coloff] > lens[coloff]) + lens[coloff] = t->len[coloff]; + } + } + for (cnt = 0, t = tbl; cnt < entries; ++cnt, ++t) { + for (coloff = 0; coloff < t->cols - 1; ++coloff) + (void) wprintf(L"%ls%*ls", t->list[coloff], + lens[coloff] - t->len[coloff] + 2, L" "); + (void) wprintf(L"%ls\n", t->list[coloff]); + } +} + +#define DEFNUM 1000 +#define MAXLINELEN (LINE_MAX + 1) + +static void +input(FILE *fp) +{ + static int maxentry; + int len; + wchar_t *p, buf[MAXLINELEN]; + + if (!list) + if ((list = calloc((maxentry = DEFNUM), sizeof (*list))) == + NULL) + err(1, (char *)NULL); + while (fgetws(buf, MAXLINELEN, fp)) { + for (p = buf; *p && iswspace(*p); ++p) + ; + if (!*p) + continue; + if (!(p = wcschr(p, L'\n'))) { + warnx("line too long"); + eval = 1; + continue; + } + *p = L'\0'; + len = width(buf); + if (maxlength < len) + maxlength = len; + if (entries == maxentry) { + maxentry += DEFNUM; + if (!(list = realloc(list, + (uint_t)maxentry * sizeof (*list)))) + err(1, NULL); + } + list[entries] = malloc((wcslen(buf) + 1) * sizeof (wchar_t)); + if (list[entries] == NULL) + err(1, NULL); + (void) wcscpy(list[entries], buf); + entries++; + } +} + +/* Like wcswidth(), but ignores non-printing characters. */ +static int +width(const wchar_t *wcs) +{ + int w, cw; + + for (w = 0; *wcs != L'\0'; wcs++) + if ((cw = wcwidth(*wcs)) > 0) + w += cw; + return (w); +} + +static void +usage(void) +{ + + (void) fprintf(stderr, + "usage: column [-tx] [-c columns] [-s sep] [file ...]\n"); + exit(1); +} diff --git a/usr/src/cmd/connstat/Makefile b/usr/src/cmd/connstat/Makefile new file mode 100644 index 0000000000..847bd05428 --- /dev/null +++ b/usr/src/cmd/connstat/Makefile @@ -0,0 +1,51 @@ +# +# CDDL HEADER START +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# CDDL HEADER END +# +# +# Copyright (c) 2015 by Delphix. All rights reserved. +# + +PROG= connstat +OBJS= connstat_main.o connstat_mib.o connstat_tcp.o +SRCS= $(OBJS:%.o=%.c) +POFILES= connstat_main.po connstat_tcp.po connstat_mib.po +POFILE= connstat.po + +include ../Makefile.cmd +include ../Makefile.ctf + +CSTD= $(CSTD_GNU99) +LDLIBS += -lsocket -lnsl -lumem -lofmt +XGETFLAGS += -a -x $(PROG).xcl + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) + +$(POFILE): $(POFILES) + $(RM) $@ + cat $(POFILES) > $@ + +install: all $(ROOTPROG) + +clean: + $(RM) $(OBJS) + +lint: lint_SRCS + +include ../Makefile.targ diff --git a/usr/src/cmd/connstat/connstat.h b/usr/src/cmd/connstat/connstat.h new file mode 100644 index 0000000000..a50049b3c7 --- /dev/null +++ b/usr/src/cmd/connstat/connstat.h @@ -0,0 +1,79 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2015, 2016 by Delphix. All rights reserved. + */ + +#ifndef _CONNSTAT_H +#define _CONNSTAT_H + +#include <sys/types.h> +#include <sys/socket.h> +#include <ofmt.h> +#include <sys/stropts.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct connstat_conn_attr_s { + struct sockaddr_storage ca_laddr; + struct sockaddr_storage ca_raddr; + int ca_lport; + int ca_rport; + int ca_state; +} connstat_conn_attr_t; + +typedef struct conn_walk_state_s { + ofmt_handle_t cws_ofmt; + uint_t cws_flags; + connstat_conn_attr_t cws_filter; +} conn_walk_state_t; + +/* cws_flags */ +#define CS_LOOPBACK 0x0001 /* Include loopback connections */ +#define CS_IPV4 0x0002 /* Show only IPv4 connections */ +#define CS_IPV6 0x0004 /* Show only IPv6 connections */ +#define CS_LADDR 0x0008 /* Filter by laddr in cws_filter */ +#define CS_RADDR 0x0010 /* Filter by raddr in cws_filter */ +#define CS_LPORT 0x0020 /* Filter by lport in cws_filter */ +#define CS_RPORT 0x0040 /* Filter by rport in cws_filter */ +#define CS_STATE 0x0080 /* Filter by state in cws_filter */ +#define CS_PARSABLE 0x0100 /* Parsable output */ + +typedef ofmt_field_t *connstat_getfieldsfunc_t(void); +typedef void connstat_walkfunc_t(struct strbuf *, conn_walk_state_t *); + +typedef struct connstat_proto_s { + char *csp_proto; + char *csp_default_fields; + int csp_miblevel; + int csp_mibv4name; + int csp_mibv6name; + connstat_getfieldsfunc_t *csp_getfields; + connstat_walkfunc_t *csp_v4walk; + connstat_walkfunc_t *csp_v6walk; +} connstat_proto_t; + +boolean_t print_string(ofmt_arg_t *, char *, uint_t); +boolean_t print_uint16(ofmt_arg_t *, char *, uint_t); +boolean_t print_uint32(ofmt_arg_t *, char *, uint_t); +boolean_t print_uint64(ofmt_arg_t *, char *, uint_t); + +#ifdef __cplusplus +} +#endif + +#endif /* _CONNSTAT_H */ diff --git a/usr/src/cmd/connstat/connstat.xcl b/usr/src/cmd/connstat/connstat.xcl new file mode 100644 index 0000000000..089bc7358e --- /dev/null +++ b/usr/src/cmd/connstat/connstat.xcl @@ -0,0 +1,84 @@ +# +# CDDL HEADER START +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# CDDL HEADER END +# +# +# Copyright (c) 2015 by Delphix. All rights reserved. +# + +msgid "count" +msgid "established" +msgid "filter" +msgid "help" +msgid "interval" +msgid "ipv4" +msgid "ipv6" +msgid "no-loopback" +msgid "output" +msgid "parsable" +msgid "protocol" +msgid "timestamp" +msgid "tcp" +msgid "laddr,lport,raddr,rport,inbytes,outbytes," + "retransbytes,suna,swnd,cwnd,rwnd" +msgid " %s\n" +msgid "" +msgid "c:eF:hi:Lo:Pp:T:46" +msgid "all" +msgid "laddr" +msgid "raddr" +msgid "lport" +msgid "rport" +msgid "= " +msgid "%s%ld\n" +msgid "%s%s\n" +msgid "%hu" +msgid "%u" +msgid "%llu" +msgid "%s: " +msgid "LADDR" +msgid "RADDR" +msgid "LPORT" +msgid "RPORT" +msgid "INBYTES" +msgid "INSEGS" +msgid "INUNORDERBYTES" +msgid "INUNORDERSEGS" +msgid "OUTBYTES" +msgid "OUTSEGS" +msgid "RETRANSBYTES" +msgid "RETRANSSEGS" +msgid "SUNA" +msgid "count" +msgid "SWND" +msgid "CWND" +msgid "RWND" +msgid "STATE" +msgid "CLOSED" +msgid "IDLE" +msgid "BOUND" +msgid "LISTEN" +msgid "SYN_SENT" +msgid "SYN_RCVD" +msgid "ESTABLISHED" +msgid "CLOSE_WAIT" +msgid "FIN_WAIT_1" +msgid "CLOSING" +msgid "LAST_ACK" +msgid "FIN_WAIT_2" +msgid "TIME_WAIT" +msgid "UNKNOWN(%d)" +msgid "/dev/arp" +msgid "putmsg" +msgid "getmsg" +msgid "malloc" diff --git a/usr/src/cmd/connstat/connstat_main.c b/usr/src/cmd/connstat/connstat_main.c new file mode 100644 index 0000000000..dd58e2ac2b --- /dev/null +++ b/usr/src/cmd/connstat/connstat_main.c @@ -0,0 +1,567 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2015, 2016 by Delphix. All rights reserved. + */ + +#include <err.h> +#include <stdio.h> +#include <errno.h> +#include <getopt.h> +#include <stdlib.h> +#include <stddef.h> +#include <strings.h> +#include <unistd.h> +#include <libgen.h> +#include <libintl.h> +#include <limits.h> +#include <locale.h> +#include <langinfo.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <sys/varargs.h> +#include <ofmt.h> +#include <inet/tcp.h> +#include <netinet/in.h> +#include <inet/mib2.h> +#include "connstat.h" +#include "connstat_mib.h" +#include "connstat_tcp.h" + +#define DEFAULT_PROTO "tcp" + +static const char *invalid_v4v6_msg = + "Invalid combination of IPv4 and IPv6 arguments\n"; + +static const char *invalid_T_msg = + "Invalid -T arg \"%s\". Must be \"u\" or \"d\"\n"; + +static const struct option longopts[] = { + { "count", required_argument, 0, 'c' }, + { "established", no_argument, 0, 'e' }, + { "filter", required_argument, 0, 'F' }, + { "help", no_argument, 0, 'h' }, + { "interval", required_argument, 0, 'i' }, + { "ipv4", no_argument, 0, '4' }, + { "ipv6", no_argument, 0, '6' }, + { "no-loopback", no_argument, 0, 'L' }, + { "output", required_argument, 0, 'o' }, + { "parsable", no_argument, 0, 'P' }, + { "protocol", required_argument, 0, 'p' }, + { "timestamp", required_argument, 0, 'T' }, + { NULL, 0, 0, 0 } +}; + +static connstat_proto_t connstat_protos[] = { + CONNSTAT_TCP_PROTO, + { NULL, NULL, 0, 0, 0, NULL, NULL, NULL } +}; + +typedef enum { NOTIMESTAMP, UTIMESTAMP, DTIMESTAMP } timestamp_fmt_t; + +static void die(const char *, ...) __NORETURN; +static void process_filter(char *, connstat_conn_attr_t *, uint_t *); +static void show_stats(connstat_proto_t *, ofmt_handle_t, uint_t, + connstat_conn_attr_t *, timestamp_fmt_t, uint_t, uint_t); + +static void __NORETURN +usage(int code) +{ + static const char *opts[] = { + "-4, --ipv4 Only display IPv4 connections", + "-6, --ipv6 Only display IPv6 connections", + "-c, --count=COUNT Only print COUNT reports", + "-e, --established Only display established connections", + "-F, --filter=FILTER Only display connections that match " + "FILTER", + "-h, --help Print this help", + "-i, --interval=SECONDS Report once every SECONDS seconds", + "-L, --no-loopback Omit loopback connections", + "-o, --output=FIELDS Restrict output to the comma-separated " + "list of fields\n" + " specified", + "-P, --parsable Parsable output mode", + "-T, --timestamp=TYPE Display a timestamp for each iteration", + NULL + }; + + (void) fprintf(stderr, gettext("usage: ")); + (void) fprintf(stderr, + gettext("%s [-eLP] [-4|-6] [-T d|u] [-F <filter>]\n" + " [-i <interval> [-c <count>]] [-o <field>[,...]]\n"), + getprogname()); + + (void) fprintf(stderr, gettext("\nOptions:\n")); + for (const char **optp = opts; *optp != NULL; optp++) { + (void) fprintf(stderr, " %s\n", gettext(*optp)); + } + + (void) fprintf(stderr, gettext("\nFilter:\n")); + (void) fprintf(stderr, gettext(" The FILTER argument for the -F " + "option is of the form:\n" + " <field>=<value>,[<field>=<value>,...]\n")); + (void) fprintf(stderr, gettext(" Filterable fields are laddr, lport, " + "raddr, rport, and state.\n")); + + (void) fprintf(stderr, gettext("\nFields:\n")); + (void) fprintf(stderr, gettext( + " laddr Local IP address\n" + " raddr Remote IP address\n" + " lport Local port\n" + " rport Remote port\n" + " inbytes Total bytes received\n" + " insegs Total segments received\n" + " inunorderbytes Bytes received out of order\n" + " inunordersegs Segments received out of order\n" + " outbytes Total bytes sent\n" + " outsegs Total segments sent\n" + " retransbytes Bytes retransmitted\n" + " retranssegs Segments retransmitted\n" + " suna Current unacknowledged bytes sent\n" + " unsent Unsent bytes on the transmit queue\n" + " swnd Send window size (peer's receive window)\n" + " cwnd Congestion window size\n" + " rwnd Receive window size\n" + " mss Maximum segment size\n" + " rto Retransmission timeout (ms)\n" + " rtt Smoothed round-trip time (us)\n" + " rtts Sum round-trip time (us)\n" + " rttc Count of round-trip times\n" + " state Connection state\n")); + exit(code); +} + +static connstat_proto_t * +getproto(const char *proto) +{ + for (connstat_proto_t *current = &connstat_protos[0]; + current->csp_proto != NULL; current++) { + if (strcasecmp(proto, current->csp_proto) == 0) { + return (current); + } + } + return (NULL); +} + +int +main(int argc, char *argv[]) +{ + int option; + int count = 0; + int interval = 0; + const char *errstr = NULL; + char *fields = NULL; + char *filterstr = NULL; + connstat_conn_attr_t filter = {0}; + char *protostr = DEFAULT_PROTO; + connstat_proto_t *proto; + ofmt_handle_t ofmt; + ofmt_status_t oferr; + char oferrbuf[OFMT_BUFSIZE]; + uint_t ofmtflags = OFMT_NOHEADER; + uint_t flags = CS_LOOPBACK | CS_IPV4 | CS_IPV6; + timestamp_fmt_t timestamp_fmt = NOTIMESTAMP; + + (void) setlocale(LC_ALL, ""); +#if !defined(TEXT_DOMAIN) +#define TEXT_DOMAIN "SYS_TEST" +#endif + (void) textdomain(TEXT_DOMAIN); + + setprogname(basename(argv[0])); + + while ((option = getopt_long(argc, argv, "c:eF:hi:Lo:Pp:T:46", + longopts, NULL)) != -1) { + switch (option) { + case 'c': + count = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr != NULL) { + (void) fprintf(stderr, gettext( + "error parsing -c argument (%s): %s\n"), + optarg, errstr); + usage(1); + } + break; + case 'e': + flags |= CS_STATE; + filter.ca_state = TCPS_ESTABLISHED; + break; + case 'F': + filterstr = optarg; + break; + case 'i': + interval = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr != NULL) { + (void) fprintf(stderr, gettext( + "error parsing -i argument (%s): %s\n"), + optarg, errstr); + usage(1); + } + break; + case 'L': + flags &= ~CS_LOOPBACK; + break; + case 'o': + fields = optarg; + break; + case 'P': + ofmtflags |= OFMT_PARSABLE; + flags |= CS_PARSABLE; + break; + case 'p': + /* + * -p is an undocumented flag whose only supported + * argument is "tcp". The idea is to reserve this + * flag for potential future use in case connstat + * is extended to support stats for other protocols. + */ + protostr = optarg; + break; + case 'T': + if (strcmp(optarg, "u") == 0) { + timestamp_fmt = UTIMESTAMP; + } else if (strcmp(optarg, "d") == 0) { + timestamp_fmt = DTIMESTAMP; + } else { + (void) fprintf(stderr, gettext( + invalid_T_msg), optarg); + usage(1); + } + break; + case '4': + if (!(flags & CS_IPV4)) { + (void) fprintf(stderr, gettext( + invalid_v4v6_msg)); + usage(1); + } + flags &= ~CS_IPV6; + break; + case '6': + if (!(flags & CS_IPV6)) { + (void) fprintf(stderr, gettext( + invalid_v4v6_msg)); + usage(1); + } + flags &= ~CS_IPV4; + break; + case '?': + default: + usage(1); + break; + } + } + + if ((proto = getproto(protostr)) == NULL) { + die("unknown protocol given to \"-p\": %s", protostr); + } + + if ((ofmtflags & OFMT_PARSABLE) && fields == NULL) { + die("parsable output requires \"-o\""); + } + + if ((ofmtflags & OFMT_PARSABLE) && fields != NULL && + strcasecmp(fields, "all") == 0) { + die("\"-o all\" is invalid with parsable output"); + } + + if (fields == NULL) { + fields = proto->csp_default_fields; + } + + /* If count is specified, then interval must also be specified. */ + if (count != 0 && interval == 0) { + die("\"-c\" requires \"-i\""); + } + + /* If interval is not specified, then the default count is 1. */ + if (interval == 0 && count == 0) { + count = 1; + } + + if (filterstr != NULL) { + process_filter(filterstr, &filter, &flags); + } + + oferr = ofmt_open(fields, proto->csp_getfields(), ofmtflags, 0, &ofmt); + if (oferr != OFMT_SUCCESS) { + (void) ofmt_strerror(ofmt, oferr, oferrbuf, sizeof (oferrbuf)); + die(oferrbuf); + } + ofmt_set_fs(ofmt, ','); + + show_stats(proto, ofmt, flags, &filter, timestamp_fmt, interval, count); + + ofmt_close(ofmt); + return (0); +} + +/* + * Convert the input IP address literal to sockaddr of the appropriate address + * family. Preserves any potential port number that may have been set in the + * input sockaddr_storage structure. + */ +static void +str2sockaddr(const char *addr, struct sockaddr_storage *ss) +{ + struct addrinfo hints, *res; + + bzero(&hints, sizeof (hints)); + hints.ai_flags = AI_NUMERICHOST; + if (getaddrinfo(addr, NULL, &hints, &res) != 0) { + die("invalid literal IP address: %s", addr); + } + bcopy(res->ai_addr, ss, res->ai_addrlen); + freeaddrinfo(res); +} + +/* + * The filterstr argument is of the form: <attr>=<value>[,...] + * Possible attributes are laddr, raddr, lport, and rport. Parse this + * filter and store the results into the provided attribute structure. + */ +static void +process_filter(char *filterstr, connstat_conn_attr_t *filter, uint_t *flags) +{ + int option; + char *val; + enum { F_LADDR, F_RADDR, F_LPORT, F_RPORT, F_STATE }; + static char *filter_optstr[] = + { "laddr", "raddr", "lport", "rport", "state", NULL }; + uint_t flag = 0; + struct sockaddr_storage *addrp = NULL; + const char *errstr = NULL; + int *portp = NULL; + + while (*filterstr != '\0') { + option = getsubopt(&filterstr, filter_optstr, &val); + errno = 0; + + switch (option) { + case F_LADDR: + flag = CS_LADDR; + addrp = &filter->ca_laddr; + break; + case F_RADDR: + flag = CS_RADDR; + addrp = &filter->ca_raddr; + break; + case F_LPORT: + flag = CS_LPORT; + portp = &filter->ca_lport; + break; + case F_RPORT: + flag = CS_RPORT; + portp = &filter->ca_rport; + break; + case F_STATE: + flag = CS_STATE; + break; + default: + usage(1); + } + + if (*flags & flag) { + (void) fprintf(stderr, gettext( + "Ambiguous filter provided. The \"%s\" field " + "appears more than once.\n"), + filter_optstr[option]); + usage(1); + } + *flags |= flag; + + switch (flag) { + case CS_LADDR: + case CS_RADDR: + str2sockaddr(val, addrp); + if (addrp->ss_family == AF_INET) { + if (!(*flags & CS_IPV4)) { + (void) fprintf(stderr, gettext( + invalid_v4v6_msg)); + usage(1); + } + *flags &= ~CS_IPV6; + } else { + if (!(*flags & CS_IPV6)) { + (void) fprintf(stderr, gettext( + invalid_v4v6_msg)); + usage(1); + } + *flags &= ~CS_IPV4; + } + break; + case CS_LPORT: + case CS_RPORT: + *portp = strtonum(val, 1, UINT16_MAX, &errstr); + if (errstr != NULL) { + (void) fprintf(stderr, gettext( + "error parsing port (%s): %s\n"), + val, errstr); + usage(1); + } + break; + case CS_STATE: + filter->ca_state = tcp_str2state(val); + if (filter->ca_state < TCPS_CLOSED) { + (void) fprintf(stderr, gettext( + "invalid TCP state: %s\n"), val); + usage(1); + } + break; + } + } + + /* Make sure that laddr and raddr are at least in the same family. */ + if ((*flags & (CS_LADDR|CS_RADDR)) == (CS_LADDR|CS_RADDR)) { + if (filter->ca_laddr.ss_family != filter->ca_raddr.ss_family) { + die("laddr and raddr must be of the same family."); + } + } +} + +/* + * Print timestamp as decimal representation of time_t value (-T u was + * specified) or in date(1) format (-T d was specified). + */ +static void +print_timestamp(timestamp_fmt_t timestamp_fmt, boolean_t parsable) +{ + time_t t = time(NULL); + char *pfx = parsable ? "= " : ""; + static char *fmt = NULL; + + /* We only need to retrieve this once per invocation */ + if (fmt == NULL) { + fmt = nl_langinfo(_DATE_FMT); + } + + switch (timestamp_fmt) { + case NOTIMESTAMP: + break; + case UTIMESTAMP: + (void) printf("%s%ld\n", pfx, t); + break; + case DTIMESTAMP: { + char dstr[64]; + size_t len; + + len = strftime(dstr, sizeof (dstr), fmt, localtime(&t)); + if (len > 0) { + (void) printf("%s%s\n", pfx, dstr); + } + break; + } + default: + abort(); + break; + } +} + +static void +show_stats(connstat_proto_t *proto, ofmt_handle_t ofmt, uint_t flags, + connstat_conn_attr_t *filter, timestamp_fmt_t timestamp_fmt, + uint_t interval, uint_t count) +{ + boolean_t done = B_FALSE; + uint_t i = 0; + int mibfd; + conn_walk_state_t state; + + state.cws_ofmt = ofmt; + state.cws_flags = flags; + state.cws_filter = *filter; + + if ((mibfd = mibopen(proto->csp_proto)) == -1) { + die("failed to open MIB stream: %s", strerror(errno)); + } + + do { + if (timestamp_fmt != NOTIMESTAMP) { + print_timestamp(timestamp_fmt, flags & CS_PARSABLE); + } + if (!(flags & CS_PARSABLE)) { + ofmt_print_header(ofmt); + } + + if (conn_walk(mibfd, proto, &state) != 0) { + die("failed to fetch and print connection info"); + } + + if (count != 0 && ++i == count) { + done = B_TRUE; + } else { + (void) sleep(interval); + } + } while (!done); +} + +/* + * ofmt callbacks for printing individual fields of various types. + */ +boolean_t +print_string(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + char *value; + + value = (char *)ofarg->ofmt_cbarg + ofarg->ofmt_id; + (void) strlcpy(buf, value, bufsize); + return (B_TRUE); +} + +boolean_t +print_uint16(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + uint16_t value; + + /* LINTED E_BAD_PTR_CAST_ALIGN */ + value = *(uint16_t *)((char *)ofarg->ofmt_cbarg + ofarg->ofmt_id); + (void) snprintf(buf, bufsize, "%hu", value); + return (B_TRUE); +} + +boolean_t +print_uint32(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + uint32_t value; + + /* LINTED E_BAD_PTR_CAST_ALIGN */ + value = *(uint32_t *)((char *)ofarg->ofmt_cbarg + ofarg->ofmt_id); + (void) snprintf(buf, bufsize, "%u", value); + return (B_TRUE); +} + +boolean_t +print_uint64(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + uint64_t value; + + /* LINTED E_BAD_PTR_CAST_ALIGN */ + value = *(uint64_t *)((char *)ofarg->ofmt_cbarg + ofarg->ofmt_id); + (void) snprintf(buf, bufsize, "%llu", value); + return (B_TRUE); +} + +/* PRINTFLIKE1 */ +static void +die(const char *format, ...) +{ + va_list alist; + + format = gettext(format); + + va_start(alist, format); + verrx(1, format, alist); + va_end(alist); +} diff --git a/usr/src/cmd/connstat/connstat_mib.c b/usr/src/cmd/connstat/connstat_mib.c new file mode 100644 index 0000000000..4b3e532c63 --- /dev/null +++ b/usr/src/cmd/connstat/connstat_mib.c @@ -0,0 +1,177 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2015 by Delphix. All rights reserved. + */ + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <fcntl.h> +#include <strings.h> +#include <unistd.h> +#include <stropts.h> +#include <sys/debug.h> +#include <sys/tihdr.h> +#include "connstat.h" + +int +mibopen(const char *proto) +{ + int saved; + int fd; + + fd = open("/dev/arp", O_RDWR); + if (fd == -1) { + return (-1); + } + + if (ioctl(fd, I_PUSH, proto) == -1) { + saved = errno; + (void) close(fd); + errno = saved; + return (-1); + } + + return (fd); +} + +int +conn_walk(int fd, connstat_proto_t *proto, conn_walk_state_t *state) +{ + struct strbuf cbuf, dbuf; + struct opthdr *hdr; + int flags, r, err = 0; + struct { + struct T_optmgmt_req req; + struct opthdr hdr; + } req; + union { + struct T_optmgmt_ack ack; + uint8_t space[sizeof (struct T_optmgmt_ack) + + sizeof (struct opthdr) * 2]; + } ack; + + bzero(&cbuf, sizeof (cbuf)); + bzero(&dbuf, sizeof (dbuf)); + + req.req.PRIM_type = T_OPTMGMT_REQ; + req.req.OPT_offset = (caddr_t)&req.hdr - (caddr_t)&req; + req.req.OPT_length = sizeof (req.hdr); + req.req.MGMT_flags = T_CURRENT; + + req.hdr.level = proto->csp_miblevel; + req.hdr.name = 0; + req.hdr.len = 0; + + cbuf.buf = (caddr_t)&req; + cbuf.len = sizeof (req); + + if (putmsg(fd, &cbuf, NULL, 0) == -1) { + warn("failed to request connection info: putmsg"); + return (-1); + } + + /* + * Each reply consists of a control part for one fixed structure or + * table, as defined in mib2.h. The format is a T_OPTMGMT_ACK + * containing an opthdr structure. The level and name identify the + * entry, and len is the size of the data part of the message. + */ + for (;;) { + cbuf.buf = (caddr_t)&ack; + cbuf.maxlen = sizeof (ack); + flags = 0; + + /* + * We first do a getmsg() for the control part so that we + * can allocate a properly sized buffer to read the data + * part. + */ + do { + r = getmsg(fd, &cbuf, NULL, &flags); + } while (r < 0 && errno == EINTR); + + if (r < 0) { + warn("failed to fetch further connection info"); + err = -1; + break; + } else if ((r & MORECTL) != 0) { + warnx("failed to fetch full control message"); + err = -1; + break; + } + + if (cbuf.len < sizeof (struct T_optmgmt_ack) || + ack.ack.PRIM_type != T_OPTMGMT_ACK || + ack.ack.MGMT_flags != T_SUCCESS || + ack.ack.OPT_length < sizeof (struct opthdr)) { + warnx("cannot process invalid message from getmsg()"); + err = -1; + break; + } + + /* LINTED E_BAD_PTR_CAST_ALIGN */ + hdr = (struct opthdr *)((caddr_t)&ack + ack.ack.OPT_offset); + if (r == 0 && hdr->level == 0 && hdr->name == 0) { + /* + * snmpcom_req() has sent us the final End-Of-Data + * message, so there's nothing further to read. + */ + break; + } + + /* Only data should remain. */ + VERIFY3S(r, ==, MOREDATA); + + /* Allocate a buffer to hold the data portion of the message */ + if ((dbuf.buf = realloc(dbuf.buf, hdr->len)) == NULL) { + warn("failed to realloc() buffer"); + err = -1; + break; + } + dbuf.maxlen = hdr->len; + dbuf.len = 0; + flags = 0; + + do { + r = getmsg(fd, NULL, &dbuf, &flags); + } while (r < 0 && errno == EINTR); + + if (r < 0) { + warn("failed to fetch connection data: getmsg()"); + err = -1; + break; + } else if (r != 0) { + warnx("failed to fetch all data: " + "getmsg() returned %d", r); + err = -1; + break; + } + + if ((state->cws_flags & CS_IPV4) && + hdr->name == proto->csp_mibv4name) { + proto->csp_v4walk(&dbuf, state); + } else if ((state->cws_flags & CS_IPV6) && + hdr->name == proto->csp_mibv6name) { + proto->csp_v6walk(&dbuf, state); + } + } + + free(dbuf.buf); + + return (err); +} diff --git a/usr/src/cmd/connstat/connstat_mib.h b/usr/src/cmd/connstat/connstat_mib.h new file mode 100644 index 0000000000..038ac2d874 --- /dev/null +++ b/usr/src/cmd/connstat/connstat_mib.h @@ -0,0 +1,35 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2015 by Delphix. All rights reserved. + */ + +#ifndef _CONNSTAT_MIB_H +#define _CONNSTAT_MIB_H + +#include "connstat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int mibopen(const char *); +int conn_walk(int, connstat_proto_t *, conn_walk_state_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _CONNSTAT_MIB_H */ diff --git a/usr/src/cmd/connstat/connstat_tcp.c b/usr/src/cmd/connstat/connstat_tcp.c new file mode 100644 index 0000000000..4cd20c9b09 --- /dev/null +++ b/usr/src/cmd/connstat/connstat_tcp.c @@ -0,0 +1,403 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2015, 2016 by Delphix. All rights reserved. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <inet/mib2.h> +#include <sys/debug.h> +#include <sys/stropts.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <inet/tcp.h> +#include <arpa/inet.h> +#include <ofmt.h> +#include <sys/time.h> +#include "connstat_mib.h" +#include "connstat_tcp.h" + +/* + * The byte order of some of the fields in this code can be a bit confusing. + * When using sockaddr_in(6) structs, the address and ports are always in + * Network Byte Order (Big Endian), as required by sockaddr(3SOCKET). + * + * When using the structs mib2_tcpConnEntry_t and mib2_tcp6ConnEntry_t, the + * address fields (tcp(6)ConnLocalAddress and tcp(6)ConnRemAdddress) are in + * Network Byte Order. Note, however, that the port fields ARE NOT, but are + * instead in Host Byte Order. This isn't a problem though, since the ports + * we filter on from the command-line (ca_lport and ca_rport) are kept in + * Host Byte Order after parsing. + * + * Since the t_lport and t_rport fields come from the MIB structs, they are + * likewise stored in Host Byte Order (and need to be for printing). The + * t_laddr and t_raddr fields are string representations of the addresses, + * so they don't require any special attention. + * + * All of the statistics (such as bytes read and written, current window + * sizes, etc.) are in Host Byte Order. + */ + +typedef struct tcp_fields_buf_s { + char t_laddr[INET6_ADDRSTRLEN]; + char t_raddr[INET6_ADDRSTRLEN]; + uint16_t t_lport; + uint16_t t_rport; + uint64_t t_inbytes; + uint64_t t_insegs; + uint64_t t_inunorderbytes; + uint64_t t_inunordersegs; + uint64_t t_outbytes; + uint64_t t_outsegs; + uint64_t t_retransbytes; + uint64_t t_retranssegs; + uint32_t t_suna; + uint32_t t_unsent; + uint32_t t_swnd; + uint32_t t_cwnd; + uint32_t t_rwnd; + uint32_t t_mss; + uint32_t t_rto; + uint32_t t_rtt_cnt; + uint64_t t_rtt_sum; + int t_state; + uint64_t t_rtt; +} tcp_fields_buf_t; + +static boolean_t print_tcp_state(ofmt_arg_t *, char *, uint_t); + +static ofmt_field_t tcp_fields[] = { + { "LADDR", 26, + offsetof(tcp_fields_buf_t, t_laddr), print_string }, + { "RADDR", 26, + offsetof(tcp_fields_buf_t, t_raddr), print_string }, + { "LPORT", 6, + offsetof(tcp_fields_buf_t, t_lport), print_uint16 }, + { "RPORT", 6, + offsetof(tcp_fields_buf_t, t_rport), print_uint16 }, + { "INBYTES", 11, + offsetof(tcp_fields_buf_t, t_inbytes), print_uint64 }, + { "INSEGS", 11, + offsetof(tcp_fields_buf_t, t_insegs), print_uint64 }, + { "INUNORDERBYTES", 15, + offsetof(tcp_fields_buf_t, t_inunorderbytes), print_uint64 }, + { "INUNORDERSEGS", 14, + offsetof(tcp_fields_buf_t, t_inunordersegs), print_uint64 }, + { "OUTBYTES", 11, + offsetof(tcp_fields_buf_t, t_outbytes), print_uint64 }, + { "OUTSEGS", 11, + offsetof(tcp_fields_buf_t, t_outsegs), print_uint64 }, + { "RETRANSBYTES", 13, + offsetof(tcp_fields_buf_t, t_retransbytes), print_uint64 }, + { "RETRANSSEGS", 12, + offsetof(tcp_fields_buf_t, t_retranssegs), print_uint64 }, + { "SUNA", 11, + offsetof(tcp_fields_buf_t, t_suna), print_uint32 }, + { "UNSENT", 11, + offsetof(tcp_fields_buf_t, t_unsent), print_uint32 }, + { "SWND", 11, + offsetof(tcp_fields_buf_t, t_swnd), print_uint32 }, + { "CWND", 11, + offsetof(tcp_fields_buf_t, t_cwnd), print_uint32 }, + { "RWND", 11, + offsetof(tcp_fields_buf_t, t_rwnd), print_uint32 }, + { "MSS", 6, + offsetof(tcp_fields_buf_t, t_mss), print_uint32 }, + { "RTO", 8, + offsetof(tcp_fields_buf_t, t_rto), print_uint32 }, + { "RTT", 8, + offsetof(tcp_fields_buf_t, t_rtt), print_uint64 }, + { "RTTS", 8, + offsetof(tcp_fields_buf_t, t_rtt_sum), print_uint64 }, + { "RTTC", 11, + offsetof(tcp_fields_buf_t, t_rtt_cnt), print_uint32 }, + { "STATE", 12, + offsetof(tcp_fields_buf_t, t_state), print_tcp_state }, + { NULL, 0, 0, NULL} +}; + +static tcp_fields_buf_t fields_buf; + + +typedef struct tcp_state_info_s { + int tsi_state; + const char *tsi_string; +} tcp_state_info_t; + +tcp_state_info_t tcp_state_info[] = { + { TCPS_CLOSED, "CLOSED" }, + { TCPS_IDLE, "IDLE" }, + { TCPS_BOUND, "BOUND" }, + { TCPS_LISTEN, "LISTEN" }, + { TCPS_SYN_SENT, "SYN_SENT" }, + { TCPS_SYN_RCVD, "SYN_RCVD" }, + { TCPS_ESTABLISHED, "ESTABLISHED" }, + { TCPS_CLOSE_WAIT, "CLOSE_WAIT" }, + { TCPS_FIN_WAIT_1, "FIN_WAIT_1" }, + { TCPS_CLOSING, "CLOSING" }, + { TCPS_LAST_ACK, "LAST_ACK" }, + { TCPS_FIN_WAIT_2, "FIN_WAIT_2" }, + { TCPS_TIME_WAIT, "TIME_WAIT" }, + { TCPS_CLOSED - 1, NULL } +}; + +ofmt_field_t * +tcp_get_fields(void) +{ + return (tcp_fields); +} + +/* + * Extract information from the connection info structure into the global + * output buffer. + */ +static void +tcp_ci2buf(struct tcpConnEntryInfo_s *ci) +{ + fields_buf.t_inbytes = + ci->ce_in_data_inorder_bytes + ci->ce_in_data_unorder_bytes; + fields_buf.t_insegs = + ci->ce_in_data_inorder_segs + ci->ce_in_data_unorder_segs; + fields_buf.t_inunorderbytes = ci->ce_in_data_unorder_bytes; + fields_buf.t_inunordersegs = ci->ce_in_data_unorder_segs; + fields_buf.t_outbytes = ci->ce_out_data_bytes; + fields_buf.t_outsegs = ci->ce_out_data_segs; + fields_buf.t_retransbytes = ci->ce_out_retrans_bytes; + fields_buf.t_retranssegs = ci->ce_out_retrans_segs; + fields_buf.t_suna = ci->ce_snxt - ci->ce_suna; + fields_buf.t_unsent = ci->ce_unsent; + fields_buf.t_swnd = ci->ce_swnd; + fields_buf.t_cwnd = ci->ce_cwnd; + fields_buf.t_rwnd = ci->ce_rwnd; + fields_buf.t_mss = ci->ce_mss; + fields_buf.t_rto = ci->ce_rto; + fields_buf.t_rtt = (ci->ce_out_data_segs == 0 ? 0 : ci->ce_rtt_sa); + fields_buf.t_rtt_sum = ci->ce_rtt_sum; + fields_buf.t_rtt_cnt = ci->ce_rtt_cnt; + fields_buf.t_state = ci->ce_state; +} + +/* + * Extract information from the connection entry into the global output + * buffer. + */ +static void +tcp_ipv4_ce2buf(mib2_tcpConnEntry_t *ce) +{ + VERIFY3P(inet_ntop(AF_INET, (void *)&ce->tcpConnLocalAddress, + fields_buf.t_laddr, sizeof (fields_buf.t_laddr)), !=, NULL); + VERIFY3P(inet_ntop(AF_INET, (void *)&ce->tcpConnRemAddress, + fields_buf.t_raddr, sizeof (fields_buf.t_raddr)), !=, NULL); + + fields_buf.t_lport = ce->tcpConnLocalPort; + fields_buf.t_rport = ce->tcpConnRemPort; + + tcp_ci2buf(&ce->tcpConnEntryInfo); +} + +static void +tcp_ipv6_ce2buf(mib2_tcp6ConnEntry_t *ce) +{ + VERIFY3P(inet_ntop(AF_INET6, (void *)&ce->tcp6ConnLocalAddress, + fields_buf.t_laddr, sizeof (fields_buf.t_laddr)), !=, NULL); + VERIFY3P(inet_ntop(AF_INET6, (void *)&ce->tcp6ConnRemAddress, + fields_buf.t_raddr, sizeof (fields_buf.t_raddr)), !=, NULL); + + fields_buf.t_lport = ce->tcp6ConnLocalPort; + fields_buf.t_rport = ce->tcp6ConnRemPort; + + tcp_ci2buf(&ce->tcp6ConnEntryInfo); +} + +/* + * Print a single IPv4 connection entry, taking into account possible + * filters that have been set in state. + */ +static void +tcp_ipv4_print(mib2_tcpConnEntry_t *ce, conn_walk_state_t *state) +{ + if (!(state->cws_flags & CS_LOOPBACK) && + ntohl(ce->tcpConnLocalAddress) == INADDR_LOOPBACK) { + return; + } + + if (state->cws_flags & CS_LADDR) { + struct sockaddr_in *sin = + (struct sockaddr_in *)&state->cws_filter.ca_laddr; + if (ce->tcpConnLocalAddress != sin->sin_addr.s_addr) { + return; + } + } + if (state->cws_flags & CS_RADDR) { + struct sockaddr_in *sin = + (struct sockaddr_in *)&state->cws_filter.ca_raddr; + if (ce->tcpConnRemAddress != sin->sin_addr.s_addr) { + return; + } + } + if (state->cws_flags & CS_LPORT) { + if (ce->tcpConnLocalPort != state->cws_filter.ca_lport) { + return; + } + } + if (state->cws_flags & CS_RPORT) { + if (ce->tcpConnRemPort != state->cws_filter.ca_rport) { + return; + } + } + + if ((state->cws_flags & CS_STATE) && + ce->tcpConnEntryInfo.ce_state != state->cws_filter.ca_state) { + return; + } + + tcp_ipv4_ce2buf(ce); + ofmt_print(state->cws_ofmt, &fields_buf); +} + +/* + * Print a single IPv6 connection entry, taking into account possible + * filters that have been set in state. + */ +static void +tcp_ipv6_print(mib2_tcp6ConnEntry_t *ce, conn_walk_state_t *state) +{ + if (!(state->cws_flags & CS_LOOPBACK) && + IN6_IS_ADDR_LOOPBACK( + (struct in6_addr *)&ce->tcp6ConnLocalAddress)) { + return; + } + + if (state->cws_flags & CS_LADDR) { + struct sockaddr_in6 *sin6 = + (struct sockaddr_in6 *)&state->cws_filter.ca_laddr; + if (!IN6_ARE_ADDR_EQUAL( + (struct in6_addr *)&ce->tcp6ConnLocalAddress, + &sin6->sin6_addr)) { + return; + } + } + if (state->cws_flags & CS_RADDR) { + struct sockaddr_in6 *sin6 = + (struct sockaddr_in6 *)&state->cws_filter.ca_raddr; + if (!IN6_ARE_ADDR_EQUAL( + (struct in6_addr *)&ce->tcp6ConnRemAddress, + &sin6->sin6_addr)) { + return; + } + } + if (state->cws_flags & CS_LPORT) { + if (ce->tcp6ConnLocalPort != state->cws_filter.ca_lport) { + return; + } + } + if (state->cws_flags & CS_RPORT) { + if (ce->tcp6ConnRemPort != state->cws_filter.ca_rport) { + return; + } + } + + if ((state->cws_flags & CS_STATE) && + ce->tcp6ConnEntryInfo.ce_state != state->cws_filter.ca_state) { + return; + } + + tcp_ipv6_ce2buf(ce); + ofmt_print(state->cws_ofmt, &fields_buf); +} + +void +tcp_walk_ipv4(struct strbuf *dbuf, conn_walk_state_t *state) +{ + uint_t nconns = (dbuf->len / sizeof (mib2_tcpConnEntry_t)); + /* LINTED E_BAD_PTR_CAST_ALIGN */ + mib2_tcpConnEntry_t *ce = (mib2_tcpConnEntry_t *)dbuf->buf; + + for (; nconns > 0; ce++, nconns--) { + tcp_ipv4_print(ce, state); + } +} + +void +tcp_walk_ipv6(struct strbuf *dbuf, conn_walk_state_t *state) +{ + uint_t nconns = (dbuf->len / sizeof (mib2_tcp6ConnEntry_t)); + /* LINTED E_BAD_PTR_CAST_ALIGN */ + mib2_tcp6ConnEntry_t *ce = (mib2_tcp6ConnEntry_t *)dbuf->buf; + + for (; nconns > 0; ce++, nconns--) { + tcp_ipv6_print(ce, state); + } +} + +static tcp_state_info_t * +tcp_stateinfobystate(int state) +{ + tcp_state_info_t *sip; + + for (sip = tcp_state_info; sip->tsi_string != NULL; sip++) { + if (sip->tsi_state == state) { + return (sip); + } + } + return (NULL); +} + +static tcp_state_info_t * +tcp_stateinfobystr(const char *statestr) +{ + tcp_state_info_t *sip; + + for (sip = tcp_state_info; sip->tsi_string != NULL; sip++) { + if (strncasecmp(statestr, sip->tsi_string, + strlen(sip->tsi_string)) == 0) { + return (sip); + } + } + return (NULL); +} + +int +tcp_str2state(const char *statestr) +{ + tcp_state_info_t *sip = tcp_stateinfobystr(statestr); + return (sip == NULL ? TCPS_CLOSED - 1 : sip->tsi_state); +} + +static const char * +tcp_state2str(int state) +{ + tcp_state_info_t *sip = tcp_stateinfobystate(state); + return (sip == NULL ? NULL : sip->tsi_string); +} + +static boolean_t +print_tcp_state(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + /* LINTED E_BAD_PTR_CAST_ALIGN */ + int state = *(int *)((char *)ofarg->ofmt_cbarg + ofarg->ofmt_id); + const char *statestr = tcp_state2str(state); + + if (statestr != NULL) { + (void) strlcpy(buf, statestr, bufsize); + } else { + (void) snprintf(buf, bufsize, "UNKNOWN(%d)", state); + } + + return (B_TRUE); +} diff --git a/usr/src/cmd/connstat/connstat_tcp.h b/usr/src/cmd/connstat/connstat_tcp.h new file mode 100644 index 0000000000..7cad46370d --- /dev/null +++ b/usr/src/cmd/connstat/connstat_tcp.h @@ -0,0 +1,50 @@ +/* + * CDDL HEADER START + * + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2015, 2016 by Delphix. All rights reserved. + */ + +#ifndef _CONNSTAT_TCP_H +#define _CONNSTAT_TCP_H + +#include <stddef.h> +#include "connstat.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int tcp_str2state(const char *state); +connstat_getfieldsfunc_t tcp_get_fields; +connstat_walkfunc_t tcp_walk_ipv4, tcp_walk_ipv6; + +/* + * Keep the default output to < 80 columns. For most interactive workflows, + * the user will run the command without arguments to get an idea of what + * connections exist before narrowing down the investigation to a single + * connection (with filtering) and specifying additional fields to output + * depending on what the user is interested in. + */ +#define TCP_DEFAULT_FIELDS "laddr,lport,raddr,rport,state" + +#define CONNSTAT_TCP_PROTO \ + { "tcp", TCP_DEFAULT_FIELDS, MIB2_TCP, MIB2_TCP_CONN, MIB2_TCP6_CONN, \ + tcp_get_fields, tcp_walk_ipv4, tcp_walk_ipv6 } + +#ifdef __cplusplus +} +#endif + +#endif /* _CONNSTAT_TCP_H */ diff --git a/usr/src/cmd/coreadm/coreadm.c b/usr/src/cmd/coreadm/coreadm.c index ca7edc179e..23916a7c06 100644 --- a/usr/src/cmd/coreadm/coreadm.c +++ b/usr/src/cmd/coreadm/coreadm.c @@ -244,6 +244,12 @@ main(int argc, char **argv) command); usage(); } + if (glob_pattern != NULL && glob_pattern[0] != '/') { + (void) fprintf(stderr, gettext( + "%s: The -g option must specify an absolute path\n"), + command); + usage(); + } if ((proc_pattern != NULL || proc_content != CC_CONTENT_INVALID) && npids == 0) { (void) sprintf(curpid, "%u", (uint_t)getppid()); diff --git a/usr/src/cmd/coreadm/coreadm.xml b/usr/src/cmd/coreadm/coreadm.xml index 46a4cda17a..28f1e27240 100644 --- a/usr/src/cmd/coreadm/coreadm.xml +++ b/usr/src/cmd/coreadm/coreadm.xml @@ -48,14 +48,6 @@ <service_fmri value='svc:/system/filesystem/minimal' /> </dependency> - <dependency - name='coreadm_manifest-import' - type='service' - grouping='require_all' - restart_on='none'> - <service_fmri value='svc:/system/manifest-import:default' /> - </dependency> - <instance name='default' enabled='false'> <exec_method type='method' diff --git a/usr/src/cmd/cron/Makefile b/usr/src/cmd/cron/Makefile index 5c324d9e86..d8df76960f 100644 --- a/usr/src/cmd/cron/Makefile +++ b/usr/src/cmd/cron/Makefile @@ -27,6 +27,7 @@ DEFAULTFILES = cron.dfl include ../Makefile.cmd +include ../Makefile.ctf MANIFEST = cron.xml @@ -100,20 +101,20 @@ XPG4ATOBJS= $(ATOBJS:%=objs.xpg4/%) $(XPG4OBJS:%=objs.xpg4/%) XPG6COMMONOBJS= $(COMMONOBJS:%=objs.xpg6/%) XPG6CTOBJS= $(CRONTABOBJS:%=objs.xpg6/%) -cron := POBJS = $(CRONOBJS) $(COMMONOBJ2) -at := POBJS = $(ATOBJS) $(COMMONOBJS) -at.xpg4 := POBJS = $(XPG4ATOBJS) $(XPG4COMMONOBJS) -atrm := POBJS = $(ATRMOBJS) $(COMMONOBJS) -atq := POBJS = $(ATQOBJS) $(COMMONOBJS) -crontab := POBJS = $(CRONTABOBJS) $(COMMONOBJS) -crontab.xpg4 := POBJS = $(XPG4CTOBJS) $(XPG4COMMONOBJS) -crontab.xpg6 := POBJS = $(XPG6CTOBJS) $(XPG6COMMONOBJS) +cron := OBJS = $(CRONOBJS) $(COMMONOBJ2) +at := OBJS = $(ATOBJS) $(COMMONOBJS) +at.xpg4 := OBJS = $(XPG4ATOBJS) $(XPG4COMMONOBJS) +atrm := OBJS = $(ATRMOBJS) $(COMMONOBJS) +atq := OBJS = $(ATQOBJS) $(COMMONOBJS) +crontab := OBJS = $(CRONTABOBJS) $(COMMONOBJS) +crontab.xpg4 := OBJS = $(XPG4CTOBJS) $(XPG4COMMONOBJS) +crontab.xpg6 := OBJS = $(XPG6CTOBJS) $(XPG6COMMONOBJS) CFLAGS += $(CCVERBOSE) NOBJS= $(CRONOBJS) $(ATOBJS) $(ATRMOBJS1) $(ATQOBJS) $(CRONTABOBJS1) \ $(COMMONOBJS) -OBJS = $(NOBJS) $(XPG4COMMONOBJS) $(XPG4ATOBJS) $(XPG4CTOBJS) \ +COBJS = $(NOBJS) $(XPG4COMMONOBJS) $(XPG4ATOBJS) $(XPG4CTOBJS) \ $(XPG6COMMONOBJS) $(XPG6CTOBJS) $(GETRESPOBJ) SRCS = $(NOBJS:%.o=%.c) $(GETRESPSRC) @@ -161,32 +162,35 @@ all : $(PROG) $(XPG4) $(XPG6) $(SCRIPT) $(XPG4SCRIPT) $(FILES) install : all $(ROOTPROG) $(ROOTETCDEFAULTFILES) $(ROOTSYMLINK) \ $(ROOTMANIFEST) $(ROOTMETHOD) -$(PROG) : $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) +$(PROG) : $$(OBJS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) -$(XPG4) : objs.xpg4 $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) +$(XPG4) : objs.xpg4 $$(OBJS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) -$(XPG6) : objs.xpg6 $$(POBJS) - $(LINK.c) $(POBJS) -o $@ $(LDLIBS) +$(XPG6) : objs.xpg6 $$(OBJS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) objs.xpg6/%.o: %.c $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) objs.xpg6: -@mkdir -p $@ objs.xpg4/%.o: %.c $(COMPILE.c) -o $@ $< + $(POST_PROCESS_O) objs.xpg4: -@mkdir -p $@ objs.xpg4/values-xpg4.o: ../../lib/crt/common/values-xpg4.c $(COMPILE.c) -o $@ ../../lib/crt/common/values-xpg4.c + $(POST_PROCESS_O) %.o: $(SRC)/common/util/%.c $(COMPILE.c) $(OUTPUT_OPTION) $< @@ -223,7 +227,7 @@ $(POFILE): $(POFILES) $(RM) $@; cat $(POFILES) > $@ clean : - $(RM) $(OBJS) att1.h att1.c att2.c + $(RM) $(COBJS) att1.h att1.c att2.c lint : lint_SRCS diff --git a/usr/src/cmd/cron/cron.c b/usr/src/cmd/cron/cron.c index 55df389cd7..e2c9086536 100644 --- a/usr/src/cmd/cron/cron.c +++ b/usr/src/cmd/cron/cron.c @@ -23,7 +23,7 @@ * Use is subject to license terms. * * Copyright 2013 Joshua M. Clulow <josh@sysmgr.org> - * + * Copyright 2013 Joyent, Inc. All rights reserved. * Copyright (c) 2014 Gary Mills * Copyright (c) 2016 by Delphix. All rights reserved. */ @@ -316,7 +316,8 @@ static int ex(struct event *e); static void read_dirs(int); static void mail(char *, char *, int); static char *next_field(int, int); -static void readcron(struct usr *, time_t); +static void readcron(char *, struct usr *, time_t); +static void readcronfile(FILE *, struct usr *, time_t); static int next_ge(int, char *); static void free_if_unused(struct usr *); static void del_atjob(char *, char *); @@ -421,7 +422,7 @@ extern void el_delete(void); static int valid_entry(char *, int); static struct usr *create_ulist(char *, int); -static void init_cronevent(char *, int); +static void init_cronevent(char *, char *); static void init_atevent(char *, time_t, int, int); static void update_atevent(struct usr *, char *, time_t, int); @@ -760,6 +761,18 @@ read_dirs(int first) time_t tim; + if (chdir(SYSCRONDIR) != -1) { + cwd = CRON; + if ((dir = opendir(".")) != NULL) { + while ((dp = readdir(dir)) != NULL) { + if (!valid_entry(dp->d_name, CRONEVENT)) + continue; + init_cronevent(SYSCRONDIR, dp->d_name); + } + (void) closedir(dir); + } + } + if (chdir(CRONDIR) == -1) crabort(BADCD, REMOVE_FIFO|CONSOLE_MSG); cwd = CRON; @@ -768,7 +781,7 @@ read_dirs(int first) while ((dp = readdir(dir)) != NULL) { if (!valid_entry(dp->d_name, CRONEVENT)) continue; - init_cronevent(dp->d_name, first); + init_cronevent(CRONDIR, dp->d_name); } (void) closedir(dir); @@ -854,23 +867,18 @@ create_ulist(char *name, int type) } void -init_cronevent(char *name, int first) +init_cronevent(char *basedir, char *name) { struct usr *u; - if (first) { + if ((u = find_usr(name)) == NULL) { u = create_ulist(name, CRONEVENT); - readcron(u, 0); + readcron(basedir, u, 0); } else { - if ((u = find_usr(name)) == NULL) { - u = create_ulist(name, CRONEVENT); - readcron(u, 0); - } else { - u->ctexists = TRUE; - rm_ctevents(u); - el_remove(u->ctid, 0); - readcron(u, 0); - } + u->ctexists = TRUE; + rm_ctevents(u); + el_remove(u->ctid, 0); + readcron(basedir, u, 0); } } @@ -951,7 +959,7 @@ mod_ctab(char *name, time_t reftime) (void) strcpy(u->home, pw->pw_dir); u->uid = pw->pw_uid; u->gid = pw->pw_gid; - readcron(u, reftime); + readcron(CRONDIR, u, reftime); } else { u->uid = pw->pw_uid; u->gid = pw->pw_gid; @@ -974,7 +982,7 @@ mod_ctab(char *name, time_t reftime) /* user didnt have a crontab last time */ u->ctid = ecid++; u->ctevents = NULL; - readcron(u, reftime); + readcron(CRONDIR, u, reftime); return; } #ifdef DEBUG @@ -982,7 +990,7 @@ mod_ctab(char *name, time_t reftime) #endif rm_ctevents(u); el_remove(u->ctid, 0); - readcron(u, reftime); + readcron(CRONDIR, u, reftime); } } @@ -1117,8 +1125,94 @@ update_atevent(struct usr *u, char *name, time_t tim, int jobtype) static char line[CTLINESIZE]; /* holds a line from a crontab file */ static int cursor; /* cursor for the above line */ +static int +copyfile(char *name, FILE *dp) +{ + FILE *tf; + + if ((tf = fopen(name, "r")) == NULL) { + (void) fclose(dp); + return (1); + } + + while (fgets(line, CTLINESIZE, tf) != NULL) { + if (fputs(line, dp) == EOF) { + (void) fclose(tf); + (void) fclose(dp); + return (1); + } + } + (void) fclose(tf); + + return (0); +} + +static void +readcron(char *basedir, struct usr *u, time_t reftime) +{ + char *altpath; + struct stat sb; + FILE *cf; /* cf will be a user's crontab file */ + char altnamebuf[PATH_MAX]; + char namebuf[PATH_MAX]; + + if (strcmp(basedir, SYSCRONDIR) == 0) + altpath = CRONDIR; + else + altpath = SYSCRONDIR; + + if (snprintf(altnamebuf, sizeof (altnamebuf), "%s/%s", altpath, + u->name) >= sizeof (altnamebuf)) + return; + + if (snprintf(namebuf, sizeof (namebuf), "%s/%s", basedir, u->name) >= + sizeof (namebuf)) + return; + + if (stat(altnamebuf, &sb) != -1) { + /* + * There is a secondary crontab for this user. We need to + * merge the two crontabs into a temporary file for loading. + */ + int fd; + char tmpfile[PATH_MAX]; + + (void) strlcpy(tmpfile, "/tmp/cronXXXXXX", sizeof (tmpfile)); + if ((fd = mkstemp(tmpfile)) == -1) + return; + + unlink(tmpfile); + if ((cf = fdopen(fd, "w+")) == NULL) { + close(fd); + return; + } + + if (copyfile(namebuf, cf) != 0) + return; + + if (copyfile(altnamebuf, cf) != 0) + return; + + (void) fflush(cf); + rewind(cf); + + } else { + /* + * Only one crontab, open it directly. + */ + if ((cf = fopen(namebuf, "r")) == NULL) { + mail(u->name, NOREAD, ERR_UNIXERR); + return; + } + } + + readcronfile(cf, u, reftime); + + (void) fclose(cf); +} + static void -readcron(struct usr *u, time_t reftime) +readcronfile(FILE *cf, struct usr *u, time_t reftime) { /* * readcron reads in a crontab file for a user (u). The list of @@ -1126,12 +1220,9 @@ readcron(struct usr *u, time_t reftime) * this list. Each event is also entered into the main event * list. */ - FILE *cf; /* cf will be a user's crontab file */ struct event *e; int start; unsigned int i; - char namebuf[PATH_MAX]; - char *pname; struct shared *tz = NULL; struct shared *home = NULL; struct shared *shell = NULL; @@ -1139,19 +1230,6 @@ readcron(struct usr *u, time_t reftime) /* read the crontab file */ cte_init(); /* Init error handling */ - if (cwd != CRON) { - if (snprintf(namebuf, sizeof (namebuf), "%s/%s", - CRONDIR, u->name) >= sizeof (namebuf)) { - return; - } - pname = namebuf; - } else { - pname = u->name; - } - if ((cf = fopen(pname, "r")) == NULL) { - mail(u->name, NOREAD, ERR_UNIXERR); - return; - } while (fgets(line, CTLINESIZE, cf) != NULL) { char *tmp; /* process a line of a crontab file */ @@ -1280,7 +1358,6 @@ again: #endif } cte_sendmail(u->name); /* mail errors if any to user */ - (void) fclose(cf); rel_shared(tz); rel_shared(shell); rel_shared(home); @@ -2443,6 +2520,9 @@ ex(struct event *e) } else { r = audit_cron_session(e->u->name, CRONDIR, e->u->uid, e->u->gid, NULL); + if (r != 0) + r = audit_cron_session(e->u->name, SYSCRONDIR, + e->u->uid, e->u->gid, NULL); } if (r != 0) { msg("cron audit problem. job failed (%s) for user %s", diff --git a/usr/src/cmd/cron/cron.h b/usr/src/cmd/cron/cron.h index a76016299c..93e21e7b41 100644 --- a/usr/src/cmd/cron/cron.h +++ b/usr/src/cmd/cron/cron.h @@ -71,6 +71,9 @@ struct message { char logname[LLEN]; }; +/* anything below here can be changed */ + +#define SYSCRONDIR "/etc/cron.d/crontabs" #define CRONDIR "/var/spool/cron/crontabs" #define ATDIR "/var/spool/cron/atjobs" #define ACCTFILE "/var/cron/log" diff --git a/usr/src/cmd/cron/crontab.c b/usr/src/cmd/cron/crontab.c index 327a71388b..cdb4e1e394 100644 --- a/usr/src/cmd/cron/crontab.c +++ b/usr/src/cmd/cron/crontab.c @@ -71,7 +71,7 @@ "usage:\n" \ "\tcrontab [file]\n" \ "\tcrontab -e [username]\n" \ - "\tcrontab -l [username]\n" \ + "\tcrontab -l [-g] [username]\n" \ "\tcrontab -r [username]" #define INVALIDUSER "you are not a valid user (no entry in /etc/passwd)." #define NOTALLOWED "you are not authorized to use cron. Sorry." @@ -120,6 +120,7 @@ main(int argc, char **argv) int c, r; int rflag = 0; int lflag = 0; + int gflag = 0; int eflag = 0; int errflg = 0; char *pp; @@ -151,11 +152,14 @@ main(int argc, char **argv) exit(1); } - while ((c = getopt(argc, argv, "elr")) != EOF) + while ((c = getopt(argc, argv, "eglr")) != EOF) switch (c) { case 'e': eflag++; break; + case 'g': + gflag++; + break; case 'l': lflag++; break; @@ -170,6 +174,9 @@ main(int argc, char **argv) if (eflag + lflag + rflag > 1) errflg++; + if (gflag && !lflag) + errflg++; + argc -= optind; argv += optind; if (errflg || argc > 1) @@ -236,12 +243,27 @@ main(int argc, char **argv) exit(0); } if (lflag) { - if ((fp = fopen(cf, "r")) == NULL) - crabort(BADOPEN); - while (fgets(line, CTLINESIZE, fp) != NULL) - fputs(line, stdout); - fclose(fp); - exit(0); + char sysconf[PATH_MAX]; + + if (gflag) { + if (snprintf(sysconf, sizeof (sysconf), "%s/%s", + SYSCRONDIR, login) < sizeof (sysconf) && + (fp = fopen(sysconf, "r")) != NULL) { + while (fgets(line, CTLINESIZE, fp) != NULL) + fputs(line, stdout); + fclose(fp); + exit(0); + } else { + crabort(BADOPEN); + } + } else { + if ((fp = fopen(cf, "r")) == NULL) + crabort(BADOPEN); + while (fgets(line, CTLINESIZE, fp) != NULL) + fputs(line, stdout); + fclose(fp); + exit(0); + } } if (eflag) { if ((fp = fopen(cf, "r")) == NULL) { diff --git a/usr/src/cmd/devfsadm/Makefile.com b/usr/src/cmd/devfsadm/Makefile.com index b446b148ff..cec58108c8 100644 --- a/usr/src/cmd/devfsadm/Makefile.com +++ b/usr/src/cmd/devfsadm/Makefile.com @@ -21,7 +21,7 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright (c) 2018, Joyent, Inc. +# Copyright 2019, Joyent, Inc. # This target builds both a command (daemon) and various shared objects. This # isn't a typical target, and the inclusion of both library and command @@ -71,7 +71,8 @@ LINK_OBJS_CMN = \ dtrace_link.o \ vscan_link.o \ zfs_link.o \ - zut_link.o + zut_link.o \ + sensor_link.o LINK_OBJS = $(LINK_OBJS_CMN) \ $(LINK_OBJS_$(MACH)) @@ -164,7 +165,7 @@ install: all \ clean: - $(RM) $(OBJS) + $(RM) $(OBJS) lint: $(DEVFSADM_MOD).ln $(LINT_MODULES) diff --git a/usr/src/cmd/devfsadm/devfsadm.c b/usr/src/cmd/devfsadm/devfsadm.c index f81d5b5d67..52f4f4c0da 100644 --- a/usr/src/cmd/devfsadm/devfsadm.c +++ b/usr/src/cmd/devfsadm/devfsadm.c @@ -23,6 +23,7 @@ * Copyright 2016 Toomas Soome <tsoome@me.com> * Copyright 2016 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2019, Joyent, Inc. */ /* @@ -2073,6 +2074,16 @@ class_ok(char *class) return (DEVFSADM_SUCCESS); } + /* + * Some create tabs operate on multiple classes of devices because the + * kernel doesn't have a good way for a driver to indicate that a + * particular minor's class is different from that of the dev_info_t + * it belongs to. As such, we'll always fail to match those here. + */ + if (class == NULL) { + return (DEVFSADM_FAILURE); + } + for (i = 0; i < num_classes; i++) { if (strcmp(class, classes[i]) == 0) { return (DEVFSADM_SUCCESS); @@ -3717,10 +3728,10 @@ do_inst_sync(char *filename, char *instfilename) * safely, the database is flushed to a temporary file, then moved into place. * * The following files are used during this process: - * /etc/path_to_inst: The path_to_inst file - * /etc/path_to_inst.<pid>: Contains data flushed from the kernel - * /etc/path_to_inst.old: The backup file - * /etc/path_to_inst.old.<pid>: Temp file for creating backup + * /etc/path_to_inst: The path_to_inst file + * /etc/path_to_inst.<pid>: Contains data flushed from the kernel + * /etc/path_to_inst.old: The backup file + * /etc/path_to_inst.old.<pid>: Temp file for creating backup * */ static void @@ -7803,7 +7814,7 @@ add_verbose_id(char *mid) * returns DEVFSADM_TRUE if contents is a minor node in /devices. * If mn_root is not NULL, mn_root is set to: * if contents is a /dev node, mn_root = contents - * OR + * OR * if contents is a /devices node, mn_root set to the '/' * following /devices. */ diff --git a/usr/src/cmd/devfsadm/devlink.tab.sh b/usr/src/cmd/devfsadm/devlink.tab.sh index 6724fcb573..0267efeb9f 100644 --- a/usr/src/cmd/devfsadm/devlink.tab.sh +++ b/usr/src/cmd/devfsadm/devlink.tab.sh @@ -22,8 +22,7 @@ # # Copyright (c) 1998, 2000 by Sun Microsystems, Inc. # All rights reserved. -# -#ident "%Z%%M% %I% %E% SMI" +# Copyright (c) 2012 Joyent, Inc. All rights reserved. # # This is the script that generates the devlink.tab file. It is # architecture-aware, and dumps different stuff for x86 and sparc. @@ -34,8 +33,6 @@ # cat <<EOM -#ident "%Z%%M% %I% %E% SMI" -# # Copyright (c) 1998 by Sun Microsystems, Inc. # # diff --git a/usr/src/cmd/devfsadm/i386/Makefile b/usr/src/cmd/devfsadm/i386/Makefile index 179db79979..8bd5a45401 100644 --- a/usr/src/cmd/devfsadm/i386/Makefile +++ b/usr/src/cmd/devfsadm/i386/Makefile @@ -25,8 +25,11 @@ LINK_OBJS_i386 = \ drm_link_i386.o \ misc_link_i386.o \ + lx_link_i386.o \ xen_link.o +lx_link_i386.o lx_link_i386.po lx_link_i386.ln := CPPFLAGS += -I$(UTSBASE)/common/brand/lx + xen_link.o xen_link.ln xen_link.po := CPPFLAGS += -I$(UTSBASE)/i86xpv include ../Makefile.com diff --git a/usr/src/cmd/devfsadm/i386/lx_link_i386.c b/usr/src/cmd/devfsadm/i386/lx_link_i386.c new file mode 100644 index 0000000000..b99a8361a0 --- /dev/null +++ b/usr/src/cmd/devfsadm/i386/lx_link_i386.c @@ -0,0 +1,81 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * Copyright 2016 Joyent, Inc. + */ + +#include <devfsadm.h> +#include <strings.h> +#include <stdio.h> +#include <sys/lx_ptm.h> +#include <sys/lx_autofs.h> + +static int lx_ptm(di_minor_t minor, di_node_t node); +static int lx_autofs(di_minor_t minor, di_node_t node); +static int lx_systrace(di_minor_t minor, di_node_t node); + +static devfsadm_create_t lx_create_cbt[] = { + { "pseudo", "ddi_pseudo", LX_PTM_DRV, + TYPE_EXACT | DRV_EXACT, ILEVEL_0, lx_ptm }, + { "pseudo", "ddi_pseudo", LX_AUTOFS_NAME, + TYPE_EXACT | DRV_EXACT, ILEVEL_0, lx_autofs }, + { "pseudo", "ddi_pseudo", "lx_systrace", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, lx_systrace }, +}; + +DEVFSADM_CREATE_INIT_V0(lx_create_cbt); + +static int +lx_ptm(di_minor_t minor, di_node_t node) +{ + char *mname = di_minor_name(minor); + + if (strcmp(LX_PTM_MINOR_NODE, mname) == 0) + (void) devfsadm_mklink("brand/lx/ptmx", node, minor, 0); + + return (DEVFSADM_CONTINUE); +} + +static int +lx_autofs(di_minor_t minor, di_node_t node) +{ + char *mname = di_minor_name(minor); + + if (strcmp(LX_AUTOFS_MINORNAME, mname) == 0) + (void) devfsadm_mklink("brand/lx/autofs", node, minor, 0); + + return (DEVFSADM_CONTINUE); +} + +static int +lx_systrace(di_minor_t minor, di_node_t node) +{ + char *mname = di_minor_name(minor); + char path[MAXPATHLEN]; + + (void) snprintf(path, sizeof (path), "dtrace/provider/%s", mname); + (void) devfsadm_mklink(path, node, minor, 0); + + return (DEVFSADM_CONTINUE); +} diff --git a/usr/src/cmd/devfsadm/i386/misc_link_i386.c b/usr/src/cmd/devfsadm/i386/misc_link_i386.c index 67d06ee101..6b21eabe3b 100644 --- a/usr/src/cmd/devfsadm/i386/misc_link_i386.c +++ b/usr/src/cmd/devfsadm/i386/misc_link_i386.c @@ -21,7 +21,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2012 Joyent, Inc. All rights reserved. + * Copyright 2018 Joyent, Inc. All rights reserved. */ #include <regex.h> @@ -36,6 +36,7 @@ extern int system_labeled; +static int ln_minor_name(di_minor_t minor, di_node_t node); static int lp(di_minor_t minor, di_node_t node); static int serial_dialout(di_minor_t minor, di_node_t node); static int serial(di_minor_t minor, di_node_t node); @@ -43,12 +44,9 @@ static int diskette(di_minor_t minor, di_node_t node); static int vt00(di_minor_t minor, di_node_t node); static int kdmouse(di_minor_t minor, di_node_t node); static int ipmi(di_minor_t minor, di_node_t node); -static int smbios(di_minor_t minor, di_node_t node); static int mc_node(di_minor_t minor, di_node_t node); -static int xsvc(di_minor_t minor, di_node_t node); -static int srn(di_minor_t minor, di_node_t node); -static int ucode(di_minor_t minor, di_node_t node); - +static int vmmctl(di_minor_t minor, di_node_t node); +static int ppt(di_minor_t minor, di_node_t node); static devfsadm_create_t misc_cbt[] = { { "vt00", "ddi_display", NULL, @@ -61,7 +59,7 @@ static devfsadm_create_t misc_cbt[] = { TYPE_EXACT | DRV_EXACT, ILEVEL_0, ipmi, }, { "pseudo", "ddi_pseudo", "smbios", - TYPE_EXACT | DRV_EXACT, ILEVEL_1, smbios, + TYPE_EXACT | DRV_EXACT, ILEVEL_1, ln_minor_name, }, /* floppies share the same class, but not link regex, as hard disks */ { "disk", "ddi_block:diskette", NULL, @@ -76,18 +74,27 @@ static devfsadm_create_t misc_cbt[] = { { "serial", "ddi_serial:dialout,mb", NULL, TYPE_EXACT, ILEVEL_1, serial_dialout }, - { "pseudo", "ddi_pseudo", NULL, - TYPE_EXACT, ILEVEL_0, xsvc + { "pseudo", "ddi_pseudo", "xsvc", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, ln_minor_name, }, - { "pseudo", "ddi_pseudo", NULL, - TYPE_EXACT, ILEVEL_0, srn + { "pseudo", "ddi_pseudo", "srn", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, ln_minor_name, }, { "memory-controller", "ddi_mem_ctrl", NULL, TYPE_EXACT, ILEVEL_0, mc_node }, { "pseudo", "ddi_pseudo", "ucode", - TYPE_EXACT | DRV_EXACT, ILEVEL_0, ucode, + TYPE_EXACT | DRV_EXACT, ILEVEL_0, ln_minor_name, + }, + { "pseudo", "ddi_pseudo", "viona", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, ln_minor_name, + }, + { "pseudo", "ddi_pseudo", "vmm", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, vmmctl, }, + { "pseudo", "ddi_pseudo", "ppt", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, ppt, + } }; DEVFSADM_CREATE_INIT_V0(misc_cbt); @@ -113,12 +120,32 @@ static devfsadm_remove_t misc_remove_cbt[] = { }, { "serial", "^tty[a-z]$", RM_ALWAYS | RM_PRE, ILEVEL_1, devfsadm_rm_all + }, + { "pseudo", "^viona$", RM_ALWAYS | RM_PRE | RM_HOT, + ILEVEL_0, devfsadm_rm_all + }, + { "pseudo", "^vmmctl$", RM_ALWAYS | RM_PRE | RM_HOT, + ILEVEL_0, devfsadm_rm_all + }, + { "pseudo", "^ppt$", RM_ALWAYS | RM_PRE | RM_HOT, + ILEVEL_0, devfsadm_rm_all } }; DEVFSADM_REMOVE_INIT_V0(misc_remove_cbt); /* + * Any /dev/foo named named after the minor name such as + * /devices/.../driver@0:foo + */ +static int +ln_minor_name(di_minor_t minor, di_node_t node) +{ + (void) devfsadm_mklink(di_minor_name(minor), node, minor, 0); + return (DEVFSADM_CONTINUE); +} + +/* * Handles minor node type "ddi_display", in addition to generic processing * done by display(). * @@ -305,13 +332,6 @@ ipmi(di_minor_t minor, di_node_t node) return (DEVFSADM_CONTINUE); } -static int -smbios(di_minor_t minor, di_node_t node) -{ - (void) devfsadm_mklink("smbios", node, minor, 0); - return (DEVFSADM_CONTINUE); -} - /* * /dev/mc/mc<chipid> -> /devices/.../pci1022,1102@<chipid+24>,2:mc-amd */ @@ -347,49 +367,24 @@ mc_node(di_minor_t minor, di_node_t node) } /* - * Creates \M0 devlink for xsvc node + * /dev/vmmctl -> /devices/pseudo/vmm@0:ctl */ static int -xsvc(di_minor_t minor, di_node_t node) +vmmctl(di_minor_t minor, di_node_t node) { - char *mn; - - if (strcmp(di_node_name(node), "xsvc") != 0) - return (DEVFSADM_CONTINUE); - - mn = di_minor_name(minor); - if (mn == NULL) - return (DEVFSADM_CONTINUE); - - (void) devfsadm_mklink(mn, node, minor, 0); + if (strcmp(di_minor_name(minor), "ctl") == 0) + (void) devfsadm_mklink("vmmctl", node, minor, 0); return (DEVFSADM_CONTINUE); } -/* - * Creates \M0 devlink for srn device - */ static int -srn(di_minor_t minor, di_node_t node) +ppt(di_minor_t minor, di_node_t node) { - char *mn; - - if (strcmp(di_node_name(node), "srn") != 0) - return (DEVFSADM_CONTINUE); - - mn = di_minor_name(minor); - if (mn == NULL) - return (DEVFSADM_CONTINUE); + char linkpath[PATH_MAX]; - (void) devfsadm_mklink(mn, node, minor, 0); - return (DEVFSADM_CONTINUE); -} + (void) snprintf(linkpath, sizeof (linkpath), "ppt%d", + di_instance(node)); -/* - * /dev/ucode -> /devices/pseudo/ucode@0:ucode - */ -static int -ucode(di_minor_t minor, di_node_t node) -{ - (void) devfsadm_mklink("ucode", node, minor, 0); + (void) devfsadm_mklink(linkpath, node, minor, 0); return (DEVFSADM_CONTINUE); } diff --git a/usr/src/cmd/devfsadm/misc_link.c b/usr/src/cmd/devfsadm/misc_link.c index 5f241df296..55aff1e4f7 100644 --- a/usr/src/cmd/devfsadm/misc_link.c +++ b/usr/src/cmd/devfsadm/misc_link.c @@ -32,6 +32,7 @@ #include <limits.h> #include <sys/zone.h> #include <sys/zcons.h> +#include <sys/zfd.h> #include <sys/cpuid_drv.h> static int display(di_minor_t minor, di_node_t node); @@ -53,6 +54,7 @@ static int av_create(di_minor_t minor, di_node_t node); static int tsalarm_create(di_minor_t minor, di_node_t node); static int ntwdt_create(di_minor_t minor, di_node_t node); static int zcons_create(di_minor_t minor, di_node_t node); +static int zfd_create(di_minor_t minor, di_node_t node); static int cpuid(di_minor_t minor, di_node_t node); static int glvc(di_minor_t minor, di_node_t node); static int ses_callback(di_minor_t minor, di_node_t node); @@ -114,6 +116,9 @@ static devfsadm_create_t misc_cbt[] = { "(^nca$)|(^rds$)|(^sdp$)|(^ipnet$)|(^dlpistub$)|(^bpf$)", TYPE_EXACT | DRV_RE, ILEVEL_1, minor_name }, + { "pseudo", "ddi_pseudo", "inotify", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name + }, { "pseudo", "ddi_pseudo", "ipd", TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name }, @@ -180,6 +185,9 @@ static devfsadm_create_t misc_cbt[] = { { "pseudo", "ddi_pseudo", "zcons", TYPE_EXACT | DRV_EXACT, ILEVEL_0, zcons_create, }, + { "pseudo", "ddi_pseudo", "zfd", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, zfd_create, + }, { "pseudo", "ddi_pseudo", CPUID_DRIVER_NAME, TYPE_EXACT | DRV_EXACT, ILEVEL_0, cpuid, }, @@ -204,6 +212,9 @@ static devfsadm_create_t misc_cbt[] = { { "pseudo", "ddi_pseudo", "tpm", TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name }, + { "pseudo", "ddi_pseudo", "overlay", + TYPE_EXACT | DRV_EXACT, ILEVEL_0, minor_name + } }; DEVFSADM_CREATE_INIT_V0(misc_cbt); @@ -228,6 +239,9 @@ static devfsadm_remove_t misc_remove_cbt[] = { ZCONS_SLAVE_NAME ")$", RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all }, + { "pseudo", "^zfd/" ZONENAME_REGEXP "/(master|slave)/[0-9]+$", + RM_PRE | RM_HOT | RM_ALWAYS, ILEVEL_0, devfsadm_rm_all + }, { "pseudo", "^" CPUID_SELF_NAME "$", RM_ALWAYS | RM_PRE | RM_HOT, ILEVEL_0, devfsadm_rm_all }, @@ -675,6 +689,35 @@ zcons_create(di_minor_t minor, di_node_t node) return (DEVFSADM_CONTINUE); } +static int +zfd_create(di_minor_t minor, di_node_t node) +{ + char *minor_str; + char *zonename; + int *id; + char path[MAXPATHLEN]; + + minor_str = di_minor_name(minor); + + if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "zfd_zname", + &zonename) == -1) + return (DEVFSADM_CONTINUE); + + if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "zfd_id", &id) == -1) + return (DEVFSADM_CONTINUE); + + if (strncmp(minor_str, "slave", 5) == 0) { + (void) snprintf(path, sizeof (path), "zfd/%s/slave/%d", + zonename, id[0]); + } else { + (void) snprintf(path, sizeof (path), "zfd/%s/master/%d", + zonename, id[0]); + } + (void) devfsadm_mklink(path, node, minor, 0); + + return (DEVFSADM_CONTINUE); +} + /* * /dev/cpu/self/cpuid -> /devices/pseudo/cpuid@0:self */ diff --git a/usr/src/cmd/devfsadm/sensor_link.c b/usr/src/cmd/devfsadm/sensor_link.c new file mode 100644 index 0000000000..7a2b48af75 --- /dev/null +++ b/usr/src/cmd/devfsadm/sensor_link.c @@ -0,0 +1,79 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019, Joyent, Inc. + */ + +/* + * Create /devices links for various sensors. The sensor series of node types + * all begin with ddi_sensor. After which, there is a series of : delineated + * paths in the node type. Those represent the directory under /dev/sensors that + * the nodes should ultimately be created. + * + * For example, ddi_sensor:temperature:cpu would cause us to place the named + * minor under /dev/sensors/temperature/cpu/. Currently it is up to drivers to + * not conflict in names or if there is a fear of conflicting, make sure their + * minor is unique. + */ + +#include <devfsadm.h> +#include <string.h> + +#define SENSORS_BASE "sensors" + +static int +sensor_link(di_minor_t minor, di_node_t node) +{ + const char *t, *minor_name, *dir_path = NULL; + char *type, *c; + char buf[PATH_MAX]; + size_t len; + + if ((t = di_minor_nodetype(minor)) == NULL) { + return (DEVFSADM_CONTINUE); + } + + if ((minor_name = di_minor_name(minor)) == NULL) { + return (DEVFSADM_CONTINUE); + } + + if ((type = strdup(t)) == NULL) { + return (DEVFSADM_TERMINATE); + } + + while ((c = strchr(type, ':')) != NULL) { + if (dir_path == NULL) { + dir_path = c + 1; + } + *c = '/'; + } + + if (dir_path == NULL || *dir_path == '\0') { + len = snprintf(buf, sizeof (buf), "%s/%s", SENSORS_BASE, + minor_name); + } else { + len = snprintf(buf, sizeof (buf), "%s/%s/%s", SENSORS_BASE, + dir_path, minor_name); + } + + if (len < sizeof (buf)) { + (void) devfsadm_mklink(buf, node, minor, 0); + } + + free(type); + return (DEVFSADM_CONTINUE); +} + +static devfsadm_create_t sensor_create_cbt[] = { + { NULL, "ddi_sensor", NULL, TYPE_PARTIAL, ILEVEL_0, sensor_link } +}; +DEVFSADM_CREATE_INIT_V0(sensor_create_cbt); diff --git a/usr/src/cmd/dis/dis_util.c b/usr/src/cmd/dis/dis_util.c index f74e7cef67..af38189cb4 100644 --- a/usr/src/cmd/dis/dis_util.c +++ b/usr/src/cmd/dis/dis_util.c @@ -24,6 +24,7 @@ * Use is subject to license terms. * * Copyright 2018 Jason King. + * Copyright 2018, Joyent, Inc. */ #include <dlfcn.h> @@ -106,6 +107,6 @@ dis_demangle(const char *name) * from previous invocations is freed. */ free(demangled_name); - demangled_name = sysdemangle(name, SYSDEM_LANG_CPP, NULL); + demangled_name = sysdemangle(name, SYSDEM_LANG_AUTO, NULL); return ((demangled_name != NULL) ? demangled_name : name); } diff --git a/usr/src/cmd/dladm/Makefile b/usr/src/cmd/dladm/Makefile index ef2b9868ef..734ecd8268 100644 --- a/usr/src/cmd/dladm/Makefile +++ b/usr/src/cmd/dladm/Makefile @@ -20,6 +20,7 @@ # # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2018 Joyent, Inc. # # Copyright (c) 2018, Joyent, Inc. @@ -38,7 +39,7 @@ XGETFLAGS += -a -x $(PROG).xcl LDLIBS += -L$(ROOT)/lib -lsocket LDLIBS += -ldladm -ldlpi -lkstat -lsecdb -lbsm -lofmt -linetutil -ldevinfo -LDLIBS += $(ZLAZYLOAD) -lrstp $(ZNOLAZYLOAD) +LDLIBS += $(ZLAZYLOAD) -lrstp $(ZNOLAZYLOAD) -lnsl -lumem -lcustr CERRWARN += -_gcc=-Wno-switch CERRWARN += -_gcc=-Wno-unused-label diff --git a/usr/src/cmd/dladm/dladm.c b/usr/src/cmd/dladm/dladm.c index 252fc4b6ae..97fc010fa2 100644 --- a/usr/src/cmd/dladm/dladm.c +++ b/usr/src/cmd/dladm/dladm.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Joyent, Inc. * Copyright 2016 Nexenta Systems, Inc. */ @@ -61,6 +62,7 @@ #include <libdliptun.h> #include <libdlsim.h> #include <libdlbridge.h> +#include <libdloverlay.h> #include <libinetutil.h> #include <libvrrpadm.h> #include <bsm/adt.h> @@ -76,6 +78,7 @@ #include <stddef.h> #include <stp_in.h> #include <ofmt.h> +#include <libcustr.h> #define MAXPORT 256 #define MAXVNIC 256 @@ -156,6 +159,7 @@ typedef struct show_vnic_state { dladm_status_t vs_status; uint32_t vs_flags; ofmt_handle_t vs_ofmt; + char *vs_zonename; } show_vnic_state_t; typedef struct show_part_state { @@ -186,6 +190,11 @@ typedef struct show_usage_state_s { ofmt_handle_t us_ofmt; } show_usage_state_t; +typedef struct show_overlay_request_s { + boolean_t sor_failed; + ofmt_handle_t sor_ofmt; +} show_overlay_request_t; + /* * callback functions for printing output and error diagnostics. */ @@ -194,6 +203,7 @@ static ofmt_cb_t print_lacp_cb, print_phys_one_mac_cb; static ofmt_cb_t print_xaggr_cb, print_aggr_stats_cb; static ofmt_cb_t print_phys_one_hwgrp_cb, print_wlan_attr_cb; static ofmt_cb_t print_wifi_status_cb, print_link_attr_cb; +static ofmt_cb_t print_overlay_cb, print_overlay_fma_cb, print_overlay_targ_cb; typedef void cmdfunc_t(int, char **, const char *); @@ -220,6 +230,8 @@ static cmdfunc_t do_create_bridge, do_modify_bridge, do_delete_bridge; static cmdfunc_t do_add_bridge, do_remove_bridge, do_show_bridge; static cmdfunc_t do_create_iptun, do_modify_iptun, do_delete_iptun; static cmdfunc_t do_show_iptun, do_up_iptun, do_down_iptun; +static cmdfunc_t do_create_overlay, do_delete_overlay, do_modify_overlay; +static cmdfunc_t do_show_overlay; static void do_up_vnic_common(int, char **, const char *, boolean_t); @@ -255,8 +267,11 @@ static void die(const char *, ...); static void die_optdup(int); static void die_opterr(int, int, const char *); static void die_dlerr(dladm_status_t, const char *, ...); +static void die_dlerrlist(dladm_status_t, dladm_errlist_t *, + const char *, ...); static void warn(const char *, ...); static void warn_dlerr(dladm_status_t, const char *, ...); +static void warn_dlerrlist(dladm_errlist_t *); typedef struct cmd { char *c_name; @@ -266,7 +281,7 @@ typedef struct cmd { static cmd_t cmds[] = { { "rename-link", do_rename_link, - " rename-link <oldlink> <newlink>" }, + " rename-link [-z zonename] <oldlink> <newlink>" }, { "show-link", do_show_link, " show-link [-pP] [-o <field>,..] [-s [-i <interval>]] " "[<link>]\n" }, @@ -301,12 +316,13 @@ static cmd_t cmds[] = { { "show-wifi", do_show_wifi, " show-wifi [-p] [-o <field>,...] [<link>]\n" }, { "set-linkprop", do_set_linkprop, - " set-linkprop [-t] -p <prop>=<value>[,...] <name>" }, + " set-linkprop [-t] [-z zonename] -p <prop>=<value>[,...] " + "<name>" }, { "reset-linkprop", do_reset_linkprop, - " reset-linkprop [-t] [-p <prop>,...] <name>" }, + " reset-linkprop [-t] [-z zonename] [-p <prop>,...] <name>"}, { "show-linkprop", do_show_linkprop, - " show-linkprop [-cP] [-o <field>,...] [-p <prop>,...] " - "<name>\n" }, + " show-linkprop [-cP] [-o <field>,...] [-z zonename] " + "[-p <prop>,...] <name>\n" }, { "show-ether", do_show_ether, " show-ether [-px][-o <field>,...] <link>\n" }, { "create-secobj", do_create_secobj, @@ -348,10 +364,10 @@ static cmd_t cmds[] = { "\t\t {vrrp -V <vrid> -A {inet | inet6}} [-v <vid> [-f]]\n" "\t\t [-p <prop>=<value>[,...]] <vnic-link>" }, { "delete-vnic", do_delete_vnic, - " delete-vnic [-t] <vnic-link>" }, + " delete-vnic [-t] [-z zonename] <vnic-link>" }, { "show-vnic", do_show_vnic, - " show-vnic [-pP] [-l <link>] [-s [-i <interval>]] " - "[<link>]\n" }, + " show-vnic [-pP] [-l <link>] [-z zonename] " + "[-s [-i <interval>]] [<link>]\n" }, { "up-vnic", do_up_vnic, NULL }, { "create-part", do_create_part, " create-part [-t] [-f] -l <link> [-P <pkey>]\n" @@ -402,6 +418,17 @@ static cmd_t cmds[] = { " <bridge>\n" " show-bridge -t [-p] [-o <field>,...] [-s [-i <interval>]]" " <bridge>\n" }, + { "create-overlay", do_create_overlay, + " create-overlay [-t] -e <encap> -s <search> -v <vnetid>\n" + "\t\t [ -p <prop>=<value>[,...]] <overlay>" }, + { "delete-overlay", do_delete_overlay, + " delete-overlay <overlay>" }, + { "modify-overlay", do_modify_overlay, + " modify-overlay -d mac | -f | -s mac=ip:port " + "<overlay>" }, + { "show-overlay", do_show_overlay, + " show-overlay [-f | -t] [[-p] -o <field>,...] " + "[<overlay>]\n" }, { "show-usage", do_show_usage, " show-usage [-a] [-d | -F <format>] " "[-s <DD/MM/YYYY,HH:MM:SS>]\n" @@ -960,6 +987,7 @@ typedef struct show_linkprop_state { char ls_link[MAXLINKNAMELEN]; char *ls_line; char **ls_propvals; + char *ls_zonename; dladm_arg_list_t *ls_proplist; boolean_t ls_parsable; boolean_t ls_persist; @@ -1012,21 +1040,24 @@ typedef struct vnic_fields_buf_s char vnic_macaddr[18]; char vnic_macaddrtype[19]; char vnic_vid[6]; + char vnic_zone[ZONENAME_MAX]; } vnic_fields_buf_t; static const ofmt_field_t vnic_fields[] = { { "LINK", 13, offsetof(vnic_fields_buf_t, vnic_link), print_default_cb}, -{ "OVER", 13, +{ "OVER", 11, offsetof(vnic_fields_buf_t, vnic_over), print_default_cb}, -{ "SPEED", 7, +{ "SPEED", 6, offsetof(vnic_fields_buf_t, vnic_speed), print_default_cb}, { "MACADDRESS", 18, offsetof(vnic_fields_buf_t, vnic_macaddr), print_default_cb}, -{ "MACADDRTYPE", 20, +{ "MACADDRTYPE", 12, offsetof(vnic_fields_buf_t, vnic_macaddrtype), print_default_cb}, -{ "VID", 7, +{ "VID", 5, offsetof(vnic_fields_buf_t, vnic_vid), print_default_cb}, +{ "ZONE", 20, + offsetof(vnic_fields_buf_t, vnic_zone), print_default_cb}, { NULL, 0, 0, NULL}} ; @@ -1426,6 +1457,82 @@ static ofmt_field_t bridge_trill_fields[] = { offsetof(bridge_trill_fields_buf_t, bridget_nexthop), print_default_cb }, { NULL, 0, 0, NULL}}; +static const struct option overlay_create_lopts[] = { + { "encap", required_argument, NULL, 'e' }, + { "prop", required_argument, NULL, 'p' }, + { "search", required_argument, NULL, 's' }, + { "temporary", no_argument, NULL, 't' }, + { "vnetid", required_argument, NULL, 'v' }, + { NULL, 0, NULL, 0 } +}; + +static const struct option overlay_modify_lopts[] = { + { "delete-entry", required_argument, NULL, 'd' }, + { "flush-table", no_argument, NULL, 'f' }, + { "set-entry", required_argument, NULL, 's' }, + { NULL, 0, NULL, 0 } +}; + +static const struct option overlay_show_lopts[] = { + { "fma", no_argument, NULL, 'f' }, + { "target", no_argument, NULL, 't' }, + { "parsable", no_argument, NULL, 'p' }, + { "parseable", no_argument, NULL, 'p' }, + { "output", required_argument, NULL, 'o' }, + { NULL, 0, NULL, 0 } +}; + +/* + * Structures for dladm show-overlay + */ +typedef enum { + OVERLAY_LINK, + OVERLAY_PROPERTY, + OVERLAY_PERM, + OVERLAY_REQ, + OVERLAY_VALUE, + OVERLAY_DEFAULT, + OVERLAY_POSSIBLE +} overlay_field_index_t; + +static const ofmt_field_t overlay_fields[] = { +/* name, field width, index */ +{ "LINK", 19, OVERLAY_LINK, print_overlay_cb }, +{ "PROPERTY", 19, OVERLAY_PROPERTY, print_overlay_cb }, +{ "PERM", 5, OVERLAY_PERM, print_overlay_cb }, +{ "REQ", 4, OVERLAY_REQ, print_overlay_cb }, +{ "VALUE", 11, OVERLAY_VALUE, print_overlay_cb }, +{ "DEFAULT", 10, OVERLAY_DEFAULT, print_overlay_cb }, +{ "POSSIBLE", 10, OVERLAY_POSSIBLE, print_overlay_cb }, +{ NULL, 0, 0, NULL } +}; + +typedef enum { + OVERLAY_FMA_LINK, + OVERLAY_FMA_STATUS, + OVERLAY_FMA_DETAILS +} overlay_fma_field_index_t; + +static const ofmt_field_t overlay_fma_fields[] = { +{ "LINK", 20, OVERLAY_FMA_LINK, print_overlay_fma_cb }, +{ "STATUS", 8, OVERLAY_FMA_STATUS, print_overlay_fma_cb }, +{ "DETAILS", 52, OVERLAY_FMA_DETAILS, print_overlay_fma_cb }, +{ NULL, 0, 0, NULL } +}; + +typedef enum { + OVERLAY_TARG_LINK, + OVERLAY_TARG_TARGET, + OVERLAY_TARG_DEST +} overlay_targ_field_index_t; + +static const ofmt_field_t overlay_targ_fields[] = { +{ "LINK", 20, OVERLAY_TARG_LINK, print_overlay_targ_cb }, +{ "TARGET", 18, OVERLAY_TARG_TARGET, print_overlay_targ_cb }, +{ "DESTINATION", 42, OVERLAY_TARG_DEST, print_overlay_targ_cb }, +{ NULL, 0, 0, NULL } +}; + static char *progname; static sig_atomic_t signalled; @@ -1435,6 +1542,12 @@ static sig_atomic_t signalled; */ static dladm_handle_t handle = NULL; +/* + * Global error list that all routines can use. It's initialized by the main + * code. + */ +static dladm_errlist_t errlist; + #define DLADM_ETHERSTUB_NAME "etherstub" #define DLADM_IS_ETHERSTUB(id) (id == DATALINK_INVALID_LINKID) @@ -1485,6 +1598,8 @@ main(int argc, char *argv[]) "could not open /dev/dld"); } + dladm_errlist_init(&errlist); + cmdp->c_fn(argc - 1, &argv[1], cmdp->c_usage); dladm_close(handle); @@ -2496,13 +2611,17 @@ do_rename_link(int argc, char *argv[], const char *use) char *link1, *link2; char *altroot = NULL; dladm_status_t status; + char *zonename = NULL; opterr = 0; - while ((option = getopt_long(argc, argv, ":R:", lopts, NULL)) != -1) { + while ((option = getopt_long(argc, argv, ":R:z:", lopts, NULL)) != -1) { switch (option) { case 'R': altroot = optarg; break; + case 'z': + zonename = optarg; + break; default: die_opterr(optopt, option, use); break; @@ -2518,7 +2637,7 @@ do_rename_link(int argc, char *argv[], const char *use) link1 = argv[optind++]; link2 = argv[optind]; - if ((status = dladm_rename_link(handle, link1, link2)) != + if ((status = dladm_rename_link(handle, zonename, link1, link2)) != DLADM_STATUS_OK) die_dlerr(status, "rename operation failed"); } @@ -3407,11 +3526,12 @@ do_show_link(int argc, char *argv[], const char *use) ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = 0; + char *zonename = NULL; bzero(&state, sizeof (state)); opterr = 0; - while ((option = getopt_long(argc, argv, ":pPsi:o:", + while ((option = getopt_long(argc, argv, ":pPsi:o:z:", show_lopts, NULL)) != -1) { switch (option) { case 'p': @@ -3444,6 +3564,9 @@ do_show_link(int argc, char *argv[], const char *use) if (!dladm_str2interval(optarg, &interval)) die("invalid interval value '%s'", optarg); break; + case 'z': + zonename = optarg; + break; default: die_opterr(optopt, option, use); break; @@ -3463,8 +3586,8 @@ do_show_link(int argc, char *argv[], const char *use) if (strlcpy(linkname, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN) die("link name too long"); - if ((status = dladm_name2info(handle, linkname, &linkid, &f, - NULL, NULL)) != DLADM_STATUS_OK) { + if ((status = dladm_zname2info(handle, zonename, linkname, + &linkid, &f, NULL, NULL)) != DLADM_STATUS_OK) { die_dlerr(status, "link %s is not valid", linkname); } @@ -4733,6 +4856,12 @@ do_create_vnic(int argc, char *argv[], const char *use) if ((flags & DLADM_OPT_FORCE) != 0 && vid == 0) die("-f option can only be used with -v"); + /* + * If creating a transient VNIC for a zone, mark it in the kernel. + */ + if (strstr(propstr, "zone=") != NULL && !(flags & DLADM_OPT_PERSIST)) + flags |= DLADM_OPT_TRANSIENT; + if (mac_prefix_len != 0 && mac_addr_type != VNIC_MAC_ADDR_TYPE_RANDOM && mac_addr_type != VNIC_MAC_ADDR_TYPE_FIXED) usage(); @@ -4777,7 +4906,7 @@ do_create_vnic(int argc, char *argv[], const char *use) status = dladm_vnic_create(handle, name, dev_linkid, mac_addr_type, mac_addr, maclen, &mac_slot, mac_prefix_len, vid, vrid, af, - &linkid, proplist, flags); + &linkid, proplist, &errlist, flags); switch (status) { case DLADM_STATUS_OK: break; @@ -4788,7 +4917,8 @@ do_create_vnic(int argc, char *argv[], const char *use) break; default: - die_dlerr(status, "vnic creation over %s failed", devname); + die_dlerrlist(status, &errlist, "vnic creation over %s failed", + devname); } dladm_free_props(proplist); @@ -4824,9 +4954,10 @@ do_delete_vnic_common(int argc, char *argv[], const char *use, datalink_id_t linkid; char *altroot = NULL; dladm_status_t status; + char *zonename = NULL; opterr = 0; - while ((option = getopt_long(argc, argv, ":R:t", lopts, + while ((option = getopt_long(argc, argv, ":R:tz:", lopts, NULL)) != -1) { switch (option) { case 't': @@ -4835,6 +4966,9 @@ do_delete_vnic_common(int argc, char *argv[], const char *use, case 'R': altroot = optarg; break; + case 'z': + zonename = optarg; + break; default: die_opterr(optopt, option, use); } @@ -4847,8 +4981,8 @@ do_delete_vnic_common(int argc, char *argv[], const char *use, if (altroot != NULL) altroot_cmd(altroot, argc, argv); - status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, - NULL); + status = dladm_zname2info(handle, zonename, argv[optind], &linkid, NULL, + NULL, NULL); if (status != DLADM_STATUS_OK) die("invalid link name '%s'", argv[optind]); @@ -4980,6 +5114,9 @@ print_vnic(show_vnic_state_t *state, datalink_id_t linkid) char vnic_name[MAXLINKNAMELEN]; char mstr[MAXMACADDRLEN * 3]; vnic_fields_buf_t vbuf; + uint_t valcnt = 1; + char zonename[DLADM_PROP_VAL_MAX + 1]; + char *valptr[1]; if ((status = dladm_vnic_info(handle, linkid, vnic, state->vs_flags)) != DLADM_STATUS_OK) @@ -5009,6 +5146,18 @@ print_vnic(show_vnic_state_t *state, datalink_id_t linkid) NULL, devname, sizeof (devname)) != DLADM_STATUS_OK) (void) sprintf(devname, "?"); + + zonename[0] = '\0'; + if (!is_etherstub) { + valptr[0] = zonename; + (void) dladm_get_linkprop(handle, linkid, + DLADM_PROP_VAL_CURRENT, "zone", (char **)valptr, &valcnt); + } + + if (state->vs_zonename != NULL && + strcmp(state->vs_zonename, zonename) != 0) + return (DLADM_STATUS_OK); + state->vs_found = B_TRUE; if (state->vs_stats) { /* print vnic statistics */ @@ -5084,6 +5233,13 @@ print_vnic(show_vnic_state_t *state, datalink_id_t linkid) (void) snprintf(vbuf.vnic_vid, sizeof (vbuf.vnic_vid), "%d", vnic->va_vid); + + if (zonename[0] != '\0') + (void) snprintf(vbuf.vnic_zone, + sizeof (vbuf.vnic_zone), "%s", zonename); + else + (void) strlcpy(vbuf.vnic_zone, "--", + sizeof (vbuf.vnic_zone)); } ofmt_print(state->vs_ofmt, &vbuf); @@ -5122,10 +5278,11 @@ do_show_vnic_common(int argc, char *argv[], const char *use, ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = 0; + char *zonename = NULL; bzero(&state, sizeof (state)); opterr = 0; - while ((option = getopt_long(argc, argv, ":pPl:si:o:", lopts, + while ((option = getopt_long(argc, argv, ":pPl:si:o:z:", lopts, NULL)) != -1) { switch (option) { case 'p': @@ -5164,6 +5321,9 @@ do_show_vnic_common(int argc, char *argv[], const char *use, o_arg = B_TRUE; fields_str = optarg; break; + case 'z': + zonename = optarg; + break; default: die_opterr(optopt, option, use); } @@ -5174,8 +5334,8 @@ do_show_vnic_common(int argc, char *argv[], const char *use, /* get vnic ID (optional last argument) */ if (optind == (argc - 1)) { - status = dladm_name2info(handle, argv[optind], &linkid, NULL, - NULL, NULL); + status = dladm_zname2info(handle, zonename, argv[optind], + &linkid, NULL, NULL, NULL); if (status != DLADM_STATUS_OK) { die_dlerr(status, "invalid vnic name '%s'", argv[optind]); @@ -5186,8 +5346,8 @@ do_show_vnic_common(int argc, char *argv[], const char *use, } if (l_arg) { - status = dladm_name2info(handle, state.vs_link, &dev_linkid, - NULL, NULL, NULL); + status = dladm_zname2info(handle, zonename, state.vs_link, + &dev_linkid, NULL, NULL, NULL); if (status != DLADM_STATUS_OK) { die_dlerr(status, "invalid link name '%s'", state.vs_link); @@ -5199,6 +5359,7 @@ do_show_vnic_common(int argc, char *argv[], const char *use, state.vs_etherstub = etherstub; state.vs_found = B_FALSE; state.vs_flags = flags; + state.vs_zonename = zonename; if (!o_arg || (o_arg && strcasecmp(fields_str, "all") == 0)) { if (etherstub) @@ -5287,7 +5448,7 @@ do_create_etherstub(int argc, char *argv[], const char *use) status = dladm_vnic_create(handle, name, DATALINK_INVALID_LINKID, VNIC_MAC_ADDR_TYPE_AUTO, mac_addr, ETHERADDRL, NULL, 0, 0, - VRRP_VRID_NONE, AF_UNSPEC, NULL, NULL, flags); + VRRP_VRID_NONE, AF_UNSPEC, NULL, NULL, &errlist, flags); if (status != DLADM_STATUS_OK) die_dlerr(status, "etherstub creation failed"); } @@ -6687,6 +6848,7 @@ do_show_linkprop(int argc, char **argv, const char *use) ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = 0; + char *zonename = NULL; bzero(propstr, DLADM_STRSIZE); opterr = 0; @@ -6697,7 +6859,7 @@ do_show_linkprop(int argc, char **argv, const char *use) state.ls_header = B_TRUE; state.ls_retstatus = DLADM_STATUS_OK; - while ((option = getopt_long(argc, argv, ":p:cPo:", + while ((option = getopt_long(argc, argv, ":p:cPo:z:", prop_longopts, NULL)) != -1) { switch (option) { case 'p': @@ -6716,6 +6878,9 @@ do_show_linkprop(int argc, char **argv, const char *use) case 'o': fields_str = optarg; break; + case 'z': + zonename = optarg; + break; default: die_opterr(optopt, option, use); break; @@ -6723,8 +6888,8 @@ do_show_linkprop(int argc, char **argv, const char *use) } if (optind == (argc - 1)) { - if ((status = dladm_name2info(handle, argv[optind], &linkid, - NULL, NULL, NULL)) != DLADM_STATUS_OK) { + if ((status = dladm_zname2info(handle, zonename, argv[optind], + &linkid, NULL, NULL, NULL)) != DLADM_STATUS_OK) { die_dlerr(status, "link %s is not valid", argv[optind]); } } else if (optind != argc) { @@ -6735,6 +6900,7 @@ do_show_linkprop(int argc, char **argv, const char *use) != DLADM_STATUS_OK) die("invalid link properties specified"); state.ls_proplist = proplist; + state.ls_zonename = zonename; state.ls_status = DLADM_STATUS_OK; if (state.ls_parsable) @@ -6779,6 +6945,17 @@ show_linkprop_onelink(dladm_handle_t hdl, datalink_id_t linkid, void *arg) return (DLADM_WALK_CONTINUE); } + if (statep->ls_zonename != NULL) { + datalink_id_t tlinkid; + + if (dladm_zname2info(hdl, statep->ls_zonename, statep->ls_link, + &tlinkid, NULL, NULL, NULL) != DLADM_STATUS_OK || + linkid != tlinkid) { + statep->ls_status = DLADM_STATUS_NOTFOUND; + return (DLADM_WALK_CONTINUE); + } + } + if ((statep->ls_persist && !(flags & DLADM_OPT_PERSIST)) || (!statep->ls_persist && !(flags & DLADM_OPT_ACTIVE))) { statep->ls_status = DLADM_STATUS_BADARG; @@ -6861,11 +7038,12 @@ set_linkprop(int argc, char **argv, boolean_t reset, const char *use) dladm_status_t status = DLADM_STATUS_OK; char propstr[DLADM_STRSIZE]; dladm_arg_list_t *proplist = NULL; + char *zonename = NULL; opterr = 0; bzero(propstr, DLADM_STRSIZE); - while ((option = getopt_long(argc, argv, ":p:R:t", + while ((option = getopt_long(argc, argv, ":p:R:tz:", prop_longopts, NULL)) != -1) { switch (option) { case 'p': @@ -6880,6 +7058,9 @@ set_linkprop(int argc, char **argv, boolean_t reset, const char *use) case 'R': altroot = optarg; break; + case 'z': + zonename = optarg; + break; default: die_opterr(optopt, option, use); @@ -6902,8 +7083,8 @@ set_linkprop(int argc, char **argv, boolean_t reset, const char *use) altroot_cmd(altroot, argc, argv); } - status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, - NULL); + status = dladm_zname2info(handle, zonename, argv[optind], &linkid, + NULL, NULL, NULL); if (status != DLADM_STATUS_OK) die_dlerr(status, "link %s is not valid", argv[optind]); @@ -8926,6 +9107,21 @@ warn_dlerr(dladm_status_t err, const char *format, ...) (void) fprintf(stderr, ": %s\n", dladm_status2str(err, errmsg)); } +static void +warn_dlerrlist(dladm_errlist_t *errlist) +{ + if (errlist != NULL && errlist->el_count > 0) { + int i; + for (i = 0; i < errlist->el_count; i++) { + (void) fprintf(stderr, gettext("%s: warning: "), + progname); + + (void) fprintf(stderr, "%s\n", + gettext(errlist->el_errs[i])); + } + } +} + /* * Also closes the dladm handle if it is not NULL. */ @@ -8951,6 +9147,34 @@ die_dlerr(dladm_status_t err, const char *format, ...) exit(EXIT_FAILURE); } +/* + * Like die_dlerr, but uses the errlist for additional information. + */ +/* PRINTFLIKE3 */ +static void +die_dlerrlist(dladm_status_t err, dladm_errlist_t *errlist, + const char *format, ...) +{ + va_list alist; + char errmsg[DLADM_STRSIZE]; + + warn_dlerrlist(errlist); + format = gettext(format); + (void) fprintf(stderr, "%s: ", progname); + + va_start(alist, format); + (void) vfprintf(stderr, format, alist); + va_end(alist); + (void) fprintf(stderr, ": %s\n", dladm_status2str(err, errmsg)); + + /* close dladm handle if it was opened */ + if (handle != NULL) + dladm_close(handle); + + exit(EXIT_FAILURE); + +} + /* PRINTFLIKE1 */ static void die(const char *format, ...) @@ -9658,3 +9882,702 @@ do_up_part(int argc, char *argv[], const char *use) (void) dladm_part_up(handle, partid, 0); } + +static void +do_create_overlay(int argc, char *argv[], const char *use) +{ + int opt; + char *encap = NULL, *endp, *search = NULL; + char name[MAXLINKNAMELEN]; + dladm_status_t status; + uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; + uint64_t vid; + boolean_t havevid = B_FALSE; + char propstr[DLADM_STRSIZE]; + dladm_arg_list_t *proplist = NULL; + + bzero(propstr, sizeof (propstr)); + while ((opt = getopt_long(argc, argv, ":te:v:p:s:", + overlay_create_lopts, NULL)) != -1) { + switch (opt) { + case 'e': + encap = optarg; + break; + case 's': + search = optarg; + break; + case 't': + flags &= ~DLADM_OPT_PERSIST; + break; + case 'p': + (void) strlcat(propstr, optarg, DLADM_STRSIZE); + if (strlcat(propstr, ",", DLADM_STRSIZE) >= + DLADM_STRSIZE) + die("property list too long '%s'", propstr); + break; + case 'v': + vid = strtoul(optarg, &endp, 10); + if (*endp != '\0' || (vid == 0 && errno == EINVAL)) + die("couldn't parse virtual networkd id: %s", + optarg); + if (vid == ULONG_MAX && errno == ERANGE) + die("virtual networkd id too large: %s", + optarg); + havevid = B_TRUE; + break; + default: + die_opterr(optopt, opt, use); + } + } + + if (havevid == B_FALSE) + die("missing required virtual network id"); + + if (encap == NULL) + die("missing required encapsulation plugin"); + + if (encap == NULL) + die("missing required search plugin"); + + if (optind != (argc - 1)) + die("missing device name"); + + if (strlcpy(name, argv[optind], MAXLINKNAMELEN) >= MAXLINKNAMELEN) + die("link name too long '%s'", argv[optind]); + + if (!dladm_valid_linkname(name)) + die("invalid link name '%s'", argv[optind]); + + if (strlen(encap) + 1 > MAXLINKNAMELEN) + die("encapsulation plugin name too long '%s'", encap); + + if (strlen(search) + 1 > MAXLINKNAMELEN) + die("search plugin name too long '%s'", encap); + + if (dladm_parse_link_props(propstr, &proplist, B_FALSE) + != DLADM_STATUS_OK) + die("invalid overlay property"); + + status = dladm_overlay_create(handle, name, encap, search, vid, + proplist, &errlist, flags); + dladm_free_props(proplist); + if (status != DLADM_STATUS_OK) { + die_dlerrlist(status, &errlist, "overlay creation failed"); + } +} + +/* ARGSUSED */ +static void +do_delete_overlay(int argc, char *argv[], const char *use) +{ + datalink_id_t linkid = DATALINK_ALL_LINKID; + dladm_status_t status; + + if (argc != 2) { + usage(); + } + + status = dladm_name2info(handle, argv[1], &linkid, NULL, NULL, NULL); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to delete %s", argv[1]); + + status = dladm_overlay_delete(handle, linkid); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to delete %s", argv[1]); +} + +typedef struct showoverlay_state { + ofmt_handle_t sho_ofmt; + const char *sho_linkname; + dladm_overlay_propinfo_handle_t sho_info; + uint8_t sho_value[DLADM_OVERLAY_PROP_SIZEMAX]; + uint32_t sho_size; +} showoverlay_state_t; + +typedef struct showoverlay_fma_state { + ofmt_handle_t shof_ofmt; + const char *shof_linkname; + dladm_overlay_status_t *shof_status; +} showoverlay_fma_state_t; + +typedef struct showoverlay_targ_state { + ofmt_handle_t shot_ofmt; + const char *shot_linkname; + const struct ether_addr *shot_key; + const dladm_overlay_point_t *shot_point; +} showoverlay_targ_state_t; + +static void +print_overlay_value(char *outbuf, uint_t bufsize, uint_t type, const void *pbuf, + const size_t psize) +{ + const struct in6_addr *ipv6; + struct in_addr ip; + + switch (type) { + case OVERLAY_PROP_T_INT: + if (psize != 1 && psize != 2 && psize != 4 && psize != 8) { + (void) snprintf(outbuf, bufsize, "?"); + break; + } + if (psize == 1) + (void) snprintf(outbuf, bufsize, "%d", *(int8_t *)pbuf); + if (psize == 2) + (void) snprintf(outbuf, bufsize, "%d", + *(int16_t *)pbuf); + if (psize == 4) + (void) snprintf(outbuf, bufsize, "%d", + *(int32_t *)pbuf); + if (psize == 8) + (void) snprintf(outbuf, bufsize, "%d", + *(int64_t *)pbuf); + break; + case OVERLAY_PROP_T_UINT: + if (psize != 1 && psize != 2 && psize != 4 && psize != 8) { + (void) snprintf(outbuf, bufsize, "?"); + break; + } + if (psize == 1) + (void) snprintf(outbuf, bufsize, "%d", + *(uint8_t *)pbuf); + if (psize == 2) + (void) snprintf(outbuf, bufsize, "%d", + *(uint16_t *)pbuf); + if (psize == 4) + (void) snprintf(outbuf, bufsize, "%d", + *(uint32_t *)pbuf); + if (psize == 8) + (void) snprintf(outbuf, bufsize, "%d", + *(uint64_t *)pbuf); + break; + case OVERLAY_PROP_T_IP: + if (psize != sizeof (struct in6_addr)) { + warn("malformed overlay IP property: %d bytes\n", + psize); + (void) snprintf(outbuf, bufsize, "--"); + break; + } + + ipv6 = pbuf; + if (IN6_IS_ADDR_V4MAPPED(ipv6)) { + IN6_V4MAPPED_TO_INADDR(ipv6, &ip); + if (inet_ntop(AF_INET, &ip, outbuf, bufsize) == NULL) { + warn("malformed overlay IP property\n"); + (void) snprintf(outbuf, bufsize, "--"); + break; + } + } else { + if (inet_ntop(AF_INET6, ipv6, outbuf, bufsize) == + NULL) { + warn("malformed overlay IP property\n"); + (void) snprintf(outbuf, bufsize, "--"); + break; + } + } + + break; + case OVERLAY_PROP_T_STRING: + (void) snprintf(outbuf, bufsize, "%s", pbuf); + break; + default: + abort(); + } + + return; + +} + +static boolean_t +print_overlay_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + dladm_status_t status; + showoverlay_state_t *sp = ofarg->ofmt_cbarg; + dladm_overlay_propinfo_handle_t infop = sp->sho_info; + const char *pname; + uint_t type, prot; + const void *def; + uint32_t defsize; + const mac_propval_range_t *rangep; + + if ((status = dladm_overlay_prop_info(infop, &pname, &type, &prot, &def, + &defsize, &rangep)) != DLADM_STATUS_OK) { + warn_dlerr(status, "failed to get get property info"); + return (B_TRUE); + } + + switch (ofarg->ofmt_id) { + case OVERLAY_LINK: + (void) snprintf(buf, bufsize, "%s", sp->sho_linkname); + break; + case OVERLAY_PROPERTY: + (void) snprintf(buf, bufsize, "%s", pname); + break; + case OVERLAY_PERM: + if ((prot & OVERLAY_PROP_PERM_RW) == OVERLAY_PROP_PERM_RW) { + (void) snprintf(buf, bufsize, "%s", "rw"); + } else if ((prot & OVERLAY_PROP_PERM_RW) == + OVERLAY_PROP_PERM_READ) { + (void) snprintf(buf, bufsize, "%s", "r-"); + } else { + (void) snprintf(buf, bufsize, "%s", "--"); + } + break; + case OVERLAY_REQ: + (void) snprintf(buf, bufsize, "%s", + prot & OVERLAY_PROP_PERM_REQ ? "y" : "-"); + break; + case OVERLAY_VALUE: + if (sp->sho_size == 0) { + (void) snprintf(buf, bufsize, "%s", "--"); + } else { + print_overlay_value(buf, bufsize, type, sp->sho_value, + sp->sho_size); + } + break; + case OVERLAY_DEFAULT: + if (defsize == 0) { + (void) snprintf(buf, bufsize, "%s", "--"); + } else { + print_overlay_value(buf, bufsize, type, def, defsize); + } + break; + case OVERLAY_POSSIBLE: { + int i; + char **vals, *ptr, *lim; + if (rangep->mpr_count == 0) { + (void) snprintf(buf, bufsize, "%s", "--"); + break; + } + + vals = malloc((sizeof (char *) + DLADM_PROP_VAL_MAX) * + rangep->mpr_count); + if (vals == NULL) + die("insufficient memory"); + for (i = 0; i < rangep->mpr_count; i++) { + vals[i] = (char *)vals + sizeof (char *) * + rangep->mpr_count + i * DLADM_MAX_PROP_VALCNT; + } + + if (dladm_range2strs(rangep, vals) != 0) { + free(vals); + (void) snprintf(buf, bufsize, "%s", "?"); + break; + } + + ptr = buf; + lim = buf + bufsize; + for (i = 0; i < rangep->mpr_count; i++) { + ptr += snprintf(ptr, lim - ptr, "%s,", vals[i]); + if (ptr >= lim) + break; + } + if (rangep->mpr_count > 0) + buf[strlen(buf) - 1] = '\0'; + free(vals); + break; + } + default: + abort(); + } + return (B_TRUE); +} + +static int +dladm_overlay_show_one(dladm_handle_t handle, datalink_id_t linkid, + dladm_overlay_propinfo_handle_t phdl, void *arg) +{ + showoverlay_state_t *sp = arg; + sp->sho_info = phdl; + + sp->sho_size = sizeof (sp->sho_value); + if (dladm_overlay_get_prop(handle, linkid, phdl, &sp->sho_value, + &sp->sho_size) != DLADM_STATUS_OK) + return (DLADM_WALK_CONTINUE); + + ofmt_print(sp->sho_ofmt, sp); + return (DLADM_WALK_CONTINUE); +} + +static int +show_one_overlay(dladm_handle_t hdl, datalink_id_t linkid, void *arg) +{ + char buf[MAXLINKNAMELEN]; + dladm_status_t info_status; + showoverlay_state_t state; + datalink_class_t class; + show_overlay_request_t *req = arg; + + if ((info_status = dladm_datalink_id2info(hdl, linkid, NULL, &class, + NULL, buf, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { + warn_dlerr(info_status, "failed to get info for " + "datalink id %u", linkid); + req->sor_failed = B_TRUE; + return (DLADM_WALK_CONTINUE); + } + + if (class != DATALINK_CLASS_OVERLAY) { + warn("%s is not an overlay", buf); + req->sor_failed = B_TRUE; + return (DLADM_WALK_CONTINUE); + } + + state.sho_linkname = buf; + state.sho_ofmt = req->sor_ofmt; + + dladm_errlist_reset(&errlist); + (void) dladm_overlay_walk_prop(handle, linkid, dladm_overlay_show_one, + &state, &errlist); + warn_dlerrlist(&errlist); + if (errlist.el_count) { + req->sor_failed = B_TRUE; + } + + return (DLADM_WALK_CONTINUE); +} + +static boolean_t +print_overlay_targ_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + char keybuf[ETHERADDRSTRL]; + const showoverlay_targ_state_t *shot = ofarg->ofmt_cbarg; + const dladm_overlay_point_t *point = shot->shot_point; + char macbuf[ETHERADDRSTRL]; + char ipbuf[INET6_ADDRSTRLEN]; + custr_t *cus; + + switch (ofarg->ofmt_id) { + case OVERLAY_TARG_LINK: + (void) snprintf(buf, bufsize, shot->shot_linkname); + break; + case OVERLAY_TARG_TARGET: + if ((point->dop_flags & DLADM_OVERLAY_F_DEFAULT) != 0) { + (void) snprintf(buf, bufsize, "*:*:*:*:*:*"); + } else { + if (ether_ntoa_r(shot->shot_key, keybuf) == NULL) { + warn("encountered malformed mac address key\n"); + return (B_FALSE); + } + (void) snprintf(buf, bufsize, "%s", keybuf); + } + break; + case OVERLAY_TARG_DEST: + if (custr_alloc_buf(&cus, buf, bufsize) != 0) { + die("ran out of memory for printing the overlay " + "target destination"); + } + + if (point->dop_dest & OVERLAY_PLUGIN_D_ETHERNET) { + if (ether_ntoa_r(&point->dop_mac, macbuf) == NULL) { + warn("encountered malformed mac address target " + "for key %s\n", keybuf); + return (B_FALSE); + } + (void) custr_append(cus, macbuf); + } + + if (point->dop_dest & OVERLAY_PLUGIN_D_IP) { + if (IN6_IS_ADDR_V4MAPPED(&point->dop_ip)) { + struct in_addr v4; + IN6_V4MAPPED_TO_INADDR(&point->dop_ip, &v4); + if (inet_ntop(AF_INET, &v4, ipbuf, + sizeof (ipbuf)) == NULL) + abort(); + } else if (inet_ntop(AF_INET6, &point->dop_ip, ipbuf, + sizeof (ipbuf)) == NULL) { + /* + * The only failrues we should get are + * EAFNOSUPPORT and ENOSPC because of buffer + * exhaustion. In either of these cases, that + * means something has gone horribly wrong. + */ + abort(); + } + if (point->dop_dest & OVERLAY_PLUGIN_D_ETHERNET) + (void) custr_appendc(cus, ','); + (void) custr_append(cus, ipbuf); + } + + if (point->dop_dest & OVERLAY_PLUGIN_D_PORT) { + if (point->dop_dest & OVERLAY_PLUGIN_D_IP) + (void) custr_appendc(cus, ':'); + else if (point->dop_dest & OVERLAY_PLUGIN_D_ETHERNET) + (void) custr_appendc(cus, ','); + (void) custr_append_printf(cus, "%u", point->dop_port); + } + + custr_free(cus); + + break; + } + return (B_TRUE); +} + +/* ARGSUSED */ +static int +show_one_overlay_table_entry(dladm_handle_t handle, datalink_id_t linkid, + const struct ether_addr *key, const dladm_overlay_point_t *point, void *arg) +{ + showoverlay_targ_state_t *shot = arg; + + shot->shot_key = key; + shot->shot_point = point; + ofmt_print(shot->shot_ofmt, shot); + + return (DLADM_WALK_CONTINUE); +} + +/* ARGSUSED */ +static int +show_one_overlay_table(dladm_handle_t handle, datalink_id_t linkid, void *arg) +{ + char linkbuf[MAXLINKNAMELEN]; + dladm_status_t info_status; + showoverlay_targ_state_t shot; + datalink_class_t class; + show_overlay_request_t *req = arg; + + if ((info_status = dladm_datalink_id2info(handle, linkid, NULL, &class, + NULL, linkbuf, MAXLINKNAMELEN)) != DLADM_STATUS_OK) { + warn_dlerr(info_status, "failed to get info for " + "datalink id %u", linkid); + req->sor_failed = B_TRUE; + return (DLADM_WALK_CONTINUE); + } + + if (class != DATALINK_CLASS_OVERLAY) { + warn("%s is not an overlay", linkbuf); + req->sor_failed = B_TRUE; + return (DLADM_WALK_CONTINUE); + } + + shot.shot_ofmt = req->sor_ofmt; + shot.shot_linkname = linkbuf; + + (void) dladm_overlay_walk_cache(handle, linkid, + show_one_overlay_table_entry, &shot); + + return (DLADM_WALK_CONTINUE); +} + +static boolean_t +print_overlay_fma_cb(ofmt_arg_t *ofarg, char *buf, uint_t bufsize) +{ + showoverlay_fma_state_t *shof = ofarg->ofmt_cbarg; + dladm_overlay_status_t *st = shof->shof_status; + + switch (ofarg->ofmt_id) { + case OVERLAY_FMA_LINK: + (void) snprintf(buf, bufsize, "%s", shof->shof_linkname); + break; + case OVERLAY_FMA_STATUS: + (void) snprintf(buf, bufsize, st->dos_degraded == B_TRUE ? + "DEGRADED": "ONLINE"); + break; + case OVERLAY_FMA_DETAILS: + (void) snprintf(buf, bufsize, "%s", st->dos_degraded == B_TRUE ? + st->dos_fmamsg : "-"); + break; + default: + abort(); + } + return (B_TRUE); +} + +/* ARGSUSED */ +static void +show_one_overlay_fma_cb(dladm_handle_t handle, datalink_id_t linkid, + dladm_overlay_status_t *stat, void *arg) +{ + showoverlay_fma_state_t *shof = arg; + shof->shof_status = stat; + ofmt_print(shof->shof_ofmt, shof); +} + + +static int +show_one_overlay_fma(dladm_handle_t handle, datalink_id_t linkid, void *arg) +{ + dladm_status_t status; + char linkbuf[MAXLINKNAMELEN]; + datalink_class_t class; + showoverlay_fma_state_t shof; + show_overlay_request_t *req = arg; + + if (dladm_datalink_id2info(handle, linkid, NULL, &class, NULL, linkbuf, + MAXLINKNAMELEN) != DLADM_STATUS_OK || + class != DATALINK_CLASS_OVERLAY) { + die("datalink %s is not an overlay device\n", linkbuf); + } + + shof.shof_ofmt = req->sor_ofmt; + shof.shof_linkname = linkbuf; + + status = dladm_overlay_status(handle, linkid, + show_one_overlay_fma_cb, &shof); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to obtain device status for %s", + linkbuf); + + return (DLADM_WALK_CONTINUE); +} + +static void +do_show_overlay(int argc, char *argv[], const char *use) +{ + int i, opt; + datalink_id_t linkid = DATALINK_ALL_LINKID; + dladm_status_t status; + int (*funcp)(dladm_handle_t, datalink_id_t, void *); + char *fields_str = NULL; + const ofmt_field_t *fieldsp; + ofmt_status_t oferr; + boolean_t parse; + show_overlay_request_t req; + uint_t ofmtflags; + int err; + + funcp = show_one_overlay; + fieldsp = overlay_fields; + parse = B_FALSE; + req.sor_failed = B_FALSE; + ofmtflags = OFMT_WRAP; + while ((opt = getopt_long(argc, argv, ":o:pft", overlay_show_lopts, + NULL)) != -1) { + switch (opt) { + case 'f': + funcp = show_one_overlay_fma; + fieldsp = overlay_fma_fields; + break; + case 'o': + fields_str = optarg; + break; + case 'p': + parse = B_TRUE; + ofmtflags = OFMT_PARSABLE; + break; + case 't': + funcp = show_one_overlay_table; + fieldsp = overlay_targ_fields; + break; + default: + die_opterr(optopt, opt, use); + } + } + + if (fields_str != NULL && strcasecmp(fields_str, "all") == 0) + fields_str = NULL; + + oferr = ofmt_open(fields_str, fieldsp, ofmtflags, 0, &req.sor_ofmt); + ofmt_check(oferr, parse, req.sor_ofmt, die, warn); + + err = 0; + if (argc > optind) { + for (i = optind; i < argc; i++) { + status = dladm_name2info(handle, argv[i], &linkid, + NULL, NULL, NULL); + if (status != DLADM_STATUS_OK) { + warn_dlerr(status, "failed to find %s", + argv[i]); + err = 1; + continue; + } + (void) funcp(handle, linkid, &req); + } + } else { + (void) dladm_walk_datalink_id(funcp, handle, &req, + DATALINK_CLASS_OVERLAY, DATALINK_ANY_MEDIATYPE, + DLADM_OPT_ACTIVE); + } + if (req.sor_failed) { + err = 1; + } + ofmt_close(req.sor_ofmt); + + exit(err); +} + +static void +do_modify_overlay(int argc, char *argv[], const char *use) +{ + int opt, ocnt = 0; + boolean_t flush, set, delete; + struct ether_addr e; + char *dest; + datalink_id_t linkid = DATALINK_ALL_LINKID; + dladm_status_t status; + + flush = set = delete = B_FALSE; + while ((opt = getopt_long(argc, argv, ":fd:s:", overlay_modify_lopts, + NULL)) != -1) { + switch (opt) { + case 'd': + if (delete == B_TRUE) + die_optdup('d'); + delete = B_TRUE; + ocnt++; + if (ether_aton_r(optarg, &e) == NULL) + die("invalid mac address: %s\n", optarg); + break; + case 'f': + if (flush == B_TRUE) + die_optdup('f'); + flush = B_TRUE; + ocnt++; + break; + case 's': + if (set == B_TRUE) + die_optdup('s'); + set = B_TRUE; + ocnt++; + dest = strchr(optarg, '='); + *dest = '\0'; + dest++; + if (dest == NULL) + die("malformed value, expected mac=dest, " + "got: %s\n", optarg); + if (ether_aton_r(optarg, &e) == NULL) + die("invalid mac address: %s\n", optarg); + break; + default: + die_opterr(optopt, opt, use); + } + } + + if (ocnt == 0) + die("need to specify one of -d, -f, or -s"); + if (ocnt > 1) + die("only one of -d, -f, or -s may be used"); + + if (argv[optind] == NULL) + die("missing required overlay device\n"); + if (argc > optind + 1) + die("only one overlay device may be specified\n"); + + status = dladm_name2info(handle, argv[optind], &linkid, NULL, NULL, + NULL); + if (status != DLADM_STATUS_OK) { + die_dlerr(status, "failed to find overlay %s", argv[optind]); + } + + if (flush == B_TRUE) { + status = dladm_overlay_cache_flush(handle, linkid); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to flush target cache for " + "overlay %s", argv[optind]); + } + + if (delete == B_TRUE) { + status = dladm_overlay_cache_delete(handle, linkid, &e); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to flush target %s from " + "overlay target cache %s", optarg, argv[optind]); + } + + if (set == B_TRUE) { + status = dladm_overlay_cache_set(handle, linkid, &e, dest); + if (status != DLADM_STATUS_OK) + die_dlerr(status, "failed to set target %s for overlay " + "target cache %s", optarg, argv[optind]); + } + +} diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_db.c b/usr/src/cmd/dlmgmtd/dlmgmt_db.c index 99307dbc03..6ccd9d97b8 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_db.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_db.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2016 Joyent, Inc. */ #include <assert.h> @@ -43,6 +44,7 @@ #include <libcontract.h> #include <libcontract_priv.h> #include <sys/contract/process.h> +#include <zone.h> #include "dlmgmt_impl.h" typedef enum dlmgmt_db_op { @@ -552,6 +554,10 @@ dlmgmt_db_update(dlmgmt_db_op_t op, const char *entryname, dlmgmt_link_t *linkp, linkp->ll_zoneid, flags, &err)) == NULL) return (err); + /* If transient op and onloan, use the global zone cache file. */ + if (flags == DLMGMT_ACTIVE && linkp->ll_onloan) + req->ls_zoneid = GLOBAL_ZONEID; + /* * If the return error is EINPROGRESS, this request is handled * asynchronously; return success. @@ -714,11 +720,13 @@ parse_linkprops(char *buf, dlmgmt_link_t *linkp) char attr_name[MAXLINKATTRLEN]; size_t attr_buf_len = 0; void *attr_buf = NULL; + boolean_t rename; curr = buf; len = strlen(buf); attr_name[0] = '\0'; for (i = 0; i < len; i++) { + rename = B_FALSE; char c = buf[i]; boolean_t match = (c == '=' || (c == ',' && !found_type) || c == ';'); @@ -768,6 +776,21 @@ parse_linkprops(char *buf, dlmgmt_link_t *linkp) goto parse_fail; linkp->ll_media = (uint32_t)*(int64_t *)attr_buf; + } else if (strcmp(attr_name, "zone") == 0) { + if (read_str(curr, &attr_buf) == 0) + goto parse_fail; + linkp->ll_zoneid = getzoneidbyname(attr_buf); + if (linkp->ll_zoneid == -1) { + if (errno == EFAULT) + abort(); + /* + * If we can't find the zone, assign the + * link to the GZ and mark it for being + * renamed. + */ + linkp->ll_zoneid = 0; + rename = B_TRUE; + } } else { attr_buf_len = translators[type].read_func(curr, &attr_buf); @@ -811,6 +834,16 @@ parse_linkprops(char *buf, dlmgmt_link_t *linkp) (void) snprintf(attr_name, MAXLINKATTRLEN, "%s", curr); } + + /* + * The zone that this link belongs to has died, we are + * reparenting it to the GZ and renaming it to avoid name + * collisions. + */ + if (rename == B_TRUE) { + (void) snprintf(linkp->ll_link, MAXLINKNAMELEN, + "SUNWorphan%u", (uint16_t)(gethrtime() / 1000)); + } curr = buf + i + 1; } @@ -1222,12 +1255,19 @@ generate_link_line(dlmgmt_link_t *linkp, boolean_t persist, char *buf) ptr += snprintf(ptr, BUFLEN(lim, ptr), "%s\t", linkp->ll_link); if (!persist) { + char zname[ZONENAME_MAX]; /* - * We store the linkid in the active database so that dlmgmtd - * can recover in the event that it is restarted. + * We store the linkid and the zone name in the active database + * so that dlmgmtd can recover in the event that it is + * restarted. */ u64 = linkp->ll_linkid; ptr += write_uint64(ptr, BUFLEN(lim, ptr), "linkid", &u64); + + if (getzonenamebyid(linkp->ll_zoneid, zname, + sizeof (zname)) != -1) { + ptr += write_str(ptr, BUFLEN(lim, ptr), "zone", zname); + } } u64 = linkp->ll_class; ptr += write_uint64(ptr, BUFLEN(lim, ptr), "class", &u64); @@ -1382,38 +1422,88 @@ dlmgmt_db_walk(zoneid_t zoneid, datalink_class_t class, db_walk_func_t *func) } /* + * Attempt to mitigate one of the deadlocks in the dlmgmtd architecture. + * + * dlmgmt_db_init() calls dlmgmt_process_db_req() which eventually gets to + * dlmgmt_zfop() which tries to fork, enter the zone and read the file. + * Because of the upcall architecture of dlmgmtd this can lead to deadlock + * with the following scenario: + * a) the thread preparing to fork will have acquired the malloc locks + * then attempt to suspend every thread in preparation to fork. + * b) all of the upcalls will be blocked in door_ucred() trying to malloc() + * and get the credentials of their caller. + * c) we can't suspend the in-kernel thread making the upcall. + * + * Thus, we cannot serve door requests because we're blocked in malloc() + * which fork() owns, but fork() is in turn blocked on the in-kernel thread + * making the door upcall. This is a fundamental architectural problem with + * any server handling upcalls and also trying to fork(). + * + * To minimize the chance of this deadlock occuring, we check ahead of time to + * see if the file we want to read actually exists in the zone (which it almost + * never does), so we don't need fork in that case (i.e. rarely to never). + */ +static boolean_t +zone_file_exists(char *zoneroot, char *filename) +{ + struct stat sb; + char fname[MAXPATHLEN]; + + (void) snprintf(fname, sizeof (fname), "%s/%s", zoneroot, filename); + + if (stat(fname, &sb) == -1) + return (B_FALSE); + + return (B_TRUE); +} + +/* * Initialize the datalink <link name, linkid> mapping and the link's * attributes list based on the configuration file /etc/dladm/datalink.conf * and the active configuration cache file * /etc/svc/volatile/dladm/datalink-management:default.cache. */ int -dlmgmt_db_init(zoneid_t zoneid) +dlmgmt_db_init(zoneid_t zoneid, char *zoneroot) { dlmgmt_db_req_t *req; int err; boolean_t boot = B_FALSE; + char tdir[MAXPATHLEN]; + char *path = cachefile; if ((req = dlmgmt_db_req_alloc(DLMGMT_DB_OP_READ, NULL, DATALINK_INVALID_LINKID, zoneid, DLMGMT_ACTIVE, &err)) == NULL) return (err); - if ((err = dlmgmt_process_db_req(req)) != 0) { - /* - * If we get back ENOENT, that means that the active - * configuration file doesn't exist yet, and is not an error. - * We'll create it down below after we've loaded the - * persistent configuration. - */ - if (err != ENOENT) - goto done; + /* Handle running in a non-native branded zone (i.e. has /native) */ + if (zone_file_exists(zoneroot, "/native" DLMGMT_TMPFS_DIR)) { + (void) snprintf(tdir, sizeof (tdir), "/native%s", cachefile); + path = tdir; + } + + if (zone_file_exists(zoneroot, path)) { + if ((err = dlmgmt_process_db_req(req)) != 0) { + /* + * If we get back ENOENT, that means that the active + * configuration file doesn't exist yet, and is not an + * error. We'll create it down below after we've + * loaded the persistent configuration. + */ + if (err != ENOENT) + goto done; + boot = B_TRUE; + } + } else { boot = B_TRUE; } - req->ls_flags = DLMGMT_PERSIST; - err = dlmgmt_process_db_req(req); - if (err != 0 && err != ENOENT) - goto done; + if (zone_file_exists(zoneroot, DLMGMT_PERSISTENT_DB_PATH)) { + req->ls_flags = DLMGMT_PERSIST; + err = dlmgmt_process_db_req(req); + if (err != 0 && err != ENOENT) + goto done; + } err = 0; if (rewrite_needed) { /* diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_door.c b/usr/src/cmd/dlmgmtd/dlmgmt_door.c index 11e4329669..2bebaa24c3 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_door.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_door.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Joyent, Inc. */ /* @@ -58,6 +59,7 @@ #include <libsysevent.h> #include <libdlmgmt.h> #include <librcm.h> +#include <unistd.h> #include "dlmgmt_impl.h" typedef void dlmgmt_door_handler_t(void *, void *, size_t *, zoneid_t, @@ -423,8 +425,11 @@ dlmgmt_getname(void *argp, void *retp, size_t *sz, zoneid_t zoneid, retvalp->lr_flags = linkp->ll_flags; retvalp->lr_class = linkp->ll_class; retvalp->lr_media = linkp->ll_media; + retvalp->lr_flags |= (linkp->ll_trans == B_TRUE) ? + DLMGMT_TRANSIENT : 0; } + dlmgmt_table_unlock(); retvalp->lr_err = err; } @@ -439,6 +444,10 @@ dlmgmt_getlinkid(void *argp, void *retp, size_t *sz, zoneid_t zoneid, dlmgmt_link_t *linkp; int err = 0; + /* Enable the global zone to lookup links it has given away. */ + if (zoneid == GLOBAL_ZONEID && getlinkid->ld_zoneid != -1) + zoneid = getlinkid->ld_zoneid; + /* * Hold the reader lock to access the link */ @@ -648,6 +657,7 @@ dlmgmt_remapid(void *argp, void *retp, size_t *sz, zoneid_t zoneid, if ((err = dlmgmt_checkprivs(linkp->ll_class, cred)) != 0) goto done; + if (link_by_name(remapid->ld_link, linkp->ll_zoneid) != NULL) { err = EEXIST; goto done; @@ -1232,20 +1242,34 @@ dlmgmt_setzoneid(void *argp, void *retp, size_t *sz, zoneid_t zoneid, * Before we remove the link from its current zone, make sure that * there isn't a link with the same name in the destination zone. */ - if (zoneid != GLOBAL_ZONEID && - link_by_name(linkp->ll_link, newzoneid) != NULL) { + if (link_by_name(linkp->ll_link, newzoneid) != NULL) { err = EEXIST; goto done; } if (oldzoneid != GLOBAL_ZONEID) { + if (newzoneid == GLOBAL_ZONEID && linkp->ll_onloan) { + /* + * In this case we are attempting to assign a + * loaned datalink from an NGZ to the GZ. We + * can only reassign a loaned VNIC back to the + * GZ when the zone is shutting down -- + * because otherwise the VNIC is in use by the + * zone and will be busy. Leave the VNIC + * loaned to the zone and return EBUSY to the + * caller. + */ + err = EBUSY; + goto done; + } + if (zone_remove_datalink(oldzoneid, linkid) != 0) { err = errno; dlmgmt_log(LOG_WARNING, "unable to remove link %d from " "zone %d: %s", linkid, oldzoneid, strerror(err)); goto done; } - avl_remove(&dlmgmt_loan_avl, linkp); + linkp->ll_onloan = B_FALSE; } if (newzoneid != GLOBAL_ZONEID) { @@ -1256,7 +1280,6 @@ dlmgmt_setzoneid(void *argp, void *retp, size_t *sz, zoneid_t zoneid, (void) zone_add_datalink(oldzoneid, linkid); goto done; } - avl_add(&dlmgmt_loan_avl, linkp); linkp->ll_onloan = B_TRUE; } @@ -1309,6 +1332,10 @@ dlmgmt_zonehalt(void *argp, void *retp, size_t *sz, zoneid_t zoneid, int err = 0; dlmgmt_door_zonehalt_t *zonehalt = argp; dlmgmt_zonehalt_retval_t *retvalp = retp; + static char my_pid[10]; + + if (my_pid[0] == NULL) + (void) snprintf(my_pid, sizeof (my_pid), "%d\n", getpid()); if ((err = dlmgmt_checkprivs(0, cred)) == 0) { if (zoneid != GLOBAL_ZONEID) { diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_impl.h b/usr/src/cmd/dlmgmtd/dlmgmt_impl.h index cdfd0d8a4d..c65a0438d6 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_impl.h +++ b/usr/src/cmd/dlmgmtd/dlmgmt_impl.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Joyent, Inc. */ /* @@ -60,13 +61,24 @@ typedef struct dlmgmt_link_s { datalink_class_t ll_class; uint32_t ll_media; datalink_id_t ll_linkid; + + /* + * The zone that owns the link. If this is set to the id of + * an NGZ and ll_onloan is set then the link was created and + * is owned by the GZ but is currently being loaned out to an + * NGZ. E.g., when the GZ admin creates a VNIC for exclusive + * use by an NGZ. If ll_onloan is set then ll_zoneid cannot be 0. + * + * If ll_zoneid is set to the id of an NGZ but ll_onloan is + * not set then the link was created and is owned by the NGZ. + */ zoneid_t ll_zoneid; boolean_t ll_onloan; avl_node_t ll_name_node; avl_node_t ll_id_node; - avl_node_t ll_loan_node; uint32_t ll_flags; uint32_t ll_gen; /* generation number */ + boolean_t ll_trans; /* transient link */ } dlmgmt_link_t; /* @@ -91,7 +103,6 @@ extern dladm_handle_t dld_handle; extern datalink_id_t dlmgmt_nextlinkid; extern avl_tree_t dlmgmt_name_avl; extern avl_tree_t dlmgmt_id_avl; -extern avl_tree_t dlmgmt_loan_avl; extern avl_tree_t dlmgmt_dlconf_avl; boolean_t linkattr_equal(dlmgmt_linkattr_t **, const char *, void *, @@ -138,7 +149,7 @@ void dlmgmt_handler(void *, char *, size_t, door_desc_t *, uint_t); void dlmgmt_log(int, const char *, ...); int dlmgmt_write_db_entry(const char *, dlmgmt_link_t *, uint32_t); int dlmgmt_delete_db_entry(dlmgmt_link_t *, uint32_t); -int dlmgmt_db_init(zoneid_t); +int dlmgmt_db_init(zoneid_t, char *); void dlmgmt_db_fini(zoneid_t); #ifdef __cplusplus diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_main.c b/usr/src/cmd/dlmgmtd/dlmgmt_main.c index c02610bb5f..60466fd773 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_main.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_main.c @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2016 Joyent, Inc. */ /* @@ -125,15 +126,24 @@ dlmgmt_door_fini(void) dlmgmt_door_fd = -1; } -int +static int dlmgmt_door_attach(zoneid_t zoneid, char *rootdir) { int fd; int err = 0; char doorpath[MAXPATHLEN]; + struct stat statbuf; - (void) snprintf(doorpath, sizeof (doorpath), "%s%s", rootdir, - DLMGMT_DOOR); + /* Handle running in a non-native branded zone (i.e. has /native) */ + (void) snprintf(doorpath, sizeof (doorpath), "%s/native%s", + rootdir, DLMGMT_TMPFS_DIR); + if (stat(doorpath, &statbuf) == 0) { + (void) snprintf(doorpath, sizeof (doorpath), "%s/native%s", + rootdir, DLMGMT_DOOR); + } else { + (void) snprintf(doorpath, sizeof (doorpath), "%s%s", + rootdir, DLMGMT_DOOR); + } /* * Create the door file for dlmgmtd. @@ -192,8 +202,16 @@ dlmgmt_zone_init(zoneid_t zoneid) (void) snprintf(tmpfsdir, sizeof (tmpfsdir), "%s%s", rootdir, DLMGMT_TMPFS_DIR); if (stat(tmpfsdir, &statbuf) < 0) { - if (mkdir(tmpfsdir, (mode_t)0755) < 0) - return (errno); + if (mkdir(tmpfsdir, (mode_t)0755) < 0) { + /* + * Handle running in a non-native branded zone + * (i.e. has /native) + */ + (void) snprintf(tmpfsdir, sizeof (tmpfsdir), + "%s/native%s", rootdir, DLMGMT_TMPFS_DIR); + if (mkdir(tmpfsdir, (mode_t)0755) < 0) + return (errno); + } } else if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { return (ENOTDIR); } @@ -203,7 +221,7 @@ dlmgmt_zone_init(zoneid_t zoneid) return (EPERM); } - if ((err = dlmgmt_db_init(zoneid)) != 0) + if ((err = dlmgmt_db_init(zoneid, rootdir)) != 0) return (err); return (dlmgmt_door_attach(zoneid, rootdir)); } @@ -214,7 +232,7 @@ dlmgmt_zone_init(zoneid_t zoneid) static int dlmgmt_allzones_init(void) { - int err, i; + int i; zoneid_t *zids = NULL; uint_t nzids, nzids_saved; @@ -235,11 +253,37 @@ again: } for (i = 0; i < nzids; i++) { - if ((err = dlmgmt_zone_init(zids[i])) != 0) - break; + int res; + zone_status_t status; + + /* + * Skip over zones that have gone away or are going down + * since we got the list. Process all zones in the list, + * logging errors for any that failed. + */ + if (zone_getattr(zids[i], ZONE_ATTR_STATUS, &status, + sizeof (status)) < 0) + continue; + switch (status) { + case ZONE_IS_SHUTTING_DOWN: + case ZONE_IS_EMPTY: + case ZONE_IS_DOWN: + case ZONE_IS_DYING: + case ZONE_IS_DEAD: + /* FALLTHRU */ + continue; + default: + break; + } + if ((res = dlmgmt_zone_init(zids[i])) != 0) { + (void) fprintf(stderr, "zone (%ld) init error %s", + zids[i], strerror(res)); + dlmgmt_log(LOG_ERR, "zone (%d) init error %s", + zids[i], strerror(res)); + } } free(zids); - return (err); + return (0); } static int diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_util.c b/usr/src/cmd/dlmgmtd/dlmgmt_util.c index afcfbed37b..c8ba0009a0 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_util.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_util.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Joyent, Inc. */ /* @@ -45,13 +46,10 @@ /* * There are three datalink AVL tables. The dlmgmt_name_avl tree contains all * datalinks and is keyed by zoneid and link name. The dlmgmt_id_avl also - * contains all datalinks, and it is keyed by link ID. The dlmgmt_loan_avl is - * keyed by link name, and contains the set of global-zone links that are - * currently on loan to non-global zones. + * contains all datalinks, and it is keyed by link ID. */ avl_tree_t dlmgmt_name_avl; avl_tree_t dlmgmt_id_avl; -avl_tree_t dlmgmt_loan_avl; avl_tree_t dlmgmt_dlconf_avl; @@ -162,8 +160,6 @@ dlmgmt_linktable_init(void) offsetof(dlmgmt_link_t, ll_name_node)); avl_create(&dlmgmt_id_avl, cmp_link_by_id, sizeof (dlmgmt_link_t), offsetof(dlmgmt_link_t, ll_id_node)); - avl_create(&dlmgmt_loan_avl, cmp_link_by_name, sizeof (dlmgmt_link_t), - offsetof(dlmgmt_link_t, ll_loan_node)); avl_create(&dlmgmt_dlconf_avl, cmp_dlconf_by_id, sizeof (dlmgmt_dlconf_t), offsetof(dlmgmt_dlconf_t, ld_node)); dlmgmt_nextlinkid = 1; @@ -181,7 +177,6 @@ dlmgmt_linktable_fini(void) avl_destroy(&dlmgmt_dlconf_avl); avl_destroy(&dlmgmt_name_avl); - avl_destroy(&dlmgmt_loan_avl); avl_destroy(&dlmgmt_id_avl); } @@ -359,9 +354,9 @@ link_destroy(dlmgmt_link_t *linkp) } /* - * Set the DLMGMT_ACTIVE flag on the link to note that it is active. When a - * link becomes active and it belongs to a non-global zone, it is also added - * to that zone. + * Set the DLMGMT_ACTIVE flag on the link to note that it is active. + * When a link is active and is owned by an NGZ then it is added to + * that zone's datalink list. */ int link_activate(dlmgmt_link_t *linkp) @@ -369,27 +364,75 @@ link_activate(dlmgmt_link_t *linkp) int err = 0; zoneid_t zoneid = ALL_ZONES; + /* + * If zone_check_datalink() returns 0 it means we found the + * link in one of the NGZ's datalink lists. Otherwise the link + * is under the GZ. + */ if (zone_check_datalink(&zoneid, linkp->ll_linkid) == 0) { /* - * This link was already added to a non-global zone. This can - * happen if dlmgmtd is restarted. + * This is a bit subtle. If the following expression + * is true then the link was found in one of the NGZ's + * datalink lists but the link structure has it under + * the GZ. This means that the link is supposed to be + * loaned out to an NGZ but the dlmgmtd state is out + * of sync -- possibly due to the process restarting. + * In this case we need to sync the dlmgmtd state by + * marking it as on-loan to the NGZ it's currently + * under. */ if (zoneid != linkp->ll_zoneid) { + assert(linkp->ll_zoneid == 0); + assert(linkp->ll_onloan == B_FALSE); + + /* + * If dlmgmtd already has a link with this + * name under the NGZ then we have a problem. + */ if (link_by_name(linkp->ll_link, zoneid) != NULL) { err = EEXIST; goto done; } + /* + * Remove the current linkp entry from the + * list because it's under the wrong zoneid. + * We don't have to update the dlmgmt_id_avl + * because it compares entries by ll_linkid + * only. + */ if (avl_find(&dlmgmt_name_avl, linkp, NULL) != NULL) avl_remove(&dlmgmt_name_avl, linkp); + /* + * Update the link to reflect the fact that + * it's on-loan to an NGZ and re-add it to the + * list. + */ linkp->ll_zoneid = zoneid; avl_add(&dlmgmt_name_avl, linkp); - avl_add(&dlmgmt_loan_avl, linkp); linkp->ll_onloan = B_TRUE; + + /* + * When a VNIC is not persistent and loaned to + * a zone it is considered transient. This is + * the same logic found in do_create_vnic() + * and is needed here in the event of a + * dlmgmtd restart. + */ + if (linkp->ll_class == DATALINK_CLASS_VNIC && + !(linkp->ll_flags & DLMGMT_PERSIST)) + linkp->ll_trans = B_TRUE; } } else if (linkp->ll_zoneid != GLOBAL_ZONEID) { + /* + * In this case the link was not found under any NGZs + * but according to its ll_zoneid member it is owned + * by an NGZ. Add the datalink to the appropriate zone + * datalink list. + */ err = zone_add_datalink(linkp->ll_zoneid, linkp->ll_linkid); + assert(linkp->ll_onloan == B_FALSE); } done: if (err == 0) @@ -430,10 +473,6 @@ link_by_name(const char *name, zoneid_t zoneid) (void) strlcpy(link.ll_link, name, MAXLINKNAMELEN); link.ll_zoneid = zoneid; linkp = avl_find(&dlmgmt_name_avl, &link, NULL); - if (linkp == NULL && zoneid == GLOBAL_ZONEID) { - /* The link could be on loan to a non-global zone? */ - linkp = avl_find(&dlmgmt_loan_avl, &link, NULL); - } return (linkp); } @@ -449,6 +488,10 @@ dlmgmt_create_common(const char *name, datalink_class_t class, uint32_t media, return (EINVAL); if (dlmgmt_nextlinkid == DATALINK_INVALID_LINKID) return (ENOSPC); + if (flags & ~(DLMGMT_ACTIVE | DLMGMT_PERSIST | DLMGMT_TRANSIENT) || + ((flags & DLMGMT_PERSIST) && (flags & DLMGMT_TRANSIENT)) || + flags == 0) + return (EINVAL); if ((linkp = calloc(1, sizeof (dlmgmt_link_t))) == NULL) { err = ENOMEM; @@ -462,6 +505,15 @@ dlmgmt_create_common(const char *name, datalink_class_t class, uint32_t media, linkp->ll_zoneid = zoneid; linkp->ll_gen = 0; + /* + * While DLMGMT_TRANSIENT starts off as a flag it is converted + * into a link field since it is really a substate of + * DLMGMT_ACTIVE -- it should not survive as a flag beyond + * this point. + */ + linkp->ll_trans = (flags & DLMGMT_TRANSIENT) ? B_TRUE : B_FALSE; + flags &= ~DLMGMT_TRANSIENT; + if (avl_find(&dlmgmt_name_avl, linkp, &name_where) != NULL || avl_find(&dlmgmt_id_avl, linkp, &id_where) != NULL) { err = EEXIST; @@ -490,6 +542,12 @@ done: int dlmgmt_destroy_common(dlmgmt_link_t *linkp, uint32_t flags) { + /* + * After dlmgmt_create_common() the link flags should only + * ever include ACTIVE or PERSIST. + */ + assert((linkp->ll_flags & ~(DLMGMT_ACTIVE | DLMGMT_PERSIST)) == 0); + if ((linkp->ll_flags & flags) == 0) { /* * The link does not exist in the specified space. @@ -511,8 +569,6 @@ dlmgmt_destroy_common(dlmgmt_link_t *linkp, uint32_t flags) if ((flags & DLMGMT_ACTIVE) && linkp->ll_zoneid != GLOBAL_ZONEID) { (void) zone_remove_datalink(linkp->ll_zoneid, linkp->ll_linkid); - if (linkp->ll_onloan) - avl_remove(&dlmgmt_loan_avl, linkp); } if (linkp->ll_flags == 0) { diff --git a/usr/src/cmd/dlstat/dlstat.c b/usr/src/cmd/dlstat/dlstat.c index 63e844a895..8c1749475b 100644 --- a/usr/src/cmd/dlstat/dlstat.c +++ b/usr/src/cmd/dlstat/dlstat.c @@ -66,7 +66,7 @@ typedef struct link_chain_s { struct link_chain_s *lc_next; } link_chain_t; -typedef void * (*stats2str_t)(const char *, void *, +typedef void * (*stats2str_t)(const char *, const char *, void *, char, boolean_t); typedef struct show_state { @@ -143,6 +143,7 @@ typedef struct total_fields_buf_s { char t_rbytes[MAXSTATLEN]; char t_opackets[MAXSTATLEN]; char t_obytes[MAXSTATLEN]; + char t_zone[ZONENAME_MAX]; } total_fields_buf_t; static ofmt_field_t total_s_fields[] = { @@ -156,6 +157,8 @@ static ofmt_field_t total_s_fields[] = { offsetof(total_fields_buf_t, t_opackets), print_default_cb}, { "OBYTES", 8, offsetof(total_fields_buf_t, t_obytes), print_default_cb}, +{ "ZONE", 20, + offsetof(total_fields_buf_t, t_zone), print_default_cb}, { NULL, 0, 0, NULL}}; /* @@ -959,8 +962,8 @@ cleanup_removed_links(show_state_t *state) } void * -print_total_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_total_stats(const char *linkname, const char *zonename, void *statentry, + char unit, boolean_t parsable) { total_stat_entry_t *sentry = statentry; total_stat_t *link_stats = &sentry->tse_stats; @@ -972,6 +975,7 @@ print_total_stats(const char *linkname, void *statentry, char unit, (void) snprintf(buf->t_linkname, sizeof (buf->t_linkname), "%s", linkname); + (void) snprintf(buf->t_zone, sizeof (buf->t_zone), "%s", zonename); map_to_units(buf->t_ipackets, sizeof (buf->t_ipackets), link_stats->ts_ipackets, unit, parsable); @@ -990,8 +994,8 @@ done: } void * -print_rx_generic_ring_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_rx_generic_ring_stats(const char *linkname, const char *zonename, + void *statentry, char unit, boolean_t parsable) { ring_stat_entry_t *sentry = statentry; ring_stat_t *link_stats = &sentry->re_stats; @@ -1024,8 +1028,8 @@ done: } void * -print_tx_generic_ring_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_tx_generic_ring_stats(const char *linkname, const char *zonename, + void *statentry, char unit, boolean_t parsable) { ring_stat_entry_t *sentry = statentry; ring_stat_t *link_stats = &sentry->re_stats; @@ -1058,8 +1062,8 @@ done: } void * -print_rx_ring_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_rx_ring_stats(const char *linkname, const char *zonename, void *statentry, + char unit, boolean_t parsable) { ring_stat_entry_t *sentry = statentry; ring_stat_t *link_stats = &sentry->re_stats; @@ -1092,8 +1096,8 @@ done: } void * -print_tx_ring_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_tx_ring_stats(const char *linkname, const char *zonename, void *statentry, + char unit, boolean_t parsable) { ring_stat_entry_t *sentry = statentry; ring_stat_t *link_stats = &sentry->re_stats; @@ -1126,8 +1130,8 @@ done: } void * -print_rx_generic_lane_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_rx_generic_lane_stats(const char *linkname, const char *zonename, + void *statentry, char unit, boolean_t parsable) { rx_lane_stat_entry_t *sentry = statentry; rx_lane_stat_t *link_stats = &sentry->rle_stats; @@ -1174,8 +1178,8 @@ done: } void * -print_tx_generic_lane_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_tx_generic_lane_stats(const char *linkname, const char *zonename, + void *statentry, char unit, boolean_t parsable) { tx_lane_stat_entry_t *sentry = statentry; tx_lane_stat_t *link_stats = &sentry->tle_stats; @@ -1219,8 +1223,8 @@ done: } void * -print_rx_lane_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_rx_lane_stats(const char *linkname, const char *zonename, void *statentry, + char unit, boolean_t parsable) { rx_lane_stat_entry_t *sentry = statentry; rx_lane_stat_t *link_stats = &sentry->rle_stats; @@ -1285,8 +1289,8 @@ done: } void * -print_tx_lane_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_tx_lane_stats(const char *linkname, const char *zonename, void *statentry, + char unit, boolean_t parsable) { tx_lane_stat_entry_t *sentry = statentry; tx_lane_stat_t *link_stats = &sentry->tle_stats; @@ -1340,8 +1344,8 @@ done: } void * -print_fanout_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_fanout_stats(const char *linkname, const char *zonename, void *statentry, + char unit, boolean_t parsable) { fanout_stat_entry_t *sentry = statentry; fanout_stat_t *link_stats = &sentry->fe_stats; @@ -1394,8 +1398,8 @@ done: } void * -print_aggr_port_stats(const char *linkname, void *statentry, char unit, - boolean_t parsable) +print_aggr_port_stats(const char *linkname, const char *zonename, + void *statentry, char unit, boolean_t parsable) { aggr_port_stat_entry_t *sentry = statentry; aggr_port_stat_t *link_stats = &sentry->ape_stats; @@ -1472,7 +1476,8 @@ done: void walk_dlstat_stats(show_state_t *state, const char *linkname, - dladm_stat_type_t stattype, dladm_stat_chain_t *diff_stat) + const char *zonename, dladm_stat_type_t stattype, + dladm_stat_chain_t *diff_stat) { dladm_stat_chain_t *curr; @@ -1482,7 +1487,8 @@ walk_dlstat_stats(show_state_t *state, const char *linkname, /* Format the raw numbers for printing */ fields_buf = state->ls_stats2str[stattype](linkname, - curr->dc_statentry, state->ls_unit, state->ls_parsable); + zonename, curr->dc_statentry, state->ls_unit, + state->ls_parsable); /* Print the stats */ if (fields_buf != NULL) ofmt_print(state->ls_ofmt, fields_buf); @@ -1497,12 +1503,20 @@ show_queried_stats(dladm_handle_t dh, datalink_id_t linkid, void *arg) int i; dladm_stat_chain_t *diff_stat; char linkname[DLPI_LINKNAME_MAX]; + char zonename[DLADM_PROP_VAL_MAX + 1]; + char *valptr[1]; + uint_t valcnt = 1; if (dladm_datalink_id2info(dh, linkid, NULL, NULL, NULL, linkname, DLPI_LINKNAME_MAX) != DLADM_STATUS_OK) { goto done; } + valptr[0] = zonename; + if (dladm_get_linkprop(handle, linkid, DLADM_PROP_VAL_CURRENT, "zone", + (char **)valptr, &valcnt) != 0) + zonename[0] = '\0'; + for (i = 0; i < DLADM_STAT_NUM_STATS; i++) { if (state->ls_stattype[i]) { /* @@ -1510,7 +1524,8 @@ show_queried_stats(dladm_handle_t dh, datalink_id_t linkid, void *arg) * Stats are returned as chain of raw numbers */ diff_stat = query_link_stats(handle, linkid, arg, i); - walk_dlstat_stats(state, linkname, i, diff_stat); + walk_dlstat_stats(state, linkname, zonename, i, + diff_stat); dladm_link_stat_free(diff_stat); } } @@ -1630,7 +1645,7 @@ do_show(int argc, char *argv[], const char *use) char *o_fields_str = NULL; char *total_stat_fields = - "link,ipkts,rbytes,opkts,obytes"; + "link,ipkts,rbytes,opkts,obytes,zone"; char *rx_total_stat_fields = "link,ipkts,rbytes,intrs,polls,ch<10,ch10-50,ch>50"; char *tx_total_stat_fields = diff --git a/usr/src/cmd/dtrace/demo/Makefile b/usr/src/cmd/dtrace/demo/Makefile index a75a418a96..cfb35083ee 100644 --- a/usr/src/cmd/dtrace/demo/Makefile +++ b/usr/src/cmd/dtrace/demo/Makefile @@ -21,6 +21,8 @@ # # Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. # +# Copyright (c) 2018, Joyent, Inc. +# include ../../Makefile.cmd @@ -157,11 +159,11 @@ $(ROOTDEMODIR): $(ROOTDEMODIR)/%: % $(INS.file) -$(HTMLFILES): $(DFILES) $(MKDEMO) - ./$(MKDEMO) $@ +$(HTMLFILES): $(DFILES) $(MKDEMO) + $(PERL) ./$(MKDEMO) $@ -$(DFILES): $(MKDEMO) - ./$(MKDEMO) $@ +$(DFILES): $(MKDEMO) + $(PERL) ./$(MKDEMO) $@ $(ROOTDEMOFILES): $(ROOTDEMODIR) diff --git a/usr/src/cmd/dtrace/test/README b/usr/src/cmd/dtrace/test/README index 51ab650fd7..094f70e7da 100644 --- a/usr/src/cmd/dtrace/test/README +++ b/usr/src/cmd/dtrace/test/README @@ -20,13 +20,10 @@ CDDL HEADER END Copyright 2006 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. - -ident "%Z%%M% %I% %E% SMI" +Copyright 2017 Joyent, Inc. DTrace Testing Suite The SUNWdtrt package delivers a set of test programs and D source -files into the directory /opt/SUNWdtrt. For more information see -the following web site: - - http://www.opensolaris.org/os/community/dtrace/dtest +files into the directory /opt/SUNWdtrt. To run the tests: + /opt/SUNWdtrt/bin/dtest diff --git a/usr/src/cmd/dtrace/test/cmd/jdtrace/Makefile b/usr/src/cmd/dtrace/test/cmd/jdtrace/Makefile index 66479e77bc..ee93b7a258 100644 --- a/usr/src/cmd/dtrace/test/cmd/jdtrace/Makefile +++ b/usr/src/cmd/dtrace/test/cmd/jdtrace/Makefile @@ -75,7 +75,7 @@ $(PROG): $(SRCS) $(POST_PROCESS) ; $(STRIP_STABS) JFLAGS= -g -cp $(CLASSPATH) -d $(CLASSDIR) -JFLAGS += -source 1.5 -target 1.6 -Xlint:all,-options +JFLAGS += -source 1.5 -target 1.6 -Xlint:all,-options,-path COMPILE.java=$(JAVAC) $(JFLAGS) JAVASRC= JDTrace.java Getopt.java diff --git a/usr/src/cmd/dtrace/test/cmd/scripts/dtest.pl b/usr/src/cmd/dtrace/test/cmd/scripts/dtest.pl index d6f1c8c277..e7f9189822 100644 --- a/usr/src/cmd/dtrace/test/cmd/scripts/dtest.pl +++ b/usr/src/cmd/dtrace/test/cmd/scripts/dtest.pl @@ -566,7 +566,7 @@ $defdir = -d $dt_tst ? $dt_tst : '.'; $bindir = -d $dt_bin ? $dt_bin : '.'; if (!$opt_F) { - my @dependencies = ("gcc", "make", "java", "perl"); + my @dependencies = ("gcc", "cc", "make", "java", "perl", "printenv"); for my $dep (@dependencies) { if (!inpath($dep)) { diff --git a/usr/src/cmd/dtrace/test/tst/Makefile.com b/usr/src/cmd/dtrace/test/tst/Makefile.com index 0d8fb3316c..b7100f4af5 100644 --- a/usr/src/cmd/dtrace/test/tst/Makefile.com +++ b/usr/src/cmd/dtrace/test/tst/Makefile.com @@ -113,6 +113,6 @@ scripts: FRC @cd ../cmd/scripts; pwd; $(MAKE) install dstyle: FRC - @if [ -n "$(DSRCS)" ]; then $(DSTYLE) $(DSRCS); fi + @if [ -n "$(DSRCS)" ]; then $(PERL) $(DSTYLE) $(DSRCS); fi FRC: diff --git a/usr/src/cmd/dtrace/test/tst/common/Makefile b/usr/src/cmd/dtrace/test/tst/common/Makefile index a29d774069..9ec706565a 100644 --- a/usr/src/cmd/dtrace/test/tst/common/Makefile +++ b/usr/src/cmd/dtrace/test/tst/common/Makefile @@ -149,6 +149,14 @@ usdt/tst.forker.o: usdt/forker.h usdt/forker.h: usdt/forker.d $(DTRACE) -h -s usdt/forker.d -o usdt/forker.h +ustack/tst.unpriv.exe: ustack/tst.unpriv.o ustack/unpriv_helper.o + $(LINK.c) -o ustack/tst.unpriv.exe \ + ustack/tst.unpriv.o ustack/unpriv_helper.o $(LDLIBS) + $(POST_PROCESS) ; $(STRIP_STABS) + +ustack/unpriv_helper.o: ustack/unpriv_helper.d + $(COMPILE.d) -o ustack/unpriv_helper.o -s ustack/unpriv_helper.d + usdt/tst.lazyprobe.exe: usdt/tst.lazyprobe.o usdt/lazyprobe.o $(LINK.c) -o usdt/tst.lazyprobe.exe \ usdt/tst.lazyprobe.o usdt/lazyprobe.o $(LDLIBS) diff --git a/usr/src/cmd/dtrace/test/tst/common/java_api/Makefile b/usr/src/cmd/dtrace/test/tst/common/java_api/Makefile index 43daede8e8..04e6cca7b4 100644 --- a/usr/src/cmd/dtrace/test/tst/common/java_api/Makefile +++ b/usr/src/cmd/dtrace/test/tst/common/java_api/Makefile @@ -60,7 +60,7 @@ lint: install: all $(PROTO_TEST_JAR) JFLAGS= -g -cp $(CLASSPATH) -d $(CLASSDIR) -JFLAGS += -source 1.5 -target 1.6 -Xlint:all,-options,-rawtypes +JFLAGS += -source 1.5 -target 1.6 -Xlint:all,-options,-rawtypes,-path COMPILE.java=$(JAVAC) $(JFLAGS) $(TEST_JAR): $(SRCDIR)/*.java diff --git a/usr/src/cmd/dtrace/test/tst/common/llquantize/tst.range.d b/usr/src/cmd/dtrace/test/tst/common/llquantize/tst.range.d index e2882b3f8e..a9138d2f54 100644 --- a/usr/src/cmd/dtrace/test/tst/common/llquantize/tst.range.d +++ b/usr/src/cmd/dtrace/test/tst/common/llquantize/tst.range.d @@ -19,10 +19,6 @@ * CDDL HEADER END */ -/* - * Copyright (c) 2011, Joyent, Inc. All rights reserved. - */ - #pragma D option quiet BEGIN diff --git a/usr/src/cmd/dtrace/test/tst/common/mdb/tst.postmort.ksh b/usr/src/cmd/dtrace/test/tst/common/mdb/tst.postmort.ksh new file mode 100644 index 0000000000..c5921b8d28 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/mdb/tst.postmort.ksh @@ -0,0 +1,69 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2011, Joyent, Inc. All rights reserved. +# + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +dtrace=$1 +DIR=/var/tmp/dtest.$$ + +mkdir $DIR +cd $DIR + +expected=`od -t u8 -N 8 /dev/urandom | head -1 | cut -d ' ' -f2` + +$dtrace -x bufpolicy=ring -x bufsize=10k -qs /dev/stdin > /dev/null 2>&1 <<EOF & + tick-1ms + /i < 10000/ + { + printf("%d: expected is $expected!\n", i++); + } + + tick-1ms + /i >= 10000/ + { + exit(0); + } +EOF + +background=$! + +# +# Give some time for the enabling to get there... +# +sleep 2 + +echo "::walk dtrace_state | ::dtrace" | mdb -k | tee test.out +grep "expected is $expected" test.out 2> /dev/null 1>&2 +status=$? + +kill $background + +cd / +/usr/bin/rm -rf $DIR + +exit $status diff --git a/usr/src/cmd/dtrace/test/tst/common/ustack/tst.unpriv.c b/usr/src/cmd/dtrace/test/tst/common/ustack/tst.unpriv.c new file mode 100644 index 0000000000..43ba244444 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/ustack/tst.unpriv.c @@ -0,0 +1,7 @@ +int +main(int argc, char *argv[]) +{ + for (;;) + ; + return (0); +} diff --git a/usr/src/cmd/dtrace/test/tst/common/ustack/tst.unpriv.ksh b/usr/src/cmd/dtrace/test/tst/common/ustack/tst.unpriv.ksh new file mode 100644 index 0000000000..26c430bff7 --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/ustack/tst.unpriv.ksh @@ -0,0 +1,68 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright (c) 2011, Joyent, Inc. All rights reserved. +# + +ppriv -s A=basic,dtrace_user,dtrace_proc $$ + +if [ $# != 1 ]; then + echo expected one argument: '<'dtrace-path'>' + exit 2 +fi + +file=out.$$ +dtrace=$1 + +rm -f $file + +dir=`/bin/dirname $tst` + +$dtrace -o $file -c $dir/tst.unpriv.exe -ws /dev/stdin <<EOF + profile-1234hz + /pid == \$target/ + { + @[ustack(20, 8192)] = count(); + } + + tick-1s + { + secs++; + } + + tick-1s + /secs > 10/ + { + trace("test timed out"); + exit(1); + } + + profile-1234hz + /pid == \$target && secs > 5/ + { + raise(SIGINT); + exit(0); + } +EOF + +status=$? +exit $status diff --git a/usr/src/cmd/dtrace/test/tst/common/ustack/unpriv_helper.d b/usr/src/cmd/dtrace/test/tst/common/ustack/unpriv_helper.d new file mode 100644 index 0000000000..eb7b0e9e9d --- /dev/null +++ b/usr/src/cmd/dtrace/test/tst/common/ustack/unpriv_helper.d @@ -0,0 +1,4 @@ +dtrace:helper:ustack: +{ + this->otherstr = "doogle"; +} diff --git a/usr/src/cmd/flowadm/flowadm.c b/usr/src/cmd/flowadm/flowadm.c index 058c1e03d8..a1f1c7387e 100644 --- a/usr/src/cmd/flowadm/flowadm.c +++ b/usr/src/cmd/flowadm/flowadm.c @@ -236,9 +236,9 @@ usage(void) (void) fprintf(stderr, gettext("usage: flowadm <subcommand>" " <args>...\n" " add-flow [-t] -l <link> -a <attr>=<value>[,...]\n" - "\t\t [-p <prop>=<value>,...] <flow>\n" - " remove-flow [-t] {-l <link> | <flow>}\n" - " show-flow [-p] [-l <link>] " + "\t\t [-p <prop>=<value>,...] [-z zonename] <flow>\n" + " remove-flow [-t] [-z zonename] {-l <link> | <flow>}\n" + " show-flow [-p] [-l <link>] [-z zonename] " "[<flow>]\n\n" " set-flowprop [-t] -p <prop>=<value>[,...] <flow>\n" " reset-flowprop [-t] [-p <prop>,...] <flow>\n" @@ -336,11 +336,12 @@ do_add_flow(int argc, char *argv[]) dladm_arg_list_t *proplist = NULL; dladm_arg_list_t *attrlist = NULL; dladm_status_t status; + char *zonename = NULL; bzero(propstr, DLADM_STRSIZE); bzero(attrstr, DLADM_STRSIZE); - while ((option = getopt_long(argc, argv, "tR:l:a:p:", + while ((option = getopt_long(argc, argv, "tR:l:a:p:z:", prop_longopts, NULL)) != -1) { switch (option) { case 't': @@ -354,9 +355,6 @@ do_add_flow(int argc, char *argv[]) MAXLINKNAMELEN) >= MAXLINKNAMELEN) { die("link name too long"); } - if (dladm_name2info(handle, devname, &linkid, NULL, - NULL, NULL) != DLADM_STATUS_OK) - die("invalid link '%s'", devname); l_arg = B_TRUE; break; case 'a': @@ -371,6 +369,9 @@ do_add_flow(int argc, char *argv[]) DLADM_STRSIZE) die("property list too long '%s'", propstr); break; + case 'z': + zonename = optarg; + break; default: die_opterr(optopt, option); } @@ -379,6 +380,10 @@ do_add_flow(int argc, char *argv[]) die("link is required"); } + if (dladm_zname2info(handle, zonename, devname, &linkid, NULL, + NULL, NULL) != DLADM_STATUS_OK) + die("invalid link '%s'", devname); + opterr = 0; index = optind; @@ -417,11 +422,12 @@ do_remove_flow(int argc, char *argv[]) boolean_t l_arg = B_FALSE; remove_flow_state_t state; dladm_status_t status; + char *zonename = NULL; bzero(&state, sizeof (state)); opterr = 0; - while ((option = getopt_long(argc, argv, ":tR:l:", + while ((option = getopt_long(argc, argv, ":tR:l:z:", longopts, NULL)) != -1) { switch (option) { case 't': @@ -435,12 +441,11 @@ do_remove_flow(int argc, char *argv[]) MAXLINKNAMELEN) >= MAXLINKNAMELEN) { die("link name too long"); } - if (dladm_name2info(handle, linkname, &linkid, NULL, - NULL, NULL) != DLADM_STATUS_OK) { - die("invalid link '%s'", linkname); - } l_arg = B_TRUE; break; + case 'z': + zonename = optarg; + break; default: die_opterr(optopt, option); break; @@ -461,6 +466,12 @@ do_remove_flow(int argc, char *argv[]) /* if link is specified then flow name should not be there */ if (optind == argc-1) usage(); + + if (dladm_zname2info(handle, zonename, linkname, &linkid, NULL, + NULL, NULL) != DLADM_STATUS_OK) { + die("invalid link '%s'", linkname); + } + /* walk the link to find flows and remove them */ state.fs_tempop = t_arg; state.fs_altroot = altroot; @@ -600,11 +611,12 @@ do_show_flow(int argc, char *argv[]) ofmt_handle_t ofmt; ofmt_status_t oferr; uint_t ofmtflags = 0; + char *zonename = NULL; bzero(&state, sizeof (state)); opterr = 0; - while ((option = getopt_long(argc, argv, ":pPl:o:", + while ((option = getopt_long(argc, argv, ":pPl:o:z:", longopts, NULL)) != -1) { switch (option) { case 'p': @@ -625,17 +637,23 @@ do_show_flow(int argc, char *argv[]) if (strlcpy(linkname, optarg, MAXLINKNAMELEN) >= MAXLINKNAMELEN) die("link name too long\n"); - if (dladm_name2info(handle, linkname, &linkid, NULL, - NULL, NULL) != DLADM_STATUS_OK) - die("invalid link '%s'", linkname); l_arg = B_TRUE; break; + case 'z': + zonename = optarg; + break; default: die_opterr(optopt, option); break; } } + if (l_arg) { + if (dladm_zname2info(handle, zonename, linkname, &linkid, NULL, + NULL, NULL) != DLADM_STATUS_OK) + die("invalid link '%s'", linkname); + } + /* get flow name (optional last argument */ if (optind == (argc-1)) { if (strlcpy(flowname, argv[optind], MAXFLOWNAMELEN) diff --git a/usr/src/cmd/flowstat/flowstat.c b/usr/src/cmd/flowstat/flowstat.c index edfc844a94..e772470f9d 100644 --- a/usr/src/cmd/flowstat/flowstat.c +++ b/usr/src/cmd/flowstat/flowstat.c @@ -197,9 +197,9 @@ static char *progname; static dladm_handle_t handle = NULL; const char *usage_ermsg = "flowstat [-r | -t] [-i interval] " - "[-l link] [flow]\n" + "[-l link] [-z zonename] [flow]\n" " flowstat [-A] [-i interval] [-p] [ -o field[,...]]\n" - " [-u R|K|M|G|T|P] [-l link] [flow]\n" + " [-u R|K|M|G|T|P] [-l link] [-z zonename] [flow]\n" " flowstat -h [-a] [-d] [-F format]" " [-s <DD/MM/YYYY,HH:MM:SS>]\n" " [-e <DD/MM/YYYY,HH:MM:SS>] -f <logfile> " @@ -562,6 +562,7 @@ main(int argc, char *argv[]) show_flow_state_t state; char *fields_str = NULL; char *o_fields_str = NULL; + char *zonename = NULL; char *total_stat_fields = "flow,ipkts,rbytes,ierrs,opkts,obytes,oerrs"; @@ -588,10 +589,11 @@ main(int argc, char *argv[]) if ((status = dladm_open(&handle)) != DLADM_STATUS_OK) die_dlerr(status, "could not open /dev/dld"); + linkname[0] = '\0'; bzero(&state, sizeof (state)); opterr = 0; - while ((option = getopt_long(argc, argv, ":rtApi:o:u:l:h", + while ((option = getopt_long(argc, argv, ":rtApi:o:u:l:hz:", NULL, NULL)) != -1) { switch (option) { case 'r': @@ -643,9 +645,6 @@ main(int argc, char *argv[]) if (strlcpy(linkname, optarg, MAXLINKNAMELEN) >= MAXLINKNAMELEN) die("link name too long\n"); - if (dladm_name2info(handle, linkname, &linkid, NULL, - NULL, NULL) != DLADM_STATUS_OK) - die("invalid link '%s'", linkname); break; case 'h': if (r_arg || t_arg || p_arg || o_arg || u_arg || @@ -656,6 +655,9 @@ main(int argc, char *argv[]) do_show_history(argc, argv); return (0); break; + case 'z': + zonename = optarg; + break; default: die_opterr(optopt, option, usage_ermsg); break; @@ -679,6 +681,12 @@ main(int argc, char *argv[]) die("the option -A is not compatible with " "-r, -t, -p, -o, -u, -i"); + if (linkname[0] != '\0') { + if (dladm_zname2info(handle, zonename, linkname, &linkid, NULL, + NULL, NULL) != DLADM_STATUS_OK) + die("invalid link '%s'", linkname); + } + /* get flow name (optional last argument) */ if (optind == (argc-1)) { if (strlcpy(flowname, argv[optind], MAXFLOWNAMELEN) diff --git a/usr/src/cmd/fm/fmdump/common/nvlrender.c b/usr/src/cmd/fm/fmdump/common/nvlrender.c index 2c2f5ca662..99f027a77d 100644 --- a/usr/src/cmd/fm/fmdump/common/nvlrender.c +++ b/usr/src/cmd/fm/fmdump/common/nvlrender.c @@ -83,7 +83,7 @@ fmdump_render_nvlist(nvlist_prtctl_t pctl, void *private, nvlist_t *nvl, int fmdump_print_json(fmd_log_t *lp, const fmd_log_record_t *rp, FILE *fp) { - if (nvlist_print_json(fp, rp->rec_nvl) != 0 || fprintf(fp, "\n") < 0 || + if (nvlist_print_json(fp, rp->rec_nvl) < 0 || fprintf(fp, "\n") < 0 || fflush(fp) != 0) return (-1); diff --git a/usr/src/cmd/fm/fmtopo/common/fmtopo.c b/usr/src/cmd/fm/fmtopo/common/fmtopo.c index 07fe40fafd..fb27c6c13f 100644 --- a/usr/src/cmd/fm/fmtopo/common/fmtopo.c +++ b/usr/src/cmd/fm/fmtopo/common/fmtopo.c @@ -89,7 +89,7 @@ usage(FILE *fp) "\t-p display of FMRI protocol properties\n" "\t-R set root directory for libtopo plug-ins and other files\n" "\t-s display topology for the specified FMRI scheme\n" - "\t-S display FMRI status (present/usable)\n" + "\t-S display FMRI status (present/usable/occupied)\n" "\t-V set verbose mode\n" "\t-x display a xml formatted topology\n"); @@ -127,6 +127,7 @@ static void print_node(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl, const char *fmri) { int err, ret; + boolean_t is_occupied; (void) printf("%s\n", (char *)fmri); @@ -174,6 +175,13 @@ print_node(topo_hdl_t *thp, tnode_t *node, nvlist_t *nvl, const char *fmri) else (void) printf("\tUnusable: %s\n", ret ? "true" : "false"); + + ret = topo_node_occupied(node, &is_occupied); + if (ret == 0) + (void) printf("\tOccupied: %s\n", + is_occupied ? "true" : "false"); + else if (ret != ETOPO_METHOD_NOTSUP) + (void) printf("\tOccupied: -\n"); } } diff --git a/usr/src/cmd/fm/modules/common/zfs-diagnosis/zfs_de.c b/usr/src/cmd/fm/modules/common/zfs-diagnosis/zfs_de.c index d1206a34d3..5295c012bc 100644 --- a/usr/src/cmd/fm/modules/common/zfs-diagnosis/zfs_de.c +++ b/usr/src/cmd/fm/modules/common/zfs-diagnosis/zfs_de.c @@ -22,6 +22,7 @@ /* * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2019 Joyent, Inc. */ #include <assert.h> @@ -38,9 +39,9 @@ #include <sys/fm/fs/zfs.h> /* - * Our serd engines are named 'zfs_<pool_guid>_<vdev_guid>_{checksum,io}'. This - * #define reserves enough space for two 64-bit hex values plus the length of - * the longest string. + * Our serd engines are named 'zfs_<pool_guid>_<vdev_guid>_{checksum,io,probe}'. + * This #define reserves enough space for two 64-bit hex values plus the length + * of the longest string. */ #define MAX_SERDLEN (16 * 2 + sizeof ("zfs___checksum")) @@ -58,6 +59,7 @@ typedef struct zfs_case_data { int zc_pool_state; char zc_serd_checksum[MAX_SERDLEN]; char zc_serd_io[MAX_SERDLEN]; + char zc_serd_probe[MAX_SERDLEN]; int zc_has_remove_timer; } zfs_case_data_t; @@ -370,8 +372,8 @@ zfs_purge_cases(fmd_hdl_t *hdl) } /* - * Construct the name of a serd engine given the pool/vdev GUID and type (io or - * checksum). + * Construct the name of a serd engine given the pool/vdev GUID and type (io, + * checksum, or probe). */ static void zfs_serd_name(char *buf, uint64_t pool_guid, uint64_t vdev_guid, @@ -627,7 +629,8 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class) pool_found = B_TRUE; pool_load = zcp->zc_when; } - if (zcp->zc_data.zc_vdev_guid == vdev_guid) + if (zcp->zc_data.zc_vdev_guid == vdev_guid && + zcp->zc_data.zc_pool_guid == pool_guid) break; } @@ -775,6 +778,8 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class) if (zcp->zc_data.zc_serd_checksum[0] != '\0') fmd_serd_reset(hdl, zcp->zc_data.zc_serd_checksum); + if (zcp->zc_data.zc_serd_probe[0] != '\0') + fmd_serd_reset(hdl, zcp->zc_data.zc_serd_probe); } zfs_stats.resource_drops.fmds_value.ui64++; return; @@ -843,8 +848,8 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class) boolean_t checkremove = B_FALSE; /* - * If this is a checksum or I/O error, then toss it into the - * appropriate SERD engine and check to see if it has fired. + * If this is a checksum, I/O, or probe error, then toss it into + * the appropriate SERD engine and check to see if it has fired. * Ideally, we want to do something more sophisticated, * (persistent errors for a single data block, etc). For now, * a single SERD engine is sufficient. @@ -894,7 +899,18 @@ zfs_fm_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class) } } else if (fmd_nvl_class_match(hdl, nvl, ZFS_MAKE_EREPORT(FM_EREPORT_ZFS_PROBE_FAILURE))) { - checkremove = B_TRUE; + if (zcp->zc_data.zc_serd_probe[0] == '\0') { + zfs_serd_name(zcp->zc_data.zc_serd_probe, + pool_guid, vdev_guid, "probe"); + fmd_serd_create(hdl, zcp->zc_data.zc_serd_probe, + fmd_prop_get_int32(hdl, "probe_N"), + fmd_prop_get_int64(hdl, "probe_T")); + zfs_case_serialize(hdl, zcp); + } + if (fmd_serd_record(hdl, + zcp->zc_data.zc_serd_probe, ep)) { + checkremove = B_TRUE; + } } /* @@ -938,6 +954,8 @@ zfs_fm_close(fmd_hdl_t *hdl, fmd_case_t *cs) fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_checksum); if (zcp->zc_data.zc_serd_io[0] != '\0') fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_io); + if (zcp->zc_data.zc_serd_probe[0] != '\0') + fmd_serd_destroy(hdl, zcp->zc_data.zc_serd_probe); if (zcp->zc_data.zc_has_remove_timer) fmd_timer_remove(hdl, zcp->zc_remove_timer); uu_list_remove(zfs_cases, zcp); @@ -967,6 +985,8 @@ static const fmd_prop_t fmd_props[] = { { "checksum_T", FMD_TYPE_TIME, "10min" }, { "io_N", FMD_TYPE_UINT32, "10" }, { "io_T", FMD_TYPE_TIME, "10min" }, + { "probe_N", FMD_TYPE_UINT32, "5" }, + { "probe_T", FMD_TYPE_TIME, "24hour" }, { "remove_timeout", FMD_TYPE_TIME, "15sec" }, { NULL, 0, NULL } }; diff --git a/usr/src/cmd/fm/modules/common/zfs-retire/zfs_retire.c b/usr/src/cmd/fm/modules/common/zfs-retire/zfs_retire.c index 4856676d7d..e2d1a6831a 100644 --- a/usr/src/cmd/fm/modules/common/zfs-retire/zfs_retire.c +++ b/usr/src/cmd/fm/modules/common/zfs-retire/zfs_retire.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2019 Joyent, Inc. */ /* @@ -121,13 +122,21 @@ find_vdev(libzfs_handle_t *zhdl, nvlist_t *nv, const char *search_fru, } if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, - &child, &children) != 0) - return (NULL); + &child, &children) == 0) { + for (c = 0; c < children; c++) { + if ((ret = find_vdev(zhdl, child[c], search_fru, + search_guid)) != NULL) + return (ret); + } + } - for (c = 0; c < children; c++) { - if ((ret = find_vdev(zhdl, child[c], search_fru, - search_guid)) != NULL) - return (ret); + if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_SPARES, + &child, &children) == 0) { + for (c = 0; c < children; c++) { + if ((ret = find_vdev(zhdl, child[c], search_fru, + search_guid)) != NULL) + return (ret); + } } return (NULL); diff --git a/usr/src/cmd/fs.d/Makefile b/usr/src/cmd/fs.d/Makefile index 91f994ebb0..6e692b98cf 100644 --- a/usr/src/cmd/fs.d/Makefile +++ b/usr/src/cmd/fs.d/Makefile @@ -40,8 +40,8 @@ DEFAULTFILES= fs.dfl include ../Makefile.cmd -SUBDIR1= bootfs lofs zfs -SUBDIR2= dev fd pcfs nfs hsfs proc ctfs udfs ufs tmpfs \ +SUBDIR1= bootfs hyprlofs lofs zfs +SUBDIR2= dev fd pcfs nfs hsfs lxproc proc ctfs udfs ufs tmpfs \ autofs mntfs objfs sharefs smbclnt reparsed SUBDIRS= $(SUBDIR1) $(SUBDIR2) I18NDIRS= $(SUBDIR2) diff --git a/usr/src/cmd/fs.d/hyprlofs/Makefile b/usr/src/cmd/fs.d/hyprlofs/Makefile new file mode 100644 index 0000000000..1a3aaf18d3 --- /dev/null +++ b/usr/src/cmd/fs.d/hyprlofs/Makefile @@ -0,0 +1,42 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved +# + +SUBDIRS= hlcfg mount + +all:= TARGET= all +install:= TARGET= install +clean:= TARGET= clean +clobber:= TARGET= clobber +lint:= TARGET= lint + +.KEEP_STATE: + +.PARALLEL: $(SUBDIRS) + +all install clean clobber lint: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/cmd/fs.d/hyprlofs/hlcfg/Makefile b/usr/src/cmd/fs.d/hyprlofs/hlcfg/Makefile new file mode 100644 index 0000000000..d2ae22e9fd --- /dev/null +++ b/usr/src/cmd/fs.d/hyprlofs/hlcfg/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2012, Joyent, Inc. All rights reserved. +# + +FSTYPE= hyprlofs +LIBPROG= hlcfg + +include ../../Makefile.fstype +include ../../Makefile.mount +include ../../Makefile.mount.targ diff --git a/usr/src/cmd/fs.d/hyprlofs/hlcfg/hlcfg.c b/usr/src/cmd/fs.d/hyprlofs/hlcfg/hlcfg.c new file mode 100644 index 0000000000..16e8e32b1c --- /dev/null +++ b/usr/src/cmd/fs.d/hyprlofs/hlcfg/hlcfg.c @@ -0,0 +1,244 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2012, Joyent, Inc. All rights reserved. + */ + +/* + * This is a simple test program to exercise the hyprlofs ioctls. This is + * not designed as a full featured CLI and only does minimal error checking + * and reporting. + */ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <libgen.h> +#include <strings.h> +#include <sys/errno.h> +#include <sys/fs/hyprlofs.h> + +extern int errno; + +char *usage = "usage: <fs path> add [<file name> <alias>]+\n" + " <fs path> addl [<file name>]+\n" + " <fs path> rm [<alias>]+\n" + " <fs path> clear" + " <fs path> get"; + +typedef enum { + CMD_ADD, + CMD_RM, + CMD_CLR, + CMD_ADDL, + CMD_GET +} cmd_t; + +static int +get_entries(int fd) +{ + int err; + int i; + hyprlofs_curr_entries_t e; + hyprlofs_curr_entry_t *ep; + + e.hce_cnt = 0; + e.hce_entries = NULL; + + err = ioctl(fd, HYPRLOFS_GET_ENTRIES, &e); + if (err != 0 && errno != E2BIG) { + perror("ioctl"); + return (1); + } + + if (err == 0) { + (void) printf("success, but no entries\n"); + return (0); + } + + /* + * E2BIG is what we expect when there are existing mappings + * since the current cnt is still returned in that case. + */ + (void) printf("cnt: %d\n", e.hce_cnt); + + /* alloc array and call again, then print array */ + if ((ep = (hyprlofs_curr_entry_t *) + malloc(sizeof (hyprlofs_curr_entry_t) * e.hce_cnt)) == NULL) { + (void) fprintf(stderr, "out of memory\n"); + exit(1); + } + + e.hce_entries = ep; + errno = 0; + if (ioctl(fd, HYPRLOFS_GET_ENTRIES, &e) != 0) { + /* + * Not handling an increase here. We would need to free and + * start over to do that, but ok for a test program. + */ + perror("ioctl"); + free(ep); + return (1); + } + for (i = 0; i < e.hce_cnt; i++) + (void) printf("%s %s\n", ep[i].hce_path, ep[i].hce_name); + + free(ep); + return (0); +} + +int +main(int argc, char **argv) +{ + int i, ap; + cmd_t cmd; + int cnt = 0; + int fd; + int rv = 0; + hyprlofs_entry_t *e = NULL; + hyprlofs_entries_t ents; + + if (argc < 3) { + (void) fprintf(stderr, "%s\n", usage); + exit(1); + } + + if ((fd = open(argv[1], O_RDONLY)) < 0) { + perror("can't open hyprlofs mount"); + exit(1); + } + + if (strcmp(argv[2], "add") == 0) { + cmd = CMD_ADD; + } else if (strcmp(argv[2], "rm") == 0) { + cmd = CMD_RM; + } else if (strcmp(argv[2], "clear") == 0) { + cmd = CMD_CLR; + } else if (strcmp(argv[2], "addl") == 0) { + cmd = CMD_ADDL; + } else if (strcmp(argv[2], "get") == 0) { + cmd = CMD_GET; + } else { + (void) fprintf(stderr, "%s\n", usage); + exit(1); + } + + /* Count up the number of parameters. The arg format varies w/ cmd */ + switch (cmd) { + case CMD_ADD: + for (i = 3; i < argc; i++) { + /* argv[i] is the file path */ + + /* The next arg is the alias */ + if (++i >= argc) { + (void) fprintf(stderr, "missing alias for %s\n", + argv[i - 1]); + exit(1); + } + + cnt++; + } + break; + case CMD_ADDL: + cnt = argc - 3; + break; + case CMD_RM: + cnt = argc - 3; + break; + case CMD_CLR: /*FALLTHRU*/ + case CMD_GET: + if (argc > 3) { + (void) fprintf(stderr, "%s\n", usage); + exit(1); + } + break; + } + + if (cnt > 0) { + if ((e = (hyprlofs_entry_t *)malloc(sizeof (hyprlofs_entry_t) * + cnt)) == NULL) { + (void) fprintf(stderr, "out of memory\n"); + exit(1); + } + } + + /* + * Format up the args. + * We only setup the path member for the add cmd. + * We won't run this loop for the clear cmd. + * The addl command is special since we use basename to get the alias. + */ + for (i = 0, ap = 3; i < cnt; i++, ap++) { + if (cmd == CMD_ADDL) { + e[i].hle_path = argv[ap]; + e[i].hle_plen = strlen(e[i].hle_path); + + e[i].hle_name = basename(argv[ap]); + e[i].hle_nlen = strlen(e[i].hle_name); + + continue; + } + + if (cmd == CMD_ADD) { + e[i].hle_path = argv[ap++]; + e[i].hle_plen = strlen(e[i].hle_path); + } + + e[i].hle_name = argv[ap]; + e[i].hle_nlen = strlen(e[i].hle_name); + } + + ents.hle_entries = e; + ents.hle_len = cnt; + + switch (cmd) { + case CMD_ADD: /*FALLTHRU*/ + case CMD_ADDL: + if (ioctl(fd, HYPRLOFS_ADD_ENTRIES, &ents) < 0) { + perror("ioctl"); + rv = 1; + } + break; + case CMD_RM: + if (ioctl(fd, HYPRLOFS_RM_ENTRIES, &ents) < 0) { + perror("ioctl"); + rv = 1; + } + break; + case CMD_CLR: + if (ioctl(fd, HYPRLOFS_RM_ALL) < 0) { + perror("ioctl"); + rv = 1; + } + break; + case CMD_GET: + rv = get_entries(fd); + break; + } + + (void) close(fd); + if (cnt > 0) + free(e); + return (rv); +} diff --git a/usr/src/cmd/fs.d/hyprlofs/mount/Makefile b/usr/src/cmd/fs.d/hyprlofs/mount/Makefile new file mode 100644 index 0000000000..a0b63d211c --- /dev/null +++ b/usr/src/cmd/fs.d/hyprlofs/mount/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2012 Joyent, Inc. All rights reserved. +# + +FSTYPE= hyprlofs +LIBPROG= mount + +include ../../Makefile.fstype +include ../../Makefile.mount +include ../../Makefile.mount.targ diff --git a/usr/src/cmd/fs.d/hyprlofs/mount/mount.c b/usr/src/cmd/fs.d/hyprlofs/mount/mount.c new file mode 100644 index 0000000000..a95c9ca3c2 --- /dev/null +++ b/usr/src/cmd/fs.d/hyprlofs/mount/mount.c @@ -0,0 +1,148 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * Copyright 2012 Joyent, Inc. All rights reserved. + */ + +#define HLFS +#define MNTTYPE_HYFS "hyprlofs" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <libintl.h> +#include <errno.h> +#include <sys/fstyp.h> +#include <sys/fsid.h> +#include <sys/mntent.h> +#include <sys/mnttab.h> +#include <sys/mount.h> +#include <sys/signal.h> +#include <sys/stat.h> +#include <fslib.h> + +#define RET_OK 0 +/* + * /sbin/mount and the fs-local method understand this exit code to + * mean that all the mount failures were related to hyprlofs mounts. Since + * this program only attempts to mount hyfs file systems, when it fails + * it returns this exit status. + */ +#define RET_ERR 111 + +static void usage(void); + +static char optbuf[MAX_MNTOPT_STR] = { '\0', }; +static int optsize = 0; + +static char fstype[] = MNTTYPE_HYFS; + +/* + * usage: mount [-Ormq] [-o options] special mountp + * + * This mount program is exec'ed by /usr/sbin/mount if '-F hyprlofs' is + * specified. + */ +int +main(int argc, char *argv[]) +{ + int c; + char *special; /* Entity being mounted */ + char *mountp; /* Entity being mounted on */ + char *savedoptbuf; + char *myname; + char typename[64]; + int flags = 0; + int errflag = 0; + int qflg = 0; + + myname = strrchr(argv[0], '/'); + myname = myname ? myname+1 : argv[0]; + (void) snprintf(typename, sizeof (typename), "%s %s", fstype, myname); + argv[0] = typename; + + while ((c = getopt(argc, argv, "o:rmOq")) != EOF) { + switch (c) { + case '?': + errflag++; + break; + + case 'o': + if (strlcpy(optbuf, optarg, sizeof (optbuf)) >= + sizeof (optbuf)) { + (void) fprintf(stderr, + gettext("%s: Invalid argument: %s\n"), + myname, optarg); + return (2); + } + optsize = strlen(optbuf); + break; + case 'O': + flags |= MS_OVERLAY; + break; + case 'r': + flags |= MS_RDONLY; + break; + + case 'm': + flags |= MS_NOMNTTAB; + break; + + case 'q': + qflg = 1; + break; + + default: + usage(); + } + } + if ((argc - optind != 2) || errflag) { + usage(); + } + special = argv[argc - 2]; + mountp = argv[argc - 1]; + + if ((savedoptbuf = strdup(optbuf)) == NULL) { + (void) fprintf(stderr, gettext("%s: out of memory\n"), + myname); + exit(2); + } + if (mount(special, mountp, flags | MS_OPTIONSTR, fstype, NULL, 0, + optbuf, MAX_MNTOPT_STR)) { + (void) fprintf(stderr, "mount: "); + perror(special); + exit(RET_ERR); + } + if (optsize && !qflg) + cmp_requested_to_actual_options(savedoptbuf, optbuf, + special, mountp); + return (0); +} + +void +usage(void) +{ + (void) fprintf(stderr, + "Usage: mount [-Ormq] [-o options] special mountpoint\n"); + exit(RET_ERR); +} diff --git a/usr/src/cmd/fs.d/lxproc/Makefile b/usr/src/cmd/fs.d/lxproc/Makefile new file mode 100644 index 0000000000..77075ef1dd --- /dev/null +++ b/usr/src/cmd/fs.d/lxproc/Makefile @@ -0,0 +1,32 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +FSTYPE= lxproc +LIBPROG= mount + +include ../Makefile.fstype +include ../Makefile.mount +include ../Makefile.mount.targ diff --git a/usr/src/cmd/fs.d/lxproc/mount.c b/usr/src/cmd/fs.d/lxproc/mount.c new file mode 100644 index 0000000000..5a000997bd --- /dev/null +++ b/usr/src/cmd/fs.d/lxproc/mount.c @@ -0,0 +1,140 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * Copyright 2012 Joyent, Inc. All rights reserved. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <libintl.h> +#include <errno.h> +#include <sys/fstyp.h> +#include <sys/fsid.h> +#include <sys/mntent.h> +#include <sys/mnttab.h> +#include <sys/mount.h> +#include <sys/signal.h> +#include <sys/stat.h> +#include <fslib.h> + +#define RET_OK 0 +#define RET_ERR 33 + +static void usage(void); + +static char optbuf[MAX_MNTOPT_STR] = { '\0', }; +static int optsize = 0; + +static char fstype[] = "lxproc"; + +/* + * usage: mount [-Ormq] [-o options] special mountp + * + * This mount program is exec'ed by /usr/sbin/mount if '-F lxproc' is + * specified. + */ +int +main(int argc, char *argv[]) +{ + int c; + char *special; /* Entity being mounted */ + char *mountp; /* Entity being mounted on */ + char *savedoptbuf; + char *myname; + char typename[64]; + int flags = 0; + int errflag = 0; + int qflg = 0; + + myname = strrchr(argv[0], '/'); + myname = myname ? myname+1 : argv[0]; + (void) snprintf(typename, sizeof (typename), "%s %s", fstype, myname); + argv[0] = typename; + + while ((c = getopt(argc, argv, "o:rmOq")) != EOF) { + switch (c) { + case '?': + errflag++; + break; + + case 'o': + if (strlcpy(optbuf, optarg, sizeof (optbuf)) >= + sizeof (optbuf)) { + (void) fprintf(stderr, + gettext("%s: Invalid argument: %s\n"), + myname, optarg); + return (2); + } + optsize = strlen(optbuf); + break; + case 'O': + flags |= MS_OVERLAY; + break; + case 'r': + flags |= MS_RDONLY; + break; + + case 'm': + flags |= MS_NOMNTTAB; + break; + + case 'q': + qflg = 1; + break; + + default: + usage(); + } + } + if ((argc - optind != 2) || errflag) { + usage(); + } + special = argv[argc - 2]; + mountp = argv[argc - 1]; + + if ((savedoptbuf = strdup(optbuf)) == NULL) { + (void) fprintf(stderr, gettext("%s: out of memory\n"), + myname); + exit(2); + } + if (mount(special, mountp, flags | MS_OPTIONSTR, fstype, NULL, 0, + optbuf, MAX_MNTOPT_STR)) { + (void) fprintf(stderr, "mount: "); + perror(special); + exit(RET_ERR); + } + if (optsize && !qflg) + cmp_requested_to_actual_options(savedoptbuf, optbuf, + special, mountp); + return (0); +} + +void +usage(void) +{ + (void) fprintf(stderr, + "Usage: mount [-Ormq] [-o options] special mountpoint\n"); + exit(RET_ERR); +} diff --git a/usr/src/cmd/fs.d/mount.c b/usr/src/cmd/fs.d/mount.c index 947767f5db..c048d0f2fd 100644 --- a/usr/src/cmd/fs.d/mount.c +++ b/usr/src/cmd/fs.d/mount.c @@ -21,6 +21,7 @@ /* * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2016 Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -55,6 +56,7 @@ #include <stropts.h> #include <sys/conf.h> #include <locale.h> +#include <zone.h> #include "fslib.h" #define VFS_PATH "/usr/lib/fs" @@ -801,6 +803,7 @@ mnterror(int flag) void doexec(char *fstype, char *newargv[]) { + const char *zroot = zone_get_nroot(); char full_path[PATH_MAX]; char alter_path[PATH_MAX]; char *vfs_path = VFS_PATH; @@ -808,7 +811,8 @@ doexec(char *fstype, char *newargv[]) int i; /* build the full pathname of the fstype dependent command. */ - sprintf(full_path, "%s/%s/%s", vfs_path, fstype, myname); + (void) snprintf(full_path, sizeof (full_path), "%s/%s/%s/%s", + (zroot != NULL ? zroot : ""), vfs_path, fstype, myname); sprintf(alter_path, "%s/%s/%s", alt_path, fstype, myname); newargv[1] = myname; diff --git a/usr/src/cmd/fs.d/nfs/lib/nfs_sec.c b/usr/src/cmd/fs.d/nfs/lib/nfs_sec.c index 06dc44a12c..af83923825 100644 --- a/usr/src/cmd/fs.d/nfs/lib/nfs_sec.c +++ b/usr/src/cmd/fs.d/nfs/lib/nfs_sec.c @@ -45,6 +45,7 @@ #include <stdlib.h> #include <syslog.h> #include <synch.h> +#include <zone.h> #include <rpc/rpc.h> #include <nfs/nfs_sec.h> #include <rpc/rpcsec_gss.h> @@ -707,12 +708,17 @@ get_seconfig(int whichway, char *name, int num, { char line[BUFSIZ]; /* holds each line of NFSSEC_CONF */ FILE *fp; /* file stream for NFSSEC_CONF */ + char nfssec_conf[MAXPATHLEN]; + const char *zroot = zone_get_nroot(); if ((whichway == GETBYNAME) && (name == NULL)) return (SC_NOTFOUND); + (void) snprintf(nfssec_conf, sizeof (nfssec_conf), "%s%s", zroot != NULL ? + zroot : "", NFSSEC_CONF); + (void) mutex_lock(&matching_lock); - if ((fp = fopen(NFSSEC_CONF, "r")) == NULL) { + if ((fp = fopen(nfssec_conf, "r")) == NULL) { (void) mutex_unlock(&matching_lock); return (SC_OPENFAIL); } diff --git a/usr/src/cmd/fs.d/nfs/lib/smfcfg.c b/usr/src/cmd/fs.d/nfs/lib/smfcfg.c index 892f0cd052..4f9399143c 100644 --- a/usr/src/cmd/fs.d/nfs/lib/smfcfg.c +++ b/usr/src/cmd/fs.d/nfs/lib/smfcfg.c @@ -22,6 +22,7 @@ /* * Copyright 2015 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #include <stdio.h> @@ -344,8 +345,23 @@ fs_smf_get_prop(smf_fstype_t fstype, char *prop_name, char *cbuf, } else { ret = scf_error(); } - if ((ret != 0) && scf_error() != SCF_ERROR_NONE) - fprintf(stdout, gettext("%s\n"), scf_strerror(ret)); + if ((ret != 0) && scf_error() != SCF_ERROR_NONE) { + /* + * This is a workaround for the NFS service manifests not + * containing the proper properties in local zones. + * + * When in a local zone and the property doesn't exist on an NFS + * service (most likely nfs/server or nfs/client), don't print + * the error. The caller will still see the correct error code, + * but a user creating a delegated dataset or mounting an NFS + * share won't see this spurious error. + */ + if (getzoneid() == GLOBAL_ZONEID || + scf_error() != SCF_ERROR_NOT_FOUND) { + fprintf(stdout, gettext("%s\n"), scf_strerror(ret)); + } + } + out: fs_smf_fini(phandle); return (ret); diff --git a/usr/src/cmd/fs.d/nfs/lib/smfcfg.h b/usr/src/cmd/fs.d/nfs/lib/smfcfg.h index c06327d801..f0b70907aa 100644 --- a/usr/src/cmd/fs.d/nfs/lib/smfcfg.h +++ b/usr/src/cmd/fs.d/nfs/lib/smfcfg.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #ifndef _SMFCFG_H @@ -42,6 +43,7 @@ #include <locale.h> #include <errno.h> #include <sys/types.h> +#include <zone.h> #ifdef __cplusplus extern "C" { diff --git a/usr/src/cmd/fs.d/nfs/lockd/lockd.c b/usr/src/cmd/fs.d/nfs/lockd/lockd.c index 3541ee13d0..6ea338b01a 100644 --- a/usr/src/cmd/fs.d/nfs/lockd/lockd.c +++ b/usr/src/cmd/fs.d/nfs/lockd/lockd.c @@ -23,6 +23,7 @@ * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -88,7 +89,7 @@ struct lm_svc_args lmargs = { .version = LM_SVC_CUR_VERS, /* fd, n_fmly, n_proto, n_rdev (below) */ - .debug = 0, + .n_v4_only = 0, .timout = 5 * 60, .grace = 90, .retransmittimeout = 5 @@ -137,6 +138,8 @@ int (*Mysvc)(int, struct netbuf, struct netconfig *) = nlmsvc; /* used by cots_listen_event() */ int max_conns_allowed = -1; /* used by cots_listen_event() */ +int debug = 0; + int main(int ac, char *av[]) { @@ -238,7 +241,7 @@ main(int ac, char *av[]) break; case 'd': /* debug */ - lmargs.debug = atoi(optarg); + debug = atoi(optarg); break; case 'g': /* grace_period */ @@ -288,12 +291,12 @@ main(int ac, char *av[]) if (optind != ac) usage(); - if (lmargs.debug) { + if (debug != 0) { printf("%s: debug= %d, conn_idle_timout= %d," " grace_period= %d, listen_backlog= %d," " max_connections= %d, max_servers= %d," " retrans_timeout= %d\n", - MyName, lmargs.debug, lmargs.timout, + MyName, debug, lmargs.timout, lmargs.grace, listen_backlog, max_conns_allowed, max_servers, lmargs.retransmittimeout); @@ -309,7 +312,7 @@ main(int ac, char *av[]) } /* Daemonize, if not debug. */ - if (lmargs.debug == 0) + if (debug == 0) pipe_fd = daemonize_init(); openlog(MyName, LOG_PID | LOG_NDELAY, LOG_DAEMON); @@ -405,7 +408,7 @@ main(int ac, char *av[]) /* * lockd is up and running as far as we are concerned. */ - if (lmargs.debug == 0) + if (debug == 0) daemonize_fini(pipe_fd); /* diff --git a/usr/src/cmd/fs.d/nfs/mount/Makefile b/usr/src/cmd/fs.d/nfs/mount/Makefile index f20280b634..c461949514 100644 --- a/usr/src/cmd/fs.d/nfs/mount/Makefile +++ b/usr/src/cmd/fs.d/nfs/mount/Makefile @@ -25,13 +25,6 @@ FSTYPE= nfs LIBPROG= mount -ROOTFS_PROG= $(LIBPROG) - -# duplicate ROOTLIBFSTYPE value needed for installation rule -# we must define this before including Makefile.fstype -ROOTLIBFSTYPE = $(ROOT)/usr/lib/fs/$(FSTYPE) -$(ROOTLIBFSTYPE)/%: $(ROOTLIBFSTYPE) % - $(RM) $@; $(SYMLINK) ../../../../etc/fs/$(FSTYPE)/$(LIBPROG) $@ include ../../Makefile.fstype @@ -69,7 +62,7 @@ CLOBBERFILES += $(LIBPROG) .KEEP_STATE: -all: $(ROOTFS_PROG) +all: $(LIBPROG) $(LIBPROG): webnfs.h $(OBJS) $(LINK.c) -o $@ $(OBJS) $(LDLIBS) @@ -118,7 +111,9 @@ $(POFILE): $(SRCS) webnfs.h sed "/^domain/d" messages.po > $@ $(RM) $(POFILE).i messages.po -install: $(ROOTETCPROG) +install: all $(FSTYPEPROG) + $(RM) $(ROOTETCPROG) + $(SYMLINK) ../../../usr/lib/fs/$(FSTYPE)/$(LIBPROG) $(ROOTETCPROG) lint: webnfs.h webnfs_xdr.c webnfs_client.c lint_SRCS diff --git a/usr/src/cmd/fs.d/nfs/mount/mount.c b/usr/src/cmd/fs.d/nfs/mount/mount.c index efb1f998f3..e1206e186a 100644 --- a/usr/src/cmd/fs.d/nfs/mount/mount.c +++ b/usr/src/cmd/fs.d/nfs/mount/mount.c @@ -2104,7 +2104,7 @@ get_fh(struct nfs_args *args, char *fshost, char *fspath, int *versp, } while ((cl = clnt_create_vers(fshost, MOUNTPROG, &outvers, - vers_min, vers_to_try, "datagram_v")) == NULL) { + vers_min, vers_to_try, NULL)) == NULL) { if (rpc_createerr.cf_stat == RPC_UNKNOWNHOST) { pr_err(gettext("%s: %s\n"), fshost, clnt_spcreateerror("")); diff --git a/usr/src/cmd/fs.d/nfs/mountd/mountd.c b/usr/src/cmd/fs.d/nfs/mountd/mountd.c index 4ccc82f4a0..ed69c98daf 100644 --- a/usr/src/cmd/fs.d/nfs/mountd/mountd.c +++ b/usr/src/cmd/fs.d/nfs/mountd/mountd.c @@ -21,6 +21,7 @@ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2012 Joyent, Inc. All rights reserved. * Copyright (c) 2012, 2016 by Delphix. All rights reserved. * Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ @@ -487,6 +488,13 @@ main(int argc, char *argv[]) exit(1); } + /* Mountd cannot run in a non-global zone. */ + if (getzoneid() != GLOBAL_ZONEID) { + (void) fprintf(stderr, "%s: can only run in the global zone\n", + argv[0]); + exit(1); + } + if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { syslog(LOG_ERR, "getrlimit failed"); } else { diff --git a/usr/src/cmd/fs.d/nfs/nfsd/nfsd.c b/usr/src/cmd/fs.d/nfs/nfsd/nfsd.c index 5c953fa833..2177b86eca 100644 --- a/usr/src/cmd/fs.d/nfs/nfsd/nfsd.c +++ b/usr/src/cmd/fs.d/nfs/nfsd/nfsd.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -176,6 +177,13 @@ main(int ac, char *av[]) exit(1); } + /* Nfsd cannot run in a non-global zone. */ + if (getzoneid() != GLOBAL_ZONEID) { + (void) fprintf(stderr, "%s: can only run in the global zone\n", + av[0]); + exit(1); + } + (void) enable_extended_FILE_stdio(-1, -1); /* diff --git a/usr/src/cmd/fs.d/nfs/svc/nfs-server b/usr/src/cmd/fs.d/nfs/svc/nfs-server index 11a54fea8a..5c8c1a67dd 100644 --- a/usr/src/cmd/fs.d/nfs/svc/nfs-server +++ b/usr/src/cmd/fs.d/nfs/svc/nfs-server @@ -53,13 +53,13 @@ configure_ipfilter() # # Nothing to do if: + # - service's policy is 'use_global' # - ipfilter isn't online # - global policy is 'custom' - # - service's policy is 'use_global' # + [ "`get_policy $SMF_FMRI`" = "use_global" ] && return 0 service_check_state $IPF_FMRI $SMF_ONLINE || return 0 [ "`get_global_def_policy`" = "custom" ] && return 0 - [ "`get_policy $SMF_FMRI`" = "use_global" ] && return 0 svcadm restart $IPF_FMRI } diff --git a/usr/src/cmd/fs.d/nfs/umount/umount.c b/usr/src/cmd/fs.d/nfs/umount/umount.c index aabdc8a592..66d280bcdb 100644 --- a/usr/src/cmd/fs.d/nfs/umount/umount.c +++ b/usr/src/cmd/fs.d/nfs/umount/umount.c @@ -297,7 +297,7 @@ retry: */ timep = (quick ? &create_timeout : NULL); cl = clnt_create_timed(list[i].host, MOUNTPROG, vers, - "datagram_n", timep); + NULL, timep); /* * Do not print any error messages in case of forced * unmount. diff --git a/usr/src/cmd/halt/halt.c b/usr/src/cmd/halt/halt.c index a98360d6c2..84d3a723f5 100644 --- a/usr/src/cmd/halt/halt.c +++ b/usr/src/cmd/halt/halt.c @@ -21,6 +21,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2011 Joyent, Inc. All rights reserved. */ /* * Copyright (c) 2013, Joyent, Inc. All rights reserved. @@ -1237,6 +1238,17 @@ do_archives_update(int do_fast_reboot) pid_t pid; char *cmd_argv[MAXARGS]; +#if defined(__i386) + { + /* + * bootadm will complain and exit if not a grub root, so + * just skip running it. + */ + struct stat sb; + if (stat("/boot/grub/stage2", &sb) == -1) + return; + } +#endif /* __i386 */ cmd_argv[i++] = "/sbin/bootadm"; cmd_argv[i++] = "-ea"; @@ -1301,7 +1313,7 @@ main(int argc, char *argv[]) optstring = "dlnqfp"; usage = gettext("usage: %s [ -dlnq(p|f) ] [ boot args ]\n"); #endif - cmd = A_SHUTDOWN; + cmd = A_REBOOT; fcn = AD_BOOT; } else { (void) fprintf(stderr, @@ -1499,7 +1511,8 @@ main(int argc, char *argv[]) * check_zone_haltedness later on. */ if (zoneid == GLOBAL_ZONEID && cmd != A_DUMP) { - need_check_zones = halt_zones(); + if (!qflag) + need_check_zones = halt_zones(); } #if defined(__x86) @@ -1591,7 +1604,7 @@ main(int argc, char *argv[]) (void) signal(SIGINT, SIG_IGN); - if (!qflag && !nosync) { + if (!nosync) { struct utmpx wtmpx; bzero(&wtmpx, sizeof (struct utmpx)); diff --git a/usr/src/cmd/ibd_upgrade/ibd_delete_link.c b/usr/src/cmd/ibd_upgrade/ibd_delete_link.c index b9d10a56cd..f63630207d 100644 --- a/usr/src/cmd/ibd_upgrade/ibd_delete_link.c +++ b/usr/src/cmd/ibd_upgrade/ibd_delete_link.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ #include <stdio.h> @@ -86,6 +87,7 @@ ibd_delete_link(dladm_handle_t dlh, char *link) getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID; (void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN); + getlinkid.ld_zoneid = -1; if ((status = ibd_dladm_door_call(dlh, &getlinkid, sizeof (getlinkid), &retval, sizeof (retval))) != DLADM_STATUS_OK) { diff --git a/usr/src/cmd/init/Makefile b/usr/src/cmd/init/Makefile index 58d8e966a2..9d70fa9539 100644 --- a/usr/src/cmd/init/Makefile +++ b/usr/src/cmd/init/Makefile @@ -26,11 +26,13 @@ # Copyright (c) 2018, Joyent, Inc. PROG= init +OBJS= init.o ROOTFS_PROG= $(PROG) DEFAULTFILES= init.dfl include ../Makefile.cmd +include ../Makefile.ctf CSTD = $(CSTD_GNU99) LDLIBS += -lpam -lbsm -lcontract -lscf @@ -46,6 +48,10 @@ SMATCH=off all: $(ROOTFS_PROG) +$(ROOTFS_PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) + install: all $(ROOTETCDEFAULTFILES) $(ROOTSBINPROG) $(RM) $(ROOTETCPROG) $(RM) $(ROOTUSRSBINPROG) @@ -63,4 +69,8 @@ clean: lint: lint_PROG +%.o: %.c + $(COMPILE.c) $< + $(POST_PROCESS_O) + include ../Makefile.targ diff --git a/usr/src/cmd/init/init.c b/usr/src/cmd/init/init.c index a877806916..edf58e22bf 100644 --- a/usr/src/cmd/init/init.c +++ b/usr/src/cmd/init/init.c @@ -23,6 +23,7 @@ * Copyright (c) 2013 Gary Mills * * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2015, Joyent, Inc. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -144,6 +145,8 @@ #define UT_USER_SZ 32 /* Size of a utmpx ut_user field */ #define UT_LINE_SZ 32 /* Size of a utmpx ut_line field */ +#define CHECK_SVC SCF_INSTANCE_FS_MINIMAL + /* * SLEEPTIME The number of seconds "init" sleeps between wakeups if * nothing else requires this "init" wakeup. @@ -548,6 +551,8 @@ static time_t init_boot_time; /* Substitute for kernel boot time. */ #define NSTARTD_FAILURE_TIMES 3 /* trigger after 3 failures */ #define STARTD_FAILURE_RATE_NS 5000000000LL /* 1 failure/5 seconds */ +#define STARTD_THROTTLE_RETRY 60 /* space failure retry after 60 secs */ +#define ROOT_MIN_FREE 524288 /* 512KB min. space needed in root */ static hrtime_t startd_failure_time[NSTARTD_FAILURE_TIMES]; static uint_t startd_failure_index; @@ -696,9 +701,8 @@ main(int argc, char *argv[]) console(B_FALSE, "\n\n%s Release %s Version %s %d-bit\r\n", un.sysname, un.release, un.version, bits); - console(B_FALSE, - "Copyright (c) 1983, 2010, Oracle and/or its affiliates." - " All rights reserved.\r\n"); + console(B_FALSE, "Copyright (c) 2010-2012, " + "Joyent Inc. All rights reserved.\r\n"); } /* @@ -3509,6 +3513,28 @@ bail: } /* + * Attempt to confirm that svc.startd is ready to accept a user-initiated + * run-level change. startd is not ready until it has started its + * _scf_notify_wait thread to watch for events from svc.configd. This is + * inherently racy. To workaround this, we check the status of a file that + * startd will create once it has started the _scf_notify_wait thread. + * If we don't see this file after one minute, then charge ahead. + */ +static void +verify_startd_ready() +{ + struct stat64 buf; + int i; + + for (i = 0; i < 60; i++) { + if (stat64("/etc/svc/volatile/startd.ready", &buf) == 0) + return; + sleep(1); + } + console(B_TRUE, "verify startd timeout\n"); +} + +/* * Function to handle requests from users to main init running as process 1. */ static void @@ -3596,6 +3622,12 @@ userinit(int argc, char **argv) (void) audit_put_record(ADT_SUCCESS, ADT_SUCCESS, argv[1]); /* + * Before we tell init to start a run-level change, we need to be + * sure svc.startd is ready to accept that. + */ + verify_startd_ready(); + + /* * Signal init; init will take care of telling svc.startd. */ if (kill(init_pid, init_signal) == FAILURE) { @@ -4305,9 +4337,7 @@ contract_event(struct pollfd *poll) if (ret == 0) { if (cookie == STARTD_COOKIE && do_restart_startd) { - if (smf_debug) - console(B_TRUE, "Restarting " - "svc.startd.\n"); + console(B_TRUE, "Restarting svc.startd.\n"); /* * Account for the failure. If the failure rate @@ -4438,6 +4468,28 @@ startd_run(const char *cline, int tmpl, ctid_t old_ctid) if (pid == 0) { /* child */ + struct statvfs64 sbuf; + + /* + * svc.configd needs some space (a few hundred KB) in / for its + * database. One common cause for startd failure is when + * configd dies because / is full. We don't want to go into the + * fast restart loop (startd_failure_rate_critical) and enter + * maintenance so we check for this case and slow down the + * failure rate so as to keep retrying in the hope space will + * free up. + */ + if (statvfs64("/", &sbuf) != -1 && + (sbuf.f_bsize * sbuf.f_bfree) < ROOT_MIN_FREE) { + syslog(LOG_ERR, "Insufficent space (%ld) in / to " + "start svc.startd.\n", + (long)(sbuf.f_bsize * sbuf.f_bfree)); + console(B_TRUE, "Insufficent space (%ld) in / to " + "start svc.startd.\n", + (long)(sbuf.f_bsize * sbuf.f_bfree)); + sleep(STARTD_THROTTLE_RETRY); + exit(1); + } /* See the comment in efork() */ for (i = SIGHUP; i <= SIGRTMAX; ++i) { diff --git a/usr/src/cmd/initpkg/mountall.sh b/usr/src/cmd/initpkg/mountall.sh index fa59a20a41..2302c7592c 100644 --- a/usr/src/cmd/initpkg/mountall.sh +++ b/usr/src/cmd/initpkg/mountall.sh @@ -29,6 +29,8 @@ # Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T # All Rights Reserved # +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# usage () { if [ -n "$1" ]; then @@ -149,6 +151,9 @@ isremote() { # Get list of remote FS types (just once) RemoteFSTypes=`while read t junk; do echo $t; done < /etc/dfs/fstypes` +# Ensure nfs/smbfs are remote FS types even if not delivered from fstypes +isremote "nfs" || set -A RemoteFSTypes "nfs" +isremote "smbfs" || set -A RemoteFSTypes "smbfs" # # Process command line args diff --git a/usr/src/cmd/initpkg/shutdown.sh b/usr/src/cmd/initpkg/shutdown.sh index a90213cd81..e93de5568c 100644 --- a/usr/src/cmd/initpkg/shutdown.sh +++ b/usr/src/cmd/initpkg/shutdown.sh @@ -43,7 +43,7 @@ usage() { } notify() { - /usr/sbin/wall -a <<-! + /usr/sbin/wall -Za <<-! $* ! # We used to do rwall here if showmounts had any output, but diff --git a/usr/src/cmd/initpkg/umountall.sh b/usr/src/cmd/initpkg/umountall.sh index c9a94fd8f1..4a45e19e18 100644 --- a/usr/src/cmd/initpkg/umountall.sh +++ b/usr/src/cmd/initpkg/umountall.sh @@ -25,6 +25,7 @@ # Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T # All Rights Reserved # +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # usage () { @@ -98,6 +99,9 @@ isremote() { # Get list of remote FS types (just once) RemoteFSTypes=`while read t junk; do echo $t; done < /etc/dfs/fstypes` +# Ensure nfs/smbfs are remote FS types even if not delivered from fstypes +isremote "nfs" || set -A RemoteFSTypes "nfs" +isremote "smbfs" || set -A RemoteFSTypes "smbfs" # # Process command line args diff --git a/usr/src/cmd/ipf/tools/Makefile.tools b/usr/src/cmd/ipf/tools/Makefile.tools index 7c1e151762..ce0db79970 100644 --- a/usr/src/cmd/ipf/tools/Makefile.tools +++ b/usr/src/cmd/ipf/tools/Makefile.tools @@ -23,7 +23,6 @@ # Use is subject to license terms. # # Copyright 2013 Nexenta Systems, Inc. All rights reserved. -# # Copyright (c) 2012, Joyent Inc. All rights reserved. # diff --git a/usr/src/cmd/ipf/tools/ipfstat.c b/usr/src/cmd/ipf/tools/ipfstat.c index d72f6ba97a..caa9ff7468 100644 --- a/usr/src/cmd/ipf/tools/ipfstat.c +++ b/usr/src/cmd/ipf/tools/ipfstat.c @@ -165,6 +165,10 @@ static int sort_dstip __P((const void *, const void *)); static int sort_dstpt __P((const void *, const void *)); #endif +#if SOLARIS +#include "ipfzone.h" +#endif + static void usage(name) char *name; diff --git a/usr/src/cmd/ksh/Makefile.com b/usr/src/cmd/ksh/Makefile.com index 9f6b431e1f..b1aef300da 100644 --- a/usr/src/cmd/ksh/Makefile.com +++ b/usr/src/cmd/ksh/Makefile.com @@ -37,11 +37,13 @@ LIBSHELLBASE=../../../lib/libshell LIBSHELLSRC=$(LIBSHELLBASE)/common/sh SRCS= $(OBJECTS:%.o=$(LIBSHELLSRC)/%.c) +OBJS= $(OBJECTS) LDLIBS += -lshell # Set common AST build flags (e.g., needed to support the math stuff). include ../../../Makefile.ast +include ../../Makefile.ctf # 1. Make sure that the -D/-U defines in CFLAGS below are in sync # with usr/src/lib/libshell/Makefile.com diff --git a/usr/src/cmd/lofiadm/main.c b/usr/src/cmd/lofiadm/main.c index 4a4ee348c0..6ed5b49050 100644 --- a/usr/src/cmd/lofiadm/main.c +++ b/usr/src/cmd/lofiadm/main.c @@ -412,7 +412,8 @@ out: * DO NOT use this function if the filename is actually the device name. */ static int -lofi_map_file(int lfd, struct lofi_ioctl *li, const char *filename) +lofi_map_file(int lfd, struct lofi_ioctl *li, const char *filename, + boolean_t no_devlink_flag) { int minor; @@ -425,7 +426,8 @@ lofi_map_file(int lfd, struct lofi_ioctl *li, const char *filename) "unsupported")); die(gettext("could not map file %s"), filename); } - wait_until_dev_complete(li); + if (!no_devlink_flag) + wait_until_dev_complete(li); return (minor); } @@ -436,7 +438,7 @@ lofi_map_file(int lfd, struct lofi_ioctl *li, const char *filename) static void add_mapping(int lfd, const char *devicename, const char *filename, mech_alias_t *cipher, const char *rkey, size_t rksz, boolean_t rdonly, - boolean_t label) + boolean_t label, boolean_t no_devlink_flag) { struct lofi_ioctl li; @@ -475,7 +477,7 @@ add_mapping(int lfd, const char *devicename, const char *filename, char path[MAXPATHLEN]; /* pick one via the driver */ - minor = lofi_map_file(lfd, &li, filename); + minor = lofi_map_file(lfd, &li, filename, no_devlink_flag); if (minor > 0) { make_blkdevname(&li, path, sizeof (path)); @@ -500,7 +502,8 @@ add_mapping(int lfd, const char *devicename, const char *filename, die(gettext("could not map file %s to %s"), filename, devicename); } - wait_until_dev_complete(&li); + if (!no_devlink_flag) + wait_until_dev_complete(&li); } /* @@ -1393,7 +1396,7 @@ lofi_uncompress(int lfd, const char *filename) if (statbuf.st_size == 0) return; - minor = lofi_map_file(lfd, &li, filename); + minor = lofi_map_file(lfd, &li, filename, B_FALSE); (void) snprintf(devicename, sizeof (devicename), "/dev/%s/%d", LOFI_BLOCK_NAME, minor); @@ -1935,6 +1938,7 @@ main(int argc, char *argv[]) boolean_t ephflag = B_FALSE; boolean_t compressflag = B_FALSE; boolean_t uncompressflag = B_FALSE; + boolean_t no_devlink_flag = B_FALSE; /* the next two work together for -c, -k, -T, -e options only */ boolean_t need_crypto = B_FALSE; /* if any -c, -k, -T, -e */ boolean_t cipher_only = B_TRUE; /* if -c only */ @@ -1950,7 +1954,7 @@ main(int argc, char *argv[]) (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); - while ((c = getopt(argc, argv, "a:c:Cd:efk:lrs:T:U")) != EOF) { + while ((c = getopt(argc, argv, "a:c:Cd:efk:lrs:T:UX")) != EOF) { switch (c) { case 'a': addflag = B_TRUE; @@ -2031,6 +2035,13 @@ main(int argc, char *argv[]) case 'U': uncompressflag = B_TRUE; break; + case 'X': + /* + * Private flag to skip the wait for the /dev links to + * be created. + */ + no_devlink_flag = B_TRUE; + break; case '?': default: errflag = B_TRUE; @@ -2163,7 +2174,7 @@ main(int argc, char *argv[]) */ if (addflag) add_mapping(lfd, devicename, filename, cipher, rkey, rksz, - rdflag, labelflag); + rdflag, labelflag, no_devlink_flag); else if (compressflag) lofi_compress(&lfd, filename, compress_index, segsize); else if (uncompressflag) diff --git a/usr/src/cmd/machid/Makefile b/usr/src/cmd/machid/Makefile new file mode 100644 index 0000000000..6a3c7138dc --- /dev/null +++ b/usr/src/cmd/machid/Makefile @@ -0,0 +1,80 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +PROG= machid + +include ../Makefile.cmd + +# +# List of all links present on all architectures and machines. +# +# Note that this function is obsolesent and we don't generally +# add to this list (see psarc/1992/171). +# +FIRSTLINK = i286 +LINKS = i386 i486 i860 i86pc iAPX286 \ + m68k mc68000 mc68010 mc68020 mc68030 mc68040 \ + sparc sun sun2 sun3 sun3x sun4 sun4c sun4m sun4d sun4e \ + u370 u3b u3b15 u3b2 u3b5 vax pdp11 + +ROOTFIRSTLINK = $(ROOTBIN)/$(FIRSTLINK) +ROOTLINKS = $(LINKS:%=$(ROOTBIN)/%) + +# +# Install the program as the first machine in the list. +# +INSTALLIT= $(INS.link) +$(ROOTFIRSTLINK):= INSTALLIT = $(INS.rename) +$(ROOTLINKS):= INSLINKTARGET = $(ROOTFIRSTLINK) + +$(ROOTLINKS): $(ROOTFIRSTLINK) + +# +# Link installation rules +# +$(ROOTBIN)/%: $(PROG) + $(INSTALLIT) + +$(ROOTFIRSTLINK): $(ROOTBIN) + +$(ROOTBIN): + $(INS.dir) + +CFLAGS += $(CCVERBOSE) + +.KEEP_STATE: + +all: $(PROG) + +install: all $(ROOTLINKS) + +clean: + +lint: lint_PROG + +include ../Makefile.targ diff --git a/usr/src/cmd/machid/machid.c b/usr/src/cmd/machid/machid.c new file mode 100644 index 0000000000..c3d57b91f9 --- /dev/null +++ b/usr/src/cmd/machid/machid.c @@ -0,0 +1,137 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 1993-1994, by Sun Microsystems, Inc. + */ + +/* + * This program replicates the function of the links from a machine name + * (such as sun4c) through /usr/kvm to true or false as appropriate. It + * knows the correct special cases. + * + * IMPORTANT NOTE: + * + * Do not modify this program to know about additional special cases or + * reflect new platforms or instruction set architectures. This is a + * deprecated interface and strictly for backwards compatibility. This + * is psarc/1992/171. Note the following excerpt from the opinion: + * + * It is most important to note that the manual page states in + * the NOTES section: "The machid family of commands is + * obsolete. Use uname -p and uname -m instead." + * + * The intent of Kernel Architecture Project team is to provide + * only enough functionality to mimic the existing definitions + * on the SPARC and Intel x86 versions of Solaris 2.x. No new + * identifiers will ever be added to the documented and + * undocumented identifiers listed above. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <limits.h> +#include <sys/systeminfo.h> + +static char static_buf[SYS_NMLN]; +static char *progname; + +static void get_info_item(int command, char **buf, long *count); + +/* ARGSUSED */ +int +main(int argc, char *argv[], char *envp[]) +{ + char *buf = &static_buf[0]; + long buflen = SYS_NMLN; + + if ((progname = strrchr(argv[0], '/')) == NULL) + progname = argv[0]; + else + progname++; + + /* + * First possible match is on the processor type. + * + * Special case for architectures: i386 matches i486 and visa versa. + */ + get_info_item(SI_ARCHITECTURE, &buf, &buflen); + if (strcmp(buf, progname) == 0) + return (0); + if ((strcmp(buf, "i386") == 0 && strcmp(progname, "i486") == 0) || + (strcmp(buf, "i486") == 0 && strcmp(progname, "i386") == 0)) + return (0); + + /* + * Next possible match is the machine, or more exactly, the value + * which would be returned by uname(2) in the machine field or uname(1) + * with the -m option. For historical reasons this is really is + * often a class of platforms which are identical to userland processes + * such as sun4c, sun4m, etc. + */ + get_info_item(SI_MACHINE, &buf, &buflen); + if (strcmp(buf, progname) == 0) + return (0); + + /* + * Finally, match the vendor. We hardwire in one historical match. + */ + get_info_item(SI_HW_PROVIDER, &buf, &buflen); + if (strcmp(buf, progname) == 0) + return (0); + if (strcasecmp(buf, "Sun_Microsystems") == 0 && + strcmp("sun", progname) == 0) + return (0); + + return (255); +} + +/* + * get_info_item is a wrapper around the sysinfo system call. It makes sure + * the buffer is large enough, returning a larger buffer if needed. On + * unrecoverable error, it exits. An error message doesn't help and makes + * this tiny program link stdio and maybe deal with internationalization, + * so the best thing is to die silently. Note that the larger buffer is + * retained for later use. Reality is that the buffer will always be big + * enough, but this is coded to the spec rather than implementation. + */ +static void +get_info_item(int command, char **buf, long *count) +{ + long error; + + error = sysinfo(command, *buf, *count); + if (error > *count) { + *count = error; + if (*buf != static_buf) { + free(*buf); + } + *buf = (char *) malloc(*count); + error = sysinfo(command, *buf, *count); + } + + if (error == -1) + exit(-1); +} diff --git a/usr/src/cmd/man/Makefile b/usr/src/cmd/man/Makefile index 911bae6340..7c7afebb10 100644 --- a/usr/src/cmd/man/Makefile +++ b/usr/src/cmd/man/Makefile @@ -14,12 +14,7 @@ # Copyright 2014 Garrett D'Amore <garrett@damore.org> # -PROG= man -LINKS= apropos whatis catman -LIBLINKS = makewhatis -OBJS= makewhatis.o man.o stringlist.o -SRCS= $(OBJS:%.o=%.c) - +include Makefile.com include $(SRC)/cmd/Makefile.cmd CFLAGS += $(CCVERBOSE) diff --git a/usr/src/cmd/man/Makefile.com b/usr/src/cmd/man/Makefile.com new file mode 100644 index 0000000000..8f1b3adf7d --- /dev/null +++ b/usr/src/cmd/man/Makefile.com @@ -0,0 +1,23 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2012 Nexenta Systems, Inc. All rights reserved. +# Copyright 2014 Garrett D'Amore <garrett@damore.org> +# + +PROG= man +LINKS= apropos whatis catman +LIBLINKS = makewhatis +OBJS= makewhatis.o man.o stringlist.o +SRCS= $(OBJS:%.o=%.c) + + diff --git a/usr/src/cmd/mdb/Makefile.common b/usr/src/cmd/mdb/Makefile.common index 0107f36dff..79b49c8ce2 100644 --- a/usr/src/cmd/mdb/Makefile.common +++ b/usr/src/cmd/mdb/Makefile.common @@ -102,6 +102,7 @@ COMMON_MODULES_KVM = \ stmf_sbd \ ufs \ usba \ + xhci \ zfs CLOSED_COMMON_MODULES_KVM = \ diff --git a/usr/src/cmd/mdb/Makefile.module b/usr/src/cmd/mdb/Makefile.module index f77b935e47..6c2c6af170 100644 --- a/usr/src/cmd/mdb/Makefile.module +++ b/usr/src/cmd/mdb/Makefile.module @@ -104,7 +104,7 @@ LINTFILES_raw = $(LINTOBJS) LINTFILES = $(LINTFILES_$(MDBTGT)) # -# Python specific flags. To try and make life easier for folks how are +# Python specific flags. To try and make life easier for folks who are # building with an LFS python, we attempt to use -isystem when it's # available. # @@ -112,6 +112,12 @@ PYCPPFLAGS = -_gcc=-isystem -_gcc=$(ADJUNCT_PROTO)/usr/include/python$(PYTHON_V PYCPPFLAGS += -_cc=-I$(ADJUNCT_PROTO)/usr/include/python$(PYTHON_VERSION) PYLNFLAGS = -I$(ADJUNCT_PROTO)/usr/include/python$(PYTHON_VERSION) +# +# At this time, we do not have python27 in the adjunct proto area, only +# python26. As such, we explicitly override the python version dmod here. +# +PYTHON_VERSION = 2.6 + kvm_TGTFLAGS = -D_KERNEL proc_TGTFLAGS = -D_USER diff --git a/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c b/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c index 1b75f21911..787dc7cfd8 100644 --- a/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c +++ b/usr/src/cmd/mdb/common/kmdb/kmdb_kvm.c @@ -22,7 +22,7 @@ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. * - * Copyright 2018 Joyent, Inc. + * Copyright (c) 2019, Joyent, Inc. */ #include <kmdb/kmdb_kvm.h> @@ -49,6 +49,7 @@ #include <sys/kobj.h> #include <sys/kobj_impl.h> #include <sys/bitmap.h> +#include <sys/uuid.h> #include <vm/as.h> static const char KMT_RTLD_NAME[] = "krtld"; @@ -285,6 +286,8 @@ kmt_vtop(mdb_tgt_t *t, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pap) case (uintptr_t)MDB_TGT_AS_IO: return (set_errno(EINVAL)); case (uintptr_t)MDB_TGT_AS_VIRT: + case (uintptr_t)MDB_TGT_AS_VIRT_I: + case (uintptr_t)MDB_TGT_AS_VIRT_S: if ((asp = (struct as *)kmt_read_kas(t)) == NULL) return (-1); /* errno is set for us */ break; @@ -552,7 +555,7 @@ static int kmt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { struct utsname uts; - char uuid[37]; + char uuid[UUID_PRINTABLE_STRING_LENGTH]; kreg_t tt; if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, &uts, sizeof (uts), @@ -568,16 +571,14 @@ kmt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) mdb_printf("operating system: %s %s (%s)\n", uts.release, uts.version, uts.machine); - if (mdb_tgt_readsym(mdb.m_target, MDB_TGT_AS_VIRT, uuid, sizeof (uuid), - "genunix", "dump_osimage_uuid") != sizeof (uuid)) { - warn("failed to read 'dump_osimage_uuid' string from kernel\n"); - (void) strcpy(uuid, "(error)"); - } else if (*uuid == '\0') { - (void) strcpy(uuid, "(not set)"); - } else if (uuid[36] != '\0') { - (void) strcpy(uuid, "(invalid)"); + mdb_print_gitstatus(); + + if (mdb_readsym(uuid, sizeof (uuid), + "dump_osimage_uuid") == sizeof (uuid) && + uuid[sizeof (uuid) - 1] == '\0') { + mdb_printf("image uuid: %s\n", uuid[0] != '\0' ? + uuid : "(not set)"); } - mdb_printf("image uuid: %s\n", uuid); mdb_printf("DTrace state: %s\n", (kmdb_kdi_dtrace_get_state() == KDI_DTSTATE_DTRACE_ACTIVE ? "active (debugger breakpoints cannot " diff --git a/usr/src/cmd/mdb/common/mdb/mdb.h b/usr/src/cmd/mdb/common/mdb/mdb.h index 7f712ad340..cb43f4828d 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb.h +++ b/usr/src/cmd/mdb/common/mdb/mdb.h @@ -25,7 +25,7 @@ /* * Copyright (c) 2012 by Delphix. All rights reserved. - * Copyright (c) 2012 Joyent, Inc. All rights reserved. + * Copyright (c) 2017 Joyent, Inc. All rights reserved. */ #ifndef _MDB_H @@ -76,28 +76,29 @@ extern "C" { #define MDB_ARR_NOLIMIT -1UL /* No limit on number of array elements */ -#define MDB_FL_PSYM 0x00001 /* Print dot as symbol + offset when possible */ -#define MDB_FL_LOG 0x00002 /* Logging is enabled */ -#define MDB_FL_NOMODS 0x00004 /* Skip automatic mdb module loading */ -#define MDB_FL_USECUP 0x00008 /* Use terminal cup initialization sequences */ -#define MDB_FL_ADB 0x00010 /* Enable stricter adb(1) compatibility */ -#define MDB_FL_SHOWLMID 0x00020 /* Always show link map id with symbol names */ -#define MDB_FL_IGNEOF 0x00040 /* Ignore EOF as a synonym for ::quit */ -#define MDB_FL_REPLAST 0x00080 /* Naked newline repeats previous command */ -#define MDB_FL_PAGER 0x00100 /* Enable pager by default */ -#define MDB_FL_LATEST 0x00200 /* Replace version string with "latest" */ -#define MDB_FL_VCREATE 0x00400 /* Victim process was created by debugger */ -#define MDB_FL_JOBCTL 0x00800 /* Victim process jobctl stopped on same tty */ -#define MDB_FL_DEMANGLE 0x01000 /* Demangle symbols as part of %a processing */ -#define MDB_FL_EXEC 0x02000 /* Debugger exec'd by a previous instance */ -#define MDB_FL_NOCTF 0x04000 /* Skip automatic CTF data loading */ -#define MDB_FL_BPTNOSYMSTOP 0x08000 /* Stop on deferred bkpts for unk symbols */ -#define MDB_FL_TERMGUESS 0x10000 /* m_termtype derived from userland */ -#define MDB_FL_READBACK 0x20000 /* Read value back after write */ +#define MDB_FL_PSYM 0x000001 /* Print dot as symbol + offset */ +#define MDB_FL_LOG 0x000002 /* Logging is enabled */ +#define MDB_FL_NOMODS 0x000004 /* Skip automatic mdb module loading */ +#define MDB_FL_USECUP 0x000008 /* Use term cup init sequences */ +#define MDB_FL_ADB 0x000010 /* Enable stricter adb(1) compat */ +#define MDB_FL_SHOWLMID 0x000020 /* Show link map id with symbol names */ +#define MDB_FL_IGNEOF 0x000040 /* Ignore EOF as a synonym for ::quit */ +#define MDB_FL_REPLAST 0x000080 /* Naked newline repeats prev command */ +#define MDB_FL_PAGER 0x000100 /* Enable pager by default */ +#define MDB_FL_LATEST 0x000200 /* Replace verstring with "latest" */ +#define MDB_FL_VCREATE 0x000400 /* Victim process created by debugger */ +#define MDB_FL_JOBCTL 0x000800 /* Victim process jobctl on same tty */ +#define MDB_FL_DEMANGLE 0x001000 /* Demangle symbols as part of %a */ +#define MDB_FL_EXEC 0x002000 /* Debugger exec'd by a prev instance */ +#define MDB_FL_NOCTF 0x004000 /* Skip automatic CTF data loading */ +#define MDB_FL_BPTNOSYMSTOP 0x008000 /* Stop on def bkpts for unk symbols */ +#define MDB_FL_TERMGUESS 0x010000 /* m_termtype derived from userland */ +#define MDB_FL_READBACK 0x020000 /* Read value back after write */ #ifdef _KMDB -#define MDB_FL_NOUNLOAD 0x40000 /* Don't allow debugger unload */ +#define MDB_FL_NOUNLOAD 0x040000 /* Don't allow debugger unload */ #endif -#define MDB_FL_LMRAW 0x80000 /* Show unresolved link map object names */ +#define MDB_FL_LMRAW 0x080000 /* Show unres link map object names */ +#define MDB_FL_AUTOWRAP 0x100000 /* Autowrap lines at term width */ #define MDB_FL_VOLATILE 0x0001 /* Mask of all volatile flags to save/restore */ diff --git a/usr/src/cmd/mdb/common/mdb/mdb_cmds.c b/usr/src/cmd/mdb/common/mdb/mdb_cmds.c index dd3f9cd11e..878728251c 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_cmds.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_cmds.c @@ -2090,7 +2090,7 @@ cmd_dis(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) if (opt_f) as = MDB_TGT_AS_FILE; else - as = MDB_TGT_AS_VIRT; + as = MDB_TGT_AS_VIRT_I; if (opt_w == FALSE) { n++; @@ -2635,8 +2635,9 @@ tgt_status(const mdb_tgt_status_t *tsp) return (DCMD_OK); if (tsp->st_pc != 0) { - if (mdb_dis_ins2str(mdb.m_disasm, mdb.m_target, MDB_TGT_AS_VIRT, - buf, sizeof (buf), tsp->st_pc) != tsp->st_pc) + if (mdb_dis_ins2str(mdb.m_disasm, mdb.m_target, + MDB_TGT_AS_VIRT_I, buf, sizeof (buf), tsp->st_pc) != + tsp->st_pc) format = "target stopped at:\n%-#16a%8T%s\n"; else format = "target stopped at %a:\n"; @@ -3207,8 +3208,8 @@ const mdb_dcmd_t mdb_dcmd_builtins[] = { */ { "?", "fmt-list", "format data from object file", cmd_print_object }, { "$>", "[file]", "log session to a file", cmd_old_log }, - { "$g", "?", "get/set C++ demangling options", cmd_demflags }, - { "$G", NULL, "enable/disable C++ demangling support", cmd_demangle }, + { "$g", "?", "get/set demangling options", cmd_demflags }, + { "$G", NULL, "enable/disable demangling support", cmd_demangle }, { "$i", NULL, "print signals that are ignored", cmd_notsup }, { "$l", NULL, "print the representative thread's lwp id", cmd_notsup }, { "$p", ":", "change debugger target context", cmd_context }, diff --git a/usr/src/cmd/mdb/common/mdb/mdb_create.c b/usr/src/cmd/mdb/common/mdb/mdb_create.c index ea30457ef0..86490bf825 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_create.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_create.c @@ -24,7 +24,9 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright 2018 Joyent, Inc. + */ #include <mdb/mdb.h> #include <mdb/mdb_conf.h> @@ -51,6 +53,11 @@ mdb_create_builtin_tgts(void) if ((mp = mdb_module_load_builtin("mdb_raw")) != NULL) mp->mod_tgt_ctor = mdb_rawfile_tgt_create; + +#ifdef __amd64 + if ((mp = mdb_module_load_builtin("mdb_bhyve")) != NULL) + mp->mod_tgt_ctor = mdb_bhyve_tgt_create; +#endif } void diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c index 9af52917b4..f2854bb6d6 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_ctf.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_ctf.c @@ -24,7 +24,7 @@ */ /* * Copyright (c) 2013, 2016 by Delphix. All rights reserved. - * Copyright (c) 2015, Joyent, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. */ #include <mdb/mdb_ctf.h> @@ -838,6 +838,7 @@ static int member_info_cb(const char *name, mdb_ctf_id_t id, ulong_t off, void *data) { mbr_info_t *mbrp = data; + int kind, ret; if (strcmp(name, mbrp->mbr_member) == 0) { if (mbrp->mbr_offp != NULL) @@ -848,7 +849,46 @@ member_info_cb(const char *name, mdb_ctf_id_t id, ulong_t off, void *data) return (1); } - return (0); + /* + * C11 as well as earlier GNU extensions allow an embedded struct + * or union to be unnamed as long as there are no unambiguous member + * names. If we encounter a SOU member with a 0-length name, + * recurse into it and see if any of them match. + */ + if (strlen(name) != 0) + return (0); + + kind = mdb_ctf_type_kind(id); + if (kind == CTF_ERR) + return (-1); + if (kind != CTF_K_STRUCT && kind != CTF_K_UNION) + return (0); + + /* + * Search the unnamed SOU for mbrp->mbr_member, possibly recursing if + * it also contains unnamed members. If the desired member is found. + * *mbrp->mbr_offp will contain the offset of the member relative to + * this unnamed SOU (if the offset was requested) -- i.e. + * we effectively have *mbrp->mbr_offp == offsetof("", member). We want + * unnamed SOUs to act as members of the enclosing SOUs, so we need to + * return the offset as relative to the outer SOU. Since 'off' is + * the offset of the unnamed SOU relative to the enclosing SOU (i.e. + * off == offsetof(outer, "")), we add the two together to produce the + * desired offset. This can recurse as necessary -- the compiler + * prevents any ambiguities from occurring (or else it wouldn't be + * able to compile the code), and the result will be relative to + * the start of the SOU given in the mdb_ctf_member_info() call. + */ + ret = mdb_ctf_member_iter(id, member_info_cb, mbrp); + if (ret == -1) + return (-1); + if (ret == 0) + return (0); + + if (mbrp->mbr_offp != NULL) + *(mbrp->mbr_offp) += off; + + return (1); } int @@ -856,10 +896,21 @@ mdb_ctf_member_info(mdb_ctf_id_t id, const char *member, ulong_t *offp, mdb_ctf_id_t *typep) { mbr_info_t mbr; + /* + * We want the resulting offset (if requested -- offp != NULL) to + * be relative to the start of _this_ SOU. If we have to search any + * embedded unnamed SOUs, instead of merely assigning the resulting + * offset value to mbr_offp, we will have to add the offsets of + * any nested SOUs along the way (see comments in member_info_cb()). + * Therefore, initialize off to 0 here so we do not need to worry about + * recursion depth in member_info_cb (otherwise we would need to set + * mbr_offp when depth = 1, and add when depth > 1). + */ + ulong_t off = 0; int rc; mbr.mbr_member = member; - mbr.mbr_offp = offp; + mbr.mbr_offp = &off; mbr.mbr_typep = typep; rc = mdb_ctf_member_iter(id, member_info_cb, &mbr); @@ -872,6 +923,9 @@ mdb_ctf_member_info(mdb_ctf_id_t id, const char *member, ulong_t *offp, if (rc == 0) return (set_errno(EMDB_CTFNOMEMB)); + if (offp != NULL) + *offp = off; + return (0); } @@ -1236,8 +1290,9 @@ member_cb(const char *name, mdb_ctf_id_t modmid, ulong_t modoff, void *data) "member %s of type %s", name, mp->m_tgtname); if (mdb_ctf_member_info(mp->m_tgtid, name, &tgtoff, &tgtmid) != 0) { - mdb_ctf_warn(mp->m_flags, - "could not find %s\n", tgtname); + if (mp->m_flags & MDB_CTF_VREAD_IGNORE_ABSENT) + return (0); + mdb_ctf_warn(mp->m_flags, "could not find %s\n", tgtname); return (set_errno(EMDB_CTFNOMEMB)); } @@ -1612,12 +1667,11 @@ vread_helper(mdb_ctf_id_t modid, char *modbuf, * Warning: it will therefore only work with enums are only used to store * legitimate enum values (not several values or-ed together). * - * By default, if mdb_ctf_vread() can not find any members or enum values, - * it will print a descriptive message (with mdb_warn()) and fail. - * Passing MDB_CTF_VREAD_QUIET in 'flags' will suppress the warning message. - * Additional flags can be used to ignore specific types of translation - * failure, but should be used with caution, because they will silently leave - * the caller's buffer uninitialized. + * Flags values: + * + * MDB_CTF_VREAD_QUIET: keep quiet about failures + * MDB_CTF_VREAD_IGNORE_ABSENT: ignore any member that couldn't be found in the + * target struct; be careful not to use an uninitialized result. */ int mdb_ctf_vread(void *modbuf, const char *target_typename, @@ -1630,6 +1684,7 @@ mdb_ctf_vread(void *modbuf, const char *target_typename, mdb_ctf_id_t tgtid; mdb_ctf_id_t modid; mdb_module_t *mod; + int ret; if ((mod = mdb_get_module()) == NULL || (mfp = mod->mod_ctfp) == NULL) { mdb_ctf_warn(flags, "no ctf data found for mdb module %s\n", @@ -1662,15 +1717,20 @@ mdb_ctf_vread(void *modbuf, const char *target_typename, return (-1); /* errno is set for us */ } - tgtbuf = mdb_alloc(size, UM_SLEEP | UM_GC); + tgtbuf = mdb_alloc(size, UM_SLEEP); if (mdb_vread(tgtbuf, size, addr) < 0) { mdb_ctf_warn(flags, "couldn't read %s from %p\n", target_typename, addr); + mdb_free(tgtbuf, size); return (-1); /* errno is set for us */ } - return (vread_helper(modid, modbuf, tgtid, tgtbuf, NULL, flags)); + ret = vread_helper(modid, modbuf, tgtid, tgtbuf, NULL, flags); + + mdb_free(tgtbuf, size); + + return (ret); } /* diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ctf.h b/usr/src/cmd/mdb/common/mdb/mdb_ctf.h index 21f27d782b..74bc8e95da 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_ctf.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_ctf.h @@ -24,7 +24,7 @@ */ /* * Copyright (c) 2013, 2015 by Delphix. All rights reserved. - * Copyright (c) 2015, Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ #ifndef _MDB_CTF_H @@ -142,6 +142,7 @@ extern ssize_t mdb_ctf_offset_to_name(mdb_ctf_id_t, ulong_t, char *, size_t, int, mdb_ctf_id_t *, ulong_t *); #define MDB_CTF_VREAD_QUIET 0x100 +#define MDB_CTF_VREAD_IGNORE_ABSENT 0x200 extern int mdb_ctf_vread(void *, const char *, const char *, uintptr_t, uint_t); diff --git a/usr/src/cmd/mdb/common/mdb/mdb_demangle.c b/usr/src/cmd/mdb/common/mdb/mdb_demangle.c index ad7555dcc0..94386d5f66 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_demangle.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_demangle.c @@ -26,6 +26,10 @@ * Copyright 2018 Jason King */ +/* + * Copyright (c) 2019, Joyent, Inc. All rights reserved. + */ + #include <mdb/mdb_modapi.h> #include <mdb/mdb_demangle.h> #include <mdb/mdb_err.h> @@ -62,8 +66,7 @@ mdb_dem_load(void) dmp->dm_len = 0; dmp->dm_buf = NULL; dmp->dm_flags = MDB_DM_SCOPE; - /* stick with C++ for now to match old behavior */ - dmp->dm_lang = SYSDEM_LANG_CPP; + dmp->dm_lang = SYSDEM_LANG_AUTO; return (dmp); } @@ -207,7 +210,20 @@ mdb_dem_process(mdb_demangler_t *dmp, const char *name) res = sysdemangle(name + prefixlen, dmp->dm_lang, &mdb_dem_demops); if (res == NULL) { - if (errno != EINVAL) + /* + * EINVAL indicates the name is not a properly mangled name + * (or perhaps is truncated so it cannot be correctly + * demangled) while ENOTSUP means sysdemangle could not + * determine which language was used to mangle the name when + * SYSDEM_LANG_AUTO is used (the name might not be mangled, + * the name could be truncated enough to prevent determination + * of the name, etc). + * + * Both are allowed/expected failure modes, so in both cases + * do not emit a warning -- let the caller display the + * original name. + */ + if (errno != EINVAL && errno != ENOTSUP) mdb_warn("Error while demangling"); return (-1); } diff --git a/usr/src/cmd/mdb/common/mdb/mdb_fmt.c b/usr/src/cmd/mdb/common/mdb/mdb_fmt.c index 78d27bdcb9..c68f20b107 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_fmt.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_fmt.c @@ -21,7 +21,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2016 Joyent, Inc. + * Copyright 2019 Joyent, Inc. * Copyright (c) 2017 by Delphix. All rights reserved. */ @@ -82,8 +82,9 @@ typedef mdb_tgt_addr_t mdb_fmt_func_f(mdb_tgt_t *, #define FMT_PRINTF 0x2 /* f_ptr is a const char * format string */ #define FMT_MATCH 0x4 /* Match command (not supported here) */ #define FMT_WRITE 0x8 /* Command writes to address space */ +#define FMT_NOAUTOWRAP 0x10 /* Autowrap should not be autoenabled */ -#define FMT_TYPE(x) ((x) & 0x7) /* Excludes modifying flags (FMT_WRITE) */ +#define FMT_TYPE(x) ((x) & 0x7) /* Excludes modifying flags */ typedef struct mdb_fmt_desc { int f_type; /* Type of format (see above) */ @@ -120,6 +121,7 @@ static const char help_match64[] = "long long"; static const char help_match16[] = "short"; static const char help_uintptr[] = "hexadecimal uintptr_t"; static const char help_ctf[] = "whose size is inferred by CTF info"; +static const char help_jazzed[] = "jazzed-up binary unsigned long long"; /*ARGSUSED*/ static mdb_tgt_addr_t @@ -409,6 +411,9 @@ fmt_instr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) char buf[BUFSIZ]; uintptr_t naddr; + if (as == MDB_TGT_AS_VIRT) + as = MDB_TGT_AS_VIRT_I; + while (cnt-- != 0) { naddr = mdb_dis_ins2str(mdb.m_disasm, t, as, buf, sizeof (buf), addr); @@ -429,6 +434,9 @@ fmt_dotinstr(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) uintptr_t naddr; uint32_t i; + if (as == MDB_TGT_AS_VIRT) + as = MDB_TGT_AS_VIRT_I; + for (mdb_iob_clrflags(mdb.m_out, oflags); cnt-- != 0; addr = naddr) { if (mdb_tgt_aread(t, as, &i, sizeof (i), addr) != sizeof (i)) { warn("failed to read data from target"); @@ -449,10 +457,12 @@ static mdb_tgt_addr_t fmt_binary(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) { uint64_t x; + const char *fmts[] = { "%-64s", "%-65s" }; + const uint64_t mask = 0x8000000000000000ull; while (cnt-- != 0) { if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) == sizeof (x)) { - mdb_iob_printf(mdb.m_out, "%-64s", + mdb_iob_printf(mdb.m_out, fmts[(x & mask) != 0], numtostr(x, 2, NTOS_UNSIGNED)); mdb_nv_set_value(mdb.m_rvalue, x); addr += sizeof (x); @@ -465,6 +475,83 @@ fmt_binary(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) } static mdb_tgt_addr_t +fmt_jazzed(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) +{ + uint64_t x; + char buf[256]; + + while (cnt-- != 0) { + boolean_t header = B_TRUE; + + if (mdb_tgt_aread(t, as, &x, sizeof (x), addr) != sizeof (x)) { + warn("failed to read data from target"); + break; + } + + mdb_nv_set_value(mdb.m_rvalue, x); + addr += sizeof (x); + + mdb_iob_printf(mdb.m_out, "%s\n", + numtostr(x, 2, NTOS_UNSIGNED)); + + while (x != 0) { + int b = 63, forearm; + int i = 0, highbit; + + /* + * Find the high bit... + */ + while (!(x & (1ULL << b))) + b--; + + highbit = b; + + /* + * ...and iterate over the remaining bits, putting + * the upper arm in our buffer for any set bit (and + * a space otherwise). + */ + while (x & ((1ULL << b) - 1)) { + buf[i++] = x & (1ULL << b) ? '|' : ' '; + b--; + } + + /* + * If this is the header line, print the upper arm + * for the lowest set bit and continue... + */ + if (header) { + header = B_FALSE; + buf[i] = '\0'; + mdb_iob_printf(mdb.m_out, "%s|\n", buf); + continue; + } + + /* + * ...otherwise, put the elbow and forearm into our + * buffer, and print it. + */ + buf[i++] = '+'; + + for (forearm = b; forearm > -2; forearm--) + buf[i++] = '-'; + + buf[i] = '\0'; + mdb_iob_printf(mdb.m_out, "%s bit %d %smask 0x%0*llx\n", + buf, b, b < 10 && highbit >= 10 ? " " : "", + (highbit / 4) + 1, 1ULL << b); + + /* + * Finally, clear the lowest set bit and continue. + */ + x &= ~(1ULL << b); + } + } + + return (addr); +} + +static mdb_tgt_addr_t fmt_hex64(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_tgt_addr_t addr, size_t cnt) { const char *fmts[] = { "%-16llx", "%-17llx" }; @@ -554,13 +641,13 @@ static const mdb_fmt_desc_t fmttab[] = { { FMT_PRINTF, "%-8x", NULL, 1 }, /* 66 = B */ { FMT_FUNC, FUNCP(fmt_escchr), help_escchr, 1 }, /* 67 = C */ { FMT_PRINTF, "%-16d", NULL, 4 }, /* 68 = D */ - { FMT_PRINTF, "%-16llu", NULL, 8 }, /* 69 = E */ + { FMT_PRINTF, "%-21llu", NULL, 8 }, /* 69 = E */ #ifdef _KMDB { FMT_NONE, NULL, NULL, 0 }, /* 70 = F */ #else { FMT_PRINTF, "%g", NULL, sizeof (double), B_TRUE }, /* 70 = F */ #endif - { FMT_PRINTF, "%-16llo", NULL, 8 }, /* 71 = G */ + { FMT_PRINTF, "%-23llo", NULL, 8 }, /* 71 = G */ { FMT_FUNC, FUNCP(fmt_swapint), help_swapint, 4 }, /* 72 = H */ { FMT_FUNC, FUNCP(fmt_dotinstr), help_dotinstr, 0 }, /* 73 = I */ { FMT_FUNC, FUNCP(fmt_hex64), help_hex64, 8 }, /* 74 = J */ @@ -573,7 +660,7 @@ static const mdb_fmt_desc_t fmttab[] = { { FMT_MATCH, NULL, help_match64, 8 }, /* 77 = M */ { FMT_FUNC, FUNCP(fmt_nl), help_nl, SZ_NONE }, /* 78 = N */ { FMT_PRINTF, "%-#16o", NULL, 4 }, /* 79 = O */ - { FMT_PRINTF, "%-16a", NULL, sizeof (uintptr_t) }, /* 80 = P */ + { FMT_PRINTF, "%-19a", NULL, sizeof (uintptr_t) }, /* 80 = P */ { FMT_PRINTF, "%-#16q", NULL, 4 }, /* 81 = Q */ { FMT_FUNC, FUNCP(fmt_binary), help_binary, 8 }, /* 82 = R */ { FMT_FUNC, FUNCP(fmt_escstr), help_escstr, 0 }, /* 83 = S */ @@ -594,23 +681,24 @@ static const mdb_fmt_desc_t fmttab[] = { { FMT_PRINTF, "%-#8o", NULL, 1 }, /* 98 = b */ { FMT_PRINTF, "%c", NULL, 1 }, /* 99 = c */ { FMT_PRINTF, "%-8hd", NULL, 2 }, /* 100 = d */ - { FMT_PRINTF, "%-16lld", NULL, 8 }, /* 101 = e */ + { FMT_PRINTF, "%-21lld", NULL, 8 }, /* 101 = e */ #ifdef _KMDB { FMT_NONE, NULL, NULL, 0 }, /* 102 = f */ #else { FMT_FUNC, FUNCP(fmt_float), help_f, sizeof (float), B_TRUE }, /* 102 = f */ #endif - { FMT_PRINTF, "%-16llq", NULL, 8 }, /* 103 = g */ + { FMT_PRINTF, "%-24llq", NULL, 8 }, /* 103 = g */ { FMT_FUNC, FUNCP(fmt_swapshort), help_swapshort, 2 }, /* 104 = h */ { FMT_FUNC, FUNCP(fmt_instr), help_instr, 0 }, /* 105 = i */ - { FMT_NONE, NULL, NULL, 0 }, /* 106 = j */ + { FMT_FUNC|FMT_NOAUTOWRAP, + FUNCP(fmt_jazzed), help_jazzed, 8 }, /* 106 = j */ { FMT_NONE, NULL, NULL, 0 }, /* 107 = k */ { FMT_MATCH, NULL, help_match16, 2 }, /* 108 = l */ { FMT_NONE, NULL, NULL, 0 }, /* 109 = m */ { FMT_FUNC, FUNCP(fmt_nl), help_nl, SZ_NONE }, /* 110 = n */ { FMT_PRINTF, "%-#8ho", NULL, 2 }, /* 111 = o */ - { FMT_PRINTF, "%-16a", NULL, sizeof (uintptr_t) }, /* 112 = p */ + { FMT_PRINTF, "%-19a", NULL, sizeof (uintptr_t) }, /* 112 = p */ { FMT_PRINTF, "%-#8hq", NULL, 2 }, /* 113 = q */ { FMT_FUNC, FUNCP(fmt_ws), help_ws, SZ_NONE }, /* 114 = r */ { FMT_FUNC, FUNCP(fmt_rawstr), help_rawstr, 0 }, /* 115 = s */ @@ -631,6 +719,7 @@ mdb_fmt_print(mdb_tgt_t *t, mdb_tgt_as_t as, mdb_fmt_func_f *funcp; uintmax_t rvalue; void *buf; + uint_t oflags = mdb.m_flags; union { uint64_t i8; @@ -645,6 +734,14 @@ mdb_fmt_print(mdb_tgt_t *t, mdb_tgt_as_t as, return (addr); } + if (!(fp->f_type & FMT_NOAUTOWRAP)) { + /* + * Unless a format has explicitly opted out, we force autowrap + * for the duration of mdb_fmt_print(). + */ + mdb.m_flags |= MDB_FL_AUTOWRAP; + } + switch (FMT_TYPE(fp->f_type)) { case FMT_FUNC: funcp = (mdb_fmt_func_f *)fp->f_ptr; @@ -719,6 +816,8 @@ mdb_fmt_print(mdb_tgt_t *t, mdb_tgt_as_t as, warn("invalid format character -- '%c'\n", fmt); } + mdb.m_flags = oflags; + return (addr); } diff --git a/usr/src/cmd/mdb/common/mdb/mdb_grammar.y b/usr/src/cmd/mdb/common/mdb/mdb_grammar.y index 97ea454627..05171acdef 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_grammar.y +++ b/usr/src/cmd/mdb/common/mdb/mdb_grammar.y @@ -26,7 +26,7 @@ */ /* - * Copyright (c) 2015, Joyent, Inc. All rights reserved. + * Copyright (c) 2019, Joyent, Inc. All rights reserved. */ #include <mdb/mdb_types.h> @@ -112,6 +112,7 @@ yyexpand(int val) %left MDB_TOK_LSHIFT MDB_TOK_RSHIFT %left '-' '+' %left '*' '%' '#' +%left MDB_TOK_MODULUS %right MDB_COR_VALUE %right MDB_OBJ_VALUE @@ -309,6 +310,16 @@ expression: expression '+' expression { $$ = $1 + $3; } $$ = (intmax_t)$1 / (intmax_t)$3; } + | expression MDB_TOK_MODULUS expression { + + if ($3 == 0UL) + yyerror("attempted to divide by zero"); + + $$ = $1 % $3; + } + + + | expression '&' expression { $$ = $1 & $3; } | expression '|' expression { $$ = $1 | $3; } | expression '^' expression { $$ = $1 ^ $3; } diff --git a/usr/src/cmd/mdb/common/mdb/mdb_io.c b/usr/src/cmd/mdb/common/mdb/mdb_io.c index a1ebc1ebc2..f1ad8d051c 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_io.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_io.c @@ -24,7 +24,7 @@ */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2019, Joyent, Inc. All rights reserved. * Copyright (c) 2016 by Delphix. All rights reserved. */ @@ -155,14 +155,21 @@ typedef struct { #define CTRL(c) ((c) & 0x01f) #endif +#define IOB_AUTOWRAP(iob) \ + ((mdb.m_flags & MDB_FL_AUTOWRAP) && \ + ((iob)->iob_flags & MDB_IOB_AUTOWRAP)) + /* * Define macro for determining if we should automatically wrap to the next * line of output, based on the amount of consumed buffer space and the - * specified size of the next thing to be inserted (n). + * specified size of the next thing to be inserted (n) -- being careful to + * not force a spurious wrap if we're autoindented and already at the margin. */ #define IOB_WRAPNOW(iob, n) \ - (((iob)->iob_flags & MDB_IOB_AUTOWRAP) && ((iob)->iob_nbytes != 0) && \ - ((n) + (iob)->iob_nbytes > (iob)->iob_cols)) + (IOB_AUTOWRAP(iob) && (iob)->iob_nbytes != 0 && \ + ((n) + (iob)->iob_nbytes > (iob)->iob_cols) && \ + !(((iob)->iob_flags & MDB_IOB_INDENT) && \ + (iob)->iob_nbytes == (iob)->iob_margin)) /* * Define prompt string and string to erase prompt string for iob_pager @@ -414,7 +421,7 @@ void mdb_iob_destroy(mdb_iob_t *iob) { /* - * Don't flush a pipe, since it may cause a context swith when the + * Don't flush a pipe, since it may cause a context switch when the * other side has already been destroyed. */ if (!mdb_iob_isapipe(iob)) @@ -1809,7 +1816,7 @@ mdb_iob_nputs(mdb_iob_t *iob, const char *s, size_t nbytes) * flush the buffer if we reach the end of a line. */ while (nleft != 0) { - if (iob->iob_flags & MDB_IOB_AUTOWRAP) { + if (IOB_AUTOWRAP(iob)) { ASSERT(iob->iob_cols >= iob->iob_nbytes); n = iob->iob_cols - iob->iob_nbytes; } else { @@ -1827,10 +1834,11 @@ mdb_iob_nputs(mdb_iob_t *iob, const char *s, size_t nbytes) iob->iob_nbytes += m; if (m == n && nleft != 0) { - if (iob->iob_flags & MDB_IOB_AUTOWRAP) + if (IOB_AUTOWRAP(iob)) { mdb_iob_nl(iob); - else + } else { mdb_iob_flush(iob); + } } } } @@ -1876,7 +1884,7 @@ mdb_iob_fill(mdb_iob_t *iob, int c, size_t nfill) ASSERT(iob->iob_flags & MDB_IOB_WRONLY); while (nfill != 0) { - if (iob->iob_flags & MDB_IOB_AUTOWRAP) { + if (IOB_AUTOWRAP(iob)) { ASSERT(iob->iob_cols >= iob->iob_nbytes); n = iob->iob_cols - iob->iob_nbytes; } else { @@ -1893,10 +1901,11 @@ mdb_iob_fill(mdb_iob_t *iob, int c, size_t nfill) nfill -= m; if (m == n && nfill != 0) { - if (iob->iob_flags & MDB_IOB_AUTOWRAP) + if (IOB_AUTOWRAP(iob)) { mdb_iob_nl(iob); - else + } else { mdb_iob_flush(iob); + } } } } @@ -1904,7 +1913,7 @@ mdb_iob_fill(mdb_iob_t *iob, int c, size_t nfill) void mdb_iob_ws(mdb_iob_t *iob, size_t n) { - if (iob->iob_nbytes + n < iob->iob_cols) + if (!IOB_AUTOWRAP(iob) || iob->iob_nbytes + n < iob->iob_cols) mdb_iob_fill(iob, ' ', n); else mdb_iob_nl(iob); diff --git a/usr/src/cmd/mdb/common/mdb/mdb_kproc.c b/usr/src/cmd/mdb/common/mdb/mdb_kproc.c index b61b0a2b0b..f09b97db0d 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_kproc.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_kproc.c @@ -553,7 +553,8 @@ kp_vtop(mdb_tgt_t *t, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pap) kp_data_t *kp = t->t_data; physaddr_t pa; - if (as != MDB_TGT_AS_VIRT) + if (as != MDB_TGT_AS_VIRT && as != MDB_TGT_AS_VIRT_I && + as != MDB_TGT_AS_VIRT_S) return (set_errno(EINVAL)); if ((pa = kvm_physaddr(kp->kp_cookie, kp->kp_as, va)) != -1ULL) { diff --git a/usr/src/cmd/mdb/common/mdb/mdb_ks.h b/usr/src/cmd/mdb/common/mdb/mdb_ks.h index 1fe64fbc55..0717e2acce 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_ks.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_ks.h @@ -23,6 +23,10 @@ * Use is subject to license terms. */ +/* + * Copyright (c) 2019, Joyent, Inc. + */ + #ifndef _MDB_KS_H #define _MDB_KS_H @@ -140,6 +144,8 @@ extern const char *mdb_dlpi_prim(int); /* Generic function for working with MAC (network layer 2) addresses. */ extern void mdb_mac_addr(const uint8_t *, size_t, char *, size_t); +extern void mdb_print_gitstatus(void); + /* * Target-specific interfaces * diff --git a/usr/src/cmd/mdb/common/mdb/mdb_kvm.c b/usr/src/cmd/mdb/common/mdb/mdb_kvm.c index 0c2b6efbed..2646e49d6c 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_kvm.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_kvm.c @@ -23,7 +23,7 @@ */ /* - * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2019, Joyent, Inc. */ /* @@ -51,6 +51,7 @@ #include <sys/panic.h> #include <sys/dumphdr.h> #include <sys/dumpadm.h> +#include <sys/uuid.h> #include <dlfcn.h> #include <libctf.h> @@ -68,6 +69,7 @@ #include <mdb/mdb_kvm.h> #include <mdb/mdb_module.h> #include <mdb/mdb_kb.h> +#include <mdb/mdb_ks.h> #include <mdb/mdb.h> #define KT_RELOC_BUF(buf, obase, nbase) \ @@ -94,6 +96,8 @@ typedef struct kt_maparg { static const char KT_MODULE[] = "mdb_ks"; static const char KT_CTFPARENT[] = "genunix"; +static void (*print_gitstatus)(void); + static void kt_load_module(kt_data_t *kt, mdb_tgt_t *t, kt_module_t *km) { @@ -485,6 +489,9 @@ kt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) mdb_printf("operating system: %s %s (%s)\n", uts.release, uts.version, uts.machine); + if (print_gitstatus != NULL) + print_gitstatus(); + if (kt->k_dumphdr) { dumphdr_t *dh = kt->k_dumphdr; @@ -494,11 +501,13 @@ kt_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) kt->k_dump_print_content(dh, kt->k_dumpcontent); } else { - char uuid[37]; + char uuid[UUID_PRINTABLE_STRING_LENGTH]; - if (mdb_readsym(uuid, 37, "dump_osimage_uuid") == 37 && - uuid[36] == '\0') { - mdb_printf("image uuid: %s\n", uuid); + if (mdb_readsym(uuid, sizeof (uuid), + "dump_osimage_uuid") == sizeof (uuid) && + uuid[sizeof (uuid) - 1] == '\0') { + mdb_printf("image uuid: %s\n", uuid[0] != '\0' ? + uuid : "(not set)"); } } @@ -582,6 +591,9 @@ kt_activate(mdb_tgt_t *t) "some modules may not load\n"); } + print_gitstatus = (void (*)(void))dlsym(RTLD_NEXT, + "mdb_print_gitstatus"); + if (mdb_prop_postmortem && kt->k_dumphdr != NULL) { sym = dlsym(RTLD_NEXT, "mdb_dump_print_content"); if (sym != NULL) @@ -802,6 +814,8 @@ kt_vtop(mdb_tgt_t *t, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pap) case (uintptr_t)MDB_TGT_AS_IO: return (set_errno(EINVAL)); case (uintptr_t)MDB_TGT_AS_VIRT: + case (uintptr_t)MDB_TGT_AS_VIRT_I: + case (uintptr_t)MDB_TGT_AS_VIRT_S: asp = kt->k_as; break; default: diff --git a/usr/src/cmd/mdb/common/mdb/mdb_lex.l b/usr/src/cmd/mdb/common/mdb/mdb_lex.l index e777039c7b..7723f00f9e 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_lex.l +++ b/usr/src/cmd/mdb/common/mdb/mdb_lex.l @@ -28,6 +28,7 @@ /* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2017 by Delphix. All rights reserved. + * Copyright 2019, Joyent, Inc. */ #include <sys/types.h> @@ -131,6 +132,9 @@ RGX_COMMENT "//".*\n <S_INITIAL>"!=" | <S_EXPR>"!=" return (MDB_TOK_NOTEQUAL); /* Inequality operator */ +<S_INITIAL>"%%" | +<S_EXPR>"%%" return (MDB_TOK_MODULUS); /* Modulus operator */ + <S_INITIAL>"!" | <S_FMTLIST>"!" | <S_ARGLIST>"!" { diff --git a/usr/src/cmd/mdb/common/mdb/mdb_main.c b/usr/src/cmd/mdb/common/mdb/mdb_main.c index 7feec28a40..f2d6b2c368 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_main.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_main.c @@ -25,7 +25,7 @@ */ /* - * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -51,6 +51,7 @@ #include <libctf.h> #include <errno.h> #include <kvm.h> +#include <zone.h> #include <mdb/mdb_lex.h> #include <mdb/mdb_debug.h> @@ -322,12 +323,13 @@ static void usage(int status) { mdb_iob_printf(mdb.m_err, "Usage: %s [-fkmuwyAFKMSUW] [+/-o option] " - "[-p pid] [-s dist] [-I path] [-L path]\n\t[-P prompt] " + "[-b VM] [-p pid] [-s dist] [-I path] [-L path]\n\t[-P prompt] " "[-R root] [-V dis-version] [-e expr] " "[object [core] | core | suffix]\n\n", mdb.m_pname); mdb_iob_puts(mdb.m_err, + "\t-b attach to specified bhyve VM\n" "\t-e evaluate expr and return status\n" "\t-f force raw file debugging mode\n" "\t-k force kernel debugging mode\n" @@ -405,6 +407,19 @@ identify_xvm_file(const char *file, int *longmode) } #endif /* __x86 */ +#ifndef __amd64 +/* + * There is no bhyve target in a 32bit x86 or any SPARC mdb. This dummy helps + * keep the code simpler. + */ +/*ARGSUSED*/ +static int +mdb_bhyve_tgt_create(mdb_tgt_t *t, int argc, const char *argv[]) +{ + return (set_errno(EINVAL)); +} +#endif + int main(int argc, char *argv[], char *envp[]) { @@ -424,6 +439,7 @@ main(int argc, char *argv[], char *envp[]) const char *Iflag = NULL, *Lflag = NULL, *Vflag = NULL, *pidarg = NULL; const char *eflag = NULL; int fflag = 0, Kflag = 0, Rflag = 0, Sflag = 0, Oflag = 0, Uflag = 0; + int bflag = 0; int ttylike; int longmode = 0; @@ -511,8 +527,12 @@ main(int argc, char *argv[], char *envp[]) while (optind < argc) { while ((c = getopt(argc, argv, - "e:fkmo:p:s:uwyACD:FI:KL:MOP:R:SUV:W")) != (int)EOF) { + "be:fkmo:p:s:uwyACD:FI:KL:MOP:R:SUV:W")) != (int)EOF) { switch (c) { + case 'b': + bflag++; + tgt_ctor = mdb_bhyve_tgt_create; + break; case 'e': if (eflag != NULL) { warn("-e already specified\n"); @@ -797,9 +817,15 @@ main(int argc, char *argv[], char *envp[]) if (strchr(pidarg, '/') != NULL) (void) mdb_iob_snprintf(object, MAXPATHLEN, "%s/object/a.out", pidarg); - else + else { + const char *root; + (void) mdb_iob_snprintf(object, MAXPATHLEN, - "/proc/%s/object/a.out", pidarg); + "%s/proc/%s/object/a.out", + (root = zone_get_nroot()) != NULL ? root : "", + pidarg); + } + tgt_argv[tgt_argc++] = object; tgt_argv[tgt_argc++] = pidarg; } @@ -828,6 +854,15 @@ main(int argc, char *argv[], char *envp[]) if (fflag) goto tcreate; /* skip re-exec and just create target */ + /* bhyve: directly create target, or re-exec in case of 32bit */ + if (bflag) { +#ifndef __amd64 + goto reexec; +#else + goto tcreate; +#endif + } + /* * If we just have an object file name, and that file doesn't * exist, and it's a string of digits, infer it to be a diff --git a/usr/src/cmd/mdb/common/mdb/mdb_modapi.h b/usr/src/cmd/mdb/common/mdb/mdb_modapi.h index 7b4f7ecb2d..0e53be9b4d 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_modapi.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_modapi.h @@ -22,7 +22,7 @@ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 by Delphix. All rights reserved. - * Copyright (c) 2012 Joyent, Inc. All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. */ #ifndef _MDB_MODAPI_H @@ -80,11 +80,6 @@ extern "C" { #define DCMD_HDRSPEC(fl) (((fl) & DCMD_LOOPFIRST) || !((fl) & DCMD_LOOP)) /* - * Debugger tab command function flags - */ -#define DCMD_TAB_SPACE 0x01 /* Tab cb invoked with trailing space */ - -/* * Debugger command function return values: */ #define DCMD_OK 0 /* Dcmd completed successfully */ @@ -113,10 +108,18 @@ typedef struct mdb_arg { } a_un; } mdb_arg_t; +#if (MDB_API_VERSION >= 4) +/* + * Debugger tab command function flags + */ +#define DCMD_TAB_SPACE 0x01 /* Tab cb invoked with trailing space */ + typedef struct mdb_tab_cookie mdb_tab_cookie_t; -typedef int mdb_dcmd_f(uintptr_t, uint_t, int, const mdb_arg_t *); typedef int mdb_dcmd_tab_f(mdb_tab_cookie_t *, uint_t, int, const mdb_arg_t *); +#endif /* MDB_API_VERSION >= 4 */ + +typedef int mdb_dcmd_f(uintptr_t, uint_t, int, const mdb_arg_t *); typedef struct mdb_dcmd { const char *dc_name; /* Command name */ @@ -124,7 +127,9 @@ typedef struct mdb_dcmd { const char *dc_descr; /* Description */ mdb_dcmd_f *dc_funcp; /* Command function */ void (*dc_help)(void); /* Command help function (or NULL) */ +#if (MDB_API_VERSION >= 4) mdb_dcmd_tab_f *dc_tabp; /* Tab completion function */ +#endif } mdb_dcmd_t; #define WALK_ERR -1 /* Walk fatal error (terminate walk) */ @@ -346,6 +351,7 @@ typedef void (*mdb_callback_f)(void *); extern void *mdb_callback_add(int, mdb_callback_f, void *); extern void mdb_callback_remove(void *); +#if (MDB_API_VERSION >= 4) #define MDB_TABC_ALL_TYPES 0x1 /* Include array types in type output */ #define MDB_TABC_MEMBERS 0x2 /* Tab comp. types with members */ #define MDB_TABC_NOPOINT 0x4 /* Tab comp. everything but pointers */ @@ -370,6 +376,7 @@ extern int mdb_tab_typename(int *, const mdb_arg_t **, char *buf, size_t len); */ extern int mdb_tab_complete_mt(mdb_tab_cookie_t *, uint_t, int, const mdb_arg_t *); +#endif /* MDB_API_VERSION >= 4 */ extern size_t strlcat(char *, const char *, size_t); extern char *strcat(char *, const char *); diff --git a/usr/src/cmd/mdb/common/mdb/mdb_print.c b/usr/src/cmd/mdb/common/mdb/mdb_print.c index b39c7e87fe..2c0af13a25 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_print.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_print.c @@ -25,7 +25,7 @@ /* * Copyright (c) 2012, 2014 by Delphix. All rights reserved. - * Copyright 2015 Joyent, Inc. + * Copyright 2018 Joyent, Inc. * Copyright (c) 2014 Nexenta Systems, Inc. All rights reserved. */ @@ -1681,6 +1681,52 @@ elt_print(const char *name, mdb_ctf_id_t id, mdb_ctf_id_t base, mdb_printf("%s%s", pap->pa_prefix, (depth == 0) ? "" : pap->pa_suffix); mdb_printf("%s", name); + + /* + * When no name is present (i.e. an unnamed struct or union), + * display '(anon)' instead only when no prefix is present. + * When printing out a struct or union (sou), prefixes are + * only present (i.e. !NULL or non-empty) when printing + * individual members of that sou, e.g. + * `::print struct foo f_member`. When printing an entire sou, + * the prefix will be NULL or empty. We end up with: + * + * > ::print struct foo + * { + * ... + * f_member = 0xabcd + * (anon) = { + * anon_member = 0x1234 + * .... + * } + * ... + * } + * + * and + * + * > ::print struct foo anon_member + * anon_member = 0x1234 + * + * instead of: + * + * > ::print struct foo + * { + * ... + * f_member = 0xabcd + * = { + * anon_member = 0x1234 + * } + * ... + * } + * + * and + * + * > ::print struct foo anon_member + * anon_member(anon) = 0x1234 + */ + if (depth > 0 && strlen(name) == 0 && + (pap->pa_prefix == NULL || strlen(pap->pa_prefix) == 0)) + mdb_printf("(anon)"); } if ((pap->pa_flags & PA_SHOWTYPE) && kind == CTF_K_INTEGER) { @@ -1699,8 +1745,9 @@ elt_print(const char *name, mdb_ctf_id_t id, mdb_ctf_id_t base, } if (depth != 0 || - ((pap->pa_flags & PA_SHOWNAME) && pap->pa_prefix != NULL)) + ((pap->pa_flags & PA_SHOWNAME) && pap->pa_prefix != NULL)) { mdb_printf("%s ", pap->pa_flags & PA_SHOWVAL ? " =" : ""); + } if (depth == 0 && pap->pa_prefix != NULL) name = pap->pa_prefix; @@ -2106,10 +2153,10 @@ cmd_print_tab_common(mdb_tab_cookie_t *mcp, uint_t flags, int argc, /* * This is the reason that tab completion was created. We're going to go - * along and walk the delimiters until we find something a member that - * we don't recognize, at which point we'll try and tab complete it. - * Note that ::print takes multiple args, so this is going to operate on - * whatever the last arg that we have is. + * along and walk the delimiters until we find something in a member + * that we don't recognize, at which point we'll try and tab complete + * it. Note that ::print takes multiple args, so this is going to + * operate on whatever the last arg that we have is. */ if (mdb_ctf_lookup_by_name(tn, &id) != 0) return (1); @@ -2119,11 +2166,11 @@ cmd_print_tab_common(mdb_tab_cookie_t *mcp, uint_t flags, int argc, delim = parse_delimiter(&start); /* - * If we hit the case where we actually have no delimiters, than we need + * If we hit the case where we actually have no delimiters, then we need * to make sure that we properly set up the fields the loops would. */ if (delim == MEMBER_DELIM_DONE) - (void) mdb_snprintf(member, sizeof (member), "%s", start); + (void) mdb_snprintf(member, sizeof (member), start); while (delim != MEMBER_DELIM_DONE) { switch (delim) { @@ -2180,7 +2227,7 @@ cmd_print_tab_common(mdb_tab_cookie_t *mcp, uint_t flags, int argc, /* * We are going to try to resolve this name as a member. There - * are a few two different questions that we need to answer. The + * are a two different questions that we need to answer. The * first is do we recognize this member. The second is are we at * the end of the string. If we encounter a member that we don't * recognize before the end, then we have to error out and can't @@ -2210,6 +2257,7 @@ cmd_print_tab_common(mdb_tab_cookie_t *mcp, uint_t flags, int argc, * already have in rid. */ return (mdb_tab_complete_member_by_id(mcp, rid, member)); + } int @@ -2419,8 +2467,10 @@ cmd_print(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) kind = mdb_ctf_type_kind(rid); if (last_deref && IS_SOU(kind)) { char *end; + size_t len = strlen(member); (void) mdb_snprintf(buf, sizeof (buf), - "%s", member); + "%s", (len == 0) ? + "<anon>" : member); end = strrchr(buf, '['); *end = '\0'; pa.pa_suffix = "->"; @@ -2539,8 +2589,7 @@ print_help(void) } static int -printf_signed(mdb_ctf_id_t id, uintptr_t addr, ulong_t off, char *fmt, - boolean_t sign) +printf_signed(mdb_ctf_id_t id, uintptr_t addr, ulong_t off, char *fmt, int sign) { ssize_t size; mdb_ctf_id_t base; @@ -2558,7 +2607,7 @@ printf_signed(mdb_ctf_id_t id, uintptr_t addr, ulong_t off, char *fmt, } u; if (mdb_ctf_type_resolve(id, &base) == -1) { - mdb_warn("could not resolve type"); + mdb_warn("could not resolve type\n"); return (DCMD_ABORT); } @@ -2796,7 +2845,6 @@ printf_string(mdb_ctf_id_t id, uintptr_t addr, ulong_t off, char *fmt) if (size != 1) { mdb_warn("string format specifier requires " "an array of characters\n"); - return (DCMD_ABORT); } bzero(buf, sizeof (buf)); @@ -2930,7 +2978,7 @@ cmd_printf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) if (argc == 0 || argv[0].a_type != MDB_TYPE_STRING) { mdb_warn("expected a format string\n"); - return (DCMD_USAGE); + return (DCMD_ABORT); } /* @@ -2939,12 +2987,6 @@ cmd_printf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) * subset of mdb_printf() format strings that we allow. */ fmt = argv[0].a_un.a_str; - /* - * 'dest' must be large enough to hold a copy of the format string, - * plus a NUL and up to 2 additional characters for each conversion - * in the format string. This gives us a bloat factor of 5/2 ~= 3. - * e.g. "%d" (strlen of 2) --> "%lld\0" (need 5 bytes) - */ dest = mdb_zalloc(strlen(fmt) * 3, UM_SLEEP | UM_GC); fmts = mdb_zalloc(strlen(fmt) * sizeof (char *), UM_SLEEP | UM_GC); funcs = mdb_zalloc(strlen(fmt) * sizeof (void *), UM_SLEEP | UM_GC); @@ -3128,22 +3170,22 @@ static char _mdb_printf_help[] = "\n" " %% Prints the '%' symbol.\n" " %a Prints the member in symbolic form.\n" -" %d Prints the member as a decimal integer. If the member is a signed\n" +" %d Prints the member as a decimal integer. If the member is a signed\n" " integer type, the output will be signed.\n" " %H Prints the member as a human-readable size.\n" " %I Prints the member as an IPv4 address (must be 32-bit integer type).\n" " %N Prints the member as an IPv6 address (must be of type in6_addr_t).\n" " %o Prints the member as an unsigned octal integer.\n" " %p Prints the member as a pointer, in hexadecimal.\n" -" %q Prints the member in signed octal. Honk if you ever use this!\n" -" %r Prints the member as an unsigned value in the current output radix.\n" -" %R Prints the member as a signed value in the current output radix.\n" +" %q Prints the member in signed octal. Honk if you ever use this!\n" +" %r Prints the member as an unsigned value in the current output radix. \n" +" %R Prints the member as a signed value in the current output radix. \n" " %s Prints the member as a string (requires a pointer or an array of\n" " characters).\n" " %u Prints the member as an unsigned decimal integer.\n" " %x Prints the member in hexadecimal.\n" " %X Prints the member in hexadecimal, using the characters A-F as the\n" -" digits for the values 10-15.\n" +" digits for the values 10-15. \n" " %Y Prints the member as a time_t as the string " "'year month day HH:MM:SS'.\n" "\n" @@ -3156,13 +3198,13 @@ static char _mdb_printf_help[] = "\n" "The following flag specifers are recognized by ::printf:\n" "\n" -" %- Left-justify the output within the specified field width. If the\n" +" %- Left-justify the output within the specified field width. If the\n" " width of the output is less than the specified field width, the\n" -" output will be padded with blanks on the right-hand side. Without\n" +" output will be padded with blanks on the right-hand side. Without\n" " %-, values are right-justified by default.\n" "\n" " %0 Zero-fill the output field if the output is right-justified and the\n" -" width of the output is less than the specified field width. Without\n" +" width of the output is less than the specified field width. Without\n" " %0, right-justified values are prepended with blanks in order to\n" " fill the field.\n" "\n" diff --git a/usr/src/cmd/mdb/common/mdb/mdb_rawfile.c b/usr/src/cmd/mdb/common/mdb/mdb_rawfile.c index d2857a6579..529b71a581 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_rawfile.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_rawfile.c @@ -143,6 +143,8 @@ rf_aread(mdb_tgt_t *t, mdb_tgt_as_t as, void *buf, { switch ((uintptr_t)as) { case (uintptr_t)MDB_TGT_AS_VIRT: + case (uintptr_t)MDB_TGT_AS_VIRT_I: + case (uintptr_t)MDB_TGT_AS_VIRT_S: case (uintptr_t)MDB_TGT_AS_PHYS: if (RF_CORE(t->t_data) != NULL) return (rf_read(RF_CORE(t->t_data), buf, len, addr)); @@ -160,6 +162,8 @@ rf_awrite(mdb_tgt_t *t, mdb_tgt_as_t as, const void *buf, { switch ((uintptr_t)as) { case (uintptr_t)MDB_TGT_AS_VIRT: + case (uintptr_t)MDB_TGT_AS_VIRT_I: + case (uintptr_t)MDB_TGT_AS_VIRT_S: case (uintptr_t)MDB_TGT_AS_PHYS: if (RF_CORE(t->t_data) != NULL) return (rf_write(RF_CORE(t->t_data), buf, len, addr)); diff --git a/usr/src/cmd/mdb/common/mdb/mdb_set.c b/usr/src/cmd/mdb/common/mdb/mdb_set.c index c1c8538219..cd8926fbcc 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_set.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_set.c @@ -24,6 +24,10 @@ */ /* + * Copyright 2017 Joyent, Inc. + */ + +/* * Support for ::set dcmd. The +/-o option processing code is provided in a * stand-alone function so it can be used by the command-line option processing * code in mdb_main.c. This facility provides an easy way for us to add more @@ -165,6 +169,7 @@ mdb_set_options(const char *s, int enable) { "pager", opt_pager, MDB_FL_PAGER }, { "term", opt_set_term, 0 }, + { "autowrap", opt_set_mflags, MDB_FL_AUTOWRAP }, { "ignoreeof", opt_set_mflags, MDB_FL_IGNEOF }, { "repeatlast", opt_set_mflags, MDB_FL_REPLAST }, { "latest", opt_set_mflags, MDB_FL_LATEST }, @@ -265,6 +270,13 @@ print_properties(void) mdb_printf("%*s ", LABEL_INDENT, "debugger options:"); (void) mdb_inc_indent(LABEL_INDENT + 1); + /* + * The ::set output implicitly relies on "autowrap" being enabled, so + * we enable it for the duration of the command. + */ + oflags = mdb.m_flags; + mdb.m_flags |= MDB_FL_AUTOWRAP; + mdb_printf("follow_exec_mode="); switch (mdb.m_execmode) { case MDB_EM_ASK: @@ -295,6 +307,8 @@ print_properties(void) if (mdb.m_flags & MDB_FL_ADB) COMMAFLAG("adb"); + if (oflags & MDB_FL_AUTOWRAP) + COMMAFLAG("autowrap"); if (mdb.m_flags & MDB_FL_IGNEOF) COMMAFLAG("ignoreeof"); if (mdb.m_flags & MDB_FL_LMRAW) @@ -331,6 +345,8 @@ print_properties(void) COMMAFLAG("no-stop"); mdb_printf("\n"); (void) mdb_dec_indent(LABEL_INDENT + 1); + + mdb.m_flags = oflags; } /*ARGSUSED*/ diff --git a/usr/src/cmd/mdb/common/mdb/mdb_tab.c b/usr/src/cmd/mdb/common/mdb/mdb_tab.c index 8addc11a46..cd6995f887 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_tab.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_tab.c @@ -388,11 +388,6 @@ mdb_tab_size(mdb_tab_cookie_t *mcp) return (mdb_nv_size(&mcp->mtc_nv)); } -/* - * Determine whether the specified name is a valid tab completion for - * the given command. If the name is a valid tab completion then - * it will be saved in the mdb_tab_cookie_t. - */ void mdb_tab_insert(mdb_tab_cookie_t *mcp, const char *name) { @@ -501,31 +496,18 @@ tab_complete_type(mdb_ctf_id_t id, void *arg) mdb_tab_cookie_t *mcp = arg; uint_t flags = (uint_t)(uintptr_t)mcp->mtc_cba; - /* - * CTF data includes types that mdb commands don't understand. Before - * we resolve the actual type prune any entry that is a type we - * don't care about. - */ - switch (mdb_ctf_type_kind(id)) { - case CTF_K_CONST: - case CTF_K_RESTRICT: - case CTF_K_VOLATILE: - return (0); - } - if (mdb_ctf_type_resolve(id, &rid) != 0) return (1); rkind = mdb_ctf_type_kind(rid); - - if ((flags & MDB_TABC_MEMBERS) && rkind != CTF_K_STRUCT && + if (flags & MDB_TABC_MEMBERS && rkind != CTF_K_STRUCT && rkind != CTF_K_UNION) return (0); - if ((flags & MDB_TABC_NOPOINT) && rkind == CTF_K_POINTER) + if (flags & MDB_TABC_NOPOINT && rkind == CTF_K_POINTER) return (0); - if ((flags & MDB_TABC_NOARRAY) && rkind == CTF_K_ARRAY) + if (flags & MDB_TABC_NOARRAY && rkind == CTF_K_ARRAY) return (0); (void) mdb_ctf_type_name(id, buf, sizeof (buf)); diff --git a/usr/src/cmd/mdb/common/mdb/mdb_target.c b/usr/src/cmd/mdb/common/mdb/mdb_target.c index 17aef0aac1..e0ae29bd99 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_target.c +++ b/usr/src/cmd/mdb/common/mdb/mdb_target.c @@ -398,6 +398,8 @@ mdb_tgt_aread(mdb_tgt_t *t, mdb_tgt_as_t as, switch ((uintptr_t)as) { case (uintptr_t)MDB_TGT_AS_VIRT: + case (uintptr_t)MDB_TGT_AS_VIRT_I: + case (uintptr_t)MDB_TGT_AS_VIRT_S: return (t->t_ops->t_vread(t, buf, n, addr)); case (uintptr_t)MDB_TGT_AS_PHYS: return (t->t_ops->t_pread(t, buf, n, addr)); @@ -421,6 +423,8 @@ mdb_tgt_awrite(mdb_tgt_t *t, mdb_tgt_as_t as, switch ((uintptr_t)as) { case (uintptr_t)MDB_TGT_AS_VIRT: + case (uintptr_t)MDB_TGT_AS_VIRT_I: + case (uintptr_t)MDB_TGT_AS_VIRT_S: return (t->t_ops->t_vwrite(t, buf, n, addr)); case (uintptr_t)MDB_TGT_AS_PHYS: return (t->t_ops->t_pwrite(t, buf, n, addr)); diff --git a/usr/src/cmd/mdb/common/mdb/mdb_target.h b/usr/src/cmd/mdb/common/mdb/mdb_target.h index c36b85e2f3..e385caa38e 100644 --- a/usr/src/cmd/mdb/common/mdb/mdb_target.h +++ b/usr/src/cmd/mdb/common/mdb/mdb_target.h @@ -64,6 +64,9 @@ extern int mdb_kvm_tgt_create(mdb_tgt_t *, int, const char *[]); extern int mdb_proc_tgt_create(mdb_tgt_t *, int, const char *[]); extern int mdb_kproc_tgt_create(mdb_tgt_t *, int, const char *[]); extern int mdb_rawfile_tgt_create(mdb_tgt_t *, int, const char *[]); +#ifdef __amd64 +extern int mdb_bhyve_tgt_create(mdb_tgt_t *, int, const char *[]); +#endif #else extern int kmdb_kvm_create(mdb_tgt_t *, int, const char *[]); #endif @@ -139,10 +142,12 @@ typedef void * mdb_tgt_as_t; /* Opaque address space id */ typedef uint64_t mdb_tgt_addr_t; /* Generic unsigned address */ typedef uint64_t physaddr_t; /* Physical memory address */ -#define MDB_TGT_AS_VIRT ((mdb_tgt_as_t)-1L) /* Virtual address space */ -#define MDB_TGT_AS_PHYS ((mdb_tgt_as_t)-2L) /* Physical address space */ -#define MDB_TGT_AS_FILE ((mdb_tgt_as_t)-3L) /* Object file address space */ -#define MDB_TGT_AS_IO ((mdb_tgt_as_t)-4L) /* I/o address space */ +#define MDB_TGT_AS_VIRT ((mdb_tgt_as_t)-1L) /* Virtual address space: */ +#define MDB_TGT_AS_VIRT_I ((mdb_tgt_as_t)-2L) /* special case for code */ +#define MDB_TGT_AS_VIRT_S ((mdb_tgt_as_t)-3L) /* special case for stack */ +#define MDB_TGT_AS_PHYS ((mdb_tgt_as_t)-4L) /* Physical address space */ +#define MDB_TGT_AS_FILE ((mdb_tgt_as_t)-5L) /* Object file address space */ +#define MDB_TGT_AS_IO ((mdb_tgt_as_t)-6L) /* I/o address space */ extern ssize_t mdb_tgt_aread(mdb_tgt_t *, mdb_tgt_as_t, void *, size_t, mdb_tgt_addr_t); diff --git a/usr/src/cmd/mdb/common/modules/genunix/Makefile.files b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files index c78f42e7cb..44ed819316 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/Makefile.files +++ b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files @@ -21,7 +21,7 @@ # # Copyright 2011 Nexenta Systems, Inc. All rights reserved. # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright (c) 2019, Joyent, Inc. +# Copyright 2019, Joyent, Inc. # Copyright (c) 2013 by Delphix. All rights reserved. # @@ -69,8 +69,10 @@ GENUNIX_SRCS = \ net.c \ netstack.c \ nvpair.c \ + pci.c \ pg.c \ rctl.c \ + refhash.c \ sobj.c \ streams.c \ sysevent.c \ diff --git a/usr/src/cmd/mdb/common/modules/genunix/ctxop.c b/usr/src/cmd/mdb/common/modules/genunix/ctxop.c index 486113031d..c8a59ce9ac 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/ctxop.c +++ b/usr/src/cmd/mdb/common/modules/genunix/ctxop.c @@ -23,54 +23,98 @@ * Copyright (c) 2000 by Sun Microsystems, Inc. * All rights reserved. */ +/* + * Copyright 2018 Joyent, Inc. + */ #include <sys/mdb_modapi.h> +#include <mdb/mdb_ctf.h> #include <sys/thread.h> #include "ctxop.h" +struct ctxop_walk_state { + uintptr_t cws_head; + uint_t cws_next_offset; +}; + int ctxop_walk_init(mdb_walk_state_t *wsp) { - kthread_t thread, *tp = &thread; + struct ctxop_walk_state *priv; + int offset; + uintptr_t addr; if (wsp->walk_addr == 0) { mdb_warn("must specify thread for ctxop walk\n"); return (WALK_ERR); } - if (mdb_vread(tp, sizeof (*tp), wsp->walk_addr) == -1) { - mdb_warn("failed to read thread at %p", wsp->walk_addr); + + offset = mdb_ctf_offsetof_by_name("kthread_t", "t_ctx"); + if (offset == -1) + return (WALK_ERR); + + if (mdb_vread(&addr, sizeof (addr), + wsp->walk_addr + offset) != sizeof (addr)) { + mdb_warn("failed to read thread %p", wsp->walk_addr); return (WALK_ERR); } - wsp->walk_data = mdb_alloc(sizeof (ctxop_t), UM_SLEEP); - wsp->walk_addr = (uintptr_t)tp->t_ctx; + /* No further work for threads with a NULL t_ctx */ + if (addr == 0) { + wsp->walk_data = NULL; + return (WALK_DONE); + } + /* rely on CTF for the offset of the 'next' pointer */ + offset = mdb_ctf_offsetof_by_name("struct ctxop", "next"); + if (offset == -1) + return (WALK_ERR); + + priv = mdb_alloc(sizeof (*priv), UM_SLEEP); + priv->cws_head = addr; + priv->cws_next_offset = (uint_t)offset; + + wsp->walk_data = priv; + wsp->walk_addr = addr; return (WALK_NEXT); } int ctxop_walk_step(mdb_walk_state_t *wsp) { + struct ctxop_walk_state *priv = wsp->walk_data; + uintptr_t next; int status; - if (wsp->walk_addr == 0) - return (WALK_DONE); - - if (mdb_vread(wsp->walk_data, - sizeof (ctxop_t), wsp->walk_addr) == -1) { - mdb_warn("failed to read ctxop at %p", wsp->walk_addr); + if (mdb_vread(&next, sizeof (next), + wsp->walk_addr + priv->cws_next_offset) == -1) { + mdb_warn("failed to read ctxop`next at %p", + wsp->walk_addr + priv->cws_next_offset); return (WALK_DONE); } - status = wsp->walk_callback(wsp->walk_addr, wsp->walk_data, - wsp->walk_cbdata); + status = wsp->walk_callback(wsp->walk_addr, NULL, wsp->walk_cbdata); - wsp->walk_addr = (uintptr_t)(((ctxop_t *)wsp->walk_data)->next); + if (status == WALK_NEXT) { + /* + * If a NULL terminator or a loop back to the head element is + * encountered, the walk is done. + */ + if (next == 0 || next == priv->cws_head) { + status = WALK_DONE; + } + } + + wsp->walk_addr = next; return (status); } void ctxop_walk_fini(mdb_walk_state_t *wsp) { - mdb_free(wsp->walk_data, sizeof (ctxop_t)); + struct ctxop_walk_state *priv = wsp->walk_data; + + if (priv != NULL) { + mdb_free(priv, sizeof (*priv)); + } } diff --git a/usr/src/cmd/mdb/common/modules/genunix/ctxop.h b/usr/src/cmd/mdb/common/modules/genunix/ctxop.h index 529db3844c..0d0af0b931 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/ctxop.h +++ b/usr/src/cmd/mdb/common/modules/genunix/ctxop.h @@ -27,8 +27,6 @@ #ifndef _MDB_CTXOP_H #define _MDB_CTXOP_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <mdb/mdb_modapi.h> #ifdef __cplusplus diff --git a/usr/src/cmd/mdb/common/modules/genunix/devinfo.c b/usr/src/cmd/mdb/common/modules/genunix/devinfo.c index 61bb29777a..0d7492e6b7 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/devinfo.c +++ b/usr/src/cmd/mdb/common/modules/genunix/devinfo.c @@ -41,6 +41,7 @@ #include <mdb/mdb_ks.h> #include "nvpair.h" +#include "pci.h" #include "devinfo.h" #define DEVINFO_TREE_INDENT 4 /* Indent for devs one down in tree */ @@ -78,15 +79,22 @@ prtconf_help(void) " -v be verbose - print device property lists\n" " -p only print the ancestors of the given node\n" " -c only print the children of the given node\n" - " -d driver only print instances of driver\n"); + " -d driver only print instances of driver\n" + " -i inst only print if the driver instance number is inst\n"); } void devinfo_help(void) { mdb_printf("Switches:\n" - " -q be quiet - don't print device property lists\n" - " -s print summary of dev_info structures\n"); + " -b type print bus of device if it matches type\n" + " -d print device private data\n" + " -q be quiet - don't print device property lists\n" + " -s print summary of dev_info structures\n" + "\n" + "The following types are supported for -b:\n" + "\n" + " * pcie print the PCI Express bus (pcie_bus_t)\n"); } @@ -995,6 +1003,11 @@ devinfo_print(uintptr_t addr, struct dev_info *dev, devinfo_cb_data_t *data) return (WALK_NEXT); } + if (data->di_instance != UINT64_MAX && + data->di_instance != (uint64_t)dev->devi_instance) { + return (WALK_NEXT); + } + /* * If we are output to a pipe, we only print the address of the * devinfo_t. @@ -1048,12 +1061,14 @@ prtconf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) data.di_flags = DEVINFO_PARENT | DEVINFO_CHILD; data.di_filter = NULL; + data.di_instance = UINT64_MAX; if (flags & DCMD_PIPE_OUT) data.di_flags |= DEVINFO_PIPE; if (mdb_getopts(argc, argv, 'd', MDB_OPT_STR, &data.di_filter, + 'i', MDB_OPT_UINT64, &data.di_instance, 'v', MDB_OPT_SETBITS, DEVINFO_VERBOSE, &data.di_flags, 'p', MDB_OPT_CLRBITS, DEVINFO_CHILD, &data.di_flags, 'c', MDB_OPT_CLRBITS, DEVINFO_PARENT, &data.di_flags, NULL) != argc) @@ -1113,6 +1128,7 @@ devinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) struct dev_info devi; devinfo_node_t din; devinfo_cb_data_t data; + char *bus = NULL; static const mdb_bitmask_t devi_state_masks[] = { { "DEVICE_OFFLINE", DEVI_DEVICE_OFFLINE, DEVI_DEVICE_OFFLINE }, @@ -1155,20 +1171,64 @@ devinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) data.di_flags = DEVINFO_VERBOSE; data.di_base = addr; data.di_filter = NULL; + data.di_instance = UINT64_MAX; if (mdb_getopts(argc, argv, + 'b', MDB_OPT_STR, &bus, + 'd', MDB_OPT_SETBITS, DEVINFO_DRIVER, &data.di_flags, 'q', MDB_OPT_CLRBITS, DEVINFO_VERBOSE, &data.di_flags, 's', MDB_OPT_SETBITS, DEVINFO_SUMMARY, &data.di_flags, NULL) != argc) return (DCMD_USAGE); + if (bus != NULL && data.di_flags != DEVINFO_VERBOSE) { + mdb_warn("the -b option cannot be used with other options\n"); + return (DCMD_USAGE); + } + + if ((data.di_flags & DEVINFO_DRIVER) != 0 && + data.di_flags != (DEVINFO_DRIVER | DEVINFO_VERBOSE)) { + mdb_warn("the -d option cannot be used with other options\n"); + return (DCMD_USAGE); + } + if ((flags & DCMD_ADDRSPEC) == 0) { mdb_warn( "devinfo doesn't give global information (try prtconf)\n"); return (DCMD_ERR); } - if (DCMD_HDRSPEC(flags) && data.di_flags & DEVINFO_SUMMARY) + if (mdb_vread(&devi, sizeof (devi), addr) == -1) { + mdb_warn("failed to read device"); + return (DCMD_ERR); + } + + if (bus != NULL) { + if (strcmp(bus, "pcie") == 0) { + uintptr_t bus_addr; + if (pcie_bus_match(&devi, &bus_addr)) { + mdb_printf("%p\n", bus_addr); + return (DCMD_OK); + } else { + mdb_warn("%p does not have a PCIe bus\n", + addr); + } + } + + mdb_warn("unknown bus type: %s\n", bus); + return (DCMD_ERR); + } + + if ((data.di_flags & DEVINFO_DRIVER) != 0) { + if ((flags & DCMD_PIPE_OUT) != 0 && + devi.devi_driver_data == NULL) { + return (DCMD_OK); + } + mdb_printf("%p\n", devi.devi_driver_data); + return (DCMD_OK); + } + + if (DCMD_HDRSPEC(flags) && data.di_flags & DEVINFO_SUMMARY) { mdb_printf( "%-?s %5s %?s %-20s %-s\n" "%-?s %5s %?s %-20s %-s\n" @@ -1176,10 +1236,6 @@ devinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) "DEVINFO", "MAJ", "REFCNT", "NODENAME", "NODESTATE", "", "INST", "CIRCULAR", "BINDNAME", "STATE", "", "", "THREAD", "", "FLAGS"); - - if (mdb_vread(&devi, sizeof (devi), addr) == -1) { - mdb_warn("failed to read device"); - return (DCMD_ERR); } if (data.di_flags & DEVINFO_SUMMARY) { diff --git a/usr/src/cmd/mdb/common/modules/genunix/devinfo.h b/usr/src/cmd/mdb/common/modules/genunix/devinfo.h index 438fc2268f..f8ddc6b046 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/devinfo.h +++ b/usr/src/cmd/mdb/common/modules/genunix/devinfo.h @@ -22,6 +22,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2019, Joyent, Inc. */ #ifndef _DEVINFO_H @@ -43,11 +44,13 @@ extern "C" { #define DEVINFO_SUMMARY 0x10 #define DEVINFO_HP_PHYSICAL 0x20 #define DEVINFO_PIPE 0x40 +#define DEVINFO_DRIVER 0x80 typedef struct devinfo_cb_data { uintptr_t di_base; uint_t di_flags; - char *di_filter; + char *di_filter; + uint64_t di_instance; } devinfo_cb_data_t; extern int devinfo_walk_init(mdb_walk_state_t *); @@ -88,6 +91,7 @@ extern int devt(uintptr_t, uint_t, int, const mdb_arg_t *); extern int softstate(uintptr_t, uint_t, int, const mdb_arg_t *); extern int devinfo_fm(uintptr_t, uint_t, int, const mdb_arg_t *); extern int devinfo_fmce(uintptr_t, uint_t, int, const mdb_arg_t *); +extern int devinfo2bus(uintptr_t, uint_t, int, const mdb_arg_t *); extern int soft_state_walk_init(mdb_walk_state_t *); extern int soft_state_walk_step(mdb_walk_state_t *); @@ -120,6 +124,7 @@ extern int minornodes(uintptr_t, uint_t, int, const mdb_arg_t *); extern void prtconf_help(void); extern void devinfo_help(void); +extern void devinfo2bus_help(void); #ifdef __cplusplus } diff --git a/usr/src/cmd/mdb/common/modules/genunix/genunix.c b/usr/src/cmd/mdb/common/modules/genunix/genunix.c index 61c98952c1..fadd3c110c 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/genunix.c +++ b/usr/src/cmd/mdb/common/modules/genunix/genunix.c @@ -21,7 +21,7 @@ /* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2018, Joyent, Inc. + * Copyright 2019, Joyent, Inc. * Copyright (c) 2013 by Delphix. All rights reserved. */ @@ -95,8 +95,10 @@ #include "net.h" #include "netstack.h" #include "nvpair.h" +#include "pci.h" #include "pg.h" #include "rctl.h" +#include "refhash.h" #include "sobj.h" #include "streams.h" #include "sysevent.h" @@ -114,10 +116,6 @@ */ #define NINTR 16 -#define KILOS 10 -#define MEGS 20 -#define GIGS 30 - #ifndef STACK_BIAS #define STACK_BIAS 0 #endif @@ -2038,24 +2036,24 @@ typedef struct datafmt { } datafmt_t; static datafmt_t kmemfmt[] = { - { "cache ", "name ", - "-------------------------", "%-25s " }, - { " buf", " size", "------", "%6u " }, - { " buf", "in use", "------", "%6u " }, - { " buf", " total", "------", "%6u " }, - { " memory", " in use", "----------", "%10lu%c " }, - { " alloc", " succeed", "---------", "%9u " }, - { "alloc", " fail", "-----", "%5u " }, + { "cache ", "name ", + "------------------------------", "%-30s " }, + { " buf", " size", "-----", "%5H " }, + { " buf", " in use", "---------", "%9u " }, + { " buf", " total", "---------", "%9u " }, + { "memory", "in use", "------", "%6lH " }, + { " alloc", " succeed", "----------", "%10u " }, + { "alloc", " fail", "-----", "%5u" }, { NULL, NULL, NULL, NULL } }; static datafmt_t vmemfmt[] = { - { "vmem ", "name ", - "-------------------------", "%-*s " }, - { " memory", " in use", "----------", "%9llu%c " }, - { " memory", " total", "-----------", "%10llu%c " }, - { " memory", " import", "----------", "%9llu%c " }, - { " alloc", " succeed", "---------", "%9llu " }, + { "vmem ", "name ", + "------------------------------", "%-*s " }, + { " memory", " in use", "---------", "%9llH " }, + { " memory", " total", "----------", "%10llH " }, + { " memory", " import", "---------", "%9llH " }, + { " alloc", " succeed", "----------", "%10llu " }, { "alloc", " fail", "-----", "%5llu " }, { NULL, NULL, NULL, NULL } }; @@ -2107,15 +2105,9 @@ typedef struct kmastat_vmem { int kv_fail; } kmastat_vmem_t; -typedef struct kmastat_args { - kmastat_vmem_t **ka_kvpp; - uint_t ka_shift; -} kmastat_args_t; - static int -kmastat_cache(uintptr_t addr, const kmem_cache_t *cp, kmastat_args_t *kap) +kmastat_cache(uintptr_t addr, const kmem_cache_t *cp, kmastat_vmem_t **kvpp) { - kmastat_vmem_t **kvpp = kap->ka_kvpp; kmastat_vmem_t *kv; datafmt_t *dfp = kmemfmt; int magsize; @@ -2156,9 +2148,7 @@ out: mdb_printf((dfp++)->fmt, cp->cache_bufsize); mdb_printf((dfp++)->fmt, total - avail); mdb_printf((dfp++)->fmt, total); - mdb_printf((dfp++)->fmt, meminuse >> kap->ka_shift, - kap->ka_shift == GIGS ? 'G' : kap->ka_shift == MEGS ? 'M' : - kap->ka_shift == KILOS ? 'K' : 'B'); + mdb_printf((dfp++)->fmt, meminuse); mdb_printf((dfp++)->fmt, alloc); mdb_printf((dfp++)->fmt, cp->cache_alloc_fail); mdb_printf("\n"); @@ -2167,9 +2157,8 @@ out: } static int -kmastat_vmem_totals(uintptr_t addr, const vmem_t *v, kmastat_args_t *kap) +kmastat_vmem_totals(uintptr_t addr, const vmem_t *v, kmastat_vmem_t *kv) { - kmastat_vmem_t *kv = *kap->ka_kvpp; size_t len; while (kv != NULL && kv->kv_addr != addr) @@ -2178,20 +2167,18 @@ kmastat_vmem_totals(uintptr_t addr, const vmem_t *v, kmastat_args_t *kap) if (kv == NULL || kv->kv_alloc == 0) return (WALK_NEXT); - len = MIN(17, strlen(v->vm_name)); + len = MIN(22, strlen(v->vm_name)); - mdb_printf("Total [%s]%*s %6s %6s %6s %10lu%c %9u %5u\n", v->vm_name, - 17 - len, "", "", "", "", - kv->kv_meminuse >> kap->ka_shift, - kap->ka_shift == GIGS ? 'G' : kap->ka_shift == MEGS ? 'M' : - kap->ka_shift == KILOS ? 'K' : 'B', kv->kv_alloc, kv->kv_fail); + mdb_printf("Total [%s]%*s %5s %9s %9s %6lH %10u %5u\n", v->vm_name, + 22 - len, "", "", "", "", + kv->kv_meminuse, kv->kv_alloc, kv->kv_fail); return (WALK_NEXT); } /*ARGSUSED*/ static int -kmastat_vmem(uintptr_t addr, const vmem_t *v, const uint_t *shiftp) +kmastat_vmem(uintptr_t addr, const vmem_t *v, const void *ignored) { datafmt_t *dfp = vmemfmt; const vmem_kstat_t *vkp = &v->vm_kstat; @@ -2209,16 +2196,10 @@ kmastat_vmem(uintptr_t addr, const vmem_t *v, const uint_t *shiftp) } mdb_printf("%*s", ident, ""); - mdb_printf((dfp++)->fmt, 25 - ident, v->vm_name); - mdb_printf((dfp++)->fmt, vkp->vk_mem_inuse.value.ui64 >> *shiftp, - *shiftp == GIGS ? 'G' : *shiftp == MEGS ? 'M' : - *shiftp == KILOS ? 'K' : 'B'); - mdb_printf((dfp++)->fmt, vkp->vk_mem_total.value.ui64 >> *shiftp, - *shiftp == GIGS ? 'G' : *shiftp == MEGS ? 'M' : - *shiftp == KILOS ? 'K' : 'B'); - mdb_printf((dfp++)->fmt, vkp->vk_mem_import.value.ui64 >> *shiftp, - *shiftp == GIGS ? 'G' : *shiftp == MEGS ? 'M' : - *shiftp == KILOS ? 'K' : 'B'); + mdb_printf((dfp++)->fmt, 30 - ident, v->vm_name); + mdb_printf((dfp++)->fmt, vkp->vk_mem_inuse.value.ui64); + mdb_printf((dfp++)->fmt, vkp->vk_mem_total.value.ui64); + mdb_printf((dfp++)->fmt, vkp->vk_mem_import.value.ui64); mdb_printf((dfp++)->fmt, vkp->vk_alloc.value.ui64); mdb_printf((dfp++)->fmt, vkp->vk_fail.value.ui64); @@ -2233,44 +2214,35 @@ kmastat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { kmastat_vmem_t *kv = NULL; datafmt_t *dfp; - kmastat_args_t ka; - - ka.ka_shift = 0; - if (mdb_getopts(argc, argv, - 'k', MDB_OPT_SETBITS, KILOS, &ka.ka_shift, - 'm', MDB_OPT_SETBITS, MEGS, &ka.ka_shift, - 'g', MDB_OPT_SETBITS, GIGS, &ka.ka_shift, NULL) != argc) - return (DCMD_USAGE); for (dfp = kmemfmt; dfp->hdr1 != NULL; dfp++) - mdb_printf("%s ", dfp->hdr1); + mdb_printf("%s%s", dfp == kmemfmt ? "" : " ", dfp->hdr1); mdb_printf("\n"); for (dfp = kmemfmt; dfp->hdr1 != NULL; dfp++) - mdb_printf("%s ", dfp->hdr2); + mdb_printf("%s%s", dfp == kmemfmt ? "" : " ", dfp->hdr2); mdb_printf("\n"); for (dfp = kmemfmt; dfp->hdr1 != NULL; dfp++) - mdb_printf("%s ", dfp->dashes); + mdb_printf("%s%s", dfp == kmemfmt ? "" : " ", dfp->dashes); mdb_printf("\n"); - ka.ka_kvpp = &kv; - if (mdb_walk("kmem_cache", (mdb_walk_cb_t)kmastat_cache, &ka) == -1) { + if (mdb_walk("kmem_cache", (mdb_walk_cb_t)kmastat_cache, &kv) == -1) { mdb_warn("can't walk 'kmem_cache'"); return (DCMD_ERR); } for (dfp = kmemfmt; dfp->hdr1 != NULL; dfp++) - mdb_printf("%s ", dfp->dashes); + mdb_printf("%s%s", dfp == kmemfmt ? "" : " ", dfp->dashes); mdb_printf("\n"); - if (mdb_walk("vmem", (mdb_walk_cb_t)kmastat_vmem_totals, &ka) == -1) { + if (mdb_walk("vmem", (mdb_walk_cb_t)kmastat_vmem_totals, kv) == -1) { mdb_warn("can't walk 'vmem'"); return (DCMD_ERR); } for (dfp = kmemfmt; dfp->hdr1 != NULL; dfp++) - mdb_printf("%s ", dfp->dashes); + mdb_printf("%s%s", dfp == kmemfmt ? "" : " ", dfp->dashes); mdb_printf("\n"); mdb_printf("\n"); @@ -2287,7 +2259,7 @@ kmastat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) mdb_printf("%s ", dfp->dashes); mdb_printf("\n"); - if (mdb_walk("vmem", (mdb_walk_cb_t)kmastat_vmem, &ka.ka_shift) == -1) { + if (mdb_walk("vmem", (mdb_walk_cb_t)kmastat_vmem, NULL) == -1) { mdb_warn("can't walk 'vmem'"); return (DCMD_ERR); } @@ -4121,8 +4093,8 @@ static const mdb_dcmd_t dcmds[] = { { "devbindings", "?[-qs] [device-name | major-num]", "print devinfo nodes bound to device-name or major-num", devbindings, devinfo_help }, - { "devinfo", ":[-qs]", "detailed devinfo of one node", devinfo, - devinfo_help }, + { "devinfo", ":[-qsd] [-b bus]", "detailed devinfo of one node", + devinfo, devinfo_help }, { "devinfo_audit", ":[-v]", "devinfo configuration audit record", devinfo_audit }, { "devinfo_audit_log", "?[-v]", "system wide devinfo configuration log", @@ -4146,8 +4118,8 @@ static const mdb_dcmd_t dcmds[] = { modctl2devinfo }, { "name2major", "<dev-name>", "convert dev name to major number", name2major }, - { "prtconf", "?[-vpc] [-d driver]", "print devinfo tree", prtconf, - prtconf_help }, + { "prtconf", "?[-vpc] [-d driver] [-i inst]", "print devinfo tree", + prtconf, prtconf_help }, { "softstate", ":<instance>", "retrieve soft-state pointer", softstate }, { "devinfo_fm", ":", "devinfo fault managment configuration", @@ -4193,8 +4165,7 @@ static const mdb_dcmd_t dcmds[] = { { "freedby", ":", "given a thread, print its freed buffers", freedby }, { "kmalog", "?[ fail | slab ]", "display kmem transaction log and stack traces", kmalog }, - { "kmastat", "[-kmg]", "kernel memory allocator stats", - kmastat }, + { "kmastat", NULL, "kernel memory allocator stats", kmastat }, { "kmausers", "?[-ef] [cache ...]", "current medium and large users " "of the kmem allocator", kmausers, kmausers_help }, { "kmem_cache", "?[-n name]", @@ -4391,6 +4362,8 @@ static const mdb_dcmd_t dcmds[] = { /* from zone.c */ { "zid2zone", ":", "find the zone_t with the given zone id", zid2zone }, + { "zdid2zone", ":", "find the zone_t with the given zone debug id", + zdid2zone }, { "zone", "?[-r [-v]]", "display kernel zone(s)", zoneprt }, { "zsd", ":[-v] [zsd_key]", "display zone-specific-data entries for " "selected zones", zsd }, @@ -4708,6 +4681,10 @@ static const mdb_walker_t walkers[] = { { NVPAIR_WALKER_NAME, NVPAIR_WALKER_DESCR, nvpair_walk_init, nvpair_walk_step, NULL }, + /* from pci.c */ + { "pcie_bus", "walk all pcie_bus_t's", pcie_bus_walk_init, + pcie_bus_walk_step, NULL }, + /* from rctl.c */ { "rctl_dict_list", "walk all rctl_dict_entry_t's from rctl_lists", rctl_dict_walk_init, rctl_dict_walk_step, NULL }, @@ -4716,6 +4693,10 @@ static const mdb_walker_t walkers[] = { { "rctl_val", "given a rctl_t, walk all rctl_val entries associated", rctl_val_walk_init, rctl_val_walk_step }, + /* from refhash.c */ + { REFHASH_WALK_NAME, REFHASH_WALK_DESC, + refhash_walk_init, refhash_walk_step, NULL }, + /* from sobj.c */ { "blocked", "walk threads blocked on a given sobj", blocked_walk_init, blocked_walk_step, NULL }, diff --git a/usr/src/cmd/mdb/common/modules/genunix/hotplug.c b/usr/src/cmd/mdb/common/modules/genunix/hotplug.c index 725a44eb7d..f44b5218de 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/hotplug.c +++ b/usr/src/cmd/mdb/common/modules/genunix/hotplug.c @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2019, Joyent, Inc. */ #include <sys/mdb_modapi.h> @@ -115,6 +116,7 @@ hotplug(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) data.di_flags = 0; data.di_filter = NULL; + data.di_instance = UINT64_MAX; if (mdb_getopts(argc, argv, 'p', MDB_OPT_SETBITS, DEVINFO_HP_PHYSICAL, &data.di_flags, NULL) != argc) diff --git a/usr/src/cmd/mdb/common/modules/genunix/kmem.c b/usr/src/cmd/mdb/common/modules/genunix/kmem.c index c615af3c66..146317e012 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/kmem.c +++ b/usr/src/cmd/mdb/common/modules/genunix/kmem.c @@ -3917,6 +3917,8 @@ kmalog(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) logname = "kmem_failure_log"; else if (strcmp(argv->a_un.a_str, "slab") == 0) logname = "kmem_slab_log"; + else if (strcmp(argv->a_un.a_str, "zerosized") == 0) + logname = "kmem_zerosized_log"; else return (DCMD_USAGE); } diff --git a/usr/src/cmd/mdb/common/modules/genunix/memory.c b/usr/src/cmd/mdb/common/modules/genunix/memory.c index 3f0802f0a5..ba498f13a8 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/memory.c +++ b/usr/src/cmd/mdb/common/modules/genunix/memory.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2017 Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ #include <mdb/mdb_param.h> @@ -443,11 +443,11 @@ vn_get(vn_htable_t *hp, struct vnode *vp, uintptr_t ptr) /* Summary statistics of pages */ typedef struct memstat { - struct vnode *ms_kvp; /* Cached address of kernel vnode */ struct vnode *ms_unused_vp; /* Unused pages vnode pointer */ - struct vnode *ms_zvp; /* Cached address of zio vnode */ + struct vnode *ms_kvps; /* Cached address of vnode array */ uint64_t ms_kmem; /* Pages of kernel memory */ uint64_t ms_zfs_data; /* Pages of zfs data */ + uint64_t ms_vmm_mem; /* Pages of VMM mem */ uint64_t ms_anon; /* Pages of anonymous memory */ uint64_t ms_vnode; /* Pages of named (vnode) memory */ uint64_t ms_exec; /* Pages of exec/library memory */ @@ -458,11 +458,8 @@ typedef struct memstat { struct vnode ms_vn; /* vnode buffer */ } memstat_t; -#define MS_PP_ISKAS(pp, stats) \ - ((pp)->p_vnode == (stats)->ms_kvp) - -#define MS_PP_ISZFS_DATA(pp, stats) \ - (((stats)->ms_zvp != NULL) && ((pp)->p_vnode == (stats)->ms_zvp)) +#define MS_PP_ISTYPE(pp, stats, index) \ + ((pp)->p_vnode == &(stats->ms_kvps[index])) /* * Summarize pages by type and update stat information @@ -478,10 +475,12 @@ memstat_callback(page_t *page, page_t *pp, memstat_t *stats) stats->ms_bootpages++; else if (pp->p_vnode == NULL || pp->p_vnode == stats->ms_unused_vp) return (WALK_NEXT); - else if (MS_PP_ISKAS(pp, stats)) + else if (MS_PP_ISTYPE(pp, stats, KV_KVP)) stats->ms_kmem++; - else if (MS_PP_ISZFS_DATA(pp, stats)) + else if (MS_PP_ISTYPE(pp, stats, KV_ZVP)) stats->ms_zfs_data++; + else if (MS_PP_ISTYPE(pp, stats, KV_VVP)) + stats->ms_vmm_mem++; else if (PP_ISFREE(pp)) stats->ms_cachelist++; else if (vn_get(stats->ms_vn_htable, vp, (uintptr_t)pp->p_vnode)) @@ -507,7 +506,6 @@ memstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) memstat_t stats; GElf_Sym sym; vn_htable_t ht; - struct vnode *kvps; uintptr_t vn_size = 0; #if defined(__i386) || defined(__amd64) bln_stats_t bln_stats; @@ -548,16 +546,10 @@ memstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) /* read kernel vnode array pointer */ if (mdb_lookup_by_obj(MDB_OBJ_EXEC, "kvps", (GElf_Sym *)&sym) == -1) { - mdb_warn("unable to read kvps"); + mdb_warn("unable to look up kvps"); return (DCMD_ERR); } - kvps = (struct vnode *)(uintptr_t)sym.st_value; - stats.ms_kvp = &kvps[KV_KVP]; - - /* - * Read the zio vnode pointer. - */ - stats.ms_zvp = &kvps[KV_ZVP]; + stats.ms_kvps = (struct vnode *)(uintptr_t)sym.st_value; /* * If physmem != total_pages, then the administrator has limited the @@ -605,6 +597,13 @@ memstat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) MS_PCT_TOTAL(stats.ms_zfs_data)); } + if (stats.ms_vmm_mem != 0) { + mdb_printf("VMM Memory %16llu %16llu %3lu%%\n", + stats.ms_vmm_mem, + (uint64_t)stats.ms_vmm_mem * PAGESIZE / (1024 * 1024), + MS_PCT_TOTAL(stats.ms_vmm_mem)); + } + mdb_printf("Anon %16llu %16llu %3lu%%\n", stats.ms_anon, (uint64_t)stats.ms_anon * PAGESIZE / (1024 * 1024), diff --git a/usr/src/cmd/mdb/common/modules/genunix/pci.c b/usr/src/cmd/mdb/common/modules/genunix/pci.c new file mode 100644 index 0000000000..075ce8f284 --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/pci.c @@ -0,0 +1,79 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019, Joyent, Inc. + */ + +/* + * PCIe related dcmds + */ + +#include <mdb/mdb_modapi.h> +#include <sys/dditypes.h> +#include <sys/ddi_impldefs.h> +#include <sys/pcie_impl.h> + +boolean_t +pcie_bus_match(const struct dev_info *devi, uintptr_t *bus_p) +{ + if (devi->devi_bus.port_up.info.port.type == DEVI_PORT_TYPE_PCI) { + *bus_p = (uintptr_t)devi->devi_bus.port_up.priv_p; + } else if (devi->devi_bus.port_down.info.port.type == + DEVI_PORT_TYPE_PCI) { + *bus_p = (uintptr_t)devi->devi_bus.port_down.priv_p; + } else { + return (B_FALSE); + } + + return (B_TRUE); +} + +int +pcie_bus_walk_init(mdb_walk_state_t *wsp) +{ + if (wsp->walk_addr != 0) { + mdb_warn("pcie_bus walker doesn't support non-global walks\n"); + return (WALK_ERR); + } + + if (mdb_layered_walk("devinfo", wsp) == -1) { + mdb_warn("couldn't walk \"devinfo\""); + return (WALK_ERR); + } + + return (WALK_NEXT); +} + +int +pcie_bus_walk_step(mdb_walk_state_t *wsp) +{ + const struct dev_info *devi; + uintptr_t bus_addr; + struct pcie_bus bus; + + if (wsp->walk_layer == NULL) { + mdb_warn("missing layered walk info\n"); + return (WALK_ERR); + } + + devi = wsp->walk_layer; + if (!pcie_bus_match(devi, &bus_addr)) { + return (WALK_NEXT); + } + + if (mdb_vread(&bus, sizeof (bus), bus_addr) == -1) { + mdb_warn("failed to read pcie_bus_t at %p", bus_addr); + return (WALK_NEXT); + } + + return (wsp->walk_callback(bus_addr, &bus, wsp->walk_cbdata)); +} diff --git a/usr/src/cmd/mdb/common/modules/genunix/pci.h b/usr/src/cmd/mdb/common/modules/genunix/pci.h new file mode 100644 index 0000000000..ee14a4619b --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/pci.h @@ -0,0 +1,40 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019, Joyent, Inc. + */ + +#ifndef _MDB_PCI_H +#define _MDB_PCI_H + +/* + * genunix PCI dcmds and walkers. + */ + +#include <mdb/mdb_modapi.h> +#include <sys/dditypes.h> +#include <sys/ddi_impldefs.h> + +#ifdef __cplusplus +extern "C" { +#endif + +extern int pcie_bus_walk_init(mdb_walk_state_t *); +extern int pcie_bus_walk_step(mdb_walk_state_t *); + +extern boolean_t pcie_bus_match(const struct dev_info *, uintptr_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _MDB_PCI_H */ diff --git a/usr/src/cmd/mdb/common/modules/genunix/refhash.c b/usr/src/cmd/mdb/common/modules/genunix/refhash.c new file mode 100644 index 0000000000..4b4c92dc14 --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/refhash.c @@ -0,0 +1,61 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +#include <mdb/mdb_modapi.h> +#include <mdb/mdb_ctf.h> + +#include <inttypes.h> +#include <sys/refhash.h> + +typedef struct refhash_walk_data { + size_t rwd_offset; +} refhash_walk_data_t; + +int +refhash_walk_init(mdb_walk_state_t *wsp) +{ + refhash_t refh = { 0 }; + refhash_walk_data_t *rwd; + int offset; + + /* mdb_ctf_offsetof_by_name() will print any errors */ + if ((offset = mdb_ctf_offsetof_by_name("refhash_t", "rh_objs")) == -1) + return (WALK_ERR); + + if (mdb_vread(&refh, sizeof (refhash_t), wsp->walk_addr) == -1) { + mdb_warn("failed to read refhash_t at %#lx", wsp->walk_addr); + return (WALK_ERR); + } + + rwd = wsp->walk_data = mdb_zalloc(sizeof (*rwd), UM_SLEEP | UM_GC); + rwd->rwd_offset = refh.rh_link_off; + + wsp->walk_addr += offset; + if (mdb_layered_walk("list", wsp) == -1) { + mdb_warn("can't walk refhash_t"); + return (WALK_ERR); + } + + return (WALK_NEXT); +} + +int +refhash_walk_step(mdb_walk_state_t *wsp) +{ + refhash_walk_data_t *rwd = wsp->walk_data; + uintptr_t addr = wsp->walk_addr - rwd->rwd_offset; + + return (wsp->walk_callback(addr, wsp->walk_layer, wsp->walk_cbdata)); +} diff --git a/usr/src/cmd/mdb/common/modules/genunix/refhash.h b/usr/src/cmd/mdb/common/modules/genunix/refhash.h new file mode 100644 index 0000000000..1e91ced8d5 --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/refhash.h @@ -0,0 +1,35 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +#ifndef _REFHASH_H +#define _REFHASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define REFHASH_WALK_NAME "refhash" +#define REFHASH_WALK_DESC "walk a refhash" + +struct mdb_walk_state; + +extern int refhash_walk_init(struct mdb_walk_state *); +extern int refhash_walk_step(struct mdb_walk_state *); + +#ifdef __cplusplus +} +#endif + +#endif /* _REFHASH_H */ diff --git a/usr/src/cmd/mdb/common/modules/genunix/zone.c b/usr/src/cmd/mdb/common/modules/genunix/zone.c index 49cd3e7b6e..57545d94a3 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/zone.c +++ b/usr/src/cmd/mdb/common/modules/genunix/zone.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. All rights reserved. */ #include <mdb/mdb_param.h> @@ -34,9 +34,9 @@ #define ZONE_NAMELEN 20 #ifdef _LP64 -#define ZONE_PATHLEN 32 +#define ZONE_PATHLEN 25 #else -#define ZONE_PATHLEN 40 +#define ZONE_PATHLEN 33 #endif /* @@ -52,7 +52,8 @@ char *zone_status_names[] = { "empty", /* ZONE_IS_EMPTY */ "down", /* ZONE_IS_DOWN */ "dying", /* ZONE_IS_DYING */ - "dead" /* ZONE_IS_DEAD */ + "dead", /* ZONE_IS_DEAD */ + "free" /* ZONE_IS_FREE */ }; static int @@ -80,6 +81,31 @@ zid2zone(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (DCMD_OK); } +static int +zdid_lookup_cb(uintptr_t addr, const zone_t *zone, void *arg) +{ + zoneid_t zdid = *(uintptr_t *)arg; + if (zone->zone_did == zdid) + mdb_printf("%p\n", addr); + + return (WALK_NEXT); +} + +/*ARGSUSED*/ +int +zdid2zone(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + if (!(flags & DCMD_ADDRSPEC) || argc != 0) + return (DCMD_USAGE); + + if (mdb_walk("zone", (mdb_walk_cb_t)zdid_lookup_cb, &addr) == -1) { + mdb_warn("failed to walk zone"); + return (DCMD_ERR); + } + + return (DCMD_OK); +} + int zoneprt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { @@ -122,10 +148,10 @@ zoneprt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) */ if (DCMD_HDRSPEC(flags)) { if (ropt_given == FALSE) - mdb_printf("%<u>%?s %6s %-13s %-20s %-s%</u>\n", + mdb_printf("%<u>%?s %4s %-13s %-19s %-s%</u>\n", "ADDR", "ID", "STATUS", "NAME", "PATH"); else - mdb_printf("%<u>%?s %6s %10s %10s %-20s%</u>\n", + mdb_printf("%<u>%?s %6s %10s %10s %-19s%</u>\n", "ADDR", "ID", "REFS", "CREFS", "NAME"); } @@ -164,7 +190,7 @@ zoneprt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) statusp = zone_status_names[zn.zone_status]; else statusp = "???"; - mdb_printf("%0?p %6d %-13s %-20s %s\n", addr, zn.zone_id, + mdb_printf("%0?p %4d %-13s %-19s %s\n", addr, zn.zone_id, statusp, name, path); } else { /* @@ -172,7 +198,7 @@ zoneprt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) * Display the zone's subsystem-specific reference counts if * the user specified the '-v' option. */ - mdb_printf("%0?p %6d %10u %10u %-20s\n", addr, zn.zone_id, + mdb_printf("%0?p %6d %10u %10u %-19s\n", addr, zn.zone_id, zn.zone_ref, zn.zone_cred_ref, name); if (vopt_given == TRUE) { GElf_Sym subsys_names_sym; @@ -410,7 +436,7 @@ zsd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) * Prepare to output the specified zone's ZSD information. */ if (DCMD_HDRSPEC(flags)) - mdb_printf("%<u>%-20s %?s %?s %8s%</u>\n", "ZONE", "KEY", + mdb_printf("%<u>%-19s %?s %?s %8s%</u>\n", "ZONE", "KEY", "VALUE", "FLAGS"); len = mdb_readstr(name, ZONE_NAMELEN, (uintptr_t)zone.zone_name); if (len > 0) { @@ -419,7 +445,7 @@ zsd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) } else { (void) strcpy(name, "??"); } - mdb_printf("%-20s ", name); + mdb_printf("%-19s ", name); /* * Display the requested ZSD entries. diff --git a/usr/src/cmd/mdb/common/modules/genunix/zone.h b/usr/src/cmd/mdb/common/modules/genunix/zone.h index 0881f9bbae..94a383e41c 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/zone.h +++ b/usr/src/cmd/mdb/common/modules/genunix/zone.h @@ -34,6 +34,7 @@ extern "C" { #endif extern int zid2zone(uintptr_t, uint_t, int argc, const mdb_arg_t *); +extern int zdid2zone(uintptr_t, uint_t, int argc, const mdb_arg_t *); extern int zoneprt(uintptr_t, uint_t, int argc, const mdb_arg_t *); extern int zone_walk_init(mdb_walk_state_t *); diff --git a/usr/src/cmd/mdb/common/modules/ipc/ipc.c b/usr/src/cmd/mdb/common/modules/ipc/ipc.c index 97102579cf..60b40dddb6 100644 --- a/usr/src/cmd/mdb/common/modules/ipc/ipc.c +++ b/usr/src/cmd/mdb/common/modules/ipc/ipc.c @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2016 Joyent, Inc. */ #include <mdb/mdb_modapi.h> @@ -229,7 +230,9 @@ shm_print(kshmid_t *shmid, uintptr_t addr) printtime_nice("ctime: ", shmid->shm_ctime); mdb_printf("sptinfo: %-?p sptseg: %-?p\n", shmid->shm_sptinfo, shmid->shm_sptseg); - mdb_printf("sptprot: <%lb>\n", shmid->shm_sptprot, prot_flag_bits); + mdb_printf("opts: rmpend: %d prot: <%b>\n", + ((shmid->shm_opts & SHM_RM_PENDING) != 0), + (shmid->shm_opts & SHM_PROT_MASK), prot_flag_bits); } diff --git a/usr/src/cmd/mdb/common/modules/libc/libc.c b/usr/src/cmd/mdb/common/modules/libc/libc.c index 4e2aabf061..b9de1dc936 100644 --- a/usr/src/cmd/mdb/common/modules/libc/libc.c +++ b/usr/src/cmd/mdb/common/modules/libc/libc.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. - * Copyright 2017, Joyent, Inc. + * Copyright 2019, Joyent, Inc. * Copyright (c) 2019 Carlos Neira <cneirabustos@gmail.com> * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. */ @@ -138,6 +138,8 @@ d_ucontext(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) uc.uc_stack.ss_sp, uc.uc_stack.ss_size, stack_flags(&uc.uc_stack)); mdb_printf(" mcontext = 0x%p\n", addr + OFFSETOF(ucontext_t, uc_mcontext)); + mdb_printf(" brand = 0x%p 0x%p 0x%p\n", + uc.uc_brand_data[0], uc.uc_brand_data[1], uc.uc_brand_data[2]); return (DCMD_OK); } @@ -849,14 +851,19 @@ d_uberdata(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) prt_addr(uberdata.all_lwps, 1), prt_addr(uberdata.all_zombies, 0)); - HD("nthreads nzombies ndaemons pid sigacthandler"); - mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d %s\n", + HD("nthreads nzombies ndaemons pid"); + mdb_printf(OFFSTR "%-10d %-10d %-10d %-10d\n", OFFSET(nthreads), uberdata.nthreads, uberdata.nzombies, uberdata.ndaemons, - (int)uberdata.pid, - prt_addr((void *)uberdata.sigacthandler, 0)); + (int)uberdata.pid); + + HD("sigacthandler setctxt"); + mdb_printf(OFFSTR "%s %s\n", + OFFSET(sigacthandler), + prt_addr((void *)uberdata.sigacthandler, 1), + prt_addr((void *)uberdata.setctxt, 1)); HD("lwp_stacks lwp_laststack nfreestack stk_cache"); mdb_printf(OFFSTR "%s %s %-10d %d\n", @@ -879,12 +886,17 @@ d_uberdata(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) prt_addr(uberdata.ulwp_replace_last, 1), prt_addr(uberdata.atforklist, 0)); - HD("robustlocks robustlist progname"); - mdb_printf(OFFSTR "%s %s %s\n", + HD("robustlocks robustlist"); + mdb_printf(OFFSTR "%s %s\n", OFFSET(robustlocks), prt_addr(uberdata.robustlocks, 1), - prt_addr(uberdata.robustlist, 1), - prt_addr(uberdata.progname, 0)); + prt_addr(uberdata.robustlist, 1)); + + HD("progname ub_broot"); + mdb_printf(OFFSTR "%s %s\n", + OFFSET(progname), + prt_addr(uberdata.progname, 1), + prt_addr(uberdata.ub_broot, 1)); HD("tdb_bootstrap tdb_sync_addr_hash tdb_'count tdb_'fail"); mdb_printf(OFFSTR "%s %s %-10d %d\n", @@ -1097,9 +1109,14 @@ tid2ulwp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (error); } +/* + * This is used by both d_tsd and d_errno, and contains the sum of all + * members used by both commands. + */ typedef struct mdb_libc_ulwp { void *ul_ftsd[TSD_NFAST]; tsd_t *ul_stsd; + int *ul_errnop; } mdb_libc_ulwp_t; /* @@ -1152,6 +1169,44 @@ d_tsd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (DCMD_OK); } +static int +d_errno(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + mdb_libc_ulwp_t u; + uintptr_t ulwp_addr; + int error, errval; + + if (argc != 0 || (flags & DCMD_ADDRSPEC) == 0) + return (DCMD_USAGE); + + error = tid2ulwp_impl(addr, &ulwp_addr); + if (error != DCMD_OK) + return (error); + + /* + * For historical compatibility, thread 1's errno value is stored in + * a libc global variable 'errno', while each additional thread's + * errno value is stored in ulwp_t->ul_errno. In addition, + * ulwp_t->ul_errnop is set to the address of the thread's errno value, + * (i.e. for tid 1, curthead->ul_errnop = &errno, for tid > 1, + * curthread->ul_errnop = &curthread->ul_errno). + * + * Since errno itself uses *curthread->ul_errnop (see ___errno()) to + * return the thread's current errno value, we do the same. + */ + if (mdb_ctf_vread(&u, "ulwp_t", "mdb_libc_ulwp_t", ulwp_addr, 0) == -1) + return (DCMD_ERR); + + if (mdb_vread(&errval, sizeof (errval), (uintptr_t)u.ul_errnop) == -1) { + mdb_warn("cannot read error value at 0x%p", u.ul_errnop); + return (DCMD_ERR); + } + + mdb_printf("%d\n", errval); + + return (DCMD_OK); +} + /* * Print percent from 16-bit binary fraction [0 .. 1] * Round up .01 to .1 to indicate some small percentage (the 0x7000 below). @@ -1369,6 +1424,7 @@ d_psinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) } static const mdb_dcmd_t dcmds[] = { + { "errno", "?", "print errno of a given TID", d_errno, NULL }, { "jmp_buf", ":", "print jmp_buf contents", d_jmp_buf, NULL }, { "sigjmp_buf", ":", "print sigjmp_buf contents", d_sigjmp_buf, NULL }, { "siginfo", ":", "print siginfo_t structure", d_siginfo, NULL }, diff --git a/usr/src/cmd/mdb/common/modules/mac/mac.c b/usr/src/cmd/mdb/common/modules/mac/mac.c index d42066a37d..1f80e11096 100644 --- a/usr/src/cmd/mdb/common/modules/mac/mac.c +++ b/usr/src/cmd/mdb/common/modules/mac/mac.c @@ -21,6 +21,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2018 Joyent, Inc. */ #include <sys/mdb_modapi.h> @@ -967,6 +968,8 @@ mac_ring_classify2str(mac_classify_type_t classify) return ("sw"); case MAC_HW_CLASSIFIER: return ("hw"); + case MAC_PASSTHRU_CLASSIFIER: + return ("pass"); } return ("--"); } diff --git a/usr/src/cmd/mdb/common/modules/mdb_ks/mdb_ks.c b/usr/src/cmd/mdb/common/modules/mdb_ks/mdb_ks.c index d4b817295d..cdbfd3d755 100644 --- a/usr/src/cmd/mdb/common/modules/mdb_ks/mdb_ks.c +++ b/usr/src/cmd/mdb/common/modules/mdb_ks/mdb_ks.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2017 Joyent, Inc. + * Copyright (c) 2019, Joyent, Inc. */ /* @@ -60,6 +60,12 @@ #define MDB_PATH_NELEM 256 /* Maximum path components */ +/* + * Due to mdb_param.h shenanigans, there's no simple way to include string.h + * here... + */ +extern char *strtok(char *restrict, const char *restrict); + typedef struct mdb_path { size_t mdp_nelem; /* Number of components */ uint_t mdp_complete; /* Path completely resolved? */ @@ -1810,3 +1816,71 @@ mdb_get_lbolt(void) return ((ts/nsec) - lbi.lbi_debug_time); } + +#define startswith(a, b) (strncmp((a), (b), strlen(b)) == 0) + +/* + * Dig out the branch and revision of the illumos-joyent repo, if we were + * provided with it. This is a rather fragile JSON parser, in that it requires + * JSON formatted exactly as per the boot_archive.gitstatus file that + * "gitstatus_start" is built from. + */ +void +mdb_print_gitstatus(void) +{ + boolean_t in_joyent = B_FALSE; + GElf_Sym sym; + + if (mdb_lookup_by_name("gitstatus_start", &sym) != 0) + return; + + char *str = mdb_zalloc(4096, UM_SLEEP | UM_GC); + + if (mdb_readstr(str, 4096, sym.st_value) < 1) + return; + + /* + * Each line is of the form + * + * "repo": "smartos-live", + */ + for (char *line = strtok(str, "\n"); line != NULL; + line = strtok(NULL, "\n")) { + /* skip whitespace and first " */ + line += strspn(line, " \t\""); + + if (startswith(line, "repo")) { + line += sizeof ("repo") - 1; + line += strspn(line, " \t\":"); + + if (startswith(line, "illumos-joyent")) + in_joyent = B_TRUE; + else if (in_joyent) + return; + continue; + } + + if (!in_joyent) + continue; + + if (startswith(line, "branch")) { + char *trail = strrchr(line, '"'); + if (trail != NULL) + *trail = '\0'; + line += sizeof ("branch") - 1; + line += strspn(line, " \t\":"); + mdb_printf("git branch: %s\n", line); + continue; + } + + if (startswith(line, "rev")) { + char *trail = strrchr(line, '"'); + if (trail != NULL) + *trail = '\0'; + line += sizeof ("rev") - 1; + line += strspn(line, " \t\":"); + mdb_printf("git rev: %s\n", line); + continue; + } + } +} diff --git a/usr/src/cmd/mdb/common/modules/mpt_sas/mpt_sas.c b/usr/src/cmd/mdb/common/modules/mpt_sas/mpt_sas.c index ecb2aba4cc..1a63798c93 100644 --- a/usr/src/cmd/mdb/common/modules/mpt_sas/mpt_sas.c +++ b/usr/src/cmd/mdb/common/modules/mpt_sas/mpt_sas.c @@ -34,6 +34,7 @@ #include <sys/sunmdi.h> #include <sys/list.h> #include <sys/scsi/scsi.h> +#include <sys/refhash.h> #pragma pack(1) #include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h> @@ -47,7 +48,6 @@ #pragma pack() #include <sys/scsi/adapters/mpt_sas/mptsas_var.h> -#include <sys/scsi/adapters/mpt_sas/mptsas_hash.h> struct { int value; diff --git a/usr/src/cmd/mdb/common/modules/xhci/xhci.c b/usr/src/cmd/mdb/common/modules/xhci/xhci.c new file mode 100644 index 0000000000..fbf3c42417 --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/xhci/xhci.c @@ -0,0 +1,893 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Joyent, Inc. + */ + +#include <sys/mdb_modapi.h> +#include <sys/usb/hcd/xhci/xhci.h> + +#define XHCI_MDB_TRB_INDENT 4 + +static const char *xhci_mdb_epctx_eptypes[] = { + "Not Valid", + "ISOCH OUT", + "BULK OUT", + "INTR OUT", + "CONTROL", + "ISOCH IN", + "BULK IN", + "INTR IN" +}; + +static const char *xhci_mdb_epctx_states[] = { + "Disabled", + "Running", + "Halted", + "Stopped", + "Error", + "<Unknown>", + "<Unknown>", + "<Unknown>" +}; + +static const mdb_bitmask_t xhci_mdb_trb_flags[] = { + { "C", XHCI_TRB_CYCLE, XHCI_TRB_CYCLE }, + { "ENT", XHCI_TRB_ENT, XHCI_TRB_ENT }, + { "ISP", XHCI_TRB_ISP, XHCI_TRB_ISP }, + { "NS", XHCI_TRB_NOSNOOP, XHCI_TRB_NOSNOOP }, + { "CH", XHCI_TRB_CHAIN, XHCI_TRB_CHAIN }, + { "IOC", XHCI_TRB_IOC, XHCI_TRB_IOC }, + { "IDT", XHCI_TRB_IDT, XHCI_TRB_IDT }, + { "BEI", XHCI_TRB_BEI, XHCI_TRB_BEI }, + { NULL, 0, 0 } +}; + +typedef struct xhci_mdb_walk_endpoint { + xhci_device_t xmwe_device; + uint_t xmwe_ep; +} xhci_mdb_walk_endpoint_t; + +static const char * +xhci_mdb_trb_code_to_str(int code) +{ + switch (code) { + case XHCI_CODE_INVALID: + return ("Invalid"); + case XHCI_CODE_SUCCESS: + return ("Success"); + case XHCI_CODE_DATA_BUF: + return ("Data Overrun or Underrun"); + case XHCI_CODE_BABBLE: + return ("Babble"); + case XHCI_CODE_TXERR: + return ("Transaction Error"); + case XHCI_CODE_TRB: + return ("Invalid TRB"); + case XHCI_CODE_STALL: + return ("Stall"); + case XHCI_CODE_RESOURCE: + return ("No Resources Available"); + case XHCI_CODE_BANDWIDTH: + return ("No Bandwidth Available"); + case XHCI_CODE_NO_SLOTS: + return ("No Slots Available"); + case XHCI_CODE_STREAM_TYPE: + return ("Stream Context Type Detected"); + case XHCI_CODE_SLOT_NOT_ON: + return ("Slot disabled"); + case XHCI_CODE_ENDP_NOT_ON: + return ("Endpoint disabled"); + case XHCI_CODE_SHORT_XFER: + return ("Short Transfer"); + case XHCI_CODE_RING_UNDERRUN: + return ("Isoch. Ring Underrun"); + case XHCI_CODE_RING_OVERRUN: + return ("Isoch. Ring Overrun"); + case XHCI_CODE_VF_RING_FULL: + return ("VF Ring Full"); + case XHCI_CODE_PARAMETER: + return ("Invalid Context Paramenter"); + case XHCI_CODE_BW_OVERRUN: + return ("Bandwidth Overrun"); + case XHCI_CODE_CONTEXT_STATE: + return ("Illegal Context Transition"); + case XHCI_CODE_NO_PING_RESP: + return ("Failed to Complete Periodic Transfer"); + case XHCI_CODE_EV_RING_FULL: + return ("Event Ring Full"); + case XHCI_CODE_INCOMPAT_DEV: + return ("Incompatible Device"); + case XHCI_CODE_MISSED_SRV: + return ("Missed Isoch. Service Window"); + case XHCI_CODE_CMD_RING_STOP: + return ("Command Ring Stop"); + case XHCI_CODE_CMD_ABORTED: + return ("Command Aborted"); + case XHCI_CODE_XFER_STOPPED: + return ("Transfer Stopped"); + case XHCI_CODE_XFER_STOPINV: + return ("Invalid Transfer Length"); + case XHCI_CODE_XFER_STOPSHORT: + return ("Stopped before End of Transfer Descriptor"); + case XHCI_CODE_MELAT: + return ("Max Exit Latency too large"); + case XHCI_CODE_RESERVED: + return ("Reserved"); + case XHCI_CODE_ISOC_OVERRUN: + return ("Isochronus Overrun"); + case XHCI_CODE_EVENT_LOST: + return ("Event Lost"); + case XHCI_CODE_UNDEFINED: + return ("Undefined Fatal Error"); + case XHCI_CODE_INVALID_SID: + return ("Invalid Stream ID"); + case XHCI_CODE_SEC_BW: + return ("Secondary Bandwith Allocation Failure"); + case XHCI_CODE_SPLITERR: + return ("USB2 SPlit Transaction Error"); + default: + break; + } + + if (code >= 192 && code <= 223) + return ("Vendor Defined Error"); + if (code >= 224 && code <= 255) + return ("Vendor Defined Info"); + + return ("Reserved"); +} + +static const char * +xhci_mdb_trb_type_to_str(int code) +{ + /* + * The macros for the types are all already shifted over based on their + * place in the TRB, so shift there again ourselves. + */ + switch (code << 10) { + case XHCI_TRB_TYPE_NORMAL: + return ("Normal"); + case XHCI_TRB_TYPE_SETUP: + return ("Setup"); + case XHCI_TRB_TYPE_DATA: + return ("Data"); + case XHCI_TRB_TYPE_STATUS: + return ("Status"); + case XHCI_TRB_TYPE_LINK: + return ("Link"); + case XHCI_TRB_TYPE_EVENT: + return ("Event"); + case XHCI_TRB_TYPE_NOOP: + return ("No-Op"); + case XHCI_CMD_ENABLE_SLOT: + return ("Enable Slot"); + case XHCI_CMD_DISABLE_SLOT: + return ("Disable Slot"); + case XHCI_CMD_ADDRESS_DEVICE: + return ("Address Device"); + case XHCI_CMD_CONFIG_EP: + return ("Configure Endpoint"); + case XHCI_CMD_EVAL_CTX: + return ("Evaluate Context"); + case XHCI_CMD_RESET_EP: + return ("Reset Endpoint"); + case XHCI_CMD_STOP_EP: + return ("Stop Endpoint"); + case XHCI_CMD_SET_TR_DEQ: + return ("Set Transfer Ring Dequeue Pointer"); + case XHCI_CMD_RESET_DEV: + return ("Reset Device"); + case XHCI_CMD_FEVENT: + return ("Force Event"); + case XHCI_CMD_NEG_BW: + return ("Negotiate Bandwidth"); + case XHCI_CMD_SET_LT: + return ("Set Latency Tolerance"); + case XHCI_CMD_GET_BW: + return ("Get Bandwidth"); + case XHCI_CMD_FHEADER: + return ("Force Header"); + case XHCI_CMD_NOOP: + return ("No-Op Command"); + case XHCI_EVT_XFER: + return ("Transfer Event"); + case XHCI_EVT_CMD_COMPLETE: + return ("Command Completion Event"); + case XHCI_EVT_PORT_CHANGE: + return ("Port Status Change Event"); + case XHCI_EVT_BW_REQUEST: + return ("Bandwidth Request Event"); + case XHCI_EVT_DOORBELL: + return ("Doorbell Event"); + case XHCI_EVT_HOST_CTRL: + return ("Host Controller Event"); + case XHCI_EVT_DEVICE_NOTIFY: + return ("Device Notification Event"); + case XHCI_EVT_MFINDEX_WRAP: + return ("MFINDEX Wrap Event"); + default: + break; + } + + if (code >= 43 && code <= 63) + return ("Vendor Defiend"); + return ("Reserved"); +} + +/* ARGSUSED */ +static int +xhci_mdb_print_epctx(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + uint32_t info, info2, txinfo; + xhci_endpoint_context_t epctx; + + if (!(flags & DCMD_ADDRSPEC)) { + mdb_warn("::xhci_epctx requires an address\n"); + return (DCMD_USAGE); + } + + if (mdb_vread(&epctx, sizeof (epctx), addr) != sizeof (epctx)) { + mdb_warn("failed to read xhci_endpoint_context_t at %p", addr); + return (DCMD_ERR); + } + + info = LE_32(epctx.xec_info); + info2 = LE_32(epctx.xec_info2); + txinfo = LE_32(epctx.xec_txinfo); + + mdb_printf("Endpoint State: %s (%d)\n", + xhci_mdb_epctx_states[XHCI_EPCTX_STATE(info)], + XHCI_EPCTX_STATE(info)); + + mdb_printf("Mult: %d\n", XHCI_EPCTX_GET_MULT(info)); + mdb_printf("Max Streams: %d\n", XHCI_EPCTX_GET_MAXP_STREAMS(info)); + mdb_printf("LSA: %d\n", XHCI_EPCTX_GET_LSA(info)); + mdb_printf("Interval: %d\n", XHCI_EPCTX_GET_IVAL(info)); + mdb_printf("Max ESIT Hi: %d\n", XHCI_EPCTX_GET_MAX_ESIT_HI(info)); + + mdb_printf("CErr: %d\n", XHCI_EPCTX_GET_CERR(info2)); + mdb_printf("EP Type: %s (%d)\n", + xhci_mdb_epctx_eptypes[XHCI_EPCTX_GET_EPTYPE(info2)], + XHCI_EPCTX_GET_EPTYPE(info2)); + mdb_printf("Host Initiate Disable: %d\n", XHCI_EPCTX_GET_HID(info2)); + mdb_printf("Max Burst: %d\n", XHCI_EPCTX_GET_MAXB(info2)); + mdb_printf("Max Packet Size: %d\n", XHCI_EPCTX_GET_MPS(info2)); + + mdb_printf("Ring DCS: %d\n", LE_64(epctx.xec_dequeue) & 0x1); + mdb_printf("Ring PA: 0x%lx\n", LE_64(epctx.xec_dequeue) & ~0xf); + + mdb_printf("Average TRB Length: %d\n", XHCI_EPCTX_AVG_TRB_LEN(txinfo)); + mdb_printf("Max ESIT: %d\n", XHCI_EPCTX_GET_MAX_ESIT_PAYLOAD(txinfo)); + + return (DCMD_OK); +} + +/* ARGSUSED */ +static int +xhci_mdb_print_slotctx(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + uint32_t info, info2, tt, state; + xhci_slot_context_t sctx; + + if (!(flags & DCMD_ADDRSPEC)) { + mdb_warn("::xhci_slotctx requires an address\n"); + return (DCMD_USAGE); + } + + if (mdb_vread(&sctx, sizeof (sctx), addr) != sizeof (sctx)) { + mdb_warn("failed to read xhci_slot_context_t at %p", addr); + return (DCMD_ERR); + } + + info = LE_32(sctx.xsc_info); + info2 = LE_32(sctx.xsc_info2); + tt = LE_32(sctx.xsc_tt); + state = LE_32(sctx.xsc_state); + + mdb_printf("Route: 0x%x\n", XHCI_SCTX_GET_ROUTE(info)); + + mdb_printf("Slot Speed: "); + switch (XHCI_SCTX_GET_SPEED(info)) { + case XHCI_SPEED_FULL: + mdb_printf("Full"); + break; + case XHCI_SPEED_LOW: + mdb_printf("Low"); + break; + case XHCI_SPEED_HIGH: + mdb_printf("High"); + break; + case XHCI_SPEED_SUPER: + mdb_printf("Super"); + break; + default: + mdb_printf("Unknown"); + break; + } + mdb_printf(" (%d)\n", XHCI_SCTX_GET_SPEED(info)); + + + mdb_printf("MTT: %d\n", XHCI_SCTX_GET_MTT(info)); + mdb_printf("HUB: %d\n", XHCI_SCTX_GET_HUB(info)); + mdb_printf("DCI: %d\n", XHCI_SCTX_GET_DCI(info)); + + mdb_printf("Max Exit Latency: %d\n", XHCI_SCTX_GET_MAX_EL(info2)); + mdb_printf("Root Hub Port: %d\n", XHCI_SCTX_GET_RHPORT(info2)); + mdb_printf("Hub Number of Ports: %d\n", XHCI_SCTX_GET_NPORTS(info2)); + + mdb_printf("TT Hub Slot id: %d\n", XHCI_SCTX_GET_TT_HUB_SID(tt)); + mdb_printf("TT Port Number: %d\n", XHCI_SCTX_GET_TT_PORT_NUM(tt)); + mdb_printf("TT Think Time: %d\n", XHCI_SCTX_GET_TT_THINK_TIME(tt)); + mdb_printf("IRQ Target: %d\n", XHCI_SCTX_GET_IRQ_TARGET(tt)); + + mdb_printf("Device Address: 0x%x\n", XHCI_SCTX_GET_DEV_ADDR(state)); + mdb_printf("Slot State: "); + switch (XHCI_SCTX_GET_SLOT_STATE(state)) { + case XHCI_SLOT_DIS_ENAB: + mdb_printf("Disabled/Enabled"); + break; + case XHCI_SLOT_DEFAULT: + mdb_printf("Default"); + break; + case XHCI_SLOT_ADDRESSED: + mdb_printf("Addressed"); + break; + case XHCI_SLOT_CONFIGURED: + mdb_printf("Configured"); + break; + default: + mdb_printf("Unknown"); + break; + } + mdb_printf(" (%d)\n", XHCI_SCTX_GET_SLOT_STATE(state)); + + return (DCMD_OK); +} + +static int +xhci_mdb_print_transfer_event(uint64_t pa, uint32_t status, uint32_t flags) +{ + mdb_printf("TRB Address: 0x%lx\n", pa); + mdb_printf("Transfer Length (Remain): %d\n", XHCI_TRB_REMAIN(status)); + mdb_printf("Completion Code: %s (%d)\n", + xhci_mdb_trb_code_to_str(XHCI_TRB_GET_CODE(status)), + XHCI_TRB_GET_CODE(status)); + + mdb_printf("Cycle: %d\n", XHCI_TRB_GET_CYCLE(flags)); + mdb_printf("Event Data: %d\n", XHCI_TRB_GET_ED(flags)); + mdb_printf("Endpoint ID: %d\n", XHCI_TRB_GET_EP(flags)); + mdb_printf("Slot ID: %d\n", XHCI_TRB_GET_SLOT(flags)); + mdb_dec_indent(XHCI_MDB_TRB_INDENT); + + return (DCMD_OK); +} + +static int +xhci_mdb_print_command_event(uint64_t pa, uint32_t status, uint32_t flags) +{ + mdb_printf("TRB Address: 0x%lx\n", pa); + mdb_printf("Command Param: 0x%x\n", XHCI_TRB_REMAIN(status)); + mdb_printf("Completion Code: %s (%d)\n", + xhci_mdb_trb_code_to_str(XHCI_TRB_GET_CODE(status)), + XHCI_TRB_GET_CODE(status)); + + mdb_printf("Cycle: %d\n", XHCI_TRB_GET_CYCLE(flags)); + /* Skip VF ID as we don't support VFs */ + mdb_printf("Slot ID: %d\n", XHCI_TRB_GET_SLOT(flags)); + mdb_dec_indent(XHCI_MDB_TRB_INDENT); + + return (DCMD_OK); +} + +/* ARGSUSED */ +static int +xhci_mdb_print_psc(uint64_t pa, uint32_t status, uint32_t flags) +{ + mdb_printf("Port: %d\n", XHCI_TRB_PORTID(pa)); + mdb_printf("Completion Code: %s (%d)\n", + xhci_mdb_trb_code_to_str(XHCI_TRB_GET_CODE(status)), + XHCI_TRB_GET_CODE(status)); + mdb_dec_indent(XHCI_MDB_TRB_INDENT); + return (DCMD_OK); +} + +static int +xhci_mdb_print_normal_trb(uint64_t pa, uint32_t status, uint32_t flags) +{ + mdb_printf("TRB Address: 0x%lx\n", pa); + mdb_printf("TRB Length: %d bytes\n", XHCI_TRB_LEN(status)); + mdb_printf("TRB TD Size: %d packets\n", XHCI_TRB_GET_TDREM(status)); + mdb_printf("TRB Interrupt: %d\n", XHCI_TRB_GET_INTR(status)); + mdb_printf("TRB Flags: %b (0x%x)\n", flags, xhci_mdb_trb_flags, + XHCI_TRB_GET_FLAGS(flags)); + mdb_dec_indent(XHCI_MDB_TRB_INDENT); + + return (DCMD_OK); +} + +/* ARGSUSED */ +static int +xhci_mdb_print_trb(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + xhci_trb_t trb; + uint64_t pa; + uint32_t status, trbflags, type; + + if (!(flags & DCMD_ADDRSPEC)) { + mdb_warn("::xhci_trb expects an address\n"); + return (DCMD_USAGE); + } + + if (mdb_vread(&trb, sizeof (trb), addr) != sizeof (trb)) { + mdb_warn("failed to read xhci_trb_t at 0x%x", addr); + return (DCMD_ERR); + } + + pa = LE_64(trb.trb_addr); + status = LE_32(trb.trb_status); + trbflags = LE_32(trb.trb_flags); + + type = XHCI_TRB_GET_TYPE(trbflags); + + if ((flags & DCMD_LOOP) && !(flags & DCMD_LOOPFIRST)) + mdb_printf("\n"); + + mdb_set_dot(addr + sizeof (xhci_trb_t)); + mdb_printf("%s TRB (%d)\n", xhci_mdb_trb_type_to_str(type), type); + mdb_inc_indent(XHCI_MDB_TRB_INDENT); + + switch (XHCI_RING_TYPE_SHIFT(type)) { + case XHCI_EVT_XFER: + return (xhci_mdb_print_transfer_event(pa, status, trbflags)); + case XHCI_EVT_CMD_COMPLETE: + return (xhci_mdb_print_command_event(pa, status, trbflags)); + case XHCI_EVT_PORT_CHANGE: + return (xhci_mdb_print_psc(pa, status, trbflags)); + case XHCI_TRB_TYPE_NORMAL: + return (xhci_mdb_print_normal_trb(pa, status, trbflags)); + } + + /* + * Just print generic information if we don't have a specific printer + * for that TRB type. + */ + mdb_printf("TRB Address: 0x%lx\n", pa); + mdb_printf("TRB Status: 0x%x\n", status); + mdb_printf("TRB Flags: 0x%x\n", trbflags); + mdb_dec_indent(XHCI_MDB_TRB_INDENT); + + return (DCMD_OK); +} + +static int +xhci_mdb_walk_xhci_init(mdb_walk_state_t *wsp) +{ + GElf_Sym sym; + uintptr_t addr; + + if (wsp->walk_addr != 0) { + mdb_warn("::walk xhci only supports global walks\n"); + return (WALK_ERR); + } + + if (mdb_lookup_by_obj("xhci", "xhci_soft_state", &sym) != 0) { + mdb_warn("failed to find xhci_soft_state symbol"); + return (WALK_ERR); + } + + if (mdb_vread(&addr, sizeof (addr), sym.st_value) != sizeof (addr)) { + mdb_warn("failed to read xhci_soft_state at %p", addr); + return (WALK_ERR); + } + + wsp->walk_addr = addr; + if (mdb_layered_walk("softstate", wsp) != 0) { + mdb_warn("failed to walk softstate"); + return (WALK_ERR); + } + + return (WALK_NEXT); +} + +static int +xhci_mdb_walk_xhci_step(mdb_walk_state_t *wsp) +{ + xhci_t xhci; + + if (mdb_vread(&xhci, sizeof (xhci), wsp->walk_addr) != sizeof (xhci)) { + mdb_warn("failed to read xhci_t at %p", wsp->walk_addr); + return (WALK_ERR); + } + + return (wsp->walk_callback(wsp->walk_addr, &xhci, wsp->walk_cbdata)); +} + +static int +xhci_mdb_walk_xhci_device_init(mdb_walk_state_t *wsp) +{ + uintptr_t addr; + + if (wsp->walk_addr == 0) { + mdb_warn("::walk xhci_device requires an xhci_t\n"); + return (WALK_ERR); + } + + addr = wsp->walk_addr; + addr += offsetof(xhci_t, xhci_usba); + addr += offsetof(xhci_usba_t, xa_devices); + wsp->walk_addr = (uintptr_t)addr; + if (mdb_layered_walk("list", wsp) != 0) { + mdb_warn("failed to walk list"); + return (WALK_ERR); + } + + return (WALK_NEXT); +} + +static int +xhci_mdb_walk_xhci_device_step(mdb_walk_state_t *wsp) +{ + xhci_device_t xd; + + if (mdb_vread(&xd, sizeof (xd), wsp->walk_addr) != sizeof (xd)) { + mdb_warn("failed to read xhci_device_t at %p", wsp->walk_addr); + return (WALK_ERR); + } + + return (wsp->walk_callback(wsp->walk_addr, &xd, wsp->walk_cbdata)); +} + +static int +xhci_mdb_walk_xhci_endpoint_init(mdb_walk_state_t *wsp) +{ + xhci_mdb_walk_endpoint_t *xm; + xhci_device_t *xd; + + if (wsp->walk_addr == 0) { + mdb_warn("::walk xhci_endpoint requires an xhci_device_t\n"); + return (WALK_ERR); + } + + xm = mdb_alloc(sizeof (xhci_mdb_walk_endpoint_t), UM_SLEEP | UM_GC); + xm->xmwe_ep = 0; + xd = &xm->xmwe_device; + if (mdb_vread(xd, sizeof (*xd), wsp->walk_addr) != sizeof (*xd)) { + mdb_warn("failed to read xhci_endpoint_t at %p", + wsp->walk_addr); + return (WALK_ERR); + } + wsp->walk_data = xm; + + return (WALK_NEXT); +} + +static int +xhci_mdb_walk_xhci_endpoint_step(mdb_walk_state_t *wsp) +{ + int ret; + uintptr_t addr; + xhci_mdb_walk_endpoint_t *xm = wsp->walk_data; + + if (xm->xmwe_ep >= XHCI_NUM_ENDPOINTS) + return (WALK_DONE); + + addr = (uintptr_t)xm->xmwe_device.xd_endpoints[xm->xmwe_ep]; + if (addr != NULL) { + xhci_endpoint_t xe; + + if (mdb_vread(&xe, sizeof (xe), addr) != sizeof (xe)) { + mdb_warn("failed to read xhci_endpoint_t at %p", + xm->xmwe_device.xd_endpoints[xm->xmwe_ep]); + return (WALK_ERR); + } + + ret = wsp->walk_callback(addr, &xe, wsp->walk_cbdata); + } else { + ret = WALK_NEXT; + } + xm->xmwe_ep++; + + return (ret); +} + +typedef struct xhci_mdb_find { + int xmf_slot; + int xmf_ep; + uintptr_t xmf_addr; +} xhci_mdb_find_t; + +static int +xhci_mdb_find_endpoint_cb(uintptr_t addr, const void *data, void *arg) +{ + const xhci_endpoint_t *xep = data; + xhci_mdb_find_t *xmf = arg; + + /* + * The endpoints that are presented here are off by one from the actual + * endpoint ID in the xhci_endpoint_t, as we're really displaying the + * index into the device input context. + */ + if (xep->xep_num + 1 == xmf->xmf_ep) { + xmf->xmf_addr = addr; + return (WALK_DONE); + } + + return (WALK_NEXT); +} + +static int +xhci_mdb_find_device_cb(uintptr_t addr, const void *data, void *arg) +{ + const xhci_device_t *xd = data; + xhci_mdb_find_t *xmf = arg; + + if (xd->xd_slot == xmf->xmf_slot) { + if (xmf->xmf_ep == -1) { + xmf->xmf_addr = addr; + return (WALK_DONE); + } + + if (mdb_pwalk("xhci`xhci_endpoint", xhci_mdb_find_endpoint_cb, + xmf, addr) == -1) { + mdb_warn("failed to walk xhci_endpoint at %p", addr); + return (WALK_ERR); + } + + return (WALK_DONE); + } + + return (WALK_NEXT); +} + +static int +xhci_mdb_find(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + uintptr_t ep, slot; + boolean_t ep_set, slot_set; + xhci_mdb_find_t xmf; + + if ((flags & DCMD_ADDRSPEC) == 0) + return (DCMD_USAGE); + + ep_set = slot_set = B_FALSE; + if (mdb_getopts(argc, argv, 'e', MDB_OPT_UINTPTR_SET, &ep_set, &ep, + 's', MDB_OPT_UINTPTR_SET, &slot_set, &slot) != argc) + return (DCMD_USAGE); + + if (!slot_set) { + mdb_warn("-s is required\n"); + return (DCMD_USAGE); + } + + xmf.xmf_slot = (int)slot; + if (ep_set) + xmf.xmf_ep = (int)ep; + else + xmf.xmf_ep = -1; + xmf.xmf_addr = 0; + + if (mdb_pwalk("xhci`xhci_device", xhci_mdb_find_device_cb, + &xmf, addr) == -1) { + mdb_warn("failed to walk xhci_device at %p", addr); + return (DCMD_ERR); + } + + if (xmf.xmf_addr == 0) { + if (ep_set) { + mdb_warn("failed to find xhci_endpoint_t for slot %d " + "and endpoint %d\n", slot, ep); + } else { + mdb_warn("failed to find xhci_device_t for slot %d\n", + slot); + } + return (DCMD_ERR); + } + + mdb_printf("%p\n", xmf.xmf_addr); + return (DCMD_OK); +} + +/* ARGSUSED */ +static int +xhci_mdb_endpoint_count(uintptr_t addr, const void *ep, void *arg) +{ + int *countp = arg; + + *countp += 1; + return (WALK_NEXT); +} + +/* ARGSUSED */ +static int +xhci_mdb_print_endpoint_summary(uintptr_t addr, const void *ep, void *arg) +{ + const xhci_device_t *xd = arg; + const xhci_endpoint_t *xep = ep; + const char *type; + const char *state; + xhci_endpoint_context_t epctx; + int eptype; + + if (mdb_vread(&epctx, sizeof (epctx), + (uintptr_t)xd->xd_endout[xep->xep_num]) != sizeof (epctx)) { + mdb_warn("failed to read endpoint context at %p", + xd->xd_endout[xep->xep_num]); + return (WALK_ERR); + } + + eptype = XHCI_EPCTX_GET_EPTYPE(LE_32(epctx.xec_info2)); + type = xhci_mdb_epctx_eptypes[eptype]; + state = xhci_mdb_epctx_states[XHCI_EPCTX_STATE(LE_32(epctx.xec_info))]; + + mdb_printf("%-4d %-10s %-10s 0x%-04x 0x%-04x\n", xep->xep_num, type, + state, xep->xep_ring.xr_head, xep->xep_ring.xr_tail); + + return (WALK_NEXT); +} + +/* ARGSUSED */ +static int +xhci_mdb_print_device(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + int count; + xhci_device_t xd; + usba_device_t ud; + char product[256], mfg[256]; + + if (!(flags & DCMD_ADDRSPEC)) { + return (mdb_eval("::walk xhci`xhci | ::walk xhci`xhci_device | " + "::xhci_device")); + } + + if (mdb_vread(&xd, sizeof (xd), addr) != sizeof (xd)) { + mdb_warn("failed to read xhci_device_t at 0x%x", addr); + return (DCMD_ERR); + } + + if (mdb_vread(&ud, sizeof (ud), (uintptr_t)xd.xd_usbdev) != + sizeof (ud)) { + mdb_warn("failed to read usba_device_t at %p\n", xd.xd_usbdev); + return (DCMD_ERR); + } + + if (ud.usb_mfg_str == NULL || mdb_readstr(mfg, sizeof (mfg), + (uintptr_t)ud.usb_mfg_str) <= 0) { + (void) strlcpy(mfg, "Unknown Manufacturer", sizeof (mfg)); + } + + if (ud.usb_product_str == NULL || mdb_readstr(product, sizeof (product), + (uintptr_t)ud.usb_product_str) <= 0) { + (void) strlcpy(product, "Unknown Product", sizeof (product)); + } + + mdb_printf("%<b>%s - %s%</b>\n", mfg, product); + + count = 0; + if (mdb_pwalk("xhci`xhci_endpoint", xhci_mdb_endpoint_count, &count, + addr) == -1) { + mdb_warn("failed to walk xhci_endpoint rooted at 0x%x", addr); + return (DCMD_ERR); + } + + mdb_printf("Port %02d | Slot %02d | # Endpoints %02d\n", xd.xd_port, + xd.xd_slot, count); + mdb_printf("%<u>%-4s %-10s %-10s %-6s %-6s%</u>\n", "EP", "Type", + "State", "Head", "Tail"); + + if (mdb_pwalk("xhci`xhci_endpoint", xhci_mdb_print_endpoint_summary, + &xd, addr) == -1) { + mdb_warn("failed to walk xhci_endpoint rooted at 0x%x", addr); + return (DCMD_ERR); + } + + + mdb_printf("\n"); + + return (DCMD_OK); +} + +static int +xhci_mdb_find_trb(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + xhci_ring_t xr; + uint64_t base, max, target; + + if (!(flags & DCMD_ADDRSPEC)) { + mdb_warn("missing required xhci_ring_t\n"); + return (DCMD_USAGE); + } + + if (argc == 0) { + mdb_warn("missing required PA of ring\n"); + return (DCMD_USAGE); + } + + if (argc > 1) { + mdb_warn("too many arguments\n"); + return (DCMD_USAGE); + } + + if (mdb_vread(&xr, sizeof (xr), addr) != sizeof (xr)) { + mdb_warn("failed to read xhci_ring_t at %p", addr); + return (DCMD_USAGE); + } + + if (argv[0].a_type == MDB_TYPE_IMMEDIATE) { + target = argv[0].a_un.a_val; + } else if (argv[0].a_type == MDB_TYPE_STRING) { + target = mdb_strtoull(argv[0].a_un.a_str); + } else { + mdb_warn("argument is an unknown supported type: %d\n", + argv[0].a_type); + return (DCMD_USAGE); + } + target = roundup(target, sizeof (xhci_trb_t)); + + base = xr.xr_dma.xdb_cookies[0].dmac_laddress; + max = base + xr.xr_ntrb * sizeof (xhci_trb_t); + + if (target < base || target > max) { + mdb_warn("target address %p is outside the range of PAs for " + "TRBs in the ring [%p, %p)", target, base, max); + return (DCMD_ERR); + } + target -= base; + mdb_printf("0x%" PRIx64 "\n", target + (uintptr_t)xr.xr_trb); + + return (DCMD_OK); +} + +static const mdb_dcmd_t xhci_dcmds[] = { + { "xhci_epctx", ":", "print endpoint context", + xhci_mdb_print_epctx, NULL }, + { "xhci_slotctx", ":", "print slot context", + xhci_mdb_print_slotctx, NULL }, + { "xhci_trb", ":", "print TRB", + xhci_mdb_print_trb, NULL }, + { "xhci_find", ": -s slot [-e endpiont]", + "find given xhci slot or endpoint", + xhci_mdb_find, NULL }, + { "xhci_device", ":", "device summary", + xhci_mdb_print_device, NULL }, + { "xhci_find_trb", ": pa", "find trb with PA in ring", + xhci_mdb_find_trb, NULL }, + { NULL } +}; + +static const mdb_walker_t xhci_walkers[] = { + { "xhci", "walk list of xhci_t structures", + xhci_mdb_walk_xhci_init, xhci_mdb_walk_xhci_step, NULL }, + { "xhci_device", "walk list of xhci_device_t structures", + xhci_mdb_walk_xhci_device_init, xhci_mdb_walk_xhci_device_step, + NULL }, + { "xhci_endpoint", "walk list of xhci_endpoint_t structures", + xhci_mdb_walk_xhci_endpoint_init, xhci_mdb_walk_xhci_endpoint_step, + NULL }, + { NULL } +}; + +static const mdb_modinfo_t xhci_modinfo = { + MDB_API_VERSION, xhci_dcmds, xhci_walkers +}; + +const mdb_modinfo_t * +_mdb_init(void) +{ + return (&xhci_modinfo); +} diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile b/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile index f80ce95abd..ea8099272e 100644 --- a/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile +++ b/usr/src/cmd/mdb/i86pc/modules/unix/amd64/Makefile @@ -22,12 +22,12 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright 2016 Joyent, Inc. +# Copyright 2019 Joyent, Inc. MODULE = unix.so MDBTGT = kvm -MODSRCS = unix.c i86mmu.c +MODSRCS = unix.c i86mmu.c xcall.c MODASMSRCS = unix_sup.s include ../../../../../Makefile.cmd @@ -38,6 +38,7 @@ include ../../../../Makefile.module CPPFLAGS += -DMP -D_MACHDEP CPPFLAGS += -I../../../../common +CPPFLAGS += -I../../../../intel CPPFLAGS += -I$(SRC)/uts/i86pc CPPFLAGS += -I$(SRC)/uts/intel diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/unix.c b/usr/src/cmd/mdb/i86pc/modules/unix/unix.c index bb9c985374..bd7dfda6ed 100644 --- a/usr/src/cmd/mdb/i86pc/modules/unix/unix.c +++ b/usr/src/cmd/mdb/i86pc/modules/unix/unix.c @@ -20,11 +20,12 @@ */ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2018 Joyent, Inc. + * Copyright 2019 Joyent, Inc. */ #include <mdb/mdb_modapi.h> #include <mdb/mdb_ctf.h> +#include <mdb/mdb_x86util.h> #include <sys/cpuvar.h> #include <sys/systm.h> #include <sys/traptrace.h> @@ -770,6 +771,26 @@ ptmap_help(void) "-w run ::whatis on mapping start addresses\n"); } +static const char *const scalehrtime_desc = + "Scales a timestamp from ticks to nanoseconds. Unscaled timestamps\n" + "are used as both a quick way of accumulating relative time (as for\n" + "usage) and as a quick way of getting the absolute current time.\n" + "These uses require slightly different scaling algorithms. By\n" + "default, if a specified time is greater than half of the unscaled\n" + "time at the last tick (that is, if the unscaled time represents\n" + "more than half the time since boot), the timestamp is assumed to\n" + "be absolute, and the scaling algorithm used mimics that which the\n" + "kernel uses in gethrtime(). Otherwise, the timestamp is assumed to\n" + "be relative, and the algorithm mimics scalehrtime(). This behavior\n" + "can be overridden by forcing the unscaled time to be interpreted\n" + "as relative (via -r) or absolute (via -a).\n"; + +static void +scalehrtime_help(void) +{ + mdb_printf("%s", scalehrtime_desc); +} + /* * NSEC_SHIFT is replicated here (it is not defined in a header file), * but for amusement, the reader is directed to the comment that explains @@ -782,25 +803,34 @@ ptmap_help(void) /*ARGSUSED*/ static int -scalehrtime_cmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +scalehrtime_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { uint32_t nsec_scale; - hrtime_t tsc = addr, hrt; + hrtime_t tsc = addr, hrt, tsc_last, base, mult = 1; unsigned int *tscp = (unsigned int *)&tsc; uintptr_t scalehrtimef; uint64_t scale; GElf_Sym sym; + int expected = !(flags & DCMD_ADDRSPEC); + uint_t absolute = FALSE, relative = FALSE; - if (!(flags & DCMD_ADDRSPEC)) { - if (argc != 1) - return (DCMD_USAGE); + if (mdb_getopts(argc, argv, + 'a', MDB_OPT_SETBITS, TRUE, &absolute, + 'r', MDB_OPT_SETBITS, TRUE, &relative, NULL) != argc - expected) + return (DCMD_USAGE); + + if (absolute && relative) { + mdb_warn("can't specify both -a and -r\n"); + return (DCMD_USAGE); + } - switch (argv[0].a_type) { + if (expected == 1) { + switch (argv[argc - 1].a_type) { case MDB_TYPE_STRING: - tsc = mdb_strtoull(argv[0].a_un.a_str); + tsc = mdb_strtoull(argv[argc - 1].a_un.a_str); break; case MDB_TYPE_IMMEDIATE: - tsc = argv[0].a_un.a_val; + tsc = argv[argc - 1].a_un.a_val; break; default: return (DCMD_USAGE); @@ -829,12 +859,40 @@ scalehrtime_cmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) return (DCMD_ERR); } + if (mdb_readsym(&tsc_last, sizeof (tsc_last), "tsc_last") == -1) { + mdb_warn("couldn't read 'tsc_last'"); + return (DCMD_ERR); + } + + if (mdb_readsym(&base, sizeof (base), "tsc_hrtime_base") == -1) { + mdb_warn("couldn't read 'tsc_hrtime_base'"); + return (DCMD_ERR); + } + + /* + * If our time is greater than half of tsc_last, we will take our + * delta against tsc_last, convert it, and add that to (or subtract it + * from) tsc_hrtime_base. This mimics what the kernel actually does + * in gethrtime() (modulo the tsc_sync_tick_delta) and gets us a much + * higher precision result than trying to convert a large tsc value. + */ + if (absolute || (tsc > (tsc_last >> 1) && !relative)) { + if (tsc > tsc_last) { + tsc = tsc - tsc_last; + } else { + tsc = tsc_last - tsc; + mult = -1; + } + } else { + base = 0; + } + scale = (uint64_t)nsec_scale; hrt = ((uint64_t)tscp[1] * scale) << NSEC_SHIFT; hrt += ((uint64_t)tscp[0] * scale) >> (32 - NSEC_SHIFT); - mdb_printf("0x%llx\n", hrt); + mdb_printf("0x%llx\n", base + (hrt * mult)); return (DCMD_OK); } @@ -847,7 +905,7 @@ scalehrtime_cmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) */ /*ARGSUSED*/ static int -x86_featureset_cmd(uintptr_t addr, uint_t flags, int argc, +x86_featureset_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { void *fset; @@ -906,78 +964,32 @@ x86_featureset_cmd(uintptr_t addr, uint_t flags, int argc, static int sysregs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) { - ulong_t cr0, cr2, cr3, cr4; + struct sysregs sregs = { 0 }; desctbr_t gdtr; + boolean_t longmode = B_FALSE; - static const mdb_bitmask_t cr0_flag_bits[] = { - { "PE", CR0_PE, CR0_PE }, - { "MP", CR0_MP, CR0_MP }, - { "EM", CR0_EM, CR0_EM }, - { "TS", CR0_TS, CR0_TS }, - { "ET", CR0_ET, CR0_ET }, - { "NE", CR0_NE, CR0_NE }, - { "WP", CR0_WP, CR0_WP }, - { "AM", CR0_AM, CR0_AM }, - { "NW", CR0_NW, CR0_NW }, - { "CD", CR0_CD, CR0_CD }, - { "PG", CR0_PG, CR0_PG }, - { NULL, 0, 0 } - }; - - static const mdb_bitmask_t cr3_flag_bits[] = { - { "PCD", CR3_PCD, CR3_PCD }, - { "PWT", CR3_PWT, CR3_PWT }, - { NULL, 0, 0, } - }; - - static const mdb_bitmask_t cr4_flag_bits[] = { - { "VME", CR4_VME, CR4_VME }, - { "PVI", CR4_PVI, CR4_PVI }, - { "TSD", CR4_TSD, CR4_TSD }, - { "DE", CR4_DE, CR4_DE }, - { "PSE", CR4_PSE, CR4_PSE }, - { "PAE", CR4_PAE, CR4_PAE }, - { "MCE", CR4_MCE, CR4_MCE }, - { "PGE", CR4_PGE, CR4_PGE }, - { "PCE", CR4_PCE, CR4_PCE }, - { "OSFXSR", CR4_OSFXSR, CR4_OSFXSR }, - { "OSXMMEXCPT", CR4_OSXMMEXCPT, CR4_OSXMMEXCPT }, - { "VMXE", CR4_VMXE, CR4_VMXE }, - { "SMXE", CR4_SMXE, CR4_SMXE }, - { "PCIDE", CR4_PCIDE, CR4_PCIDE }, - { "OSXSAVE", CR4_OSXSAVE, CR4_OSXSAVE }, - { "SMEP", CR4_SMEP, CR4_SMEP }, - { "SMAP", CR4_SMAP, CR4_SMAP }, - { NULL, 0, 0 } - }; - - cr0 = kmdb_unix_getcr0(); - cr2 = kmdb_unix_getcr2(); - cr3 = kmdb_unix_getcr3(); - cr4 = kmdb_unix_getcr4(); - - kmdb_unix_getgdtr(&gdtr); - - mdb_printf("%%cr0 = 0x%lx <%b>\n", cr0, cr0, cr0_flag_bits); - mdb_printf("%%cr2 = 0x%lx <%a>\n", cr2, cr2); +#ifdef __amd64 + longmode = B_TRUE; +#endif - if ((cr4 & CR4_PCIDE)) { - mdb_printf("%%cr3 = 0x%lx <pfn:0x%lx pcid:%lu>\n", cr3, - cr3 >> MMU_PAGESHIFT, cr3 & MMU_PAGEOFFSET); - } else { - mdb_printf("%%cr3 = 0x%lx <pfn:0x%lx flags:%b>\n", cr3, - cr3 >> MMU_PAGESHIFT, cr3, cr3_flag_bits); - } + sregs.sr_cr0 = kmdb_unix_getcr0(); + sregs.sr_cr2 = kmdb_unix_getcr2(); + sregs.sr_cr3 = kmdb_unix_getcr3(); + sregs.sr_cr4 = kmdb_unix_getcr4(); - mdb_printf("%%cr4 = 0x%lx <%b>\n", cr4, cr4, cr4_flag_bits); + kmdb_unix_getgdtr(&gdtr); + sregs.sr_gdtr.d_base = gdtr.dtr_base; + sregs.sr_gdtr.d_lim = gdtr.dtr_limit; - mdb_printf("%%gdtr.base = 0x%lx, %%gdtr.limit = 0x%hx\n", - gdtr.dtr_base, gdtr.dtr_limit); + mdb_x86_print_sysregs(&sregs, longmode); return (DCMD_OK); } #endif +extern void xcall_help(void); +extern int xcall_dcmd(uintptr_t, uint_t, int, const mdb_arg_t *); + static const mdb_dcmd_t dcmds[] = { { "gate_desc", ":", "dump a gate descriptor", gate_desc }, { "idt", ":[-v]", "dump an IDT", idt }, @@ -1000,10 +1012,11 @@ static const mdb_dcmd_t dcmds[] = { { "mfntopfn", ":", "convert hypervisor machine page to physical page", mfntopfn_dcmd }, { "memseg_list", ":", "show memseg list", memseg_list }, - { "scalehrtime", ":", - "scale an unscaled high-res time", scalehrtime_cmd }, + { "scalehrtime", ":[-a|-r]", "scale an unscaled high-res time", + scalehrtime_dcmd, scalehrtime_help }, { "x86_featureset", NULL, "dump the x86_featureset vector", - x86_featureset_cmd }, + x86_featureset_dcmd }, + { "xcall", ":", "print CPU cross-call state", xcall_dcmd, xcall_help }, #ifdef _KMDB { "sysregs", NULL, "dump system registers", sysregs_dcmd }, #endif diff --git a/usr/src/cmd/mdb/i86pc/modules/unix/xcall.c b/usr/src/cmd/mdb/i86pc/modules/unix/xcall.c new file mode 100644 index 0000000000..c7b625c494 --- /dev/null +++ b/usr/src/cmd/mdb/i86pc/modules/unix/xcall.c @@ -0,0 +1,237 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ +/* + * Copyright 2018 Joyent, Inc. + */ + +#include <mdb/mdb_modapi.h> +#include <mdb/mdb_ctf.h> +#include <sys/cpuvar.h> +#include <sys/x_call.h> + +typedef struct { + uint32_t xc_work_cnt; + struct xc_msg *xc_curmsg; + struct xc_msg *xc_msgbox; + xc_data_t xc_data; +} mdb_xcall_machcpu_t; + +typedef struct { + processorid_t cpu_id; + mdb_xcall_machcpu_t cpu_m; +} mdb_xcall_cpu_t; + +typedef struct { + uint_t xd_flags; + processorid_t xd_cpu_id; + size_t xd_msg_index; + struct xc_msg xd_msgs[NCPU]; +} xcall_data_t; + +void +xcall_help(void) +{ + mdb_printf( + "Print all active cross-calls where the given CPU is the master.\n" + "The PEND column is ->xc_work_cnt, the pending message count -\n" + "this includes both master and slave messages. For each\n" + "cross call, the message type and the slave CPU ID are shown.\n"); +} + +static int +cpu_id_to_addr(processorid_t cpun, uintptr_t *addrp) +{ + uintptr_t addr; + GElf_Sym sym; + + if (mdb_lookup_by_name("cpu", &sym) == -1) { + mdb_warn("failed to find symbol for 'cpu'"); + return (-1); + } + + if (cpun * sizeof (uintptr_t) > sym.st_size) + return (-1); + + addr = (uintptr_t)sym.st_value + cpun * sizeof (uintptr_t); + + if (mdb_vread(&addr, sizeof (addr), addr) == -1) { + mdb_warn("failed to read cpu[%lu]", cpun); + return (-1); + } + + if (addr != NULL) { + *addrp = addr; + return (0); + } + + return (-1); +} + +static int +xcall_copy_msg(struct xc_msg *msg, xcall_data_t *data, boolean_t current) +{ + if (data->xd_msg_index >= NCPU) { + mdb_warn("ran out of msg space: %lu >= %lu\n", + data->xd_msg_index, NCPU); + return (-1); + } + + bcopy(msg, &data->xd_msgs[data->xd_msg_index], sizeof (*msg)); + + /* + * As we don't use .xc_next, store 'current' there. + */ + data->xd_msgs[data->xd_msg_index].xc_next = (void *)(uintptr_t)current; + data->xd_msg_index++; + return (0); +} + +static int +xcall_get_msgs(uintptr_t addr, const void *wdata, void *priv) +{ + _NOTE(ARGUNUSED(wdata)); + xcall_data_t *data = priv; + mdb_xcall_cpu_t xcpu = { 0, }; + struct xc_msg msg; + uintptr_t msgaddr; + + if (mdb_ctf_vread(&xcpu, "unix`cpu_t", "mdb_xcall_cpu_t", + addr, MDB_CTF_VREAD_IGNORE_ABSENT) == -1) + return (WALK_ERR); + + if (xcpu.cpu_m.xc_curmsg != NULL) { + msgaddr = (uintptr_t)xcpu.cpu_m.xc_curmsg; + + if (mdb_vread(&msg, sizeof (msg), msgaddr) != sizeof (msg)) + return (WALK_ERR); + + if (msg.xc_master == data->xd_cpu_id) { + if (data->xd_flags & DCMD_PIPE_OUT) + mdb_printf("%p\n", msgaddr); + else if (xcall_copy_msg(&msg, data, B_TRUE) != 0) + return (WALK_ERR); + } + } + + for (msgaddr = (uintptr_t)xcpu.cpu_m.xc_msgbox; + msgaddr != NULL; msgaddr = (uintptr_t)msg.xc_next) { + if (mdb_vread(&msg, sizeof (msg), msgaddr) != sizeof (msg)) + return (WALK_ERR); + + if (msg.xc_master != data->xd_cpu_id) + continue; + + if (data->xd_flags & DCMD_PIPE_OUT) + mdb_printf("%p\n", msgaddr); + else if (xcall_copy_msg(&msg, data, B_FALSE) != 0) + return (WALK_ERR); + } + + return (WALK_NEXT); +} + +static int +print_xcall_msg(struct xc_msg *msg) +{ + boolean_t current = (boolean_t)msg->xc_next; + char indent[] = " "; + const char *cmd; + + switch (msg->xc_command) { + case XC_MSG_ASYNC: cmd = "ASYNC"; break; + case XC_MSG_CALL: cmd = "CALL"; break; + case XC_MSG_SYNC: cmd = "SYNC"; break; + case XC_MSG_FREE:cmd = "FREE"; break; + case XC_MSG_WAITING: cmd = "WAITING"; break; + case XC_MSG_RELEASED: cmd = "RELEASED"; break; + case XC_MSG_DONE: cmd = "DONE"; break; + default: cmd = "?"; break; + } + + mdb_printf("%s %s%-*s %-6u\n", indent, current ? "*" : "", + 9 - current, cmd, msg->xc_slave); + return (0); +} + +/* + * Show all xcall messages where the master is the given CPU. + * + * As non-free messages can be on the slave's ->xc_msgbox or ->xc_curmsg, we + * need to walk across all of them to find each message where ->xc_master + * is our CPU ID. + */ +int +xcall_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + mdb_xcall_cpu_t xcpu = { 0, }; + xcall_data_t data = { 0, }; + + if (mdb_getopts(argc, argv, NULL) != argc) + return (DCMD_USAGE); + + /* + * Yep, this will re-collect all the messages each time. Shrug. + */ + if (!(flags & DCMD_ADDRSPEC)) { + if (mdb_pwalk_dcmd("cpu", "xcall", argc, argv, 0) == -1) { + mdb_warn("can't walk CPUs"); + return (DCMD_ERR); + } + + return (DCMD_OK); + } + + if (addr < NCPU && cpu_id_to_addr((processorid_t)addr, &addr) != 0) { + mdb_warn("invalid CPU ID %lu\n", addr); + return (DCMD_ERR); + } + + if (mdb_ctf_vread(&xcpu, "unix`cpu_t", "mdb_xcall_cpu_t", + addr, MDB_CTF_VREAD_IGNORE_ABSENT) == -1) { + mdb_warn("couldn't read cpu 0x%lx", addr); + return (DCMD_ERR); + } + + data.xd_cpu_id = xcpu.cpu_id; + data.xd_flags = flags; + + if (mdb_pwalk("cpu", xcall_get_msgs, &data, NULL) == -1) { + mdb_warn("can't walk CPUs"); + return (DCMD_ERR); + } + + if (flags & DCMD_PIPE_OUT) + return (DCMD_OK); + + if (DCMD_HDRSPEC(flags)) + mdb_printf("%<u>%3s %4s %s%</u>\n", "CPU", "PEND", "HANDLER"); + + if (data.xd_msg_index == 0) { + mdb_printf("%3d %4d -\n", + xcpu.cpu_id, xcpu.cpu_m.xc_work_cnt); + return (DCMD_OK); + } + + mdb_printf("%3d %4d %a(%a, %a, %a)\n", + xcpu.cpu_id, xcpu.cpu_m.xc_work_cnt, + xcpu.cpu_m.xc_data.xc_func, xcpu.cpu_m.xc_data.xc_a1, + xcpu.cpu_m.xc_data.xc_a2, xcpu.cpu_m.xc_data.xc_a3); + + if (!(flags & DCMD_PIPE_OUT)) + mdb_printf(" %<u>%-9s %-6s%</u>\n", "COMMAND", "SLAVE"); + + for (size_t i = 0; i < data.xd_msg_index; i++) { + if (print_xcall_msg(&data.xd_msgs[i]) != 0) + return (DCMD_ERR); + } + + return (DCMD_OK); +} diff --git a/usr/src/cmd/mdb/i86xpv/modules/unix/amd64/Makefile b/usr/src/cmd/mdb/i86xpv/modules/unix/amd64/Makefile index 48e79ed8dc..dd0e3d3318 100644 --- a/usr/src/cmd/mdb/i86xpv/modules/unix/amd64/Makefile +++ b/usr/src/cmd/mdb/i86xpv/modules/unix/amd64/Makefile @@ -22,12 +22,12 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright 2016 Joyent, Inc. +# Copyright 2019 Joyent, Inc. MODULE = unix.so MDBTGT = kvm -MODSRCS = unix.c i86mmu.c +MODSRCS = unix.c i86mmu.c xcall.c MODASMSRCS = unix_sup.s include ../../../../../Makefile.cmd @@ -40,6 +40,7 @@ MODSRCS_DIR = ../../../../i86pc/modules/unix/ CPPFLAGS += -DMP -D_MACHDEP -D__xpv CPPFLAGS += -I../../../../common +CPPFLAGS += -I../../../../intel CPPFLAGS += -I$(SRC)/uts/common CPPFLAGS += -I$(SRC)/uts/i86xpv CPPFLAGS += -I$(SRC)/uts/i86pc diff --git a/usr/src/cmd/mdb/intel/Makefile.kmdb b/usr/src/cmd/mdb/intel/Makefile.kmdb index 1e9efcbc83..fea041a6dc 100644 --- a/usr/src/cmd/mdb/intel/Makefile.kmdb +++ b/usr/src/cmd/mdb/intel/Makefile.kmdb @@ -68,6 +68,7 @@ KMDBLIBS = $(STANDLIBS) ../mdb_ks/kmod/mdb_ks MAPFILE_SOURCES = \ $(MAPFILE_SOURCES_COMMON) \ ../../kmdb/kmdb_dpi_isadep.h \ + ../../mdb/mdb_x86util.h \ $(MAPFILE_SOURCES_$(MACH)) %.o: ../../../../../uts/intel/promif/%.c diff --git a/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb b/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb index 61cf1541a2..8cee9ff049 100644 --- a/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb +++ b/usr/src/cmd/mdb/intel/amd64/Makefile.kmdb @@ -22,6 +22,8 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2019 Joyent, Inc. +# KMDBML += \ kaif_invoke.s \ @@ -29,6 +31,7 @@ KMDBML += \ KMDBSRCS += \ kmdb_makecontext.c \ - mdb_amd64util.c + mdb_amd64util.c \ + mdb_x86util.c SACPPFLAGS = -D__$(MACH64) -U__$(MACH) diff --git a/usr/src/cmd/mdb/intel/amd64/libpython/Makefile b/usr/src/cmd/mdb/intel/amd64/libpython/Makefile index f454b29658..d78b5e0fc2 100644 --- a/usr/src/cmd/mdb/intel/amd64/libpython/Makefile +++ b/usr/src/cmd/mdb/intel/amd64/libpython/Makefile @@ -42,7 +42,6 @@ include ../../../Makefile.module %.ln := CPPFLAGS += $(PYLNFLAGS) LINTFLAGS += -erroff=E_MACRO_REDEFINED - dmod/$(MODULE) := LDLIBS += -lproc %.o: $(MODSRCS_DIR)/%.c diff --git a/usr/src/cmd/mdb/intel/amd64/libumem/Makefile b/usr/src/cmd/mdb/intel/amd64/libumem/Makefile index 704ff65873..ae22217a1b 100644 --- a/usr/src/cmd/mdb/intel/amd64/libumem/Makefile +++ b/usr/src/cmd/mdb/intel/amd64/libumem/Makefile @@ -22,6 +22,7 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright (c) 2012 Joyent, Inc. All rights reserved. MODULE = libumem.so MDBTGT = proc diff --git a/usr/src/cmd/mdb/intel/amd64/mdb/Makefile b/usr/src/cmd/mdb/intel/amd64/mdb/Makefile index 3dfa7a34d5..918aa71ea1 100644 --- a/usr/src/cmd/mdb/intel/amd64/mdb/Makefile +++ b/usr/src/cmd/mdb/intel/amd64/mdb/Makefile @@ -22,10 +22,15 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2019 Joyent, Inc. +# SRCS = kvm_amd64dep.c \ kvm_isadep.c \ mdb_amd64util.c \ + mdb_ia32util.c \ + mdb_x86util.c \ + mdb_bhyve.c \ proc_amd64dep.c %.o: %.c @@ -42,12 +47,14 @@ SRCS = kvm_amd64dep.c \ %.ln: ../../mdb/%.c $(LINT.c) -c $< -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.amd64 -include ../../../Makefile.mdb +include $(SRC)/cmd/Makefile.cmd +include $(SRC)/cmd/Makefile.cmd.64 +include $(SRC)/cmd/mdb/intel/Makefile.amd64 +include $(SRC)/cmd/mdb/Makefile.mdb +include $(SRC)/Makefile.psm CPPFLAGS += -I../../mdb -LDLIBS += -lsaveargs + +LDLIBS += -lsaveargs -lvmm install: all $(ISAEXEC) $(ROOTPROG64) $(ROOTLINK64) diff --git a/usr/src/cmd/mdb/intel/amd64/xhci/Makefile b/usr/src/cmd/mdb/intel/amd64/xhci/Makefile new file mode 100644 index 0000000000..0de7a701a7 --- /dev/null +++ b/usr/src/cmd/mdb/intel/amd64/xhci/Makefile @@ -0,0 +1,27 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2016 Joyent, Inc. +# + + +MODULE = xhci.so +MDBTGT = kvm + +MODSRCS = xhci.c + +include ../../../../Makefile.cmd +include ../../../../Makefile.cmd.64 +include ../../Makefile.amd64 +include ../../../Makefile.module + +CPPFLAGS += -I$(SRC)/uts/common diff --git a/usr/src/cmd/mdb/intel/ia32/libumem/Makefile b/usr/src/cmd/mdb/intel/ia32/libumem/Makefile index a1ab338f40..bde1be90ac 100644 --- a/usr/src/cmd/mdb/intel/ia32/libumem/Makefile +++ b/usr/src/cmd/mdb/intel/ia32/libumem/Makefile @@ -22,6 +22,7 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright (c) 2012 Joyent, Inc. All rights reserved. MODULE = libumem.so MDBTGT = proc diff --git a/usr/src/cmd/mdb/intel/ia32/xhci/Makefile b/usr/src/cmd/mdb/intel/ia32/xhci/Makefile new file mode 100644 index 0000000000..6fb72a3b2d --- /dev/null +++ b/usr/src/cmd/mdb/intel/ia32/xhci/Makefile @@ -0,0 +1,25 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2016 Joyent, Inc. +# + +MODULE = xhci.so +MDBTGT = kvm + +MODSRCS = xhci.c + +include ../../../../Makefile.cmd +include ../../Makefile.ia32 +include ../../../Makefile.module + +CPPFLAGS += -I$(SRC)/uts/common diff --git a/usr/src/cmd/mdb/intel/kmdb/kaif.c b/usr/src/cmd/mdb/intel/kmdb/kaif.c index 39cc9b620a..e4f80ad228 100644 --- a/usr/src/cmd/mdb/intel/kmdb/kaif.c +++ b/usr/src/cmd/mdb/intel/kmdb/kaif.c @@ -296,12 +296,12 @@ kaif_brkpt_arm(uintptr_t addr, mdb_instr_t *instrp) return (set_errno(EMDB_TGTNOTSUP)); } - if (mdb_tgt_vread(mdb.m_target, instrp, sizeof (mdb_instr_t), addr) != - sizeof (mdb_instr_t)) + if (mdb_tgt_aread(mdb.m_target, MDB_TGT_AS_VIRT_I, instrp, + sizeof (mdb_instr_t), addr) != sizeof (mdb_instr_t)) return (-1); /* errno is set for us */ - if (mdb_tgt_vwrite(mdb.m_target, &bkpt, sizeof (mdb_instr_t), addr) != - sizeof (mdb_instr_t)) + if (mdb_tgt_awrite(mdb.m_target, MDB_TGT_AS_VIRT_I, &bkpt, + sizeof (mdb_instr_t), addr) != sizeof (mdb_instr_t)) return (-1); /* errno is set for us */ return (0); @@ -310,8 +310,8 @@ kaif_brkpt_arm(uintptr_t addr, mdb_instr_t *instrp) static int kaif_brkpt_disarm(uintptr_t addr, mdb_instr_t instrp) { - if (mdb_tgt_vwrite(mdb.m_target, &instrp, sizeof (mdb_instr_t), addr) != - sizeof (mdb_instr_t)) + if (mdb_tgt_awrite(mdb.m_target, MDB_TGT_AS_VIRT_I, &instrp, + sizeof (mdb_instr_t), addr) != sizeof (mdb_instr_t)) return (-1); /* errno is set for us */ return (0); @@ -486,7 +486,7 @@ kaif_step(void) } if ((npc = mdb_dis_nextins(mdb.m_disasm, mdb.m_target, - MDB_TGT_AS_VIRT, pc)) == pc) { + MDB_TGT_AS_VIRT_I, pc)) == pc) { warn("failed to decode instruction at %a for step\n", pc); return (set_errno(EINVAL)); } @@ -498,8 +498,8 @@ kaif_step(void) * versus their 64-bit counterparts. */ do { - if (mdb_tgt_vread(mdb.m_target, &instr, sizeof (mdb_instr_t), - pc + pcoff) != sizeof (mdb_instr_t)) { + if (mdb_tgt_aread(mdb.m_target, MDB_TGT_AS_VIRT_I, &instr, + sizeof (mdb_instr_t), pc + pcoff) != sizeof (mdb_instr_t)) { warn("failed to read at %p for step", (void *)(pc + pcoff)); return (-1); @@ -518,8 +518,8 @@ kaif_step(void) return (set_errno(EMDB_TGTNOTSUP)); case M_ESC: - if (mdb_tgt_vread(mdb.m_target, &instr, sizeof (mdb_instr_t), - pc + pcoff) != sizeof (mdb_instr_t)) { + if (mdb_tgt_aread(mdb.m_target, MDB_TGT_AS_VIRT_I, &instr, + sizeof (mdb_instr_t), pc + pcoff) != sizeof (mdb_instr_t)) { warn("failed to read at %p for step", (void *)(pc + pcoff)); return (-1); @@ -568,8 +568,8 @@ kaif_step(void) (void) kmdb_dpi_get_register("sp", &sp); (void) kmdb_dpi_get_register(FLAGS_REG_NAME, &fl); - if (mdb_tgt_vread(mdb.m_target, &newfl, sizeof (kreg_t), - sp) != sizeof (kreg_t)) { + if (mdb_tgt_aread(mdb.m_target, MDB_TGT_AS_VIRT_S, &newfl, + sizeof (kreg_t), sp) != sizeof (kreg_t)) { warn("failed to read " FLAGS_REG_NAME " at %p for popfl step\n", (void *)sp); return (set_errno(EMDB_TGTNOTSUP)); /* XXX ? */ @@ -577,8 +577,8 @@ kaif_step(void) fl = (fl & ~KREG_EFLAGS_IF_MASK) | KREG_EFLAGS_TF_MASK; - if (mdb_tgt_vwrite(mdb.m_target, &fl, sizeof (kreg_t), - sp) != sizeof (kreg_t)) { + if (mdb_tgt_awrite(mdb.m_target, MDB_TGT_AS_VIRT_S, &fl, + sizeof (kreg_t), sp) != sizeof (kreg_t)) { warn("failed to update " FLAGS_REG_NAME " at %p for popfl step\n", (void *)sp); return (set_errno(EMDB_TGTNOTSUP)); /* XXX ? */ @@ -617,8 +617,8 @@ kaif_step(void) */ (void) kmdb_dpi_get_register("sp", &sp); - if (mdb_tgt_vwrite(mdb.m_target, &oldfl, sizeof (kreg_t), - sp) != sizeof (kreg_t)) { + if (mdb_tgt_awrite(mdb.m_target, MDB_TGT_AS_VIRT_S, &oldfl, + sizeof (kreg_t), sp) != sizeof (kreg_t)) { warn("failed to update pushed " FLAGS_REG_NAME " at %p after pushfl step\n", (void *)sp); return (set_errno(EMDB_TGTNOTSUP)); /* XXX ? */ diff --git a/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c b/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c index 4bfb32fa20..985da328dc 100644 --- a/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c +++ b/usr/src/cmd/mdb/intel/mdb/kvm_amd64dep.c @@ -46,6 +46,7 @@ #include <mdb/mdb_modapi.h> #include <mdb/mdb_conf.h> #include <mdb/mdb_kreg_impl.h> +#include <mdb/mdb_isautil.h> #include <mdb/mdb_amd64util.h> #include <mdb/kvm_isadep.h> #include <mdb/mdb_kvm.h> diff --git a/usr/src/cmd/mdb/intel/mdb/kvm_ia32dep.c b/usr/src/cmd/mdb/intel/mdb/kvm_ia32dep.c index a5e336acdf..7cd9195f29 100644 --- a/usr/src/cmd/mdb/intel/mdb/kvm_ia32dep.c +++ b/usr/src/cmd/mdb/intel/mdb/kvm_ia32dep.c @@ -45,6 +45,7 @@ #include <mdb/mdb_modapi.h> #include <mdb/mdb_conf.h> #include <mdb/mdb_kreg_impl.h> +#include <mdb/mdb_isautil.h> #include <mdb/mdb_ia32util.h> #include <mdb/kvm_isadep.h> #include <mdb/mdb_kvm.h> diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c b/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c index 14c81f47fd..7740a82d8f 100644 --- a/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c +++ b/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.c @@ -39,6 +39,7 @@ #include <mdb/mdb_kreg_impl.h> #include <mdb/mdb_debug.h> #include <mdb/mdb_modapi.h> +#include <mdb/mdb_isautil.h> #include <mdb/mdb_amd64util.h> #include <mdb/mdb_ctf.h> #include <mdb/mdb_err.h> @@ -244,7 +245,8 @@ mdb_amd64_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, while (fp != 0) { int args_style = 0; - if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) != sizeof (fr)) { + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_S, &fr, sizeof (fr), fp) != + sizeof (fr)) { err = EMDB_NOMAP; goto badfp; } @@ -259,8 +261,9 @@ mdb_amd64_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, if (advance_tortoise != 0) { struct fr tfr; - if (mdb_tgt_vread(t, &tfr, sizeof (tfr), - tortoise_fp) != sizeof (tfr)) { + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_S, &tfr, + sizeof (tfr), tortoise_fp) != + sizeof (tfr)) { err = EMDB_NOMAP; goto badfp; } @@ -330,7 +333,8 @@ mdb_amd64_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, insnsize = MIN(MIN(s.st_size, SAVEARGS_INSN_SEQ_LEN), pc - s.st_value); - if (mdb_tgt_vread(t, ins, insnsize, s.st_value) != insnsize) + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_I, ins, insnsize, + s.st_value) != insnsize) argc = 0; if ((argc != 0) && @@ -349,8 +353,8 @@ mdb_amd64_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, if (args_style == SAVEARGS_STRUCT_ARGS) size += sizeof (long); - if (mdb_tgt_vread(t, fr_argv, size, (fp - size)) - != size) + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_S, fr_argv, size, + (fp - size)) != size) return (-1); /* errno has been set for us */ /* @@ -369,7 +373,8 @@ mdb_amd64_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, sizeof (fr_argv) - (reg_argc * sizeof (long))); - if (mdb_tgt_vread(t, &fr_argv[reg_argc], size, + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_S, + &fr_argv[reg_argc], size, fp + sizeof (fr)) != size) return (-1); /* errno has been set */ } @@ -434,14 +439,15 @@ mdb_amd64_step_out(mdb_tgt_t *t, uintptr_t *p, kreg_t pc, kreg_t fp, kreg_t sp, if (pc == s.st_value && curinstr == M_PUSHQ_RBP) fp = sp - 8; else if (pc == s.st_value + 1 && curinstr == M_REX_W) { - if (mdb_tgt_vread(t, &curinstr, sizeof (curinstr), - pc + 1) == sizeof (curinstr) && curinstr == - M_MOVL_RBP) + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_I, &curinstr, + sizeof (curinstr), pc + 1) == sizeof (curinstr) && + curinstr == M_MOVL_RBP) fp = sp; } } - if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) == sizeof (fr)) { + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_S, &fr, sizeof (fr), fp) == + sizeof (fr)) { *p = fr.fr_savpc; return (0); } @@ -476,8 +482,8 @@ mdb_amd64_next(mdb_tgt_t *t, uintptr_t *p, kreg_t pc, mdb_instr_t curinstr) /* Skip the rex prefix, if any */ callpc = pc; while (curinstr >= M_REX_LO && curinstr <= M_REX_HI) { - if (mdb_tgt_vread(t, &curinstr, sizeof (curinstr), ++callpc) != - sizeof (curinstr)) + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_I, &curinstr, + sizeof (curinstr), ++callpc) != sizeof (curinstr)) return (-1); /* errno is set for us */ } @@ -486,7 +492,8 @@ mdb_amd64_next(mdb_tgt_t *t, uintptr_t *p, kreg_t pc, mdb_instr_t curinstr) return (set_errno(EAGAIN)); } - if ((npc = mdb_dis_nextins(mdb.m_disasm, t, MDB_TGT_AS_VIRT, pc)) == pc) + npc = mdb_dis_nextins(mdb.m_disasm, t, MDB_TGT_AS_VIRT_I, pc); + if (npc == pc) return (-1); /* errno is set for us */ *p = npc; diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.h b/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.h index f8c6097cef..b3f060bf05 100644 --- a/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.h +++ b/usr/src/cmd/mdb/intel/mdb/mdb_amd64util.h @@ -22,12 +22,13 @@ * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2018, Joyent, Inc. All rights reserved. + */ #ifndef _MDB_AMD64UTIL_H #define _MDB_AMD64UTIL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <mdb/mdb_kreg.h> #include <mdb/mdb_target_impl.h> @@ -35,8 +36,6 @@ extern "C" { #endif -typedef uchar_t mdb_instr_t; - extern const mdb_tgt_regdesc_t mdb_amd64_kregs[]; extern void mdb_amd64_printregs(const mdb_tgt_gregset_t *); diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_bhyve.c b/usr/src/cmd/mdb/intel/mdb/mdb_bhyve.c new file mode 100644 index 0000000000..2bcf7f233f --- /dev/null +++ b/usr/src/cmd/mdb/intel/mdb/mdb_bhyve.c @@ -0,0 +1,1460 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. + */ + +/* + * bhyve target + * + * The bhyve target is used to examine and manipulate a bhyve VM. Access to + * a bhyve VM is provided by libvmm, which itself uses libvmmapi, which uses + * the vmm driver's ioctl interface to carry out requests. + * + * The bhyve target does not know about threads or processes, but it handles + * multiple vCPUs and can switch between them. Execution control is currently + * limited to completely stopping or resuming all vCPUs of a VM, or single- + * stepping a particular vCPU while all other vCPUs remain stopped. Breakpoints + * are not implemented yet, and as such step-out and step-over don't work yet. + * All known x86 instruction sets are support, legacy IA-16, IA-32 and AMD64. + * The current CPU instruction set is automatically determined by parsing the + * code segment (CS) attributes in the current vCPU. + * + * All of the VMs physical memory and device memory segments are mapped R/W + * into mdb's address space by libvmm. All accesses to those memory are + * facilitated through libvmm calls, which may include virtual address + * translation according to the current vCPU mode. Both real-mode and protected- + * mode segmentation are understood and used for translating virtual addresses + * into linear addresses, which may further be translated using 2-level, 3-level + * or 4-level paging. + * + * To handle disassembly and stack tracing properly when segmentation is used by + * a vCPU (always in real mode, sometimes in protected mode) the bhyve target + * has a notion of three virtual address spaces used for reading/writing memory: + * - MDB_TGT_AS_VIRT, the default virtual address space uses the DS segment + * by default, but this default can be changed with the ::defseg dcmd. + * - MDB_TGT_AS_VIRT_I, the virtual address space for instructions always + * uses the code segment (CS) for translation + * - MDB_TGT_AS_VIRT_S, the virtual address space for the stack always uses + * the stack segment (SS) for translation + * + * Register printing and stack tracing is using the common x86 ISA-specific code + * in IA-32 and AMD64 modes. There is no stack tracing for IA-16 mode yet. + * + * Todo: + * - support for breakpoint, step-out, and step-over + * - support for x86 stack tracing + */ +#include <mdb/mdb_conf.h> +#include <mdb/mdb_err.h> +#include <mdb/mdb_signal.h> +#include <mdb/mdb_modapi.h> +#include <mdb/mdb_io_impl.h> +#include <mdb/mdb_kreg_impl.h> +#include <mdb/mdb_target_impl.h> +#include <mdb/mdb_isautil.h> +#include <mdb/mdb_amd64util.h> +#include <mdb/mdb_ia32util.h> +#include <mdb/mdb_x86util.h> +#include <mdb/mdb.h> + +#include <sys/controlregs.h> +#include <sys/debugreg.h> +#include <sys/sysmacros.h> +#include <sys/note.h> +#include <unistd.h> +#include <inttypes.h> + +#include <libvmm.h> + +#define MDB_DEF_PROMPT "[%<_cpuid>]> " + +typedef struct bhyve_data { + vmm_t *bd_vmm; + uint_t bd_curcpu; + int bd_defseg; + + /* must be last */ + char bd_name[]; +} bhyve_data_t; + + +const mdb_tgt_regdesc_t bhyve_kregs[] = { + { "rdi", KREG_RDI, MDB_TGT_R_EXPORT }, + { "edi", KREG_RDI, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "di", KREG_RDI, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "dil", KREG_RDI, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "rsi", KREG_RSI, MDB_TGT_R_EXPORT }, + { "esi", KREG_RSI, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "si", KREG_RSI, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "sil", KREG_RSI, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "rdx", KREG_RDX, MDB_TGT_R_EXPORT }, + { "edx", KREG_RDX, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "dx", KREG_RDX, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "dh", KREG_RDX, MDB_TGT_R_EXPORT | MDB_TGT_R_8H }, + { "dl", KREG_RDX, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "rcx", KREG_RCX, MDB_TGT_R_EXPORT }, + { "ecx", KREG_RCX, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "cx", KREG_RCX, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "ch", KREG_RCX, MDB_TGT_R_EXPORT | MDB_TGT_R_8H }, + { "cl", KREG_RCX, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "r8", KREG_R8, MDB_TGT_R_EXPORT }, + { "r8d", KREG_R8, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "r8w", KREG_R8, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "r8l", KREG_R8, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "r9", KREG_R9, MDB_TGT_R_EXPORT }, + { "r9d", KREG_R8, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "r9w", KREG_R8, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "r9l", KREG_R8, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "rax", KREG_RAX, MDB_TGT_R_EXPORT }, + { "eax", KREG_RAX, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "ax", KREG_RAX, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "ah", KREG_RAX, MDB_TGT_R_EXPORT | MDB_TGT_R_8H }, + { "al", KREG_RAX, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "rbx", KREG_RBX, MDB_TGT_R_EXPORT }, + { "ebx", KREG_RBX, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "bx", KREG_RBX, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "bh", KREG_RBX, MDB_TGT_R_EXPORT | MDB_TGT_R_8H }, + { "bl", KREG_RBX, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "rbp", KREG_RBP, MDB_TGT_R_EXPORT }, + { "ebp", KREG_RBP, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "bp", KREG_RBP, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "bpl", KREG_RBP, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "r10", KREG_R10, MDB_TGT_R_EXPORT }, + { "r10d", KREG_R10, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "r10w", KREG_R10, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "r10l", KREG_R10, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "r11", KREG_R11, MDB_TGT_R_EXPORT }, + { "r11d", KREG_R11, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "r11w", KREG_R11, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "r11l", KREG_R11, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "r12", KREG_R12, MDB_TGT_R_EXPORT }, + { "r12d", KREG_R12, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "r12w", KREG_R12, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "r12l", KREG_R12, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "r13", KREG_R13, MDB_TGT_R_EXPORT }, + { "r13d", KREG_R13, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "r13w", KREG_R13, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "r13l", KREG_R13, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "r14", KREG_R14, MDB_TGT_R_EXPORT }, + { "r14d", KREG_R14, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "r14w", KREG_R14, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "r14l", KREG_R14, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "r15", KREG_R15, MDB_TGT_R_EXPORT }, + { "r15d", KREG_R15, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "r15w", KREG_R15, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "r15l", KREG_R15, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "ds", KREG_DS, MDB_TGT_R_EXPORT }, + { "es", KREG_ES, MDB_TGT_R_EXPORT }, + { "fs", KREG_FS, MDB_TGT_R_EXPORT }, + { "gs", KREG_GS, MDB_TGT_R_EXPORT }, + { "rip", KREG_RIP, MDB_TGT_R_EXPORT }, + { "cs", KREG_CS, MDB_TGT_R_EXPORT }, + { "rflags", KREG_RFLAGS, MDB_TGT_R_EXPORT }, + { "eflags", KREG_RFLAGS, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "rsp", KREG_RSP, MDB_TGT_R_EXPORT }, + { "esp", KREG_RSP, MDB_TGT_R_EXPORT | MDB_TGT_R_32 }, + { "sp", KREG_RSP, MDB_TGT_R_EXPORT | MDB_TGT_R_16 }, + { "spl", KREG_RSP, MDB_TGT_R_EXPORT | MDB_TGT_R_8L }, + { "ss", KREG_SS, MDB_TGT_R_EXPORT }, + { "cr2", KREG_CR2, MDB_TGT_R_EXPORT }, + { "cr3", KREG_CR3, MDB_TGT_R_EXPORT }, + { NULL, 0, 0 } +}; + +static const char *segments[] = { "CS", "DS", "ES", "FS", "GS", "SS" }; + + +/*ARGSUSED*/ +static uintmax_t +bhyve_cpuid_get(const mdb_var_t *v) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + + return (bd->bd_curcpu); +} + +static const mdb_nv_disc_t bhyve_cpuid_disc = { + .disc_get = bhyve_cpuid_get +}; + + +static uintmax_t +bhyve_reg_get(const mdb_var_t *v) +{ + mdb_tgt_reg_t r = 0; + + if (mdb_tgt_getareg(MDB_NV_COOKIE(v), 0, mdb_nv_get_name(v), &r) == -1) + mdb_warn("failed to get %%%s register", mdb_nv_get_name(v)); + + return (r); +} + +static void +bhyve_reg_set(mdb_var_t *v, uintmax_t r) +{ + if (mdb_tgt_putareg(MDB_NV_COOKIE(v), 0, mdb_nv_get_name(v), r) == -1) + mdb_warn("failed to modify %%%s register", mdb_nv_get_name(v)); +} + +static const mdb_nv_disc_t bhyve_reg_disc = { + .disc_set = bhyve_reg_set, + .disc_get = bhyve_reg_get +}; + +static int +bhyve_get_gregset(bhyve_data_t *bd, int cpu, mdb_tgt_gregset_t *gregs) +{ + vmm_desc_t fs, gs; + + /* + * Register numbers to get, the order must match the definitions of + * KREG_* in mdb_kreg.h so that we get a proper mdb_tgt_gregset_t + * that the register printing functions will understand. + * + * There are a few fields in mdb_tgt_gregset_t that can't be accessed + * with vmm_get_regset(), either because they don't exist in bhyve or + * or because they need to be accessed with vmm_get_desc(). For these + * cases we ask for RAX instead and fill it with 0 or the real value, + * respectively. + */ + static const int regnums[] = { + KREG_RAX, /* dummy for SAVFP */ + KREG_RAX, /* dummy for SAVFP */ + KREG_RDI, + KREG_RSI, + KREG_RDX, + KREG_RCX, + KREG_R8, + KREG_R9, + KREG_RAX, + KREG_RBX, + KREG_RBP, + KREG_R10, + KREG_R11, + KREG_R12, + KREG_R13, + KREG_R14, + KREG_R15, + KREG_RAX, /* dummy for FSBASE */ + KREG_RAX, /* dummy for GSBASE */ + KREG_RAX, /* dummy for KGSBASE */ + KREG_CR2, + KREG_CR3, + KREG_DS, + KREG_ES, + KREG_FS, + KREG_GS, + KREG_RAX, /* dummy for TRAPNO */ + KREG_RAX, /* dummy for ERR */ + KREG_RIP, + KREG_CS, + KREG_RFLAGS, + KREG_RSP, + KREG_SS + }; + + if (vmm_get_regset(bd->bd_vmm, cpu, KREG_NGREG, regnums, + &gregs->kregs[0]) != 0) { + mdb_warn("failed to get general-purpose registers for CPU %d", + cpu); + return (-1); + } + + if (vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_FS, &fs) != 0 || + vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_GS, &gs) != 0) { + mdb_warn("failed to get FS/GS descriptors for CPU %d", cpu); + return (-1); + } + + gregs->kregs[KREG_SAVFP] = 0; + gregs->kregs[KREG_SAVPC] = 0; + gregs->kregs[KREG_KGSBASE] = 0; + gregs->kregs[KREG_TRAPNO] = 0; + gregs->kregs[KREG_ERR] = 0; + + gregs->kregs[KREG_FSBASE] = fs.vd_base; + gregs->kregs[KREG_GSBASE] = gs.vd_base; + + return (0); +} + +static int +bhyve_cpuregs_dcmd(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + uint64_t cpu = bd->bd_curcpu; + mdb_tgt_gregset_t gregs; + int i; + + + if (flags & DCMD_ADDRSPEC) { + if (argc != 0) + return (DCMD_USAGE); + + cpu = (uint64_t)addr; + } + + i = mdb_getopts(argc, argv, 'c', MDB_OPT_UINT64, &cpu, NULL); + + argc -= i; + argv += i; + + if (argc != 0) + return (DCMD_USAGE); + + if (cpu >= vmm_ncpu(bd->bd_vmm)) { + mdb_warn("no such CPU\n"); + return (DCMD_ERR); + } + + if (bhyve_get_gregset(bd, cpu, &gregs) != 0) + return (DCMD_ERR); + + + switch (vmm_vcpu_isa(bd->bd_vmm, cpu)) { + case VMM_ISA_64: + mdb_amd64_printregs(&gregs); + break; + case VMM_ISA_32: + case VMM_ISA_16: + mdb_ia32_printregs(&gregs); + break; + default: + mdb_warn("CPU %d mode unknown", cpu); + return (DCMD_ERR); + } + + return (0); +} + +static int +bhyve_regs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + if ((flags & DCMD_ADDRSPEC) || argc != 0) + return (DCMD_USAGE); + + return (bhyve_cpuregs_dcmd(addr, flags, argc, argv)); +} + +static int +bhyve_stack_common(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv, int vcpu, boolean_t verbose) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + void *arg = (void *)(uintptr_t)mdb.m_nargs; + + mdb_tgt_gregset_t gregs; + mdb_tgt_stack_f *func; + + if (vcpu == -1) + vcpu = bd->bd_curcpu; + + if (flags & DCMD_ADDRSPEC) { + bzero(&gregs, sizeof (gregs)); + gregs.kregs[KREG_RBP] = addr; + } else if (bhyve_get_gregset(bd, vcpu, &gregs) != 0) + return (DCMD_ERR); + + switch (vmm_vcpu_isa(bd->bd_vmm, vcpu)) { + case VMM_ISA_64: + func = verbose ? mdb_amd64_kvm_framev : mdb_amd64_kvm_frame; + (void) mdb_amd64_kvm_stack_iter(mdb.m_target, &gregs, func, + arg); + break; + case VMM_ISA_32: + func = verbose ? mdb_ia32_kvm_framev : mdb_amd64_kvm_frame; + (void) mdb_ia32_kvm_stack_iter(mdb.m_target, &gregs, func, arg); + break; + case VMM_ISA_16: + mdb_warn("IA16 stack tracing not implemented\n"); + return (DCMD_ERR); + default: + mdb_warn("CPU %d mode unknown", vcpu); + return (DCMD_ERR); + } + + return (DCMD_OK); +} + +static int +bhyve_cpustack_dcmd(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + uint64_t cpu = bd->bd_curcpu; + boolean_t verbose; + int i; + + if (flags & DCMD_ADDRSPEC) { + if (argc != 0) + return (DCMD_USAGE); + + if (addr < vmm_ncpu(bd->bd_vmm)) { + cpu = (uint64_t)addr; + flags &= ~DCMD_ADDRSPEC; + } + } + + i = mdb_getopts(argc, argv, + 'c', MDB_OPT_UINT64, &cpu, + 'v', MDB_OPT_SETBITS, 1, &verbose); + + argc -= i; + argv += i; + + if (argc != 0) + return (DCMD_USAGE); + + return (bhyve_stack_common(addr, flags, argc, argv, cpu, verbose)); +} + +static int +bhyve_stack_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + return (bhyve_stack_common(addr, flags, argc, argv, -1, B_FALSE)); +} + +static int +bhyve_stackv_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + return (bhyve_stack_common(addr, flags, argc, argv, -1, B_TRUE)); +} + +static int +bhyve_stackr_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + return (bhyve_stack_common(addr, flags, argc, argv, -1, B_TRUE)); +} + +static int +bhyve_status_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + vmm_mode_t mode; + vmm_isa_t isa; + + static const char *modes[] = { + "unknown mode", + "real mode", + "protected mode, no PAE", + "protected mode, PAE", + "long mode" + }; + static const char *isas[] = { + "unknown ISA", + "IA16", + "IA32", + "AMD64" + }; + + if ((flags & DCMD_ADDRSPEC) || argc != 0) + return (DCMD_USAGE); + + mode = vmm_vcpu_mode(bd->bd_vmm, bd->bd_curcpu); + isa = vmm_vcpu_isa(bd->bd_vmm, bd->bd_curcpu); + + mdb_printf("debugging live VM '%s'\n", bd->bd_name); + mdb_printf("VM memory size: %d MB\n", + vmm_memsize(bd->bd_vmm) / 1024 / 1024); + mdb_printf("vCPUs: %d\n", vmm_ncpu(bd->bd_vmm)); + mdb_printf("current CPU: %d (%s, %s)\n", bd->bd_curcpu, modes[mode], + isas[isa]); + mdb_printf("default segment: %s", + segments[bd->bd_defseg - VMM_DESC_CS]); + + return (DCMD_OK); +} + + +static int +bhyve_sysregs_dcmd(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + uint64_t cpu = bd->bd_curcpu; + int ret = DCMD_ERR; + struct sysregs sregs; + int i; + + /* + * This array must use the order of the elements of struct sysregs. + */ + static const int regnums[] = { + VMM_REG_CR0, + VMM_REG_CR2, + VMM_REG_CR3, + VMM_REG_CR4, + VMM_REG_DR0, + VMM_REG_DR1, + VMM_REG_DR2, + VMM_REG_DR3, + VMM_REG_DR6, + VMM_REG_DR7, + VMM_REG_EFER, + VMM_REG_PDPTE0, + VMM_REG_PDPTE1, + VMM_REG_PDPTE2, + VMM_REG_PDPTE3, + VMM_REG_INTR_SHADOW + }; + + if (flags & DCMD_ADDRSPEC) { + if (argc != 0) + return (DCMD_USAGE); + + cpu = (uint64_t)addr; + } + + i = mdb_getopts(argc, argv, 'c', MDB_OPT_UINT64, &cpu, NULL); + + argc -= i; + argv += i; + + if (argc != 0) + return (DCMD_USAGE); + + if (cpu >= vmm_ncpu(bd->bd_vmm)) { + mdb_warn("no such CPU\n"); + return (DCMD_ERR); + } + + if (vmm_get_regset(bd->bd_vmm, cpu, ARRAY_SIZE(regnums), regnums, + (uint64_t *)&sregs) != 0) + goto fail; + + if (vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_GDTR, + (vmm_desc_t *)&sregs.sr_gdtr) != 0 || + vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_IDTR, + (vmm_desc_t *)&sregs.sr_idtr) != 0 || + vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_LDTR, + (vmm_desc_t *)&sregs.sr_ldtr) != 0 || + vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_TR, + (vmm_desc_t *)&sregs.sr_tr) != 0 || + vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_CS, + (vmm_desc_t *)&sregs.sr_cs) != 0 || + vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_DS, + (vmm_desc_t *)&sregs.sr_ds) != 0 || + vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_ES, + (vmm_desc_t *)&sregs.sr_es) != 0 || + vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_FS, + (vmm_desc_t *)&sregs.sr_fs) != 0 || + vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_GS, + (vmm_desc_t *)&sregs.sr_gs) != 0 || + vmm_get_desc(bd->bd_vmm, cpu, VMM_DESC_SS, + (vmm_desc_t *)&sregs.sr_ss) != 0) + goto fail; + + mdb_x86_print_sysregs(&sregs, vmm_vcpu_mode(bd->bd_vmm, cpu) == + VMM_MODE_LONG); + + ret = DCMD_OK; + +fail: + if (ret != DCMD_OK) + mdb_warn("failed to get system registers for CPU %d\n", cpu); + return (ret); +} + +static int +bhyve_dbgregs_dcmd(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + uint64_t cpu = bd->bd_curcpu; + int ret = DCMD_ERR; + vmm_desc_t gdtr, ldtr, idtr, tr, cs, ds, es, fs, gs, ss; + uint64_t *regvals; + int i; + + /* + * This array must use the order of definitions set in libvmm.h + * to make GETREG() work. + */ +#define GETREG(r) (regvals[r - VMM_REG_DR0]) + static const int regnums[] = { + VMM_REG_DR0, + VMM_REG_DR1, + VMM_REG_DR2, + VMM_REG_DR3, + VMM_REG_DR6, + VMM_REG_DR7, + }; + + static const mdb_bitmask_t dr6_flag_bits[] = { + { "DR0", DR_TRAP0, DR_TRAP0 }, + { "DR1", DR_TRAP1, DR_TRAP1 }, + { "DR2", DR_TRAP2, DR_TRAP2 }, + { "DR3", DR_TRAP3, DR_TRAP3 }, + { "debug reg", DR_ICEALSO, DR_ICEALSO }, + { "single step", DR_SINGLESTEP, DR_SINGLESTEP }, + { "task switch", DR_TASKSWITCH, DR_TASKSWITCH }, + { NULL, 0, 0 } + }; + +#define DR_RW(x, m) \ + ((DR_RW_MASK & (m)) << (DR_CONTROL_SHIFT + (x) * DR_CONTROL_SIZE)) +#define DR_LEN(x, m) \ + ((DR_LEN_MASK & (m)) << (DR_CONTROL_SHIFT + (x) * DR_CONTROL_SIZE)) + + static const mdb_bitmask_t dr7_flag_bits[] = { + { "L0", DR_ENABLE0, DR_LOCAL_ENABLE_MASK & DR_ENABLE0 }, + { "G0", DR_ENABLE0, DR_GLOBAL_ENABLE_MASK & DR_ENABLE0 }, + { "L1", DR_ENABLE1, DR_LOCAL_ENABLE_MASK & DR_ENABLE1 }, + { "G1", DR_ENABLE1, DR_GLOBAL_ENABLE_MASK & DR_ENABLE1 }, + { "L2", DR_ENABLE2, DR_LOCAL_ENABLE_MASK & DR_ENABLE2 }, + { "G2", DR_ENABLE2, DR_GLOBAL_ENABLE_MASK & DR_ENABLE2 }, + { "L3", DR_ENABLE3, DR_LOCAL_ENABLE_MASK & DR_ENABLE3 }, + { "G3", DR_ENABLE3, DR_GLOBAL_ENABLE_MASK & DR_ENABLE3 }, + { "LE", DR_LOCAL_SLOWDOWN, DR_LOCAL_SLOWDOWN }, + { "GE", DR_GLOBAL_SLOWDOWN, DR_GLOBAL_SLOWDOWN }, + { "RTM", DR_RTM, DR_RTM }, + { "GD", DR_GENERAL_DETECT, DR_GENERAL_DETECT }, + { "0:X", DR_RW(0, DR_RW_MASK), DR_RW(0, DR_RW_EXECUTE) }, + { "0:W", DR_RW(0, DR_RW_MASK), DR_RW(0, DR_RW_WRITE) }, + { "0:IO", DR_RW(0, DR_RW_MASK), DR_RW(0, DR_RW_IO_RW) }, + { "0:RW", DR_RW(0, DR_RW_MASK), DR_RW(0, DR_RW_READ) }, + { "1:X", DR_RW(1, DR_RW_MASK), DR_RW(1, DR_RW_EXECUTE) }, + { "1:W", DR_RW(1, DR_RW_MASK), DR_RW(1, DR_RW_WRITE) }, + { "1:IO", DR_RW(1, DR_RW_MASK), DR_RW(1, DR_RW_IO_RW) }, + { "1:RW", DR_RW(1, DR_RW_MASK), DR_RW(1, DR_RW_READ) }, + { "2:X", DR_RW(2, DR_RW_MASK), DR_RW(2, DR_RW_EXECUTE) }, + { "2:W", DR_RW(2, DR_RW_MASK), DR_RW(2, DR_RW_WRITE) }, + { "2:IO", DR_RW(2, DR_RW_MASK), DR_RW(2, DR_RW_IO_RW) }, + { "2:RW", DR_RW(2, DR_RW_MASK), DR_RW(2, DR_RW_READ) }, + { "3:X", DR_RW(3, DR_RW_MASK), DR_RW(3, DR_RW_EXECUTE) }, + { "3:W", DR_RW(3, DR_RW_MASK), DR_RW(3, DR_RW_WRITE) }, + { "3:IO", DR_RW(3, DR_RW_MASK), DR_RW(3, DR_RW_IO_RW) }, + { "3:RW", DR_RW(3, DR_RW_MASK), DR_RW(3, DR_RW_READ) }, + { "0:1", DR_LEN(0, DR_LEN_MASK), DR_LEN(0, DR_LEN_1) }, + { "0:2", DR_LEN(0, DR_LEN_MASK), DR_LEN(0, DR_LEN_2) }, + { "0:4", DR_LEN(0, DR_LEN_MASK), DR_LEN(0, DR_LEN_4) }, + { "0:8", DR_LEN(0, DR_LEN_MASK), DR_LEN(0, DR_LEN_8) }, + { "1:1", DR_LEN(1, DR_LEN_MASK), DR_LEN(1, DR_LEN_1) }, + { "1:2", DR_LEN(1, DR_LEN_MASK), DR_LEN(1, DR_LEN_2) }, + { "1:4", DR_LEN(1, DR_LEN_MASK), DR_LEN(1, DR_LEN_4) }, + { "1:8", DR_LEN(1, DR_LEN_MASK), DR_LEN(1, DR_LEN_8) }, + { "2:1", DR_LEN(2, DR_LEN_MASK), DR_LEN(2, DR_LEN_1) }, + { "2:2", DR_LEN(2, DR_LEN_MASK), DR_LEN(2, DR_LEN_2) }, + { "2:4", DR_LEN(2, DR_LEN_MASK), DR_LEN(2, DR_LEN_4) }, + { "2:8", DR_LEN(2, DR_LEN_MASK), DR_LEN(2, DR_LEN_8) }, + { "3:1", DR_LEN(3, DR_LEN_MASK), DR_LEN(3, DR_LEN_1) }, + { "3:2", DR_LEN(3, DR_LEN_MASK), DR_LEN(3, DR_LEN_2) }, + { "3:4", DR_LEN(3, DR_LEN_MASK), DR_LEN(3, DR_LEN_4) }, + { "3:8", DR_LEN(3, DR_LEN_MASK), DR_LEN(3, DR_LEN_8) }, + { NULL, 0, 0 }, + }; + + + if (flags & DCMD_ADDRSPEC) { + if (argc != 0) + return (DCMD_USAGE); + + cpu = (uint64_t)addr; + } + + i = mdb_getopts(argc, argv, 'c', MDB_OPT_UINT64, &cpu, NULL); + + argc -= i; + argv += i; + + if (argc != 0) + return (DCMD_USAGE); + + if (cpu >= vmm_ncpu(bd->bd_vmm)) { + mdb_warn("no such CPU\n"); + return (DCMD_ERR); + } + + regvals = mdb_zalloc(ARRAY_SIZE(regnums) * sizeof (uint64_t), UM_SLEEP); + + if (vmm_get_regset(bd->bd_vmm, cpu, ARRAY_SIZE(regnums), regnums, + regvals) != 0) + goto fail; + + mdb_printf("%%dr0 = 0x%0?p %A\n", + GETREG(VMM_REG_DR0), GETREG(VMM_REG_DR0)); + mdb_printf("%%dr1 = 0x%0?p %A\n", + GETREG(VMM_REG_DR1), GETREG(VMM_REG_DR1)); + mdb_printf("%%dr2 = 0x%0?p %A\n", + GETREG(VMM_REG_DR2), GETREG(VMM_REG_DR2)); + mdb_printf("%%dr3 = 0x%0?p %A\n", + GETREG(VMM_REG_DR3), GETREG(VMM_REG_DR3)); + mdb_printf("%%dr6 = 0x%0lx <%b>\n", + GETREG(VMM_REG_DR6), GETREG(VMM_REG_DR6), dr6_flag_bits); + mdb_printf("%%dr7 = 0x%0lx <%b>\n", + GETREG(VMM_REG_DR7), GETREG(VMM_REG_DR7), dr7_flag_bits); +#undef GETREG + + ret = DCMD_OK; + +fail: + if (ret != DCMD_OK) + mdb_warn("failed to get debug registers for CPU %d\n", cpu); + mdb_free(regvals, ARRAY_SIZE(regnums) * sizeof (uint64_t)); + return (ret); +} + +static int +bhyve_switch_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + size_t cpu = (int)addr; + + if (!(flags & DCMD_ADDRSPEC) || argc != 0) + return (DCMD_USAGE); + + if (cpu >= vmm_ncpu(bd->bd_vmm)) { + mdb_warn("no such CPU\n"); + return (DCMD_ERR); + } + + bd->bd_curcpu = cpu; + return (DCMD_OK); + +} + +static int +bhyve_seg2reg(const char *seg) +{ + if (strcasecmp(seg, "cs") == 0) + return (VMM_DESC_CS); + else if (strcasecmp(seg, "ds") == 0) + return (VMM_DESC_DS); + else if (strcasecmp(seg, "es") == 0) + return (VMM_DESC_ES); + else if (strcasecmp(seg, "fs") == 0) + return (VMM_DESC_FS); + else if (strcasecmp(seg, "gs") == 0) + return (VMM_DESC_GS); + else if (strcasecmp(seg, "ss") == 0) + return (VMM_DESC_SS); + else + return (-1); +} + +static int +bhyve_vtol_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + int segreg = bd->bd_defseg; + char *seg = ""; + uint64_t laddr; + int i; + + if (!(flags & DCMD_ADDRSPEC)) + return (DCMD_USAGE); + + i = mdb_getopts(argc, argv, 's', MDB_OPT_STR, &seg, NULL); + + argc -= i; + argv += i; + + if (i != 0) { + if (argc != 0) + return (DCMD_USAGE); + + segreg = bhyve_seg2reg(seg); + if (segreg == -1) + return (DCMD_USAGE); + } + + if (vmm_vtol(bd->bd_vmm, bd->bd_curcpu, segreg, addr, &laddr) != 0) { + if (errno == EFAULT) + set_errno(EMDB_NOMAP); + return (DCMD_ERR); + } + + if (flags & DCMD_PIPE_OUT) + mdb_printf("%llr\n", laddr); + else + mdb_printf("virtual %lr mapped to linear %llr\n", addr, laddr); + + return (DCMD_OK); +} + +static int +bhyve_vtop_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + int segreg = bd->bd_defseg; + char *seg = ""; + physaddr_t pa; + int i; + + if (!(flags & DCMD_ADDRSPEC)) + return (DCMD_USAGE); + + i = mdb_getopts(argc, argv, 's', MDB_OPT_STR, &seg, NULL); + + argc -= i; + argv += i; + + if (i != 0) { + segreg = bhyve_seg2reg(seg); + if (segreg == -1) + return (DCMD_USAGE); + } + + if (vmm_vtop(bd->bd_vmm, bd->bd_curcpu, segreg, addr, &pa) == -1) { + mdb_warn("failed to get physical mapping"); + return (DCMD_ERR); + } + + if (flags & DCMD_PIPE_OUT) + mdb_printf("%llr\n", pa); + else + mdb_printf("virtual %lr mapped to physical %llr\n", addr, pa); + return (DCMD_OK); +} + +static int +bhyve_defseg_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) +{ + bhyve_data_t *bd = mdb.m_target->t_data; + int segreg = bd->bd_defseg; + char *seg = ""; + int i; + + if (flags & DCMD_ADDRSPEC) + return (DCMD_USAGE); + + i = mdb_getopts(argc, argv, 's', MDB_OPT_STR, &seg, NULL); + + argc -= i; + argv += i; + + if (i != 0) { + if (argc != 0) + return (DCMD_USAGE); + + segreg = bhyve_seg2reg(seg); + if (segreg == -1) + return (DCMD_USAGE); + + bd->bd_defseg = segreg; + } + + mdb_printf("using segment %s for virtual to linear address translation", + segments[bd->bd_defseg - VMM_DESC_CS]); + + return (DCMD_OK); +} + +static const mdb_dcmd_t bhyve_dcmds[] = { + { "$c", NULL, "print stack backtrace", bhyve_stack_dcmd }, + { "$C", NULL, "print stack backtrace", bhyve_stackv_dcmd }, + { "$r", NULL, "print general-purpose registers", bhyve_regs_dcmd }, + { "$?", NULL, "print status and registers", bhyve_regs_dcmd }, + { ":x", ":", "change the active CPU", bhyve_switch_dcmd }, + { "cpustack", "?[-v] [-c cpuid] [cnt]", "print stack backtrace for a " + "specific CPU", bhyve_cpustack_dcmd }, + { "cpuregs", "?[-c cpuid]", "print general-purpose registers for a " + "specific CPU", bhyve_cpuregs_dcmd }, + { "dbgregs", "?[-c cpuid]", "print debug registers for a specific CPU", + bhyve_dbgregs_dcmd }, + { "defseg", "?[-s segment]", "change the default segment used to " + "translate addresses", bhyve_defseg_dcmd }, + { "regs", NULL, "print general-purpose registers", bhyve_regs_dcmd }, + { "stack", NULL, "print stack backtrace", bhyve_stack_dcmd }, + { "stackregs", NULL, "print stack backtrace and registers", + bhyve_stackr_dcmd }, + { "status", NULL, "print summary of current target", + bhyve_status_dcmd }, + { "sysregs", "?[-c cpuid]", "print system registers for a specific CPU", + bhyve_sysregs_dcmd }, + { "switch", ":", "change the active CPU", bhyve_switch_dcmd }, + { "vtol", ":[-s segment]", "print linear mapping of virtual address", + bhyve_vtol_dcmd }, + { "vtop", ":[-s segment]", "print physical mapping of virtual " + "address", bhyve_vtop_dcmd }, + { NULL } +}; + + +/* + * t_setflags: change target flags + */ +static int +bhyve_setflags(mdb_tgt_t *tgt, int flags) +{ + bhyve_data_t *bd = tgt->t_data; + + if (((tgt->t_flags ^ flags) & MDB_TGT_F_RDWR) != 0) { + boolean_t writable = (flags & MDB_TGT_F_RDWR) != 0; + + vmm_unmap(bd->bd_vmm); + if (vmm_map(bd->bd_vmm, writable) != 0) { + mdb_warn("failed to map guest memory"); + return (set_errno(EMDB_TGT)); + } + } + + tgt->t_flags = flags; + + return (0); +} + +/* + * t_activate: activate target + */ +static void +bhyve_activate(mdb_tgt_t *tgt) +{ + mdb_tgt_status_t *tsp = &tgt->t_status; + bhyve_data_t *bd = tgt->t_data; + const char *format; + char buf[BUFSIZ]; + + (void) mdb_set_prompt(MDB_DEF_PROMPT); + + (void) mdb_tgt_register_dcmds(tgt, bhyve_dcmds, MDB_MOD_FORCE); + mdb_tgt_register_regvars(tgt, bhyve_kregs, &bhyve_reg_disc, 0); + + (void) vmm_stop(bd->bd_vmm); + + if (mdb_tgt_status(tgt, tsp) != 0) + return; + + if (tsp->st_pc != 0) { + if (mdb_dis_ins2str(mdb.m_disasm, mdb.m_target, + MDB_TGT_AS_VIRT_I, buf, sizeof (buf), tsp->st_pc) != + tsp->st_pc) + format = "target stopped at:\n%-#16a%8T%s\n"; + else + format = "target stopped at %a:\n"; + mdb_warn(format, tsp->st_pc, buf); + } +} + +/* + * t_deactivate: deactivate target + */ +static void +bhyve_deactivate(mdb_tgt_t *tgt) +{ + bhyve_data_t *bd = tgt->t_data; + const mdb_tgt_regdesc_t *rd; + const mdb_dcmd_t *dc; + + for (rd = bhyve_kregs; rd->rd_name != NULL; rd++) { + mdb_var_t *var; + + if (!(rd->rd_flags & MDB_TGT_R_EXPORT)) + continue; /* didn't export register as variable */ + + if ((var = mdb_nv_lookup(&mdb.m_nv, rd->rd_name)) != NULL) { + var->v_flags &= ~MDB_NV_PERSIST; + mdb_nv_remove(&mdb.m_nv, var); + } + } + + for (dc = bhyve_dcmds; dc->dc_name != NULL; dc++) + if (mdb_module_remove_dcmd(tgt->t_module, dc->dc_name) == -1) + mdb_warn("failed to remove dcmd %s", dc->dc_name); + + (void) vmm_cont(bd->bd_vmm); +} + +/* + * t_name: return name of target + */ +static const char * +bhyve_name(mdb_tgt_t *tgt) +{ + _NOTE(ARGUNUSED(tgt)); + + return ("bhyve"); +} + +/* + * t_destroy: cleanup target private resources + */ +static void +bhyve_destroy(mdb_tgt_t *tgt) +{ + bhyve_data_t *bd = tgt->t_data; + + (void) vmm_cont(bd->bd_vmm); + vmm_unmap(bd->bd_vmm); + vmm_close_vm(bd->bd_vmm); + mdb_free(bd, sizeof (bhyve_data_t)); + tgt->t_data = NULL; +} + +/* + * t_isa: return name of target ISA + */ +const char * +bhyve_isa(mdb_tgt_t *tgt) +{ + _NOTE(ARGUNUSED(tgt)); + + return ("amd64"); +} + +/* + * t_dmodel: return target data model + */ +static int +bhyve_dmodel(mdb_tgt_t *tgt) +{ + _NOTE(ARGUNUSED(tgt)); + + return (MDB_TGT_MODEL_LP64); +} + +/*ARGSUSED*/ +static ssize_t +bhyve_aread(mdb_tgt_t *tgt, mdb_tgt_as_t as, void *buf, size_t nbytes, + mdb_tgt_addr_t addr) +{ + bhyve_data_t *bd = tgt->t_data; + ssize_t cnt; + + switch ((uintptr_t)as) { + case (uintptr_t)MDB_TGT_AS_VIRT: + cnt = vmm_vread(bd->bd_vmm, bd->bd_curcpu, bd->bd_defseg, buf, + nbytes, addr); + break; + + case (uintptr_t)MDB_TGT_AS_VIRT_I: + cnt = vmm_vread(bd->bd_vmm, bd->bd_curcpu, VMM_DESC_CS, buf, + nbytes, addr); + break; + + case (uintptr_t)MDB_TGT_AS_VIRT_S: + cnt = vmm_vread(bd->bd_vmm, bd->bd_curcpu, VMM_DESC_SS, buf, + nbytes, addr); + break; + + case (uintptr_t)MDB_TGT_AS_PHYS: + cnt = vmm_pread(bd->bd_vmm, buf, nbytes, addr); + break; + + case (uintptr_t)MDB_TGT_AS_FILE: + case (uintptr_t)MDB_TGT_AS_IO: + return (set_errno(EMDB_TGTNOTSUP)); + } + + if (errno == EFAULT) + return (set_errno(EMDB_NOMAP)); + + return (cnt); +} + +/*ARGSUSED*/ +static ssize_t +bhyve_awrite(mdb_tgt_t *tgt, mdb_tgt_as_t as, const void *buf, size_t nbytes, + mdb_tgt_addr_t addr) +{ + bhyve_data_t *bd = tgt->t_data; + ssize_t cnt; + + switch ((uintptr_t)as) { + case (uintptr_t)MDB_TGT_AS_VIRT: + cnt = vmm_vwrite(bd->bd_vmm, bd->bd_curcpu, bd->bd_defseg, buf, + nbytes, addr); + break; + + case (uintptr_t)MDB_TGT_AS_VIRT_I: + cnt = vmm_vwrite(bd->bd_vmm, bd->bd_curcpu, VMM_DESC_CS, buf, + nbytes, addr); + break; + + case (uintptr_t)MDB_TGT_AS_VIRT_S: + cnt = vmm_vwrite(bd->bd_vmm, bd->bd_curcpu, VMM_DESC_SS, buf, + nbytes, addr); + break; + + case (uintptr_t)MDB_TGT_AS_PHYS: + cnt = vmm_pwrite(bd->bd_vmm, buf, nbytes, addr); + break; + + case (uintptr_t)MDB_TGT_AS_FILE: + case (uintptr_t)MDB_TGT_AS_IO: + return (set_errno(EMDB_TGTNOTSUP)); + } + + if (errno == EFAULT) + return (set_errno(EMDB_NOMAP)); + + return (cnt); +} + +/* + * t_vread: read from virtual memory + */ +/*ARGSUSED*/ +static ssize_t +bhyve_vread(mdb_tgt_t *tgt, void *buf, size_t nbytes, uintptr_t addr) +{ + return (bhyve_aread(tgt, MDB_TGT_AS_VIRT, buf, nbytes, addr)); +} + +/* + * t_vwrite: write to virtual memory + */ +/*ARGSUSED*/ +static ssize_t +bhyve_vwrite(mdb_tgt_t *tgt, const void *buf, size_t nbytes, uintptr_t addr) +{ + return (bhyve_awrite(tgt, MDB_TGT_AS_VIRT, buf, nbytes, addr)); +} + +/* + * t_pread: read from physical memory + */ +/*ARGSUSED*/ +static ssize_t +bhyve_pread(mdb_tgt_t *tgt, void *buf, size_t nbytes, physaddr_t addr) +{ + return (bhyve_aread(tgt, MDB_TGT_AS_PHYS, buf, nbytes, addr)); +} + +/* + * t_pwrite: write to physical memory + */ +/*ARGSUSED*/ +static ssize_t +bhyve_pwrite(mdb_tgt_t *tgt, const void *buf, size_t nbytes, physaddr_t addr) +{ + return (bhyve_awrite(tgt, MDB_TGT_AS_PHYS, buf, nbytes, addr)); +} + +/* + * t_fread: read from core/object file + */ +/*ARGSUSED*/ +static ssize_t +bhyve_fread(mdb_tgt_t *tgt, void *buf, size_t nbytes, uintptr_t addr) +{ + return (bhyve_aread(tgt, MDB_TGT_AS_FILE, buf, nbytes, addr)); +} + +/* + * t_fwrite: write to core/object file + */ +/*ARGSUSED*/ +static ssize_t +bhyve_fwrite(mdb_tgt_t *tgt, const void *buf, size_t nbytes, uintptr_t addr) +{ + return (bhyve_awrite(tgt, MDB_TGT_AS_FILE, buf, nbytes, addr)); +} + +/* + * t_ioread: read from I/O space + */ +/*ARGSUSED*/ +static ssize_t +bhyve_ioread(mdb_tgt_t *tgt, void *buf, size_t nbytes, uintptr_t addr) +{ + return (bhyve_aread(tgt, MDB_TGT_AS_IO, buf, nbytes, addr)); +} + +/* + * t_iowrite: write to I/O space + */ +/*ARGSUSED*/ +static ssize_t +bhyve_iowrite(mdb_tgt_t *tgt, const void *buf, size_t nbytes, uintptr_t addr) +{ + return (bhyve_awrite(tgt, MDB_TGT_AS_IO, buf, nbytes, addr)); +} + +/* + * t_vtop: translate virtual to physical address + */ +static int +bhyve_vtop(mdb_tgt_t *tgt, mdb_tgt_as_t as, uintptr_t va, physaddr_t *pa) +{ + bhyve_data_t *bd = tgt->t_data; + int seg; + + switch ((uintptr_t)as) { + case (uintptr_t)MDB_TGT_AS_VIRT: + seg = bd->bd_defseg; + break; + + case (uintptr_t)MDB_TGT_AS_VIRT_I: + seg = VMM_DESC_CS; + break; + + case (uintptr_t)MDB_TGT_AS_VIRT_S: + seg = VMM_DESC_SS; + break; + + default: + return (set_errno(EINVAL)); + } + + if (vmm_vtop(bd->bd_vmm, bd->bd_curcpu, seg, va, pa) != 0) { + if (errno == EFAULT) + return (set_errno(EMDB_NOMAP)); + else + return (-1); + } + + return (0); +} + +/* + * t_status: get target status + */ +static int +bhyve_status(mdb_tgt_t *tgt, mdb_tgt_status_t *tsp) +{ + bhyve_data_t *bd = tgt->t_data; + mdb_tgt_reg_t rip; + vmm_desc_t cs; + int ret; + + bzero(tsp, sizeof (mdb_tgt_status_t)); + + ret = vmm_getreg(bd->bd_vmm, bd->bd_curcpu, KREG_RIP, &rip); + if (ret != 0) { + tsp->st_state = MDB_TGT_UNDEAD; + } else { + tsp->st_state = MDB_TGT_STOPPED; + tsp->st_pc = rip; + } + + switch (vmm_vcpu_isa(bd->bd_vmm, bd->bd_curcpu)) { + case VMM_ISA_16: + mdb_dis_select("ia16"); + break; + case VMM_ISA_32: + mdb_dis_select("ia32"); + break; + case VMM_ISA_64: + mdb_dis_select("amd64"); + break; + default: + break; + } + + return (0); +} + +static void +bhyve_sighdl(int sig, siginfo_t *sip, ucontext_t *ucp, mdb_tgt_t *tgt) +{ + mdb_tgt_status_t *tsp = &tgt->t_status; + bhyve_data_t *bd = tgt->t_data; + + switch (sig) { + case SIGINT: + /* + * vmm_stop() may fail if the VM was destroyed while we were + * waiting. This will be handled by mdb_tgt_status(). + */ + (void) vmm_stop(bd->bd_vmm); + (void) mdb_tgt_status(tgt, tsp); + break; + } +} + +/* + * t_step: single-step target + */ +static int +bhyve_step(mdb_tgt_t *tgt, mdb_tgt_status_t *tsp) +{ + bhyve_data_t *bd = tgt->t_data; + int ret; + + ret = vmm_step(bd->bd_vmm, bd->bd_curcpu); + (void) mdb_tgt_status(tgt, tsp); + + return (ret); +} + +/* + * t_cont: continue target execution + * + * Catch SIGINT so that the target can be stopped with Ctrl-C. + */ +static int +bhyve_cont(mdb_tgt_t *tgt, mdb_tgt_status_t *tsp) +{ + bhyve_data_t *bd = tgt->t_data; + mdb_signal_f *intf; + void *intd; + int ret; + + intf = mdb_signal_gethandler(SIGINT, &intd); + (void) mdb_signal_sethandler(SIGINT, (mdb_signal_f *)bhyve_sighdl, tgt); + + if (ret = vmm_cont(bd->bd_vmm) != 0) { + mdb_warn("failed to continue target execution: %d", ret); + return (set_errno(EMDB_TGT)); + } + + tsp->st_state = MDB_TGT_RUNNING; + pause(); + + (void) mdb_signal_sethandler(SIGINT, intf, intd); + (void) mdb_tgt_status(tgt, tsp); + + return (ret); +} + +static int +bhyve_lookup_reg(mdb_tgt_t *tgt, const char *rname) +{ + bhyve_data_t *bd = tgt->t_data; + const mdb_tgt_regdesc_t *rd; + + for (rd = bhyve_kregs; rd->rd_name != NULL; rd++) + if (strcmp(rd->rd_name, rname) == 0) + return (rd->rd_num); + + return (-1); +} + +/* + * t_getareg: get the value of a single register + */ +static int +bhyve_getareg(mdb_tgt_t *tgt, mdb_tgt_tid_t tid, const char *rname, + mdb_tgt_reg_t *rp) +{ + bhyve_data_t *bd = tgt->t_data; + int reg = bhyve_lookup_reg(tgt, rname); + int ret; + + if (reg == -1) + return (set_errno(EMDB_BADREG)); + + ret = vmm_getreg(bd->bd_vmm, bd->bd_curcpu, reg, rp); + if (ret == -1) + return (set_errno(EMDB_BADREG)); + + return (0); +} + +/* + * t_putareg: set the value of a single register + */ +static int +bhyve_putareg(mdb_tgt_t *tgt, mdb_tgt_tid_t tid, const char *rname, + mdb_tgt_reg_t r) +{ + bhyve_data_t *bd = tgt->t_data; + int reg = bhyve_lookup_reg(tgt, rname); + int ret; + + if ((tgt->t_flags & MDB_TGT_F_RDWR) == 0) + return (set_errno(EMDB_TGTRDONLY)); + + if (reg == -1) + return (set_errno(EMDB_BADREG)); + + ret = vmm_setreg(bd->bd_vmm, bd->bd_curcpu, reg, r); + if (ret == -1) + return (set_errno(EMDB_BADREG)); + + return (0); +} + +static const mdb_tgt_ops_t bhyve_ops = { + .t_setflags = bhyve_setflags, + .t_setcontext = (int (*)()) mdb_tgt_notsup, + .t_activate = bhyve_activate, + .t_deactivate = bhyve_deactivate, + .t_periodic = (void (*)()) mdb_tgt_nop, + .t_destroy = bhyve_destroy, + .t_name = bhyve_name, + .t_isa = bhyve_isa, + .t_platform = (const char *(*)()) mdb_conf_platform, + .t_uname = (int (*)()) mdb_tgt_notsup, + .t_dmodel = bhyve_dmodel, + .t_aread = bhyve_aread, + .t_awrite = bhyve_awrite, + .t_vread = bhyve_vread, + .t_vwrite = bhyve_vwrite, + .t_pread = bhyve_pread, + .t_pwrite = bhyve_pwrite, + .t_fread = bhyve_fread, + .t_fwrite = bhyve_fwrite, + .t_ioread = bhyve_ioread, + .t_iowrite = bhyve_iowrite, + .t_vtop = bhyve_vtop, + .t_lookup_by_name = (int (*)()) mdb_tgt_notsup, + .t_lookup_by_addr = (int (*)()) mdb_tgt_notsup, + .t_symbol_iter = (int (*)()) mdb_tgt_notsup, + .t_mapping_iter = (int (*)()) mdb_tgt_notsup, + .t_object_iter = (int (*)()) mdb_tgt_notsup, + .t_addr_to_map = (const mdb_map_t *(*)()) mdb_tgt_null, + .t_name_to_map = (const mdb_map_t *(*)()) mdb_tgt_null, + .t_addr_to_ctf = (struct ctf_file *(*)()) mdb_tgt_null, + .t_name_to_ctf = (struct ctf_file *(*)()) mdb_tgt_null, + .t_status = bhyve_status, + .t_run = (int (*)()) mdb_tgt_notsup, + .t_step = bhyve_step, + .t_step_out = (int (*)()) mdb_tgt_notsup, + .t_next = (int (*)()) mdb_tgt_notsup, + .t_cont = bhyve_cont, + .t_signal = (int (*)()) mdb_tgt_notsup, + .t_add_vbrkpt = (int (*)()) mdb_tgt_null, + .t_add_sbrkpt = (int (*)()) mdb_tgt_null, + .t_add_pwapt = (int (*)()) mdb_tgt_null, + .t_add_vwapt = (int (*)()) mdb_tgt_null, + .t_add_iowapt = (int (*)()) mdb_tgt_null, + .t_add_sysenter = (int (*)()) mdb_tgt_null, + .t_add_sysexit = (int (*)()) mdb_tgt_null, + .t_add_signal = (int (*)()) mdb_tgt_null, + .t_add_fault = (int (*)()) mdb_tgt_null, + .t_getareg = bhyve_getareg, + .t_putareg = bhyve_putareg, + .t_stack_iter = (int (*)()) mdb_tgt_notsup, + .t_auxv = (int (*)()) mdb_tgt_notsup +}; + +int +mdb_bhyve_tgt_create(mdb_tgt_t *tgt, int argc, const char *argv[]) +{ + bhyve_data_t *bd; + vmm_t *vmm = NULL; + boolean_t writable = (tgt->t_flags & MDB_TGT_F_RDWR) != 0; + + if (argc != 1) + return (set_errno(EINVAL)); + + vmm = vmm_open_vm(argv[0]); + if (vmm == NULL) { + mdb_warn("failed to open %s", argv[0]); + return (set_errno(EMDB_TGT)); + } + + if (vmm_map(vmm, writable) != 0) { + mdb_warn("failed to map %s", argv[0]); + vmm_close_vm(vmm); + return (set_errno(EMDB_TGT)); + } + + bd = mdb_zalloc(sizeof (bhyve_data_t) + strlen(argv[0]) + 1, UM_SLEEP); + strcpy(bd->bd_name, argv[0]); + bd->bd_vmm = vmm; + bd->bd_curcpu = 0; + bd->bd_defseg = VMM_DESC_DS; + + tgt->t_ops = &bhyve_ops; + tgt->t_data = bd; + tgt->t_flags |= MDB_TGT_F_ASIO; + + (void) mdb_nv_insert(&mdb.m_nv, "cpuid", &bhyve_cpuid_disc, 0, + MDB_NV_PERSIST | MDB_NV_RDONLY); + + return (0); +} diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_ia32util.c b/usr/src/cmd/mdb/intel/mdb/mdb_ia32util.c index d6db4811b2..22e56a0eda 100644 --- a/usr/src/cmd/mdb/intel/mdb/mdb_ia32util.c +++ b/usr/src/cmd/mdb/intel/mdb/mdb_ia32util.c @@ -23,16 +23,18 @@ * Use is subject to license terms. */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2018, Joyent, Inc. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ #include <sys/types.h> +#include <sys/types32.h> #include <sys/reg.h> #include <sys/privregs.h> #include <sys/stack.h> #include <sys/frame.h> +#include <mdb/mdb_isautil.h> #include <mdb/mdb_ia32util.h> #include <mdb/mdb_target_impl.h> #include <mdb/mdb_kreg_impl.h> @@ -41,10 +43,14 @@ #include <mdb/mdb_err.h> #include <mdb/mdb.h> +#ifndef __amd64 /* * We also define an array of register names and their corresponding * array indices. This is used by the getareg and putareg entry points, * and also by our register variable discipline. + * + * When built into an amd64 mdb this won't be used as it's only a subset of + * mdb_amd64_kregs, hence the #ifdef. */ const mdb_tgt_regdesc_t mdb_ia32_kregs[] = { { "savfp", KREG_SAVFP, MDB_TGT_R_EXPORT }, @@ -87,6 +93,7 @@ const mdb_tgt_regdesc_t mdb_ia32_kregs[] = { { "err", KREG_ERR, MDB_TGT_R_EXPORT | MDB_TGT_R_PRIV }, { NULL, 0, 0 } }; +#endif void mdb_ia32_printregs(const mdb_tgt_gregset_t *gregs) @@ -94,27 +101,27 @@ mdb_ia32_printregs(const mdb_tgt_gregset_t *gregs) const kreg_t *kregs = &gregs->kregs[0]; kreg_t eflags = kregs[KREG_EFLAGS]; - mdb_printf("%%cs = 0x%04x\t\t%%eax = 0x%0?p %A\n", + mdb_printf("%%cs = 0x%04x\t\t%%eax = 0x%08p %A\n", kregs[KREG_CS], kregs[KREG_EAX], kregs[KREG_EAX]); - mdb_printf("%%ds = 0x%04x\t\t%%ebx = 0x%0?p %A\n", + mdb_printf("%%ds = 0x%04x\t\t%%ebx = 0x%08p %A\n", kregs[KREG_DS], kregs[KREG_EBX], kregs[KREG_EBX]); - mdb_printf("%%ss = 0x%04x\t\t%%ecx = 0x%0?p %A\n", + mdb_printf("%%ss = 0x%04x\t\t%%ecx = 0x%08p %A\n", kregs[KREG_SS], kregs[KREG_ECX], kregs[KREG_ECX]); - mdb_printf("%%es = 0x%04x\t\t%%edx = 0x%0?p %A\n", + mdb_printf("%%es = 0x%04x\t\t%%edx = 0x%08p %A\n", kregs[KREG_ES], kregs[KREG_EDX], kregs[KREG_EDX]); - mdb_printf("%%fs = 0x%04x\t\t%%esi = 0x%0?p %A\n", + mdb_printf("%%fs = 0x%04x\t\t%%esi = 0x%08p %A\n", kregs[KREG_FS], kregs[KREG_ESI], kregs[KREG_ESI]); - mdb_printf("%%gs = 0x%04x\t\t%%edi = 0x%0?p %A\n\n", + mdb_printf("%%gs = 0x%04x\t\t%%edi = 0x%08p %A\n\n", kregs[KREG_GS], kregs[KREG_EDI], kregs[KREG_EDI]); - mdb_printf("%%eip = 0x%0?p %A\n", kregs[KREG_EIP], kregs[KREG_EIP]); - mdb_printf("%%ebp = 0x%0?p\n", kregs[KREG_EBP]); - mdb_printf("%%esp = 0x%0?p\n\n", kregs[KREG_ESP]); + mdb_printf("%%eip = 0x%08p %A\n", kregs[KREG_EIP], kregs[KREG_EIP]); + mdb_printf("%%ebp = 0x%08p\n", kregs[KREG_EBP]); + mdb_printf("%%esp = 0x%08p\n\n", kregs[KREG_ESP]); mdb_printf("%%eflags = 0x%08x\n", eflags); mdb_printf(" id=%u vip=%u vif=%u ac=%u vm=%u rf=%u nt=%u iopl=0x%x\n", @@ -138,8 +145,8 @@ mdb_ia32_printregs(const mdb_tgt_gregset_t *gregs) (eflags & KREG_EFLAGS_PF_MASK) ? "PF" : "pf", (eflags & KREG_EFLAGS_CF_MASK) ? "CF" : "cf"); -#ifndef _KMDB - mdb_printf(" %%uesp = 0x%0?x\n", kregs[KREG_UESP]); +#if !defined(__amd64) && !defined(_KMDB) + mdb_printf(" %%uesp = 0x%08x\n", kregs[KREG_UESP]); #endif mdb_printf("%%trapno = 0x%x\n", kregs[KREG_TRAPNO]); mdb_printf(" %%err = 0x%x\n", kregs[KREG_ERR]); @@ -166,7 +173,8 @@ kvm_argcount(mdb_tgt_t *t, uintptr_t eip, ssize_t size) M_ADD_IMM8 = 0x83 /* ADD imm8 to r/m32 */ }; - if (mdb_tgt_vread(t, ins, sizeof (ins), eip) != sizeof (ins)) + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_I, ins, sizeof (ins), eip) != + sizeof (ins)) return (0); if (ins[1] != M_MODRM_ESP) @@ -185,7 +193,7 @@ kvm_argcount(mdb_tgt_t *t, uintptr_t eip, ssize_t size) n = 0; } - return (MIN((ssize_t)n, size) / sizeof (long)); + return (MIN((ssize_t)n, size) / sizeof (uint32_t)); } int @@ -198,9 +206,9 @@ mdb_ia32_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, int err; struct fr { - uintptr_t fr_savfp; - uintptr_t fr_savpc; - long fr_argv[32]; + uintptr32_t fr_savfp; + uintptr32_t fr_savpc; + uint32_t fr_argv[32]; } fr; uintptr_t fp = gsp->kregs[KREG_EBP]; @@ -226,9 +234,9 @@ mdb_ia32_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, err = EMDB_STKALIGN; goto badfp; } - if ((size = mdb_tgt_vread(t, &fr, sizeof (fr), fp)) >= - (ssize_t)(2 * sizeof (uintptr_t))) { - size -= (ssize_t)(2 * sizeof (uintptr_t)); + if ((size = mdb_tgt_aread(t, MDB_TGT_AS_VIRT_S, &fr, + sizeof (fr), fp)) >= (ssize_t)(2 * sizeof (uintptr32_t))) { + size -= (ssize_t)(2 * sizeof (uintptr32_t)); argc = kvm_argcount(t, fr.fr_savpc, size); } else { err = EMDB_NOMAP; @@ -245,8 +253,9 @@ mdb_ia32_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, if (advance_tortoise != 0) { struct fr tfr; - if (mdb_tgt_vread(t, &tfr, sizeof (tfr), - tortoise_fp) != sizeof (tfr)) { + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_S, &tfr, + sizeof (tfr), tortoise_fp) != + sizeof (tfr)) { err = EMDB_NOMAP; goto badfp; } @@ -262,7 +271,8 @@ mdb_ia32_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp, advance_tortoise = !advance_tortoise; - if (got_pc && func(arg, pc, argc, fr.fr_argv, &gregs) != 0) + if (got_pc && + func(arg, pc, argc, (const long *)fr.fr_argv, &gregs) != 0) break; kregs[KREG_ESP] = kregs[KREG_EBP]; @@ -294,6 +304,12 @@ badfp: return (set_errno(err)); } +#ifndef __amd64 +/* + * The functions mdb_ia32_step_out and mdb_ia32_next haven't yet been adapted + * to work when built for an amd64 mdb. They are unused by the amd64-only bhyve + * target, hence the #ifdef. + */ /* * Determine the return address for the current frame. Typically this is the * fr_savpc value from the current frame, but we also perform some special @@ -321,7 +337,8 @@ mdb_ia32_step_out(mdb_tgt_t *t, uintptr_t *p, kreg_t pc, kreg_t fp, kreg_t sp, fp = sp; } - if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) == sizeof (fr)) { + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_S, &fr, sizeof (fr), fp) == + sizeof (fr)) { *p = fr.fr_savpc; return (0); } @@ -372,7 +389,8 @@ mdb_ia32_next(mdb_tgt_t *t, uintptr_t *p, kreg_t pc, mdb_instr_t curinstr) * read the subsequent Mod/RM byte to perform additional decoding. */ if (curinstr == M_CALL_REG) { - if (mdb_tgt_vread(t, &m, sizeof (m), pc + 1) != sizeof (m)) + if (mdb_tgt_aread(t, MDB_TGT_AS_VIRT_I, &m, sizeof (m), pc + 1) + != sizeof (m)) return (-1); /* errno is set for us */ /* @@ -404,13 +422,16 @@ mdb_ia32_next(mdb_tgt_t *t, uintptr_t *p, kreg_t pc, mdb_instr_t curinstr) return (set_errno(EAGAIN)); } +#endif /*ARGSUSED*/ int -mdb_ia32_kvm_frame(void *arglim, uintptr_t pc, uint_t argc, const long *argv, +mdb_ia32_kvm_frame(void *arglim, uintptr_t pc, uint_t argc, const long *largv, const mdb_tgt_gregset_t *gregs) { - argc = MIN(argc, (uint_t)arglim); + const uint32_t *argv = (const uint32_t *)largv; + + argc = MIN(argc, (uintptr_t)arglim); mdb_printf("%a(", pc); if (argc != 0) { @@ -424,11 +445,13 @@ mdb_ia32_kvm_frame(void *arglim, uintptr_t pc, uint_t argc, const long *argv, } int -mdb_ia32_kvm_framev(void *arglim, uintptr_t pc, uint_t argc, const long *argv, +mdb_ia32_kvm_framev(void *arglim, uintptr_t pc, uint_t argc, const long *largv, const mdb_tgt_gregset_t *gregs) { - argc = MIN(argc, (uint_t)arglim); - mdb_printf("%0?lr %a(", gregs->kregs[KREG_EBP], pc); + const uint32_t *argv = (const uint32_t *)largv; + + argc = MIN(argc, (uintptr_t)arglim); + mdb_printf("%08lr %a(", gregs->kregs[KREG_EBP], pc); if (argc != 0) { mdb_printf("%lr", *argv++); diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_ia32util.h b/usr/src/cmd/mdb/intel/mdb/mdb_ia32util.h index 597b234b3e..1645b86d8d 100644 --- a/usr/src/cmd/mdb/intel/mdb/mdb_ia32util.h +++ b/usr/src/cmd/mdb/intel/mdb/mdb_ia32util.h @@ -22,12 +22,13 @@ * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2018, Joyent, Inc. All rights reserved. + */ #ifndef _MDB_IA32UTIL_H #define _MDB_IA32UTIL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <mdb/mdb_kreg.h> #include <mdb/mdb_target_impl.h> @@ -35,8 +36,6 @@ extern "C" { #endif -typedef uchar_t mdb_instr_t; - extern const mdb_tgt_regdesc_t mdb_ia32_kregs[]; extern void mdb_ia32_printregs(const mdb_tgt_gregset_t *); diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_isautil.h b/usr/src/cmd/mdb/intel/mdb/mdb_isautil.h index b6d17e1045..237e6663ae 100644 --- a/usr/src/cmd/mdb/intel/mdb/mdb_isautil.h +++ b/usr/src/cmd/mdb/intel/mdb/mdb_isautil.h @@ -23,16 +23,19 @@ * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2018, Joyent, Inc. All rights reserved. + */ #ifndef _MDB_ISAUTIL_H #define _MDB_ISAUTIL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif +typedef uchar_t mdb_instr_t; + #ifdef __amd64 #include <mdb/mdb_amd64util.h> diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h b/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h index a3edf864d7..3db7d6a1d6 100644 --- a/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h +++ b/usr/src/cmd/mdb/intel/mdb/mdb_kreg.h @@ -75,6 +75,7 @@ typedef uint32_t kreg_t; #define KREG_ES KDIREG_ES #define KREG_FS KDIREG_FS #define KREG_GS KDIREG_GS +#define KREG_FSBASE KDIREG_FSBASE #define KREG_GSBASE KDIREG_GSBASE #define KREG_KGSBASE KDIREG_KGSBASE #define KREG_TRAPNO KDIREG_TRAPNO @@ -91,6 +92,17 @@ typedef uint32_t kreg_t; #define KREG_SP KREG_RSP #define KREG_FP KREG_RBP +#define KREG_EAX KREG_RAX +#define KREG_EBX KREG_RBX +#define KREG_ECX KREG_RCX +#define KREG_EDX KREG_RDX +#define KREG_ESI KREG_RSI +#define KREG_EDI KREG_RDI +#define KREG_EBP KREG_RBP +#define KREG_ESP KREG_RSP +#define KREG_EFLAGS KREG_RFLAGS +#define KREG_EIP KREG_RIP + #else /* __amd64 */ #define KREG_SAVFP KDIREG_SAVFP diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_x86util.c b/usr/src/cmd/mdb/intel/mdb/mdb_x86util.c new file mode 100644 index 0000000000..a01ee6cffb --- /dev/null +++ b/usr/src/cmd/mdb/intel/mdb/mdb_x86util.c @@ -0,0 +1,215 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. + */ + +/* + * ISA-independent utility functions for the x86 architecture + */ + +#include <mdb/mdb_modapi.h> +#include <mdb/mdb_x86util.h> + +#include <sys/controlregs.h> +#include <inttypes.h> + +#define MMU_PAGESHIFT 12 +#define MMU_PAGESIZE (1 << MMU_PAGESHIFT) +#define MMU_PAGEOFFSET (MMU_PAGESIZE - 1) +#define MMU_PAGEMASK (~MMU_PAGEOFFSET) + +#ifndef _KMDB +static void +mdb_x86_print_desc(const char *name, const mdb_x86_desc_t *desc, uint_t width) +{ + const char *type; + const mdb_bitmask_t *bits; + + static const mdb_bitmask_t mem_desc_flag_bits[] = { + { "P", 0x80, 0x80 }, + { "16b", 0x6000, 0x0 }, + { "32b", 0x6000, 0x4000 }, + { "64b", 0x6000, 0x2000 }, + { "G", 0x8000, 0x8000 }, + { "A", 0x1, 0x1 }, + { NULL, 0, 0 }, + }; + + static const char *mem_desc_types[] = { + "data, up, read-only", + "data, up, read-write", + "data, down, read-only", + "data, down, read-write", + "code, non-conforming, execute-only", + "code, non-conforming, execute-read", + "code, conforming, execute-only", + "code, conforming, execute-read" + }; + + static const mdb_bitmask_t sys_desc_flag_bits[] = { + { "P", 0x80, 0x80 }, + { "16b", 0x6000, 0x0 }, + { "32b", 0x6000, 0x4000 }, + { "64b", 0x6000, 0x2000 }, + { "G", 0x8000, 0x8000 }, + { NULL, 0, 0 }, + }; + + static const char *sys_desc_types[] = { + "reserved", + "16b TSS, available", + "LDT", + "16b TSS, busy", + "16b call gate", + "task gate", + "16b interrupt gate", + "16b trap gate", + "reserved", + "32b/64b TSS, available", + "reserved", + "32b/64b TSS, busy", + "32b/64b call gate", + "reserved", + "32b/64b interrupt gate" + "32b/64b trap gate", + }; + + if (desc->d_acc & 0x10) { + type = mem_desc_types[(desc->d_acc >> 1) & 7]; + bits = mem_desc_flag_bits; + } else { + type = sys_desc_types[desc->d_acc & 0xf]; + bits = sys_desc_flag_bits; + } + + mdb_printf("%%%s = 0x%0*lx/0x%0*x 0x%05x " + "<%susable, %s, dpl %d, flags: %b>\n", + name, width, desc->d_base, width / 2, desc->d_lim, desc->d_acc, + (desc->d_acc >> 16) & 1 ? "un" : "", type, + (desc->d_acc >> 5) & 3, desc->d_acc, bits); +} +#endif + +void +mdb_x86_print_sysregs(struct sysregs *sregs, boolean_t long_mode) +{ + const uint_t width = + 2 * (long_mode ? sizeof (uint64_t) : sizeof (uint32_t)); + + +#ifndef _KMDB + static const mdb_bitmask_t efer_flag_bits[] = { + { "SCE", AMD_EFER_SCE, AMD_EFER_SCE }, + { "LME", AMD_EFER_LME, AMD_EFER_LME }, + { "LMA", AMD_EFER_LMA, AMD_EFER_LMA }, + { "NXE", AMD_EFER_NXE, AMD_EFER_NXE }, + { "SVME", AMD_EFER_SVME, AMD_EFER_SVME }, + { "LMSLE", AMD_EFER_LMSLE, AMD_EFER_LMSLE }, + { "FFXSR", AMD_EFER_FFXSR, AMD_EFER_FFXSR }, + { "TCE", AMD_EFER_TCE, AMD_EFER_TCE }, + { NULL, 0, 0 } + }; +#endif + + static const mdb_bitmask_t cr0_flag_bits[] = { + { "PE", CR0_PE, CR0_PE }, + { "MP", CR0_MP, CR0_MP }, + { "EM", CR0_EM, CR0_EM }, + { "TS", CR0_TS, CR0_TS }, + { "ET", CR0_ET, CR0_ET }, + { "NE", CR0_NE, CR0_NE }, + { "WP", CR0_WP, CR0_WP }, + { "AM", CR0_AM, CR0_AM }, + { "NW", CR0_NW, CR0_NW }, + { "CD", CR0_CD, CR0_CD }, + { "PG", CR0_PG, CR0_PG }, + { NULL, 0, 0 } + }; + + static const mdb_bitmask_t cr3_flag_bits[] = { + { "PCD", CR3_PCD, CR3_PCD }, + { "PWT", CR3_PWT, CR3_PWT }, + { NULL, 0, 0, } + }; + + static const mdb_bitmask_t cr4_flag_bits[] = { + { "VME", CR4_VME, CR4_VME }, + { "PVI", CR4_PVI, CR4_PVI }, + { "TSD", CR4_TSD, CR4_TSD }, + { "DE", CR4_DE, CR4_DE }, + { "PSE", CR4_PSE, CR4_PSE }, + { "PAE", CR4_PAE, CR4_PAE }, + { "MCE", CR4_MCE, CR4_MCE }, + { "PGE", CR4_PGE, CR4_PGE }, + { "PCE", CR4_PCE, CR4_PCE }, + { "OSFXSR", CR4_OSFXSR, CR4_OSFXSR }, + { "OSXMMEXCPT", CR4_OSXMMEXCPT, CR4_OSXMMEXCPT }, + { "UMIP", CR4_UMIP, CR4_UMIP }, + { "VMXE", CR4_VMXE, CR4_VMXE }, + { "SMXE", CR4_SMXE, CR4_SMXE }, + { "FSGSBASE", CR4_FSGSBASE, CR4_FSGSBASE }, + { "PCIDE", CR4_PCIDE, CR4_PCIDE }, + { "OSXSAVE", CR4_OSXSAVE, CR4_OSXSAVE }, + { "SMEP", CR4_SMEP, CR4_SMEP }, + { "SMAP", CR4_SMAP, CR4_SMAP }, + { "PKE", CR4_PKE, CR4_PKE }, + { NULL, 0, 0 } + }; + +#ifndef _KMDB + mdb_printf("%%efer = 0x%0lx <%b>\n", + sregs->sr_efer, sregs->sr_efer, efer_flag_bits); +#endif + mdb_printf("%%cr0 = 0x%0lx <%b>\n", + sregs->sr_cr0, sregs->sr_cr0, cr0_flag_bits); + mdb_printf("%%cr2 = 0x%0*x <%a>\n", width, + sregs->sr_cr2, sregs->sr_cr2); + mdb_printf("%%cr3 = 0x%0lx <pfn:0x%lx ", + sregs->sr_cr3, sregs->sr_cr3 >> MMU_PAGESHIFT); + if (sregs->sr_cr4 & CR4_PCIDE) + mdb_printf("pcid:%lu>\n", sregs->sr_cr3 & MMU_PAGEOFFSET); + else + mdb_printf("flags:%b>\n", sregs->sr_cr3, cr3_flag_bits); + mdb_printf("%%cr4 = 0x%0lx <%b>\n", + sregs->sr_cr4, sregs->sr_cr4, cr4_flag_bits); + +#ifndef _KMDB + mdb_printf("\n"); + mdb_printf("%%pdpte0 = 0x%0?lx\t%%pdpte2 = 0x%0?lx\n", + sregs->sr_pdpte0, sregs->sr_pdpte2); + mdb_printf("%%pdpte1 = 0x%0?lx\t%%pdpte3 = 0x%0?lx\n", + sregs->sr_pdpte1, sregs->sr_pdpte3); + mdb_printf("\n"); + + mdb_printf("%%gdtr = 0x%0*lx/0x%hx\n", + width, sregs->sr_gdtr.d_base, sregs->sr_gdtr.d_lim); +#else + mdb_printf("%%gdtr.base = 0x%0*lx, %%gdtr.limit = 0x%hx\n", + width, sregs->sr_gdtr.d_base, sregs->sr_gdtr.d_lim); +#endif +#ifndef _KMDB + mdb_printf("%%idtr = 0x%0*lx/0x%hx\n", + width, sregs->sr_idtr.d_base, sregs->sr_idtr.d_lim); + mdb_x86_print_desc("ldtr", &sregs->sr_ldtr, width); + mdb_x86_print_desc("tr ", &sregs->sr_tr, width); + mdb_x86_print_desc("cs ", &sregs->sr_cs, width); + mdb_x86_print_desc("ss ", &sregs->sr_ss, width); + mdb_x86_print_desc("ds ", &sregs->sr_ds, width); + mdb_x86_print_desc("es ", &sregs->sr_es, width); + mdb_x86_print_desc("fs ", &sregs->sr_fs, width); + mdb_x86_print_desc("gs ", &sregs->sr_gs, width); + + mdb_printf("%%intr_shadow = 0x%lx\n", + sregs->sr_intr_shadow); +#endif +} diff --git a/usr/src/cmd/mdb/intel/mdb/mdb_x86util.h b/usr/src/cmd/mdb/intel/mdb/mdb_x86util.h new file mode 100644 index 0000000000..7641595d2a --- /dev/null +++ b/usr/src/cmd/mdb/intel/mdb/mdb_x86util.h @@ -0,0 +1,68 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. + */ + +#ifndef _MDB_X86UTIL_H +#define _MDB_X86UTIL_H + +#include <sys/types.h> +#include <inttypes.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct mdb_x86_desc { + uint64_t d_base; + uint32_t d_lim; + uint32_t d_acc; +} mdb_x86_desc_t; + +struct sysregs { + uint64_t sr_cr0; + uint64_t sr_cr2; + uint64_t sr_cr3; + uint64_t sr_cr4; + uint64_t sr_dr0; + uint64_t sr_dr1; + uint64_t sr_dr2; + uint64_t sr_dr3; + uint64_t sr_dr6; + uint64_t sr_dr7; + uint64_t sr_efer; + uint64_t sr_pdpte0; + uint64_t sr_pdpte1; + uint64_t sr_pdpte2; + uint64_t sr_pdpte3; + uint64_t sr_intr_shadow; + mdb_x86_desc_t sr_gdtr; + mdb_x86_desc_t sr_idtr; + mdb_x86_desc_t sr_ldtr; + mdb_x86_desc_t sr_tr; + mdb_x86_desc_t sr_cs; + mdb_x86_desc_t sr_ss; + mdb_x86_desc_t sr_ds; + mdb_x86_desc_t sr_es; + mdb_x86_desc_t sr_fs; + mdb_x86_desc_t sr_gs; +}; + +extern void mdb_x86_print_sysregs(struct sysregs *, boolean_t); + + +#ifdef __cplusplus +} +#endif + +#endif /* _MDB_X86UTIL_H */ diff --git a/usr/src/cmd/mdb/intel/mdb/proc_amd64dep.c b/usr/src/cmd/mdb/intel/mdb/proc_amd64dep.c index 2e374c0fc3..254ccf5af1 100644 --- a/usr/src/cmd/mdb/intel/mdb/proc_amd64dep.c +++ b/usr/src/cmd/mdb/intel/mdb/proc_amd64dep.c @@ -37,6 +37,7 @@ #include <mdb/mdb_proc.h> #include <mdb/mdb_kreg.h> #include <mdb/mdb_err.h> +#include <mdb/mdb_isautil.h> #include <mdb/mdb_amd64util.h> #include <mdb/mdb.h> @@ -143,7 +144,8 @@ pt_read_instr(mdb_tgt_t *t) const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; uint8_t ret = 0; - (void) mdb_tgt_vread(t, &ret, sizeof (ret), psp->pr_reg[REG_RIP]); + (void) mdb_tgt_aread(t, MDB_TGT_AS_VIRT_I, &ret, sizeof (ret), + psp->pr_reg[REG_RIP]); return (ret); } diff --git a/usr/src/cmd/mdb/intel/mdb/proc_ia32dep.c b/usr/src/cmd/mdb/intel/mdb/proc_ia32dep.c index 4433a36705..4efba18e4b 100644 --- a/usr/src/cmd/mdb/intel/mdb/proc_ia32dep.c +++ b/usr/src/cmd/mdb/intel/mdb/proc_ia32dep.c @@ -37,6 +37,7 @@ #include <mdb/mdb_proc.h> #include <mdb/mdb_kreg.h> #include <mdb/mdb_err.h> +#include <mdb/mdb_isautil.h> #include <mdb/mdb_ia32util.h> #include <mdb/mdb.h> @@ -98,7 +99,8 @@ pt_read_instr(mdb_tgt_t *t) const lwpstatus_t *psp = &Pstatus(t->t_pshandle)->pr_lwp; uint8_t ret = 0; - (void) mdb_tgt_vread(t, &ret, sizeof (ret), psp->pr_reg[EIP]); + (void) mdb_tgt_aread(t, MDB_TGT_AS_VIRT_I, &ret, sizeof (ret), + psp->pr_reg[EIP]); return (ret); } diff --git a/usr/src/cmd/mdb/intel/modules/i40e/amd64/Makefile b/usr/src/cmd/mdb/intel/modules/i40e/amd64/Makefile index 66f97451b6..f1632172f5 100644 --- a/usr/src/cmd/mdb/intel/modules/i40e/amd64/Makefile +++ b/usr/src/cmd/mdb/intel/modules/i40e/amd64/Makefile @@ -10,7 +10,7 @@ # # -# Copyright 2017 Joyent, Inc. +# Copyright 2018 Joyent, Inc. # MODULE = i40e.so @@ -23,6 +23,7 @@ include ../../../../../Makefile.cmd.64 include ../../../Makefile.amd64 include ../../../../Makefile.module +CPPFLAGS += -I$(SRC)/cmd/mdb/common CPPFLAGS += -I$(SRC)/uts/common/io/i40e CPPFLAGS += -I$(SRC)/uts/common/io/i40e/core CPPFLAGS += -I$(SRC)/uts/common diff --git a/usr/src/cmd/mdb/intel/modules/i40e/i40e.c b/usr/src/cmd/mdb/intel/modules/i40e/i40e.c index 6d1f900b43..3f42d24d1f 100644 --- a/usr/src/cmd/mdb/intel/modules/i40e/i40e.c +++ b/usr/src/cmd/mdb/intel/modules/i40e/i40e.c @@ -10,9 +10,10 @@ */ /* - * Copyright 2016 Joyent, Inc. + * Copyright 2018 Joyent, Inc. */ +#include <mdb/mdb_ctf.h> #include <sys/mdb_modapi.h> #include "i40e_sw.h" @@ -97,9 +98,181 @@ i40e_switch_rsrcs_dcmd(uintptr_t addr, uint_t flags, int argc, return (DCMD_OK); } +typedef struct mdb_i40e_trqpair { + uint32_t itrq_tx_ring_size; + uint32_t itrq_desc_free; + uint32_t *itrq_desc_wbhead; + uint32_t itrq_desc_head; + uint32_t itrq_desc_tail; + i40e_tx_desc_t *itrq_desc_ring; + i40e_tx_control_block_t **itrq_tcb_work_list; +} mdb_i40e_trqpair_t; + +static void +i40e_tx_ring_help() +{ + mdb_printf( + "\t -a dump all ring entries\n" + "\t or\n" + "\t combine -b [start index] with -e [end index] to specify a \n" + "\t range of ring entries to print\n"); +} + +static int +i40e_tx_ring_dcmd(uintptr_t addr, uint_t flags, int argc, + const mdb_arg_t *argv) +{ + mdb_i40e_trqpair_t trq; + i40e_tx_desc_t *descring; + i40e_tx_control_block_t **wklist; + uint32_t wbhead; + size_t ringsz, wklistsz; + boolean_t opt_a = B_FALSE; + char *opt_b = NULL, *opt_e = NULL; + uint64_t begin = UINT64_MAX, end = UINT64_MAX; + + if (!(flags & DCMD_ADDRSPEC)) { + mdb_warn("::i40e_tx_ring does not operate globally\n"); + return (DCMD_USAGE); + } + + if (mdb_getopts(argc, argv, + 'a', MDB_OPT_SETBITS, B_TRUE, &opt_a, + 'b', MDB_OPT_STR, &opt_b, + 'e', MDB_OPT_STR, &opt_e, NULL) != argc) + return (DCMD_USAGE); + + /* + * Verify that a legal combination of -a/-b/-e were used. + */ + if (opt_a && (opt_b != NULL || opt_e != NULL)) { + mdb_warn("-a and -b/-e are mutually exclusive\n"); + return (DCMD_USAGE); + } + if (argc > 0 && ! opt_a && (opt_b == NULL || opt_e == NULL)) { + mdb_warn("-b/-e must both be specified\n"); + return (DCMD_USAGE); + } + + if (mdb_ctf_vread(&trq, "i40e_trqpair_t", "mdb_i40e_trqpair_t", addr, + 0) == -1) { + mdb_warn("failed to read i40e_trqpair_t at %p", addr); + return (DCMD_ERR); + } + + if (opt_b != NULL) + begin = mdb_strtoull(opt_b); + if (opt_e != NULL) + end = mdb_strtoull(opt_e); + if (opt_a) { + begin = 0; + end = trq.itrq_tx_ring_size - 1; + } + + /* + * Verify that the requested range of ring entries makes sense. + */ + if (argc > 0 && (end < begin || begin >= trq.itrq_tx_ring_size || + end >= trq.itrq_tx_ring_size)) { + mdb_warn("invalid range specified\n"); + return (DCMD_USAGE); + } + + if (mdb_vread(&wbhead, sizeof (uint32_t), + (uintptr_t)trq.itrq_desc_wbhead) != sizeof (uint32_t)) { + mdb_warn("failed to read trq.itrq_desc_wbhead"); + return (DCMD_ERR); + } + mdb_printf("%-20s%d\n", "Ring Size:", trq.itrq_tx_ring_size); + mdb_printf("%-20s%d\n", "Free Descriptors:", trq.itrq_desc_free); + mdb_printf("%-20s%d\n", "Writeback Head:", wbhead); + mdb_printf("%-20s%d\n", "Head:", trq.itrq_desc_head); + mdb_printf("%-20s%d\n", "Tail:", trq.itrq_desc_tail); + + /* + * No arguments were specified, so we're done. + */ + if (argc == 0) + return (DCMD_OK); + + /* + * Allocate memory and read in the entire TX descriptor ring and + * TCB work list. + */ + ringsz = sizeof (i40e_tx_desc_t) * trq.itrq_tx_ring_size; + descring = mdb_alloc(ringsz, UM_SLEEP); + if (mdb_vread(descring, ringsz, (uintptr_t)trq.itrq_desc_ring) != + ringsz) { + mdb_warn("Failed to read in TX decriptor ring\n"); + mdb_free(descring, ringsz); + return (DCMD_ERR); + } + wklistsz = sizeof (i40e_tx_control_block_t *) * trq.itrq_tx_ring_size; + wklist = mdb_alloc(wklistsz, UM_SLEEP); + if (mdb_vread(wklist, wklistsz, (uintptr_t)trq.itrq_tcb_work_list) != + wklistsz) { + mdb_warn("Failed to read in TX TCB work list\n"); + mdb_free(descring, ringsz); + mdb_free(wklist, wklistsz); + return (DCMD_ERR); + } + + mdb_printf("\n%-10s %-10s %-16s %-16s %-10s\n", "Index", "Desc Type", + "Desc Ptr", "TCB Ptr", "Other"); + for (uint64_t i = begin; i <= end; i++) { + const char *dtype; + char dother[17]; + i40e_tx_desc_t *dptr; + i40e_tx_control_block_t *tcbptr; + uint64_t ctob; + + dptr = &descring[i]; + tcbptr = wklist[i]; + ctob = LE_64(dptr->cmd_type_offset_bsz); + if (ctob == 0) { + dtype = "FREE"; + } else { + switch (ctob & I40E_TXD_QW1_DTYPE_MASK) { + case (I40E_TX_DESC_DTYPE_CONTEXT): + dtype = "CONTEXT"; + break; + case (I40E_TX_DESC_DTYPE_DATA): + dtype = "DATA"; + break; + case (I40E_TX_DESC_DTYPE_FILTER_PROG): + dtype = "FILTER"; + break; + default: + dtype = "UNKNOWN"; + } + } + dother[0] = '\0'; + if (i == wbhead) + (void) strcat(dother, "WBHEAD"); + + if (i == trq.itrq_desc_head) + (void) strcat(dother, + strlen(dother) > 0 ? " HEAD" : "HEAD"); + + if (i == trq.itrq_desc_tail) + (void) strcat(dother, + strlen(dother) > 0 ? " TAIL" : "TAIL"); + + mdb_printf("%-10d %-10s %-16p %-16p %-10s\n", i, dtype, dptr, + tcbptr, dother); + } + + mdb_free(descring, ringsz); + mdb_free(wklist, wklistsz); + return (DCMD_OK); +} + static const mdb_dcmd_t i40e_dcmds[] = { { "i40e_switch_rsrcs", NULL, "print switch resources", i40e_switch_rsrcs_dcmd, NULL }, + { "i40e_tx_ring", "[-a] -b [start index] -e [end index]\n", + "dump TX descriptor ring state", i40e_tx_ring_dcmd, + i40e_tx_ring_help }, { NULL } }; diff --git a/usr/src/cmd/mdb/sparc/v7/libumem/Makefile b/usr/src/cmd/mdb/sparc/v7/libumem/Makefile index 906d05d5ea..0488e6739a 100644 --- a/usr/src/cmd/mdb/sparc/v7/libumem/Makefile +++ b/usr/src/cmd/mdb/sparc/v7/libumem/Makefile @@ -22,6 +22,7 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright (c) 2012 Joyent, Inc. All rights reserved. MODULE = libumem.so MDBTGT = proc diff --git a/usr/src/cmd/mdb/sparc/v9/libumem/Makefile b/usr/src/cmd/mdb/sparc/v9/libumem/Makefile index 09ea0473c6..87ce977423 100644 --- a/usr/src/cmd/mdb/sparc/v9/libumem/Makefile +++ b/usr/src/cmd/mdb/sparc/v9/libumem/Makefile @@ -22,6 +22,7 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright (c) 2012 Joyent, Inc. All rights reserved. MODULE = libumem.so MDBTGT = proc diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-E.mdb b/usr/src/cmd/mdb/test/format/tst.format-cap-E.mdb new file mode 100644 index 0000000000..18e9053ce4 --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-cap-E.mdb @@ -0,0 +1,2 @@ +-1,10=E +1<<0t63,10=E diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-E.mdb.out b/usr/src/cmd/mdb/test/format/tst.format-cap-E.mdb.out new file mode 100644 index 0000000000..2268a48be9 --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-cap-E.mdb.out @@ -0,0 +1,12 @@ + 18446744073709551615 18446744073709551615 18446744073709551615 + 18446744073709551615 18446744073709551615 18446744073709551615 + 18446744073709551615 18446744073709551615 18446744073709551615 + 18446744073709551615 18446744073709551615 18446744073709551615 + 18446744073709551615 18446744073709551615 18446744073709551615 + 18446744073709551615 + 9223372036854775808 9223372036854775808 9223372036854775808 + 9223372036854775808 9223372036854775808 9223372036854775808 + 9223372036854775808 9223372036854775808 9223372036854775808 + 9223372036854775808 9223372036854775808 9223372036854775808 + 9223372036854775808 9223372036854775808 9223372036854775808 + 9223372036854775808 diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-G.mdb b/usr/src/cmd/mdb/test/format/tst.format-cap-G.mdb new file mode 100644 index 0000000000..f10f78336b --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-cap-G.mdb @@ -0,0 +1,4 @@ +-1,10=G +1<<0t63,10=G +1<<0t60,10=G +1<<0t57,10=G diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-G.mdb.out b/usr/src/cmd/mdb/test/format/tst.format-cap-G.mdb.out new file mode 100644 index 0000000000..f1dfd5193b --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-cap-G.mdb.out @@ -0,0 +1,32 @@ + 1777777777777777777777 1777777777777777777777 + 1777777777777777777777 1777777777777777777777 + 1777777777777777777777 1777777777777777777777 + 1777777777777777777777 1777777777777777777777 + 1777777777777777777777 1777777777777777777777 + 1777777777777777777777 1777777777777777777777 + 1777777777777777777777 1777777777777777777777 + 1777777777777777777777 1777777777777777777777 + 1000000000000000000000 1000000000000000000000 + 1000000000000000000000 1000000000000000000000 + 1000000000000000000000 1000000000000000000000 + 1000000000000000000000 1000000000000000000000 + 1000000000000000000000 1000000000000000000000 + 1000000000000000000000 1000000000000000000000 + 1000000000000000000000 1000000000000000000000 + 1000000000000000000000 1000000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-J.mdb b/usr/src/cmd/mdb/test/format/tst.format-cap-J.mdb new file mode 100644 index 0000000000..ff9dabbce9 --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-cap-J.mdb @@ -0,0 +1,3 @@ +-1,10=J +1<<0t63,10=J +1<<0t59,10=J diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-J.mdb.out b/usr/src/cmd/mdb/test/format/tst.format-cap-J.mdb.out new file mode 100644 index 0000000000..644fee231e --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-cap-J.mdb.out @@ -0,0 +1,16 @@ + ffffffffffffffff ffffffffffffffff ffffffffffffffff + ffffffffffffffff ffffffffffffffff ffffffffffffffff + ffffffffffffffff ffffffffffffffff ffffffffffffffff + ffffffffffffffff ffffffffffffffff ffffffffffffffff + ffffffffffffffff ffffffffffffffff ffffffffffffffff + ffffffffffffffff + 8000000000000000 8000000000000000 8000000000000000 + 8000000000000000 8000000000000000 8000000000000000 + 8000000000000000 8000000000000000 8000000000000000 + 8000000000000000 8000000000000000 8000000000000000 + 8000000000000000 8000000000000000 8000000000000000 + 8000000000000000 + 800000000000000 800000000000000 800000000000000 800000000000000 + 800000000000000 800000000000000 800000000000000 800000000000000 + 800000000000000 800000000000000 800000000000000 800000000000000 + 800000000000000 800000000000000 800000000000000 800000000000000 diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-P.mdb b/usr/src/cmd/mdb/test/format/tst.format-cap-P.mdb new file mode 100644 index 0000000000..88928fda29 --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-cap-P.mdb @@ -0,0 +1 @@ +1<<0t63,10=P diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-P.mdb.out b/usr/src/cmd/mdb/test/format/tst.format-cap-P.mdb.out new file mode 100644 index 0000000000..65e05e7220 --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-cap-P.mdb.out @@ -0,0 +1,6 @@ + 0x8000000000000000 0x8000000000000000 0x8000000000000000 + 0x8000000000000000 0x8000000000000000 0x8000000000000000 + 0x8000000000000000 0x8000000000000000 0x8000000000000000 + 0x8000000000000000 0x8000000000000000 0x8000000000000000 + 0x8000000000000000 0x8000000000000000 0x8000000000000000 + 0x8000000000000000 diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-R.mdb b/usr/src/cmd/mdb/test/format/tst.format-cap-R.mdb new file mode 100644 index 0000000000..9f55408276 --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-cap-R.mdb @@ -0,0 +1,4 @@ +1=RRRR +1<<0t62=RRR +1<<0t63=RRR +-1=RRRR diff --git a/usr/src/cmd/mdb/test/format/tst.format-cap-R.mdb.out b/usr/src/cmd/mdb/test/format/tst.format-cap-R.mdb.out new file mode 100644 index 0000000000..f05b0bac4d --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-cap-R.mdb.out @@ -0,0 +1,14 @@ + 1 + 1 + 1 + 1 + 100000000000000000000000000000000000000000000000000000000000000 + 100000000000000000000000000000000000000000000000000000000000000 + 100000000000000000000000000000000000000000000000000000000000000 + 1000000000000000000000000000000000000000000000000000000000000000 + 1000000000000000000000000000000000000000000000000000000000000000 + 1000000000000000000000000000000000000000000000000000000000000000 + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 diff --git a/usr/src/cmd/mdb/test/format/tst.format-e.mdb b/usr/src/cmd/mdb/test/format/tst.format-e.mdb new file mode 100644 index 0000000000..79d4b25af4 --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-e.mdb @@ -0,0 +1,2 @@ +-1,10=e +1<<0t63,10=e diff --git a/usr/src/cmd/mdb/test/format/tst.format-e.mdb.out b/usr/src/cmd/mdb/test/format/tst.format-e.mdb.out new file mode 100644 index 0000000000..909c53cbc0 --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-e.mdb.out @@ -0,0 +1,12 @@ + -1 -1 -1 + -1 -1 -1 + -1 -1 -1 + -1 -1 -1 + -1 -1 -1 + -1 + -9223372036854775808 -9223372036854775808 -9223372036854775808 + -9223372036854775808 -9223372036854775808 -9223372036854775808 + -9223372036854775808 -9223372036854775808 -9223372036854775808 + -9223372036854775808 -9223372036854775808 -9223372036854775808 + -9223372036854775808 -9223372036854775808 -9223372036854775808 + -9223372036854775808 diff --git a/usr/src/cmd/mdb/test/format/tst.format-g.mdb b/usr/src/cmd/mdb/test/format/tst.format-g.mdb new file mode 100644 index 0000000000..b3397d21ed --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-g.mdb @@ -0,0 +1,5 @@ +-1,10=g +1<<0t63,10=g +(1<<0t63)-1,10=g +1<<0t60,10=g +1<<0t57,10=g diff --git a/usr/src/cmd/mdb/test/format/tst.format-g.mdb.out b/usr/src/cmd/mdb/test/format/tst.format-g.mdb.out new file mode 100644 index 0000000000..c46dff3594 --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-g.mdb.out @@ -0,0 +1,40 @@ + -1 -1 + -1 -1 + -1 -1 + -1 -1 + -1 -1 + -1 -1 + -1 -1 + -1 -1 + -1000000000000000000000 -1000000000000000000000 + -1000000000000000000000 -1000000000000000000000 + -1000000000000000000000 -1000000000000000000000 + -1000000000000000000000 -1000000000000000000000 + -1000000000000000000000 -1000000000000000000000 + -1000000000000000000000 -1000000000000000000000 + -1000000000000000000000 -1000000000000000000000 + -1000000000000000000000 -1000000000000000000000 + 777777777777777777777 777777777777777777777 + 777777777777777777777 777777777777777777777 + 777777777777777777777 777777777777777777777 + 777777777777777777777 777777777777777777777 + 777777777777777777777 777777777777777777777 + 777777777777777777777 777777777777777777777 + 777777777777777777777 777777777777777777777 + 777777777777777777777 777777777777777777777 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 100000000000000000000 100000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 + 10000000000000000000 10000000000000000000 diff --git a/usr/src/cmd/mdb/test/format/tst.format-j.mdb b/usr/src/cmd/mdb/test/format/tst.format-j.mdb new file mode 100644 index 0000000000..875a1e178f --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-j.mdb @@ -0,0 +1,8 @@ +-1=JRjnn +0=JRjnn +1=JRjnn +feedface=JRjnn +badfeedcafe=JRjnn +deadba11e12a=JRjnn +badb100d=JRjnn +baddefec8ed=JRjnn diff --git a/usr/src/cmd/mdb/test/format/tst.format-j.mdb.out b/usr/src/cmd/mdb/test/format/tst.format-j.mdb.out new file mode 100644 index 0000000000..3f5fa0afaf --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-j.mdb.out @@ -0,0 +1,238 @@ + ffffffffffffffff + 1111111111111111111111111111111111111111111111111111111111111111 + 1111111111111111111111111111111111111111111111111111111111111111 + |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||+-- bit 0 mask 0x0000000000000001 + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||+--- bit 1 mask 0x0000000000000002 + |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||+---- bit 2 mask 0x0000000000000004 + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||+----- bit 3 mask 0x0000000000000008 + |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||+------ bit 4 mask 0x0000000000000010 + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||+------- bit 5 mask 0x0000000000000020 + |||||||||||||||||||||||||||||||||||||||||||||||||||||||||+-------- bit 6 mask 0x0000000000000040 + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||+--------- bit 7 mask 0x0000000000000080 + |||||||||||||||||||||||||||||||||||||||||||||||||||||||+---------- bit 8 mask 0x0000000000000100 + ||||||||||||||||||||||||||||||||||||||||||||||||||||||+----------- bit 9 mask 0x0000000000000200 + |||||||||||||||||||||||||||||||||||||||||||||||||||||+------------ bit 10 mask 0x0000000000000400 + ||||||||||||||||||||||||||||||||||||||||||||||||||||+------------- bit 11 mask 0x0000000000000800 + |||||||||||||||||||||||||||||||||||||||||||||||||||+-------------- bit 12 mask 0x0000000000001000 + ||||||||||||||||||||||||||||||||||||||||||||||||||+--------------- bit 13 mask 0x0000000000002000 + |||||||||||||||||||||||||||||||||||||||||||||||||+---------------- bit 14 mask 0x0000000000004000 + ||||||||||||||||||||||||||||||||||||||||||||||||+----------------- bit 15 mask 0x0000000000008000 + |||||||||||||||||||||||||||||||||||||||||||||||+------------------ bit 16 mask 0x0000000000010000 + ||||||||||||||||||||||||||||||||||||||||||||||+------------------- bit 17 mask 0x0000000000020000 + |||||||||||||||||||||||||||||||||||||||||||||+-------------------- bit 18 mask 0x0000000000040000 + ||||||||||||||||||||||||||||||||||||||||||||+--------------------- bit 19 mask 0x0000000000080000 + |||||||||||||||||||||||||||||||||||||||||||+---------------------- bit 20 mask 0x0000000000100000 + ||||||||||||||||||||||||||||||||||||||||||+----------------------- bit 21 mask 0x0000000000200000 + |||||||||||||||||||||||||||||||||||||||||+------------------------ bit 22 mask 0x0000000000400000 + ||||||||||||||||||||||||||||||||||||||||+------------------------- bit 23 mask 0x0000000000800000 + |||||||||||||||||||||||||||||||||||||||+-------------------------- bit 24 mask 0x0000000001000000 + ||||||||||||||||||||||||||||||||||||||+--------------------------- bit 25 mask 0x0000000002000000 + |||||||||||||||||||||||||||||||||||||+---------------------------- bit 26 mask 0x0000000004000000 + ||||||||||||||||||||||||||||||||||||+----------------------------- bit 27 mask 0x0000000008000000 + |||||||||||||||||||||||||||||||||||+------------------------------ bit 28 mask 0x0000000010000000 + ||||||||||||||||||||||||||||||||||+------------------------------- bit 29 mask 0x0000000020000000 + |||||||||||||||||||||||||||||||||+-------------------------------- bit 30 mask 0x0000000040000000 + ||||||||||||||||||||||||||||||||+--------------------------------- bit 31 mask 0x0000000080000000 + |||||||||||||||||||||||||||||||+---------------------------------- bit 32 mask 0x0000000100000000 + ||||||||||||||||||||||||||||||+----------------------------------- bit 33 mask 0x0000000200000000 + |||||||||||||||||||||||||||||+------------------------------------ bit 34 mask 0x0000000400000000 + ||||||||||||||||||||||||||||+------------------------------------- bit 35 mask 0x0000000800000000 + |||||||||||||||||||||||||||+-------------------------------------- bit 36 mask 0x0000001000000000 + ||||||||||||||||||||||||||+--------------------------------------- bit 37 mask 0x0000002000000000 + |||||||||||||||||||||||||+---------------------------------------- bit 38 mask 0x0000004000000000 + ||||||||||||||||||||||||+----------------------------------------- bit 39 mask 0x0000008000000000 + |||||||||||||||||||||||+------------------------------------------ bit 40 mask 0x0000010000000000 + ||||||||||||||||||||||+------------------------------------------- bit 41 mask 0x0000020000000000 + |||||||||||||||||||||+-------------------------------------------- bit 42 mask 0x0000040000000000 + ||||||||||||||||||||+--------------------------------------------- bit 43 mask 0x0000080000000000 + |||||||||||||||||||+---------------------------------------------- bit 44 mask 0x0000100000000000 + ||||||||||||||||||+----------------------------------------------- bit 45 mask 0x0000200000000000 + |||||||||||||||||+------------------------------------------------ bit 46 mask 0x0000400000000000 + ||||||||||||||||+------------------------------------------------- bit 47 mask 0x0000800000000000 + |||||||||||||||+-------------------------------------------------- bit 48 mask 0x0001000000000000 + ||||||||||||||+--------------------------------------------------- bit 49 mask 0x0002000000000000 + |||||||||||||+---------------------------------------------------- bit 50 mask 0x0004000000000000 + ||||||||||||+----------------------------------------------------- bit 51 mask 0x0008000000000000 + |||||||||||+------------------------------------------------------ bit 52 mask 0x0010000000000000 + ||||||||||+------------------------------------------------------- bit 53 mask 0x0020000000000000 + |||||||||+-------------------------------------------------------- bit 54 mask 0x0040000000000000 + ||||||||+--------------------------------------------------------- bit 55 mask 0x0080000000000000 + |||||||+---------------------------------------------------------- bit 56 mask 0x0100000000000000 + ||||||+----------------------------------------------------------- bit 57 mask 0x0200000000000000 + |||||+------------------------------------------------------------ bit 58 mask 0x0400000000000000 + ||||+------------------------------------------------------------- bit 59 mask 0x0800000000000000 + |||+-------------------------------------------------------------- bit 60 mask 0x1000000000000000 + ||+--------------------------------------------------------------- bit 61 mask 0x2000000000000000 + |+---------------------------------------------------------------- bit 62 mask 0x4000000000000000 + +----------------------------------------------------------------- bit 63 mask 0x8000000000000000 + + + 0 + 0 + 0 + + + 1 + 1 + 1 + | + +-- bit 0 mask 0x1 + + + feedface + 11111110111011011111101011001110 + 11111110111011011111101011001110 + ||||||| ||| || |||||| | || ||| + ||||||| ||| || |||||| | || ||+--- bit 1 mask 0x00000002 + ||||||| ||| || |||||| | || |+---- bit 2 mask 0x00000004 + ||||||| ||| || |||||| | || +----- bit 3 mask 0x00000008 + ||||||| ||| || |||||| | |+-------- bit 6 mask 0x00000040 + ||||||| ||| || |||||| | +--------- bit 7 mask 0x00000080 + ||||||| ||| || |||||| +----------- bit 9 mask 0x00000200 + ||||||| ||| || |||||+------------- bit 11 mask 0x00000800 + ||||||| ||| || ||||+-------------- bit 12 mask 0x00001000 + ||||||| ||| || |||+--------------- bit 13 mask 0x00002000 + ||||||| ||| || ||+---------------- bit 14 mask 0x00004000 + ||||||| ||| || |+----------------- bit 15 mask 0x00008000 + ||||||| ||| || +------------------ bit 16 mask 0x00010000 + ||||||| ||| |+-------------------- bit 18 mask 0x00040000 + ||||||| ||| +--------------------- bit 19 mask 0x00080000 + ||||||| ||+----------------------- bit 21 mask 0x00200000 + ||||||| |+------------------------ bit 22 mask 0x00400000 + ||||||| +------------------------- bit 23 mask 0x00800000 + ||||||+--------------------------- bit 25 mask 0x02000000 + |||||+---------------------------- bit 26 mask 0x04000000 + ||||+----------------------------- bit 27 mask 0x08000000 + |||+------------------------------ bit 28 mask 0x10000000 + ||+------------------------------- bit 29 mask 0x20000000 + |+-------------------------------- bit 30 mask 0x40000000 + +--------------------------------- bit 31 mask 0x80000000 + + + badfeedcafe + 10111010110111111110111011011100101011111110 + 10111010110111111110111011011100101011111110 + | ||| | || |||||||| ||| || ||| | | ||||||| + | ||| | || |||||||| ||| || ||| | | ||||||+--- bit 1 mask 0x00000000002 + | ||| | || |||||||| ||| || ||| | | |||||+---- bit 2 mask 0x00000000004 + | ||| | || |||||||| ||| || ||| | | ||||+----- bit 3 mask 0x00000000008 + | ||| | || |||||||| ||| || ||| | | |||+------ bit 4 mask 0x00000000010 + | ||| | || |||||||| ||| || ||| | | ||+------- bit 5 mask 0x00000000020 + | ||| | || |||||||| ||| || ||| | | |+-------- bit 6 mask 0x00000000040 + | ||| | || |||||||| ||| || ||| | | +--------- bit 7 mask 0x00000000080 + | ||| | || |||||||| ||| || ||| | +----------- bit 9 mask 0x00000000200 + | ||| | || |||||||| ||| || ||| +------------- bit 11 mask 0x00000000800 + | ||| | || |||||||| ||| || ||+---------------- bit 14 mask 0x00000004000 + | ||| | || |||||||| ||| || |+----------------- bit 15 mask 0x00000008000 + | ||| | || |||||||| ||| || +------------------ bit 16 mask 0x00000010000 + | ||| | || |||||||| ||| |+-------------------- bit 18 mask 0x00000040000 + | ||| | || |||||||| ||| +--------------------- bit 19 mask 0x00000080000 + | ||| | || |||||||| ||+----------------------- bit 21 mask 0x00000200000 + | ||| | || |||||||| |+------------------------ bit 22 mask 0x00000400000 + | ||| | || |||||||| +------------------------- bit 23 mask 0x00000800000 + | ||| | || |||||||+--------------------------- bit 25 mask 0x00002000000 + | ||| | || ||||||+---------------------------- bit 26 mask 0x00004000000 + | ||| | || |||||+----------------------------- bit 27 mask 0x00008000000 + | ||| | || ||||+------------------------------ bit 28 mask 0x00010000000 + | ||| | || |||+------------------------------- bit 29 mask 0x00020000000 + | ||| | || ||+-------------------------------- bit 30 mask 0x00040000000 + | ||| | || |+--------------------------------- bit 31 mask 0x00080000000 + | ||| | || +---------------------------------- bit 32 mask 0x00100000000 + | ||| | |+------------------------------------ bit 34 mask 0x00400000000 + | ||| | +------------------------------------- bit 35 mask 0x00800000000 + | ||| +--------------------------------------- bit 37 mask 0x02000000000 + | ||+----------------------------------------- bit 39 mask 0x08000000000 + | |+------------------------------------------ bit 40 mask 0x10000000000 + | +------------------------------------------- bit 41 mask 0x20000000000 + +--------------------------------------------- bit 43 mask 0x80000000000 + + + deadba11e12a + 110111101010110110111010000100011110000100101010 + 110111101010110110111010000100011110000100101010 + || |||| | | || || ||| | | |||| | | | | + || |||| | | || || ||| | | |||| | | | +--- bit 1 mask 0x000000000002 + || |||| | | || || ||| | | |||| | | +----- bit 3 mask 0x000000000008 + || |||| | | || || ||| | | |||| | +------- bit 5 mask 0x000000000020 + || |||| | | || || ||| | | |||| +---------- bit 8 mask 0x000000000100 + || |||| | | || || ||| | | |||+--------------- bit 13 mask 0x000000002000 + || |||| | | || || ||| | | ||+---------------- bit 14 mask 0x000000004000 + || |||| | | || || ||| | | |+----------------- bit 15 mask 0x000000008000 + || |||| | | || || ||| | | +------------------ bit 16 mask 0x000000010000 + || |||| | | || || ||| | +---------------------- bit 20 mask 0x000000100000 + || |||| | | || || ||| +--------------------------- bit 25 mask 0x000002000000 + || |||| | | || || ||+----------------------------- bit 27 mask 0x000008000000 + || |||| | | || || |+------------------------------ bit 28 mask 0x000010000000 + || |||| | | || || +------------------------------- bit 29 mask 0x000020000000 + || |||| | | || |+--------------------------------- bit 31 mask 0x000080000000 + || |||| | | || +---------------------------------- bit 32 mask 0x000100000000 + || |||| | | |+------------------------------------ bit 34 mask 0x000400000000 + || |||| | | +------------------------------------- bit 35 mask 0x000800000000 + || |||| | +--------------------------------------- bit 37 mask 0x002000000000 + || |||| +----------------------------------------- bit 39 mask 0x008000000000 + || |||+------------------------------------------- bit 41 mask 0x020000000000 + || ||+-------------------------------------------- bit 42 mask 0x040000000000 + || |+--------------------------------------------- bit 43 mask 0x080000000000 + || +---------------------------------------------- bit 44 mask 0x100000000000 + |+------------------------------------------------ bit 46 mask 0x400000000000 + +------------------------------------------------- bit 47 mask 0x800000000000 + + + badb100d + 10111010110110110001000000001101 + 10111010110110110001000000001101 + | ||| | || || || | || | + | ||| | || || || | || +-- bit 0 mask 0x00000001 + | ||| | || || || | |+---- bit 2 mask 0x00000004 + | ||| | || || || | +----- bit 3 mask 0x00000008 + | ||| | || || || +-------------- bit 12 mask 0x00001000 + | ||| | || || |+------------------ bit 16 mask 0x00010000 + | ||| | || || +------------------- bit 17 mask 0x00020000 + | ||| | || |+--------------------- bit 19 mask 0x00080000 + | ||| | || +---------------------- bit 20 mask 0x00100000 + | ||| | |+------------------------ bit 22 mask 0x00400000 + | ||| | +------------------------- bit 23 mask 0x00800000 + | ||| +--------------------------- bit 25 mask 0x02000000 + | ||+----------------------------- bit 27 mask 0x08000000 + | |+------------------------------ bit 28 mask 0x10000000 + | +------------------------------- bit 29 mask 0x20000000 + +--------------------------------- bit 31 mask 0x80000000 + + + baddefec8ed + 10111010110111011110111111101100100011101101 + 10111010110111011110111111101100100011101101 + | ||| | || ||| |||| ||||||| || | ||| || | + | ||| | || ||| |||| ||||||| || | ||| || +-- bit 0 mask 0x00000000001 + | ||| | || ||| |||| ||||||| || | ||| |+---- bit 2 mask 0x00000000004 + | ||| | || ||| |||| ||||||| || | ||| +----- bit 3 mask 0x00000000008 + | ||| | || ||| |||| ||||||| || | ||+------- bit 5 mask 0x00000000020 + | ||| | || ||| |||| ||||||| || | |+-------- bit 6 mask 0x00000000040 + | ||| | || ||| |||| ||||||| || | +--------- bit 7 mask 0x00000000080 + | ||| | || ||| |||| ||||||| || +------------- bit 11 mask 0x00000000800 + | ||| | || ||| |||| ||||||| |+---------------- bit 14 mask 0x00000004000 + | ||| | || ||| |||| ||||||| +----------------- bit 15 mask 0x00000008000 + | ||| | || ||| |||| ||||||+------------------- bit 17 mask 0x00000020000 + | ||| | || ||| |||| |||||+-------------------- bit 18 mask 0x00000040000 + | ||| | || ||| |||| ||||+--------------------- bit 19 mask 0x00000080000 + | ||| | || ||| |||| |||+---------------------- bit 20 mask 0x00000100000 + | ||| | || ||| |||| ||+----------------------- bit 21 mask 0x00000200000 + | ||| | || ||| |||| |+------------------------ bit 22 mask 0x00000400000 + | ||| | || ||| |||| +------------------------- bit 23 mask 0x00000800000 + | ||| | || ||| |||+--------------------------- bit 25 mask 0x00002000000 + | ||| | || ||| ||+---------------------------- bit 26 mask 0x00004000000 + | ||| | || ||| |+----------------------------- bit 27 mask 0x00008000000 + | ||| | || ||| +------------------------------ bit 28 mask 0x00010000000 + | ||| | || ||+-------------------------------- bit 30 mask 0x00040000000 + | ||| | || |+--------------------------------- bit 31 mask 0x00080000000 + | ||| | || +---------------------------------- bit 32 mask 0x00100000000 + | ||| | |+------------------------------------ bit 34 mask 0x00400000000 + | ||| | +------------------------------------- bit 35 mask 0x00800000000 + | ||| +--------------------------------------- bit 37 mask 0x02000000000 + | ||+----------------------------------------- bit 39 mask 0x08000000000 + | |+------------------------------------------ bit 40 mask 0x10000000000 + | +------------------------------------------- bit 41 mask 0x20000000000 + +--------------------------------------------- bit 43 mask 0x80000000000 + + diff --git a/usr/src/cmd/mdb/test/format/tst.format-p.mdb b/usr/src/cmd/mdb/test/format/tst.format-p.mdb new file mode 100644 index 0000000000..ee2b989d1b --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-p.mdb @@ -0,0 +1 @@ +1<<0t63,10=p diff --git a/usr/src/cmd/mdb/test/format/tst.format-p.mdb.out b/usr/src/cmd/mdb/test/format/tst.format-p.mdb.out new file mode 100644 index 0000000000..65e05e7220 --- /dev/null +++ b/usr/src/cmd/mdb/test/format/tst.format-p.mdb.out @@ -0,0 +1,6 @@ + 0x8000000000000000 0x8000000000000000 0x8000000000000000 + 0x8000000000000000 0x8000000000000000 0x8000000000000000 + 0x8000000000000000 0x8000000000000000 0x8000000000000000 + 0x8000000000000000 0x8000000000000000 0x8000000000000000 + 0x8000000000000000 0x8000000000000000 0x8000000000000000 + 0x8000000000000000 diff --git a/usr/src/cmd/mdb/test/mtest.sh b/usr/src/cmd/mdb/test/mtest.sh index f21d0faa21..f21d0faa21 100644..100755 --- a/usr/src/cmd/mdb/test/mtest.sh +++ b/usr/src/cmd/mdb/test/mtest.sh diff --git a/usr/src/cmd/mdb/test/options/tst.autowrap.mdb b/usr/src/cmd/mdb/test/options/tst.autowrap.mdb new file mode 100644 index 0000000000..5904cbf4c7 --- /dev/null +++ b/usr/src/cmd/mdb/test/options/tst.autowrap.mdb @@ -0,0 +1,15 @@ +::set +o autowrap +::typedef -c lp32 +0::printf "Pack my box with five dozen liquor jugs. How razorback-jumping frogs can level six piqued gymnasts! Amazingly few discotheques provide jukeboxes.%d" int . + +0::printf "%-79d%d" int . . +0::printf "%-80d%d" int . . +0::printf "%-81d%d" int . . + +::set -o autowrap +0::printf "Pack my box with five dozen liquor jugs. How razorback-jumping frogs can level six piqued gymnasts! Amazingly few discotheques provide jukeboxes.%d" int . + +0::printf "%-79d%d" int . . +0::printf "%-80d%d" int . . +0::printf "%-81d%d" int . . + diff --git a/usr/src/cmd/mdb/test/options/tst.autowrap.mdb.out b/usr/src/cmd/mdb/test/options/tst.autowrap.mdb.out new file mode 100644 index 0000000000..81d3ef5293 --- /dev/null +++ b/usr/src/cmd/mdb/test/options/tst.autowrap.mdb.out @@ -0,0 +1,11 @@ +Pack my box with five dozen liquor jugs. How razorback-jumping frogs can level six piqued gymnasts! Amazingly few discotheques provide jukeboxes.0 +0 0 +0 0 +0 0 +Pack my box with five dozen liquor jugs. How razorback-jumping frogs can level s +ix piqued gymnasts! Amazingly few discotheques provide jukeboxes.0 +0 0 +0 +0 +0 +0 diff --git a/usr/src/cmd/mdb/test/typedef/tst.cleanupstruct.ksh b/usr/src/cmd/mdb/test/typedef/tst.cleanupstruct.ksh index 1abf7540ce..fabc7dfb57 100644 --- a/usr/src/cmd/mdb/test/typedef/tst.cleanupstruct.ksh +++ b/usr/src/cmd/mdb/test/typedef/tst.cleanupstruct.ksh @@ -5,7 +5,7 @@ # will fail validation. So here we go! # -TMPFILE="/tmp/$(mktemp mtest.XXXXXX)" +TMPFILE="$(mktemp -p /tmp mtest.XXXXXX)" if [[ -z "$TMPFILE" ]]; then echo "Failed to get a temp file" 2>&1 exit 1 diff --git a/usr/src/cmd/mdb/test/typedef/tst.dellist.mdb.out b/usr/src/cmd/mdb/test/typedef/tst.dellist.mdb.out new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/usr/src/cmd/mdb/test/typedef/tst.dellist.mdb.out diff --git a/usr/src/cmd/mdb/test/typedef/tst.emptylist.mdb.out b/usr/src/cmd/mdb/test/typedef/tst.emptylist.mdb.out new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/usr/src/cmd/mdb/test/typedef/tst.emptylist.mdb.out diff --git a/usr/src/cmd/nicstat/Makefile b/usr/src/cmd/nicstat/Makefile new file mode 100644 index 0000000000..935011119a --- /dev/null +++ b/usr/src/cmd/nicstat/Makefile @@ -0,0 +1,31 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013 Joyent, Inc. All rights reserved. +# + +PROG = nicstat + +include ../Makefile.cmd + +all: $(PROG) + +install: all .WAIT $(ROOTPROG) + +clean: + +$(ROOTBINPROG): $(PROG) + $(INS.file) + +lint: + +include ../Makefile.targ diff --git a/usr/src/cmd/nicstat/nicstat.pl b/usr/src/cmd/nicstat/nicstat.pl new file mode 100644 index 0000000000..fae4c797df --- /dev/null +++ b/usr/src/cmd/nicstat/nicstat.pl @@ -0,0 +1,424 @@ +#!/usr/perl5/bin/perl -w +# +# nicstat - print network traffic, Kbyte/s read and written. +# Solaris 8+, Perl (Sun::Solaris::Kstat). +# +# "netstat -i" only gives a packet count, this program gives Kbytes. +# +# 04-Apr-2011, ver 1.00J +# +# USAGE: nicstat [-hsz] [-i int[,int...]] | [interval [count]] +# +# -h # help +# -s # print summary output +# -z # skip zero lines +# -i int[,int...] # print these instances only +# eg, +# nicstat # print summary since boot +# nicstat 1 # print continually, every 1 second +# nicstat 1 5 # print 5 times, every 1 second +# nicstat -i hme0 # only examine hme0 +# +# This prints out the KB/s transferred for all the network cards (NICs), +# including packet counts and average sizes. The first line is the summary +# data since boot. +# +# FIELDS: +# Int Interface +# rKB/s read Kbytes/s +# wKB/s write Kbytes/s +# rPk/s read Packets/s +# wPk/s write Packets/s +# rAvs read Average size, bytes +# wAvs write Average size, bytes +# %Util %Utilisation (r or w/ifspeed) +# Sat Saturation (defer, nocanput, norecvbuf, noxmtbuf) +# +# NOTES: +# +# - Some unusual network cards may not provide all the details to Kstat, +# (or provide different symbols). Check for newer versions of this program, +# and the @Network array in the code below. +# - Utilisation is based on bytes transferred divided by speed of the interface +# (if the speed is known). It should be impossible to reach 100% as there +# are overheads due to bus negotiation and timing. +# - Loopback interfaces may only provide packet counts (if anything), and so +# bytes and %util will always be zero. Newer versions of Solaris (newer than +# Solaris 10 6/06) may provide loopback byte stats. +# - Saturation is determined by counting read and write errors caused by the +# interface running at saturation. This approach is not ideal, and the value +# reported is often lower than it should be (eg, 0.0). Reading the rKB/s and +# wKB/s fields may be more useful. +# +# SEE ALSO: +# nicstat.c # the C version, also on my website +# kstat -n hme0 [interval [count]] # or qfe0, ... +# netstat -iI hme0 [interval [count]] +# se netstat.se [interval] # SE Toolkit +# se nx.se [interval] # SE Toolkit +# +# COPYRIGHT: Copyright (c) 2013 Brendan Gregg. +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at docs/cddl1.txt or +# http://opensource.org/licenses/CDDL-1.0. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at docs/cddl1.txt. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2015 Joyent, Inc. All rights reserved. +# +# Author: Brendan Gregg [Sydney, Australia] +# +# 18-Jul-2004 Brendan Gregg Created this. +# 07-Jan-2005 " " added saturation value. +# 07-Jan-2005 " " added summary style (from Peter Tribble). +# 23-Jan-2006 " " Tweaked style. +# 11-Aug-2006 " " Improved output neatness. +# 30-Sep-2006 " " Added loopback, tweaked output. +# 04-Apr-2011 brendan@joyent.com Updated for smartmachines. + +use strict; +use Getopt::Std; +use Sun::Solaris::Kstat; +my $Kstat = Sun::Solaris::Kstat->new(); + + +# +# Process command line args +# +usage() if defined $ARGV[0] and $ARGV[0] eq "--help"; +getopts('hi:sz') or usage(); +usage() if defined $main::opt_h; +my $STYLE = defined $main::opt_s ? $main::opt_s : 0; +my $SKIPZERO = defined $main::opt_z ? $main::opt_z : 0; + +# process [interval [count]], +my ($interval, $loop_max); +if (defined $ARGV[0]) { + $interval = $ARGV[0]; + $loop_max = defined $ARGV[1] ? $ARGV[1] : 2**32; + usage() if $interval == 0; +} +else { + $interval = 1; + $loop_max = 1; +} + +# check for -i, +my %NetworkOnly; # network interfaces to print +my $NETWORKONLY = 0; # match on network interfaces +if (defined $main::opt_i) { + foreach my $net (split /,/, $main::opt_i) { + $NetworkOnly{$net} = 1; + } + $NETWORKONLY = 1; +} + +# globals, +my $loop = 0; # current loop number +my $PAGESIZE = 20; # max lines per header +my $line = $PAGESIZE; # counter for lines printed +my %NetworkNames; # Kstat network interfaces +my %NetworkData; # network interface data +my %NetworkDataOld; # network interface data +$main::opt_h = 0; +$| = 1; # autoflush + +# kstat "link" module includes: +my @Network = qw(dmfe bge be bnx ce eri eth external ge hme igb ige internal ixgbe le net ppp qfe rtls); +my %Network; +$Network{$_} = 1 foreach (@Network); +my $ZONENAME = `/usr/bin/zonename`; +chomp $ZONENAME; + +### Determine network interfaces +unless (find_nets()) { + if ($NETWORKONLY) { + print STDERR "ERROR1: $main::opt_i matched no network interfaces.\n"; + } + else { + print STDERR "ERROR1: No network interfaces found!\n"; + } + exit 1; +} + + +# +# Main +# +while (1) { + + ### Print Header + if ($line >= $PAGESIZE) { + if ($STYLE == 0) { + printf "%8s %12s %7s %7s %7s %7s %7s %7s %6s %5s\n", + "Time", "Int", "rKB/s", "wKB/s", "rPk/s", "wPk/s", "rAvs", + "wAvs", "%Util", "Sat"; + } + elsif ($STYLE == 1) { + printf "%8s %12s %14s %14s\n", "Time", "Int", "rKB/s", "wKB/s"; + } + + $line = 0; + } + + ### Get new data + my (@NetworkData) = fetch_net_data(); + + foreach my $network_data (@NetworkData) { + + ### Extract values + my ($int, $rbytes, $wbytes, $rpackets, $wpackets, $speed, $sat, $time) + = split /:/, $network_data; + + ### Retrieve old values + my ($old_rbytes, $old_wbytes, $old_rpackets, $old_wpackets, $old_sat, + $old_time); + if (defined $NetworkDataOld{$int}) { + ($old_rbytes, $old_wbytes, $old_rpackets, $old_wpackets, + $old_sat, $old_time) = split /:/, $NetworkDataOld{$int}; + } + else { + $old_rbytes = $old_wbytes = $old_rpackets = $old_wpackets + = $old_sat = $old_time = 0; + } + + # + # Calculate statistics + # + + # delta time + my $tdiff = $time - $old_time; + + # per second values + my $rbps = ($rbytes - $old_rbytes) / $tdiff; + my $wbps = ($wbytes - $old_wbytes) / $tdiff; + my $rkps = $rbps / 1024; + my $wkps = $wbps / 1024; + my $rpps = ($rpackets - $old_rpackets) / $tdiff; + my $wpps = ($wpackets - $old_wpackets) / $tdiff; + my $ravs = $rpps > 0 ? $rbps / $rpps : 0; + my $wavs = $wpps > 0 ? $wbps / $wpps : 0; + + # skip zero lines if asked + next if $SKIPZERO and ($rbps + $wbps) == 0; + + # % utilisation + my $util; + if ($speed > 0) { + # the following has a mysterious "800", it is 100 + # for the % conversion, and 8 for bytes2bits. + my $rutil = $rbps * 800 / $speed; + my $wutil = $wbps * 800 / $speed; + $util = $rutil > $wutil ? $rutil : $wutil; + $util = 100 if $util > 100; + } + else { + $util = 0; + } + + # saturation per sec + my $sats = ($sat - $old_sat) / $tdiff; + + # + # Print statistics + # + if ($rbps ne "") { + my @Time = localtime(); + + if ($STYLE == 0) { + printf "%02d:%02d:%02d %12s ", + $Time[2], $Time[1], $Time[0], $int; + print_neat($rkps); + print_neat($wkps); + print_neat($rpps); + print_neat($wpps); + print_neat($ravs); + print_neat($wavs); + printf "%6.2f %5.2f\n", $util, $sats; + } + elsif ($STYLE == 1) { + printf "%02d:%02d:%02d %12s %14.3f %14.3f\n", + $Time[2], $Time[1], $Time[0], $int, $rkps, $wkps; + } + + $line++; + + # for multiple interfaces, always print the header + $line += $PAGESIZE if @NetworkData > 1; + } + + ### Store old values + $NetworkDataOld{$int} + = "$rbytes:$wbytes:$rpackets:$wpackets:$sat:$time"; + } + + ### Check for end + last if ++$loop == $loop_max; + + ### Interval + sleep $interval; +} + + +# find_nets - walk Kstat to discover network interfaces. +# +# This walks %Kstat and populates a %NetworkNames with discovered +# network interfaces. +# +sub find_nets { + my $found = 0; + + ### Loop over all Kstat modules + foreach my $module (keys %$Kstat) { + my $Modules = $Kstat->{$module}; + + foreach my $instance (keys %$Modules) { + my $Instances = $Modules->{$instance}; + + foreach my $name (keys %$Instances) { + + ### Skip interface if asked + if ($NETWORKONLY) { + next unless $NetworkOnly{$name}; + } + + my $Names = $Instances->{$name}; + + # Check this is a network device. + # Matching on ifspeed has been more reliable than "class" + # we also match loopback and "link" interfaces. + if (defined $$Names{ifspeed} || $module eq "lo" + || $module eq "link") { + next if $name eq "mac"; + if ($module eq "link") { + my $nname = $name; + $nname =~ s/\d+$//; + next unless defined $Network{$nname} + or $ZONENAME eq $nname + or $ZONENAME eq "global"; + } + ### Save network interface + $NetworkNames{$name} = $Names; + $found++; + } + } + } + } + + return $found; +} + +# fetch - fetch Kstat data for the network interfaces. +# +# This uses the interfaces in %NetworkNames and returns useful Kstat data. +# The Kstat values used are rbytes64, obytes64, ipackets64, opackets64 +# (or the 32 bit versions if the 64 bit values are not there). +# +sub fetch_net_data { + my ($rbytes, $wbytes, $rpackets, $wpackets, $speed, $time); + my @NetworkData = (); + + $Kstat->update(); + + ### Loop over previously found network interfaces + foreach my $name (sort keys %NetworkNames) { + my $Names = $NetworkNames{$name}; + + if (defined $$Names{opackets}) { + + ### Fetch write bytes + if (defined $$Names{obytes64}) { + $rbytes = $$Names{rbytes64}; + $wbytes = $$Names{obytes64}; + } + elsif (defined $$Names{obytes}) { + $rbytes = $$Names{rbytes}; + $wbytes = $$Names{obytes}; + } else { + $rbytes = $wbytes = 0; + } + + ### Fetch read bytes + if (defined $$Names{opackets64}) { + $rpackets = $$Names{ipackets64}; + $wpackets = $$Names{opackets64}; + } + else { + $rpackets = $$Names{ipackets}; + $wpackets = $$Names{opackets}; + } + + ### Fetch interface speed + if (defined $$Names{ifspeed}) { + $speed = $$Names{ifspeed}; + } + else { + # if we can't fetch the speed, print the + # %Util as 0.0 . To do this we, + $speed = 2 ** 48; + } + + ### Determine saturation value + my $sat = 0; + if (defined $$Names{nocanput} or defined $$Names{norcvbuf}) { + $sat += defined $$Names{defer} ? $$Names{defer} : 0; + $sat += defined $$Names{nocanput} ? $$Names{nocanput} : 0; + $sat += defined $$Names{norcvbuf} ? $$Names{norcvbuf} : 0; + $sat += defined $$Names{noxmtbuf} ? $$Names{noxmtbuf} : 0; + } + + ### use the last snaptime value, + $time = $$Names{snaptime}; + + ### store data + push @NetworkData, "$name:$rbytes:$wbytes:" . + "$rpackets:$wpackets:$speed:$sat:$time"; + } + } + + return @NetworkData; +} + +# print_neat - print a float with decimal places if appropriate. +# +# This specifically keeps the width to 7 characters, if possible, plus +# a trailing space. +# +sub print_neat { + my $num = shift; + if ($num >= 100000) { + printf "%7d ", $num; + } elsif ($num >= 100) { + printf "%7.1f ", $num; + } else { + printf "%7.2f ", $num; + } +} + +# usage - print usage and exit. +# +sub usage { + print STDERR <<END; +USAGE: nicstat [-hsz] [-i int[,int...]] | [interval [count]] + eg, nicstat # print summary since boot + nicstat 1 # print continually every 1 second + nicstat 1 5 # print 5 times, every 1 second + nicstat -s # summary output + nicstat -i hme0 # print hme0 only +END + exit 1; +} diff --git a/usr/src/cmd/nscd/Makefile b/usr/src/cmd/nscd/Makefile index 12454b8db3..08eb99fb30 100644 --- a/usr/src/cmd/nscd/Makefile +++ b/usr/src/cmd/nscd/Makefile @@ -30,6 +30,7 @@ MANIFEST= name-service-cache.xml SVCMETHOD= svc-nscd include ../Makefile.cmd +include ../Makefile.ctf ROOTMANIFESTDIR= $(ROOTSVCSYSTEM) diff --git a/usr/src/cmd/passwd/Makefile b/usr/src/cmd/passwd/Makefile index 561357a16c..079e8b6050 100644 --- a/usr/src/cmd/passwd/Makefile +++ b/usr/src/cmd/passwd/Makefile @@ -33,6 +33,8 @@ lint := LDLIBS += -lpasswdutil LDFLAGS += $(ZIGNORE) LDLIBS += -lbsm -lpam -lnsl +CPPFLAGS += -D__EXTENSIONS__ + FILEMODE = 06555 XGETFLAGS += -a -x $(PROG).xcl diff --git a/usr/src/cmd/pgrep/pgrep.c b/usr/src/cmd/pgrep/pgrep.c index 4531f11267..857f6ef818 100644 --- a/usr/src/cmd/pgrep/pgrep.c +++ b/usr/src/cmd/pgrep/pgrep.c @@ -597,6 +597,8 @@ main(int argc, char *argv[]) const char *optstr; optdesc_t *optd; int nmatches, c; + const char *zroot; + char buf[PATH_MAX]; DIR *dirp; @@ -626,6 +628,12 @@ main(int argc, char *argv[]) opterr = 0; + zroot = zone_get_nroot(); + if (zroot != NULL) { + (void) snprintf(buf, sizeof (buf), "%s/%s", zroot, g_procdir); + g_procdir = buf; + } + while (optind < argc) { while ((c = getopt(argc, argv, optstr)) != (int)EOF) { diff --git a/usr/src/cmd/pptadm/Makefile b/usr/src/cmd/pptadm/Makefile new file mode 100644 index 0000000000..3be558a7a0 --- /dev/null +++ b/usr/src/cmd/pptadm/Makefile @@ -0,0 +1,43 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# +# Copyright 2018 Joyent, Inc. +# + +PROG = pptadm +OBJS = pptadm.o +SRCS = $(OBJS:%.o=%.c) + +include ../Makefile.cmd +include ../Makefile.ctf + +LDLIBS += -lofmt -lppt -lnvpair + +CSTD = $(CSTD_GNU99) +C99LMODE = -Xc99=%all + +CLEANFILES += $(OBJS) + +.KEEP_STATE: + +all: $(OBJS) $(PROG) + +install: all $(ROOTUSRSBINPROG) + +clean: + -$(RM) $(CLEANFILES) + +lint: lint_SRCS + +%.o: ../%.c + $(COMPILE.c) $< + $(POST_PROCESS_O) + +include ../Makefile.targ diff --git a/usr/src/cmd/pptadm/pptadm.c b/usr/src/cmd/pptadm/pptadm.c new file mode 100644 index 0000000000..c6b9094408 --- /dev/null +++ b/usr/src/cmd/pptadm/pptadm.c @@ -0,0 +1,205 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2018 Joyent, Inc. + */ + +#include <stdlib.h> +#include <stdarg.h> +#include <getopt.h> +#include <string.h> +#include <ofmt.h> +#include <err.h> + +#include <libppt.h> + +typedef enum field { + PPT_DEV, + PPT_VENDOR, + PPT_DEVICE, + PPT_SUBVENDOR, + PPT_SUBDEVICE, + PPT_REV, + PPT_PATH, + PPT_LABEL +} field_t; + +const char *valname[] = { + "dev", + "vendor-id", + "device-id", + "subsystem-vendor-id", + "subsystem-id", + "revision-id", + "path", + "label" +}; + +static ofmt_cb_t print_field; + +static ofmt_field_t fields[] = { +/* name, field width, index, callback */ +{ "DEV", sizeof ("/dev/pptXX"), PPT_DEV, print_field }, +{ "VENDOR", sizeof ("VENDOR"), PPT_VENDOR, print_field }, +{ "DEVICE", sizeof ("DEVICE"), PPT_DEVICE, print_field }, +{ "SUBVENDOR", sizeof ("SUBVENDOR"), PPT_SUBVENDOR, print_field }, +{ "SUBDEVICE", sizeof ("SUBDEVICE"), PPT_SUBDEVICE, print_field }, +{ "REV", sizeof ("REV"), PPT_REV, print_field }, +{ "PATH", 50, PPT_PATH, print_field }, +{ "LABEL", 60, PPT_LABEL, print_field }, +{ NULL, 0, 0, NULL }, +}; + +static void +usage(const char *errmsg) +{ + if (errmsg != NULL) + (void) fprintf(stderr, "pptadm: %s\n", errmsg); + (void) fprintf(errmsg != NULL ? stderr : stdout, + "Usage:\n" + "pptadm list [ -j ]\n" + "pptadm list [-ap] [-o fields]\n"); + exit(errmsg != NULL ? EXIT_FAILURE : EXIT_SUCCESS); +} + +/* PRINTFLIKE1 */ +static void +die(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrx(EXIT_FAILURE, fmt, ap); + va_end(ap); +} + +static boolean_t +print_field(ofmt_arg_t *arg, char *buf, uint_t bufsize) +{ + nvlist_t *nvl = arg->ofmt_cbarg; + nvpair_t *nvp = NULL; + + while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { + const char *name = nvpair_name(nvp); + char *val = NULL; + + (void) nvpair_value_string(nvp, &val); + + if (strcmp(name, valname[arg->ofmt_id]) != 0) + continue; + + (void) snprintf(buf, bufsize, "%s", val); + return (B_TRUE); + } + + (void) snprintf(buf, bufsize, "--"); + return (B_TRUE); +} + +static int +list(int argc, char *argv[]) +{ + const char *fields_str = NULL; + boolean_t parsable = B_FALSE; + boolean_t json = B_FALSE; + boolean_t all = B_FALSE; + uint_t ofmtflags = 0; + ofmt_status_t oferr; + ofmt_handle_t ofmt; + int opt; + + while ((opt = getopt(argc, argv, "ahjo:p")) != -1) { + switch (opt) { + case 'a': + all = B_TRUE; + break; + case 'h': + usage(NULL); + break; + case 'j': + json = B_TRUE; + break; + case 'o': + fields_str = optarg; + break; + case 'p': + ofmtflags |= OFMT_PARSABLE; + parsable = B_TRUE; + break; + default: + usage("unrecognized option"); + break; + } + } + + if (optind == (argc - 1)) + usage("unused arguments"); + + if (json && (parsable || fields_str != NULL)) + usage("-j option cannot be used with -p or -o options"); + + if (fields_str == NULL) { + if (parsable) + usage("-o must be provided when using -p option"); + fields_str = "dev,vendor,device,path"; + } + + oferr = ofmt_open(fields_str, fields, ofmtflags, 0, &ofmt); + + ofmt_check(oferr, parsable, ofmt, die, warn); + + nvlist_t *nvl = all ? ppt_list() : ppt_list_assigned(); + nvpair_t *nvp = NULL; + + if (json) { + if (printf("{\n\t\"devices\": [\n") < 0) + err(EXIT_FAILURE, "failed to write JSON"); + } + + while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) { + nvlist_t *props; + + (void) nvpair_value_nvlist(nvp, &props); + + if (json) { + if (printf("\t\t") < 0) + err(EXIT_FAILURE, "failed to write JSON"); + if (nvlist_print_json(stdout, props) < 0) + err(EXIT_FAILURE, "failed to write JSON"); + if (nvlist_next_nvpair(nvl, nvp) != NULL) + (void) printf(",\n"); + } else { + ofmt_print(ofmt, props); + } + } + + if (json) { + if (printf("\n\t]\n}\n") < 0) + err(EXIT_FAILURE, "failed to write JSON"); + } + + nvlist_free(nvl); + ofmt_close(ofmt); + return (EXIT_SUCCESS); +} + +int +main(int argc, char *argv[]) +{ + if (argc == 1) + return (list(argc - 1, argv)); + + if (strcmp(argv[1], "list") == 0) { + return (list(argc - 1, &argv[1])); + } else { + usage("unknown sub-command"); + } + + return (EXIT_SUCCESS); +} diff --git a/usr/src/cmd/prstat/prstat.c b/usr/src/cmd/prstat/prstat.c index 0ff4f51bcd..f40219d75a 100644 --- a/usr/src/cmd/prstat/prstat.c +++ b/usr/src/cmd/prstat/prstat.c @@ -182,6 +182,33 @@ optdesc_t opts = { -1 /* sort in decreasing order */ }; + +static int +proc_snprintf(char *_RESTRICT_KYWD s, size_t n, + const char *_RESTRICT_KYWD fmt, ...) +{ + static boolean_t ptools_zroot_valid = B_FALSE; + static const char *ptools_zroot = NULL; + va_list args; + int ret, nret = 0; + + if (ptools_zroot_valid == B_FALSE) { + ptools_zroot_valid = B_TRUE; + ptools_zroot = zone_get_nroot(); + } + + if (ptools_zroot != NULL) { + nret = snprintf(s, n, "%s", ptools_zroot); + if (nret > n) + return (nret); + } + va_start(args, fmt); + ret = vsnprintf(s + nret, n - nret, fmt, args); + va_end(args); + + return (ret + nret); +} + /* * Print timestamp as decimal reprentation of time_t value (-d u was specified) * or the standard date format (-d d was specified). @@ -849,9 +876,9 @@ lwp_update(lwp_info_t *lwp, pid_t pid, id_t lwpid, struct prusage *usage) static int read_procfile(fd_t **fd, char *pidstr, char *file, void *buf, size_t bufsize) { - char procfile[MAX_PROCFS_PATH]; + char procfile[PATH_MAX]; - (void) snprintf(procfile, MAX_PROCFS_PATH, + (void) proc_snprintf(procfile, PATH_MAX, "/proc/%s/%s", pidstr, file); if ((*fd = fd_open(procfile, O_RDONLY, *fd)) == NULL) return (1); @@ -1415,6 +1442,7 @@ main(int argc, char **argv) int timeout; struct pollfd pollset; char key; + char procpath[PATH_MAX]; (void) setlocale(LC_ALL, ""); (void) textdomain(TEXT_DOMAIN); @@ -1425,7 +1453,7 @@ main(int argc, char **argv) pagesize = sysconf(_SC_PAGESIZE); while ((opt = getopt(argc, argv, - "vcd:HmarRLtu:U:n:p:C:P:h:s:S:j:k:TJWz:Z")) != (int)EOF) { + "vVcd:HmarRLtu:U:n:p:C:P:h:s:S:j:k:TJWz:Z")) != (int)EOF) { switch (opt) { case 'r': opts.o_outpmode |= OPT_NORESOLVE; @@ -1505,6 +1533,9 @@ main(int argc, char **argv) while (p = strtok(NULL, ", ")) add_uid(&ruid_tbl, p); break; + case 'V': + /* obsolete argument - accepted for compatability */ + break; case 'p': fill_table(&pid_tbl, optarg, 'p'); break; @@ -1614,7 +1645,8 @@ main(int argc, char **argv) list_setkeyfunc(NULL, &opts, &lgroups, LT_LGRPS); if (opts.o_outpmode & OPT_TERMCAP) curses_on(); - if ((procdir = opendir("/proc")) == NULL) + (void) proc_snprintf(procpath, sizeof (procpath), "/proc"); + if ((procdir = opendir(procpath)) == NULL) Die(gettext("cannot open /proc directory\n")); if (opts.o_outpmode & OPT_TTY) { (void) printf(gettext("Please wait...\r")); diff --git a/usr/src/cmd/prstat/prstat.h b/usr/src/cmd/prstat/prstat.h index e205a98bd2..7d3913f731 100644 --- a/usr/src/cmd/prstat/prstat.h +++ b/usr/src/cmd/prstat/prstat.h @@ -73,6 +73,7 @@ extern "C" { #define OPT_ZONES 0x2000 /* report about zones */ #define OPT_PSETS 0x4000 /* report for specified psets */ #define OPT_LGRP 0x8000 /* report home lgroups */ + /* 0x10000 available for re-use */ #define OPT_UDATE 0x20000 /* print unix timestamp */ #define OPT_DDATE 0x40000 /* print timestamp in date(1) format */ #define OPT_NORESOLVE 0x80000 /* no nsswitch lookups */ diff --git a/usr/src/cmd/prtconf/prtconf.c b/usr/src/cmd/prtconf/prtconf.c index 9865a9190e..613fcea78c 100644 --- a/usr/src/cmd/prtconf/prtconf.c +++ b/usr/src/cmd/prtconf/prtconf.c @@ -344,10 +344,11 @@ main(int argc, char *argv[]) sizeof (hw_provider)); /* * If 0 bytes are returned (the system returns '1', for the \0), - * we're probably on x86, default to "Unknown Hardware Vendor". + * we're probably on x86, and there has been no si-hw-provider + * set in /etc/bootrc, default to Joyent. */ if (ret <= 1) { - (void) strncpy(hw_provider, "Unknown Hardware Vendor", + (void) strncpy(hw_provider, "Joyent", sizeof (hw_provider)); } (void) printf("System Configuration: %s %s\n", hw_provider, diff --git a/usr/src/cmd/ps/ps.c b/usr/src/cmd/ps/ps.c index 1a3e91689a..6a01543b00 100644 --- a/usr/src/cmd/ps/ps.c +++ b/usr/src/cmd/ps/ps.c @@ -288,7 +288,7 @@ static int nzoneid = 0; static int kbytes_per_page; static int pidwidth; -static char *procdir = "/proc"; /* standard /proc directory */ +static char procdir[MAXPATHLEN]; /* standard /proc directory */ static struct ughead euid_tbl; /* table to store selected euid's */ static struct ughead ruid_tbl; /* table to store selected real uid's */ @@ -341,6 +341,14 @@ int main(int argc, char **argv) { const char *me; + const char *zroot = zone_get_nroot(); + + /* + * If this is a branded zone, the native procfs may mounted in a + * non-standard location. Apply such a path prefix if it exists. + */ + (void) snprintf(procdir, sizeof (procdir), "%s/proc", zroot != NULL ? + zroot : ""); /* * The original two ps'es are linked in a single binary; diff --git a/usr/src/cmd/ptools/Makefile.amd64 b/usr/src/cmd/ptools/Makefile.amd64 index fb0b2d07f8..5e9b4111b6 100644 --- a/usr/src/cmd/ptools/Makefile.amd64 +++ b/usr/src/cmd/ptools/Makefile.amd64 @@ -23,8 +23,6 @@ # Copyright 2004 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# include ../../../Makefile.cmd include ../../../Makefile.cmd.64 @@ -33,6 +31,7 @@ CPPFLAGS += -D_SYSCALL32 CFLAGS64 += $(CCVERBOSE) ROOTISAPROG=$(ROOTBIN64)/$(PROG) +ROOTISALN=$(LN_$(PROG):%=$(ROOTBIN64)/%) include ../../Makefile.bld diff --git a/usr/src/cmd/ptools/Makefile.bld b/usr/src/cmd/ptools/Makefile.bld index 56fb9ca118..d18df19483 100644 --- a/usr/src/cmd/ptools/Makefile.bld +++ b/usr/src/cmd/ptools/Makefile.bld @@ -22,11 +22,14 @@ # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2015 Joyent, Inc. # # Copyright (c) 2018, Joyent, Inc. PROG:sh = basename `cd ..; pwd` +include ../../../Makefile.ctf + OBJS = $(PROG).o SRCS = ../$(PROG).c @@ -77,6 +80,12 @@ CERRWARN_pwait += -_smatch=off CERRWARN += $(CERRWARN_$(PROG)) +# +# Common code definitions +# +COBJS = ptools_common.o +CINC = -I../../common + # pargs depends on ../../common/elfcap components # pmadvise depends on pmap components @@ -87,14 +96,34 @@ CPPFLAGS_pargs = -I$(ELFCAP) OBJS_pargs = elfcap.o SRCS_pargs = $(ELFCAP)/elfcap.c -CPPFLAGS_pmap = -I$(PMAP) -OBJS_pmap = pmap_common.o +CPPFLAGS_pmap = -I$(PMAP) $(CINC) +OBJS_pmap = pmap_common.o $(COBJS) SRCS_pmap = $(PMAP)/pmap_common.c -CPPFLAGS_pmadvise = -I$(PMAP) -OBJS_pmadvise = pmap_common.o +CPPFLAGS_pmadvise = -I$(PMAP) $(CINC) +OBJS_pmadvise = pmap_common.o $(COBJS) SRCS_pmadvise = $(PMAP)/pmap_common.c +CPPFLAGS_preap = $(CINC) +OBJS_preap = $(COBJS) + +CPPFLAGS_psig = $(CINC) +OBJS_psig = $(COBJS) + +CPPFLAGS_ptime = $(CINC) +OBJS_ptime = $(COBJS) + +CPPFLAGS_ptree = $(CINC) +OBJS_ptree = $(COBJS) + +CPPFLAGS_pwait = $(CINC) +OBJS_pwait = $(COBJS) + +CPPFLAGS_pwdx = $(CINC) +OBJS_pwdx = $(COBJS) + +LN_pargs = penv pauxv + CPPFLAGS += $(CPPFLAGS_$(PROG)) OBJS += $(OBJS_$(PROG)) SRCS += $(SRCS_$(PROG)) @@ -107,15 +136,23 @@ INSTALL_LEGACY=$(RM) $(ROOTPROCBINSYMLINK) ; \ elfcap.o: $(ELFCAP)/elfcap.c $(COMPILE.c) -o $@ $(ELFCAP)/elfcap.c + $(POST_PROCESS_O) pmap_common.o: $(PMAP)/pmap_common.c $(COMPILE.c) -o $@ $(PMAP)/pmap_common.c + $(POST_PROCESS_O) %.o: ../%.c $(COMPILE.c) $< + $(POST_PROCESS_O) + +%.o: ../../common/%.c + $(COMPILE.c) $< + $(POST_PROCESS_O) -all: $(PROG) +all: $(PROG) $(LN_$(PROG)) +ROOTBINLN=$(LN_$(PROG):%=$(ROOTBIN)/%) ROOTBINPROG=$(ROOTBIN)/$(PROG) ROOTPROCBINSYMLINK=$(ROOT)/usr/proc/bin/$(PROG) @@ -127,11 +164,23 @@ $(PROG): $$(OBJS) # Install the ptool, symlinking it into /usr/proc/bin if PTOOL_TYPE is set # to LEGACY. # -install: all $(ROOTISAPROG) +install: all $(ROOTISAPROG) $(ROOTISALN) -$(RM) $(ROOTBINPROG) -$(LN) $(ISAEXEC) $(ROOTBINPROG) -$(INSTALL_$(PTOOL_TYPE)) +$(ROOTBINLN): + -$(RM) $@ + -$(LN) $(ISAEXEC) $@ + +$(ROOTISALN): $(ROOTISAPROG) + -$(RM) $@ + -$(LN) $(ROOTISAPROG) $@ + +$(LN_$(PROG)): $(PROG) + -$(RM) $@ + -$(LN) $(PROG) $@ + clean: $(RM) $(OBJS) diff --git a/usr/src/cmd/ptools/Makefile.i386 b/usr/src/cmd/ptools/Makefile.i386 index 59f42e19a0..9f4ea86151 100644 --- a/usr/src/cmd/ptools/Makefile.i386 +++ b/usr/src/cmd/ptools/Makefile.i386 @@ -20,8 +20,6 @@ # CDDL HEADER END # # -#ident "%Z%%M% %I% %E% SMI" -# # Copyright 2004 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # @@ -31,6 +29,7 @@ include ../../../Makefile.cmd CFLAGS += $(CCVERBOSE) ROOTISAPROG=$(ROOTBIN32)/$(PROG) +ROOTISALN=$(LN_$(PROG):%=$(ROOTBIN32)/%) include ../../Makefile.bld diff --git a/usr/src/cmd/ptools/Makefile.ptool b/usr/src/cmd/ptools/Makefile.ptool index c010eee64f..6a4cdcaa8e 100644 --- a/usr/src/cmd/ptools/Makefile.ptool +++ b/usr/src/cmd/ptools/Makefile.ptool @@ -20,8 +20,6 @@ # CDDL HEADER END # # -#ident "%Z%%M% %I% %E% SMI" -# # Copyright 2003 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # diff --git a/usr/src/cmd/ptools/Makefile.sparcv9 b/usr/src/cmd/ptools/Makefile.sparcv9 index fb0b2d07f8..5e9b4111b6 100644 --- a/usr/src/cmd/ptools/Makefile.sparcv9 +++ b/usr/src/cmd/ptools/Makefile.sparcv9 @@ -23,8 +23,6 @@ # Copyright 2004 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# include ../../../Makefile.cmd include ../../../Makefile.cmd.64 @@ -33,6 +31,7 @@ CPPFLAGS += -D_SYSCALL32 CFLAGS64 += $(CCVERBOSE) ROOTISAPROG=$(ROOTBIN64)/$(PROG) +ROOTISALN=$(LN_$(PROG):%=$(ROOTBIN64)/%) include ../../Makefile.bld diff --git a/usr/src/cmd/ptools/common/ptools_common.c b/usr/src/cmd/ptools/common/ptools_common.c new file mode 100644 index 0000000000..a747ab213e --- /dev/null +++ b/usr/src/cmd/ptools/common/ptools_common.c @@ -0,0 +1,50 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +#include <sys/feature_tests.h> +#include <stdio.h> +#include <stdarg.h> +#include <sys/types.h> +#include <zone.h> + +/* + * Common routines for ptools. + */ + +int +proc_snprintf(char *_RESTRICT_KYWD s, size_t n, + const char *_RESTRICT_KYWD fmt, ...) +{ + static boolean_t ptools_zroot_valid = B_FALSE; + static const char *ptools_zroot = NULL; + va_list args; + int ret, nret = 0; + + if (ptools_zroot_valid == B_FALSE) { + ptools_zroot_valid = B_TRUE; + ptools_zroot = zone_get_nroot(); + } + + if (ptools_zroot != NULL) { + nret = snprintf(s, n, "%s", ptools_zroot); + if (nret > n) + return (nret); + } + va_start(args, fmt); + ret = vsnprintf(s + nret, n - nret, fmt, args); + va_end(args); + + return (ret + nret); +} diff --git a/usr/src/cmd/ptools/common/ptools_common.h b/usr/src/cmd/ptools/common/ptools_common.h new file mode 100644 index 0000000000..52bcae9e51 --- /dev/null +++ b/usr/src/cmd/ptools/common/ptools_common.h @@ -0,0 +1,36 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +#ifndef _PTOOLS_COMMON_H +#define _PTOOLS_COMMON_H + +#include <sys/feature_tests.h> + +/* + * Common functions for the ptools. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int proc_snprintf(char *_RESTRICT_KYWD, size_t, + const char *_RESTRICT_KYWD, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* _PTOOLS_COMMON_H */ diff --git a/usr/src/cmd/ptools/pargs/pargs.c b/usr/src/cmd/ptools/pargs/pargs.c index aa7b74dce9..a96018c031 100644 --- a/usr/src/cmd/ptools/pargs/pargs.c +++ b/usr/src/cmd/ptools/pargs/pargs.c @@ -73,6 +73,13 @@ #include <wctype.h> #include <widec.h> #include <elfcap.h> +#include <libgen.h> + +typedef enum pargs_cmd { + PARGS_ARGV, + PARGS_ENV, + PARGS_AUXV +} pargs_cmd_t; typedef struct pargs_data { struct ps_prochandle *pd_proc; /* target proc handle */ @@ -815,6 +822,7 @@ static struct aux_id aux_arr[] = { { AT_BASE, "AT_BASE", at_null }, { AT_FLAGS, "AT_FLAGS", at_null }, { AT_ENTRY, "AT_ENTRY", at_null }, + { AT_RANDOM, "AT_RANDOM", at_null }, { AT_SUN_UID, "AT_SUN_UID", at_uid }, { AT_SUN_RUID, "AT_SUN_RUID", at_uid }, { AT_SUN_GID, "AT_SUN_GID", at_gid }, @@ -834,9 +842,11 @@ static struct aux_id aux_arr[] = { { AT_SUN_AUXFLAGS, "AT_SUN_AUXFLAGS", at_flags }, { AT_SUN_EMULATOR, "AT_SUN_EMULATOR", at_str }, { AT_SUN_BRANDNAME, "AT_SUN_BRANDNAME", at_str }, + { AT_SUN_BRAND_NROOT, "AT_SUN_BRAND_NROOT", at_str }, { AT_SUN_BRAND_AUX1, "AT_SUN_BRAND_AUX1", at_null }, { AT_SUN_BRAND_AUX2, "AT_SUN_BRAND_AUX2", at_null }, { AT_SUN_BRAND_AUX3, "AT_SUN_BRAND_AUX3", at_null }, + { AT_SUN_BRAND_AUX4, "AT_SUN_BRAND_AUX4", at_null }, { AT_SUN_COMMPAGE, "AT_SUN_COMMPAGE", at_null }, { AT_SUN_FPTYPE, "AT_SUN_FPTYPE", at_null }, { AT_SUN_FPSIZE, "AT_SUN_FPSIZE", at_null } @@ -1288,19 +1298,24 @@ main(int argc, char *argv[]) int opt; int error = 1; core_content_t content = 0; + pargs_cmd_t cmd = PARGS_ARGV; (void) setlocale(LC_ALL, ""); - if ((command = strrchr(argv[0], '/')) != NULL) - command++; - else - command = argv[0]; + command = basename(argv[0]); + + if (strcmp(command, "penv") == 0) + cmd = PARGS_ENV; + else if (strcmp(command, "pauxv") == 0) + cmd = PARGS_AUXV; while ((opt = getopt(argc, argv, "acelxF")) != EOF) { switch (opt) { case 'a': /* show process arguments */ content |= CC_CONTENT_STACK; aflag++; + if (cmd != PARGS_ARGV) + errflg++; break; case 'c': /* force 7-bit ascii */ cflag++; @@ -1308,13 +1323,19 @@ main(int argc, char *argv[]) case 'e': /* show environment variables */ content |= CC_CONTENT_STACK; eflag++; + if (cmd != PARGS_ARGV) + errflg++; break; case 'l': lflag++; aflag++; /* -l implies -a */ + if (cmd != PARGS_ARGV) + errflg++; break; case 'x': /* show aux vector entries */ xflag++; + if (cmd != PARGS_ARGV) + errflg++; break; case 'F': /* @@ -1331,8 +1352,19 @@ main(int argc, char *argv[]) /* -a is the default if no options are specified */ if ((aflag + eflag + xflag + lflag) == 0) { - aflag++; - content |= CC_CONTENT_STACK; + switch (cmd) { + case PARGS_ARGV: + aflag++; + content |= CC_CONTENT_STACK; + break; + case PARGS_ENV: + content |= CC_CONTENT_STACK; + eflag++; + break; + case PARGS_AUXV: + xflag++; + break; + } } /* -l cannot be used with the -x or -e flags */ diff --git a/usr/src/cmd/ptools/pfiles/pfiles.c b/usr/src/cmd/ptools/pfiles/pfiles.c index d7142809f7..9f53ca4799 100644 --- a/usr/src/cmd/ptools/pfiles/pfiles.c +++ b/usr/src/cmd/ptools/pfiles/pfiles.c @@ -559,6 +559,7 @@ show_sockaddr(const char *str, struct sockaddr *sa, socklen_t len) case AF_KEY: p = "AF_KEY"; break; case AF_POLICY: p = "AF_POLICY"; break; case AF_LINK: p = "AF_LINK"; break; + case AF_LX_NETLINK: p = "AF_LX_NETLINK"; break; } (void) printf("\t%s: %s\n", str, p); diff --git a/usr/src/cmd/ptools/pflags/pflags.c b/usr/src/cmd/ptools/pflags/pflags.c index 8054a80d3c..f19a945d95 100644 --- a/usr/src/cmd/ptools/pflags/pflags.c +++ b/usr/src/cmd/ptools/pflags/pflags.c @@ -25,7 +25,7 @@ */ /* - * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright 2015, Joyent, Inc. */ #include <stdio.h> @@ -469,6 +469,9 @@ prwhy(int why) case PR_SUSPENDED: str = "PR_SUSPENDED"; break; + case PR_BRAND: + str = "PR_BRAND"; + break; default: str = buf; (void) sprintf(str, "%d", why); diff --git a/usr/src/cmd/ptools/pmap/pmap.c b/usr/src/cmd/ptools/pmap/pmap.c index 78bfa6b596..03f8bde791 100644 --- a/usr/src/cmd/ptools/pmap/pmap.c +++ b/usr/src/cmd/ptools/pmap/pmap.c @@ -22,6 +22,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ #include <stdio.h> @@ -42,6 +43,7 @@ #include <sys/mman.h> #include <sys/lgrp_user.h> #include <libproc.h> +#include "ptools_common.h" #include "pmap_common.h" @@ -199,7 +201,7 @@ main(int argc, char **argv) const char *bar; struct rlimit rlim; struct stat64 statbuf; - char buf[128]; + char buf[PATH_MAX]; int mapfd; int prg_gflags = PGRAB_RDONLY; int prr_flags = 0; @@ -358,7 +360,7 @@ main(int argc, char **argv) proc_unctrl_psinfo(&psinfo); if (Pstate(Pr) != PS_DEAD) { - (void) snprintf(buf, sizeof (buf), + (void) proc_snprintf(buf, sizeof (buf), "/proc/%d/map", (int)psinfo.pr_pid); if ((mapfd = open(buf, O_RDONLY)) < 0) { (void) fprintf(stderr, "%s: cannot " @@ -590,7 +592,7 @@ rmapping_iter(struct ps_prochandle *Pr, proc_map_f *func, void *cd) prmap_t *prmapp, *pmp; ssize_t n; - (void) snprintf(mapname, sizeof (mapname), + (void) proc_snprintf(mapname, sizeof (mapname), "/proc/%d/rmap", (int)Pstatus(Pr)->pr_pid); if ((mapfd = open(mapname, O_RDONLY)) < 0 || fstat(mapfd, &st) != 0) { @@ -631,7 +633,7 @@ xmapping_iter(struct ps_prochandle *Pr, proc_xmap_f *func, void *cd, int doswap) prxmap_t *prmapp, *pmp; ssize_t n; - (void) snprintf(mapname, sizeof (mapname), + (void) proc_snprintf(mapname, sizeof (mapname), "/proc/%d/xmap", (int)Pstatus(Pr)->pr_pid); if ((mapfd = open(mapname, O_RDONLY)) < 0 || fstat(mapfd, &st) != 0) { diff --git a/usr/src/cmd/ptools/pmap/pmap_common.c b/usr/src/cmd/ptools/pmap/pmap_common.c index fff55ffdbc..81f42d67f7 100644 --- a/usr/src/cmd/ptools/pmap/pmap_common.c +++ b/usr/src/cmd/ptools/pmap/pmap_common.c @@ -37,6 +37,7 @@ #include <sys/types.h> #include "pmap_common.h" +#include "ptools_common.h" /* * We compare the high memory addresses since stacks are faulted in from @@ -88,7 +89,7 @@ make_name(struct ps_prochandle *Pr, int lflag, uintptr_t addr, return (NULL); /* first see if we can find a path via /proc */ - (void) snprintf(path, sizeof (path), "/proc/%d/path/%s", + (void) proc_snprintf(path, sizeof (path), "/proc/%d/path/%s", (int)Psp->pr_pid, mapname); len = readlink(path, buf, bufsz - 1); if (len >= 0) { @@ -97,7 +98,7 @@ make_name(struct ps_prochandle *Pr, int lflag, uintptr_t addr, } /* fall back to object information reported by /proc */ - (void) snprintf(path, sizeof (path), + (void) proc_snprintf(path, sizeof (path), "/proc/%d/object/%s", (int)Psp->pr_pid, mapname); if (stat(path, &statb) == 0) { dev_t dev = statb.st_dev; diff --git a/usr/src/cmd/ptools/preap/preap.c b/usr/src/cmd/ptools/preap/preap.c index 8d30b8027c..6d8eb75611 100644 --- a/usr/src/cmd/ptools/preap/preap.c +++ b/usr/src/cmd/ptools/preap/preap.c @@ -24,8 +24,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -37,6 +35,8 @@ #include <sys/types.h> #include <sys/wait.h> #include <libproc.h> +#include <limits.h> +#include "ptools_common.h" #define NOREAP_TIME 60 /* wait 60 seconds before allow a reap */ @@ -53,11 +53,11 @@ intr(int sig) static int open_usage(pid_t pid, int *perr) { - char path[64]; + char path[PATH_MAX]; struct stat64 st; int fd; - (void) snprintf(path, sizeof (path), "/proc/%d/usage", (int)pid); + (void) proc_snprintf(path, sizeof (path), "/proc/%d/usage", (int)pid); /* * Attempt to open the usage file, and return the fd if we can diff --git a/usr/src/cmd/ptools/psig/psig.c b/usr/src/cmd/ptools/psig/psig.c index 70af35cb5e..848fda834c 100644 --- a/usr/src/cmd/ptools/psig/psig.c +++ b/usr/src/cmd/ptools/psig/psig.c @@ -21,10 +21,9 @@ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdio_ext.h> #include <stdlib.h> @@ -37,6 +36,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <libproc.h> +#include "ptools_common.h" /* evil knowledge of libc internals */ #include "../../../lib/libc/inc/thr_uberdata.h" @@ -172,7 +172,7 @@ lwp_iter(void *cd, const lwpstatus_t *lwpstatus) static int look(char *arg) { - char pathname[100]; + char pathname[PATH_MAX]; struct stat statb; int fd = -1; int sig, gcode; @@ -199,7 +199,8 @@ look(char *arg) (void) memcpy(&psinfo, psinfop, sizeof (psinfo_t)); proc_unctrl_psinfo(&psinfo); - (void) sprintf(pathname, "/proc/%d/sigact", (int)psinfo.pr_pid); + (void) proc_snprintf(pathname, sizeof (pathname), "/proc/%d/sigact", + (int)psinfo.pr_pid); if ((fd = open(pathname, O_RDONLY)) < 0) { perr("open sigact"); goto look_error; @@ -213,8 +214,8 @@ look(char *arg) action = malloc(maxsig * sizeof (struct sigaction)); if (action == NULL) { (void) fprintf(stderr, - "%s: cannot malloc() space for %d sigaction structures\n", - command, maxsig); + "%s: cannot malloc() space for %d sigaction structures\n", + command, maxsig); goto look_error; } if (read(fd, (char *)action, maxsig * sizeof (struct sigaction)) != @@ -239,7 +240,7 @@ look(char *arg) if (psinfo.pr_dmodel != PR_MODEL_NATIVE) { caddr32_t addr; aharraddr = uberaddr + - offsetof(uberdata32_t, siguaction); + offsetof(uberdata32_t, siguaction); aharrlen = sizeof (siguaction32_t) * NSIG; (void) Pread(Pr, &addr, sizeof (addr), uberaddr + offsetof(uberdata32_t, sigacthandler)); @@ -248,7 +249,7 @@ look(char *arg) #endif { aharraddr = uberaddr + - offsetof(uberdata_t, siguaction); + offsetof(uberdata_t, siguaction); aharrlen = sizeof (siguaction_t) * NSIG; (void) Pread(Pr, &intfnaddr, sizeof (intfnaddr), uberaddr + offsetof(uberdata_t, sigacthandler)); @@ -323,7 +324,7 @@ look(char *arg) (void) printf("\t%-8s", hname); else (void) printf("\t0x%-8lx", - (ulong_t)haddr); + (ulong_t)haddr); s = sigflags(sig, sp->sa_flags); (void) printf("%s", (*s != '\0')? s : "\t0"); @@ -334,7 +335,7 @@ look(char *arg) } } else if (sig == SIGCLD) { s = sigflags(sig, - sp->sa_flags & (SA_NOCLDWAIT|SA_NOCLDSTOP)); + sp->sa_flags & (SA_NOCLDWAIT|SA_NOCLDSTOP)); if (*s != '\0') (void) printf("\t\t%s", s); } @@ -371,7 +372,7 @@ sigflags(int sig, int flags) static char code_buf[100]; char *str = code_buf; int flagmask = - (SA_ONSTACK|SA_RESETHAND|SA_RESTART|SA_SIGINFO|SA_NODEFER); + (SA_ONSTACK|SA_RESETHAND|SA_RESTART|SA_SIGINFO|SA_NODEFER); if (sig == SIGCLD) flagmask |= (SA_NOCLDSTOP|SA_NOCLDWAIT); @@ -414,19 +415,19 @@ deinterpose(int sig, void *aharr, psinfo_t *psinfo, struct sigaction *sp) #ifdef _LP64 if (psinfo->pr_dmodel != PR_MODEL_NATIVE) { struct sigaction32 *sa32 = (struct sigaction32 *) - ((uintptr_t)aharr + sig * sizeof (siguaction32_t) + - offsetof(siguaction32_t, sig_uaction)); + ((uintptr_t)aharr + sig * sizeof (siguaction32_t) + + offsetof(siguaction32_t, sig_uaction)); sp->sa_flags = sa32->sa_flags; sp->sa_handler = (void (*)())(uintptr_t)sa32->sa_handler; (void) memcpy(&sp->sa_mask, &sa32->sa_mask, - sizeof (sp->sa_mask)); + sizeof (sp->sa_mask)); } else #endif { struct sigaction *sa = (struct sigaction *) - ((uintptr_t)aharr + sig * sizeof (siguaction_t) + - offsetof(siguaction_t, sig_uaction)); + ((uintptr_t)aharr + sig * sizeof (siguaction_t) + + offsetof(siguaction_t, sig_uaction)); sp->sa_flags = sa->sa_flags; sp->sa_handler = sa->sa_handler; diff --git a/usr/src/cmd/ptools/ptime/ptime.c b/usr/src/cmd/ptools/ptime/ptime.c index 2da2f8d281..b1f53593c2 100644 --- a/usr/src/cmd/ptools/ptime/ptime.c +++ b/usr/src/cmd/ptools/ptime/ptime.c @@ -41,6 +41,8 @@ #include <sys/time.h> #include <signal.h> #include <libproc.h> +#include <limits.h> +#include "ptools_common.h" static int look(pid_t); static void hr_min_sec(char *, long); @@ -189,7 +191,7 @@ main(int argc, char **argv) static int look(pid_t pid) { - char pathname[100]; + char pathname[PATH_MAX]; int rval = 0; int fd; psinfo_t psinfo; @@ -203,7 +205,8 @@ look(pid_t pid) if (proc_get_psinfo(pid, &psinfo) < 0) return (perr("read psinfo")); - (void) sprintf(pathname, "/proc/%d/usage", (int)pid); + (void) proc_snprintf(pathname, sizeof (pathname), "/proc/%d/usage", + (int)pid); if ((fd = open(pathname, O_RDONLY)) < 0) return (perr("open usage")); diff --git a/usr/src/cmd/ptools/ptree/ptree.c b/usr/src/cmd/ptools/ptree/ptree.c index 27fef9b7f0..92a65e2f44 100644 --- a/usr/src/cmd/ptools/ptree/ptree.c +++ b/usr/src/cmd/ptools/ptree/ptree.c @@ -21,14 +21,13 @@ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ /* * ptree -- print family tree of processes */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <assert.h> #include <stdio.h> #include <string.h> @@ -48,6 +47,7 @@ #include <sys/ctfs.h> #include <libcontract_priv.h> #include <sys/stat.h> +#include "ptools_common.h" #define FAKEDPID0(p) (p->pid == 0 && p->psargs[0] == '\0') @@ -103,10 +103,11 @@ main(int argc, char **argv) char *s; int n; int retc = 0; + char ppath[PATH_MAX]; DIR *dirp; struct dirent *dentp; - char pname[100]; + char pname[PATH_MAX]; int pdlen; ps_t *p; @@ -169,16 +170,18 @@ main(int argc, char **argv) psize = 0; ps = NULL; + (void) proc_snprintf(ppath, sizeof (ppath), "/proc"); + /* * Search the /proc directory for all processes. */ - if ((dirp = opendir("/proc")) == NULL) { - (void) fprintf(stderr, "%s: cannot open /proc directory\n", - command); + if ((dirp = opendir(ppath)) == NULL) { + (void) fprintf(stderr, "%s: cannot open %s directory\n", + command, ppath); return (1); } - (void) strcpy(pname, "/proc"); + (void) strcpy(pname, ppath); pdlen = strlen(pname); pname[pdlen++] = '/'; diff --git a/usr/src/cmd/ptools/pwait/pwait.c b/usr/src/cmd/ptools/pwait/pwait.c index 0733c355cf..ec11573477 100644 --- a/usr/src/cmd/ptools/pwait/pwait.c +++ b/usr/src/cmd/ptools/pwait/pwait.c @@ -23,8 +23,6 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdio_ext.h> #include <ctype.h> @@ -39,6 +37,8 @@ #include <poll.h> #include <procfs.h> #include <sys/resource.h> +#include <limits.h> +#include "ptools_common.h" static int count_my_files(); static char *command; @@ -49,6 +49,7 @@ static char *command; int main(int argc, char **argv) { + char buf[PATH_MAX]; unsigned long remain = 0; struct pollfd *pollfd; struct pollfd *pfd; @@ -75,10 +76,12 @@ main(int argc, char **argv) (void) fprintf(stderr, "usage:\t%s [-v] pid ...\n", command); (void) fprintf(stderr, " (wait for processes to terminate)\n"); (void) fprintf(stderr, - " -v: verbose; report terminations to standard out\n"); + " -v: verbose; report terminations to standard out\n"); return (2); } + (void) proc_snprintf(buf, sizeof (buf), "/proc/"); + /* make sure we have enough file descriptors */ if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) { int nfiles = count_my_files(); @@ -87,8 +90,8 @@ main(int argc, char **argv) rlim.rlim_cur = argc + nfiles + SLOP; if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { (void) fprintf(stderr, - "%s: insufficient file descriptors\n", - command); + "%s: insufficient file descriptors\n", + command); return (2); } } @@ -108,11 +111,11 @@ main(int argc, char **argv) if (strchr(arg, '/') != NULL) (void) strncpy(psinfofile, arg, sizeof (psinfofile)); else { - (void) strcpy(psinfofile, "/proc/"); + (void) strcpy(psinfofile, buf); (void) strncat(psinfofile, arg, sizeof (psinfofile)-6); } (void) strncat(psinfofile, "/psinfo", - sizeof (psinfofile)-strlen(psinfofile)); + sizeof (psinfofile)-strlen(psinfofile)); pfd = &pollfd[i]; if ((pfd->fd = open(psinfofile, O_RDONLY)) >= 0) { @@ -126,7 +129,7 @@ main(int argc, char **argv) pfd->revents = 0; } else if (errno == ENOENT) { (void) fprintf(stderr, "%s: no such process: %s\n", - command, arg); + command, arg); } else { perror(arg); } @@ -160,9 +163,9 @@ main(int argc, char **argv) if (pread(pfd->fd, &psinfo, sizeof (psinfo), (off_t)0) == sizeof (psinfo)) { - (void) printf( - "%s: terminated, wait status 0x%.4x\n", - arg, psinfo.pr_wstat); + (void) printf("%s: terminated, " + "wait status 0x%.4x\n", + arg, psinfo.pr_wstat); } else { (void) printf( "%s: terminated\n", arg); @@ -170,10 +173,10 @@ main(int argc, char **argv) } if (pfd->revents & POLLNVAL) (void) printf("%s: system process\n", - arg); + arg); if (pfd->revents & ~(POLLPRI|POLLHUP|POLLNVAL)) (void) printf("%s: unknown error\n", - arg); + arg); } (void) close(pfd->fd); diff --git a/usr/src/cmd/ptools/pwdx/pwdx.c b/usr/src/cmd/ptools/pwdx/pwdx.c index adf42c0877..4a2c6f0c3f 100644 --- a/usr/src/cmd/ptools/pwdx/pwdx.c +++ b/usr/src/cmd/ptools/pwdx/pwdx.c @@ -22,10 +22,9 @@ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <unistd.h> #include <string.h> @@ -33,6 +32,8 @@ #include <libproc.h> #include <sys/param.h> +#include "ptools_common.h" + static char *command; static int @@ -49,7 +50,7 @@ show_cwd(const char *arg) return (1); } - (void) snprintf(proc, sizeof (proc), "/proc/%d/path/cwd", + (void) proc_snprintf(proc, sizeof (proc), "/proc/%d/path/cwd", (int)p.pr_pid); if ((ret = readlink(proc, cwd, sizeof (cwd) - 1)) <= 0) { diff --git a/usr/src/cmd/rcap/common/utils.c b/usr/src/cmd/rcap/common/utils.c index 799fdcef23..dd511c7c50 100644 --- a/usr/src/cmd/rcap/common/utils.c +++ b/usr/src/cmd/rcap/common/utils.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. */ #include <sys/param.h> @@ -257,77 +258,3 @@ xatoi(char *p) return (i); } } - -/* - * get_running_zones() calls zone_list(2) to find out how many zones are - * running. It then calls zone_list(2) again to fetch the list of running - * zones (stored in *zents). - */ -int -get_running_zones(uint_t *nzents, zone_entry_t **zents) -{ - zoneid_t *zids; - uint_t nzents_saved; - int i; - zone_entry_t *zentp; - zone_state_t zstate; - - *zents = NULL; - if (zone_list(NULL, nzents) != 0) { - warn(gettext("could not get zoneid list\n")); - return (E_ERROR); - } - -again: - if (*nzents == 0) - return (E_SUCCESS); - - if ((zids = (zoneid_t *)calloc(*nzents, sizeof (zoneid_t))) == NULL) { - warn(gettext("out of memory: zones will not be capped\n")); - return (E_ERROR); - } - - nzents_saved = *nzents; - - if (zone_list(zids, nzents) != 0) { - warn(gettext("could not get zone list\n")); - free(zids); - return (E_ERROR); - } - if (*nzents != nzents_saved) { - /* list changed, try again */ - free(zids); - goto again; - } - - *zents = calloc(*nzents, sizeof (zone_entry_t)); - if (*zents == NULL) { - warn(gettext("out of memory: zones will not be capped\n")); - free(zids); - return (E_ERROR); - } - - zentp = *zents; - for (i = 0; i < *nzents; i++) { - char name[ZONENAME_MAX]; - - if (getzonenamebyid(zids[i], name, sizeof (name)) < 0) { - warn(gettext("could not get name for " - "zoneid %d\n"), zids[i]); - continue; - } - - (void) strlcpy(zentp->zname, name, sizeof (zentp->zname)); - zentp->zid = zids[i]; - if (zone_get_state(name, &zstate) != Z_OK || - zstate != ZONE_STATE_RUNNING) - continue; - - - zentp++; - } - *nzents = zentp - *zents; - - free(zids); - return (E_SUCCESS); -} diff --git a/usr/src/cmd/rcap/common/utils.h b/usr/src/cmd/rcap/common/utils.h index 7196cfb4ce..cf2e17c080 100644 --- a/usr/src/cmd/rcap/common/utils.h +++ b/usr/src/cmd/rcap/common/utils.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. */ #ifndef _UTILS_H @@ -98,7 +99,6 @@ extern void vdprintfe(int, const char *, va_list); extern void dprintfe(int, char *, ...); extern void hrt2ts(hrtime_t, timestruc_t *); extern int xatoi(char *); -extern int get_running_zones(uint_t *, zone_entry_t **); #ifdef __cplusplus } diff --git a/usr/src/cmd/rcap/rcapadm/rcapadm.c b/usr/src/cmd/rcap/rcapadm/rcapadm.c index 92888b2071..b92115469a 100644 --- a/usr/src/cmd/rcap/rcapadm/rcapadm.c +++ b/usr/src/cmd/rcap/rcapadm/rcapadm.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -145,20 +146,29 @@ out: scf_handle_destroy(h); } +static int +set_zone_cap(char *zonename, uint64_t mcap) +{ + char cmd[128 + ZONENAME_MAX]; + + (void) snprintf(cmd, sizeof (cmd), "/usr/bin/prctl -r " + "-n zone.max-physical-memory -v %llu -i zone %s", mcap, zonename); + return (system(cmd)); +} + /* * Update the in-kernel memory cap for the specified zone. */ static int update_zone_mcap(char *zonename, char *maxrss) { - zoneid_t zone_id; uint64_t num; if (getzoneid() != GLOBAL_ZONEID || zonecfg_in_alt_root()) return (E_SUCCESS); /* get the running zone from the kernel */ - if ((zone_id = getzoneidbyname(zonename)) == -1) { + if (getzoneidbyname(zonename) == -1) { (void) fprintf(stderr, gettext("zone '%s' must be running\n"), zonename); return (E_ERROR); @@ -169,7 +179,7 @@ update_zone_mcap(char *zonename, char *maxrss) return (E_ERROR); } - if (zone_setattr(zone_id, ZONE_ATTR_PHYS_MCAP, &num, 0) == -1) { + if (set_zone_cap(zonename, num) == -1) { (void) fprintf(stderr, gettext("could not set memory " "cap for zone '%s'\n"), zonename); return (E_ERROR); diff --git a/usr/src/cmd/rcap/rcapd/rcapd_collection_zone.c b/usr/src/cmd/rcap/rcapd/rcapd_collection_zone.c index db86aa6276..88403dda37 100644 --- a/usr/src/cmd/rcap/rcapd/rcapd_collection_zone.c +++ b/usr/src/cmd/rcap/rcapd/rcapd_collection_zone.c @@ -21,16 +21,17 @@ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2011 Joyent, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <procfs.h> #include <project.h> #include <stdlib.h> #include <strings.h> #include <zone.h> #include <libzonecfg.h> +#include <dirent.h> +#include <libproc.h> #include "rcapd.h" #include "utils.h" @@ -39,61 +40,117 @@ extern boolean_t gz_capped; /* round up to next y = 2^n */ #define ROUNDUP(x, y) (((x) + ((y) - 1)) & ~((y) - 1)) -static void -update_zone(zone_entry_t *zent, void *walk_data) +static struct ps_prochandle * +grab_zone_proc(zoneid_t zid) { - void(*update_notification_cb)(char *, char *, int, uint64_t, int) = - (void(*)(char *, char *, int, uint64_t, int))walk_data; - int changes; - int64_t max_rss; + DIR *dirp; + struct dirent *dentp; + int pid, pid_self, tmp; + psinfo_t psinfo; + struct ps_prochandle *pr = NULL; + + pid_self = getpid(); + + if ((dirp = opendir("/proc")) == NULL) + return (NULL); + + while (dentp = readdir(dirp)) { + pid = atoi(dentp->d_name); + + /* Skip self */ + if (pid == pid_self) + continue; + + if (proc_get_psinfo(pid, &psinfo) != 0) + continue; + + if (psinfo.pr_zoneid != zid) + continue; + + /* attempt to grab process */ + if ((pr = Pgrab(pid, 0, &tmp)) != NULL) { + if (Psetflags(pr, PR_RLC) != 0) { + Prelease(pr, 0); + } + if (Pcreate_agent(pr) == 0) { + if (pr_getzoneid(pr) != zid) { + Prelease(pr, 0); + continue; + } + + (void) closedir(dirp); + return (pr); + } else { + Prelease(pr, 0); + } + } + } + + (void) closedir(dirp); + return (NULL); +} + +static uint64_t +get_zone_cap(zoneid_t zid) +{ + rctlblk_t *rblk; uint64_t mcap; - lcollection_t *lcol; - rcid_t colid; + struct ps_prochandle *pr; - if (zone_getattr(zent->zid, ZONE_ATTR_PHYS_MCAP, &mcap, - sizeof (mcap)) != -1 && mcap != 0) - max_rss = ROUNDUP(mcap, 1024) / 1024; - else - max_rss = 0; - - if (zent->zid == GLOBAL_ZONEID) { - if (max_rss > 0) - gz_capped = B_TRUE; - else - gz_capped = B_FALSE; + if ((rblk = (rctlblk_t *)malloc(rctlblk_size())) == NULL) + return (UINT64_MAX); + + if ((pr = grab_zone_proc(zid)) == NULL) { + free(rblk); + return (UINT64_MAX); } + if (pr_getrctl(pr, "zone.max-physical-memory", NULL, rblk, + RCTL_FIRST)) { + Pdestroy_agent(pr); + Prelease(pr, 0); + free(rblk); + return (UINT64_MAX); + } - colid.rcid_type = RCIDT_ZONE; - colid.rcid_val = zent->zid; + Pdestroy_agent(pr); + Prelease(pr, 0); - lcol = lcollection_insert_update(&colid, max_rss, zent->zname, - &changes); - if (update_notification_cb != NULL) - update_notification_cb("zone", zent->zname, changes, max_rss, - (lcol != NULL) ? lcol->lcol_mark : 0); + mcap = rctlblk_get_value(rblk); + free(rblk); + return (mcap); } - +/* + * For zones, rcapd only caps the global zone, since each non-global zone + * caps itself. + */ /* ARGSUSED */ void lcollection_update_zone(lcollection_update_type_t ut, void(*update_notification_cb)(char *, char *, int, uint64_t, int)) { - int i; - uint_t nzents; - zone_entry_t *zents; - - /* - * Enumerate running zones. - */ - if (get_running_zones(&nzents, &zents) != 0) - return; - - for (i = 0; i < nzents; i++) { - update_zone(&zents[i], (void *)update_notification_cb); + int changes; + int64_t max_rss; + uint64_t mcap; + lcollection_t *lcol; + rcid_t colid; + mcap = get_zone_cap(GLOBAL_ZONEID); + if (mcap != 0 && mcap != UINT64_MAX) { + max_rss = ROUNDUP(mcap, 1024) / 1024; + gz_capped = B_TRUE; + } else { + max_rss = UINT64_MAX / 1024; + gz_capped = B_FALSE; } - free(zents); + colid.rcid_type = RCIDT_ZONE; + colid.rcid_val = GLOBAL_ZONEID; + + lcol = lcollection_insert_update(&colid, max_rss, GLOBAL_ZONENAME, + &changes); + if (update_notification_cb != NULL) + update_notification_cb("zone", GLOBAL_ZONENAME, changes, + max_rss, (lcol != NULL) ? lcol->lcol_mark : 0); } diff --git a/usr/src/cmd/rcap/rcapd/rcapd_scanner.c b/usr/src/cmd/rcap/rcapd/rcapd_scanner.c index b39811b552..254bb9e922 100644 --- a/usr/src/cmd/rcap/rcapd/rcapd_scanner.c +++ b/usr/src/cmd/rcap/rcapd/rcapd_scanner.c @@ -21,6 +21,7 @@ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2012 Joyent, Inc. All rights reserved. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -551,7 +552,7 @@ pageout(pid_t pid, struct ps_prochandle *Pr, caddr_t start, caddr_t end) errno = 0; res = pr_memcntl(Pr, start, (end - start), MC_SYNC, - (caddr_t)(MS_ASYNC | MS_INVALIDATE), 0, 0); + (caddr_t)(MS_ASYNC | MS_INVALCURPROC), 0, 0); debug_high("pr_memcntl [%p-%p): %d", (void *)start, (void *)end, res); /* diff --git a/usr/src/cmd/rcap/rcapstat/rcapstat.c b/usr/src/cmd/rcap/rcapstat/rcapstat.c index 0632250fed..2838c6e5d5 100644 --- a/usr/src/cmd/rcap/rcapstat/rcapstat.c +++ b/usr/src/cmd/rcap/rcapstat/rcapstat.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -72,6 +73,8 @@ typedef struct col { static col_t *col_head; static int ncol; +#define RCAPD_NA "rcapd is not active (try zonememstat)\n" + static col_t * col_find(rcid_t id) { @@ -152,7 +155,7 @@ read_stats(rcid_type_t stat_type) struct stat st; if ((fd = open(STAT_FILE_DEFAULT, O_RDONLY)) < 0) { - warn(gettext("rcapd is not active\n")); + warn(gettext(RCAPD_NA)); return (E_ERROR); } @@ -173,7 +176,7 @@ read_stats(rcid_type_t stat_type) pid = hdr.rs_pid; (void) snprintf(procfile, 20, "/proc/%lld/psinfo", pid); if ((proc_fd = open(procfile, O_RDONLY)) < 0) { - warn(gettext("rcapd is not active\n")); + warn(gettext(RCAPD_NA)); (void) close(fd); return (E_ERROR); } diff --git a/usr/src/cmd/savecore/savecore.c b/usr/src/cmd/savecore/savecore.c index e1d3589acc..9b8e43e488 100644 --- a/usr/src/cmd/savecore/savecore.c +++ b/usr/src/cmd/savecore/savecore.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 1983, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2016 Joyent, Inc. + * Copyright 2019 Joyent, Inc. */ /* * Copyright 2016 Nexenta Systems, Inc. All rights reserved. @@ -92,6 +92,7 @@ static dumpdatahdr_t datahdr; /* compression info */ static long coreblksize; /* preferred write size (st_blksize) */ static int cflag; /* run as savecore -c */ static int mflag; /* run as savecore -m */ +static int rflag; /* run as savecore -r */ /* * Payload information for the events we raise. These are used @@ -164,7 +165,7 @@ static void usage(void) { (void) fprintf(stderr, - "usage: %s [-Lvd] [-f dumpfile] [dirname]\n", progname); + "usage: %s [-L | -r] [-vd] [-f dumpfile] [dirname]\n", progname); exit(1); } @@ -229,7 +230,7 @@ logprint(uint32_t flags, char *message, ...) * raise if run as savecore -m. If something in the * raise_event codepath calls logprint avoid recursion. */ - if (!mflag && logprint_raised++ == 0) + if (!mflag && !rflag && logprint_raised++ == 0) raise_event(SC_EVENT_SAVECORE_FAILURE, buf); code = 2; break; @@ -240,7 +241,7 @@ logprint(uint32_t flags, char *message, ...) case SC_EXIT_ERR: default: - if (!mflag && logprint_raised++ == 0 && have_dumpfile) + if (!mflag && !rflag && logprint_raised++ == 0 && have_dumpfile) raise_event(SC_EVENT_SAVECORE_FAILURE, buf); code = 1; break; @@ -355,7 +356,7 @@ read_number_from_file(const char *filename, long default_value) static void read_dumphdr(void) { - if (filemode) + if (filemode || rflag) dumpfd = Open(dumpfile, O_RDONLY, 0644); else dumpfd = Open(dumpfile, O_RDWR | O_DSYNC, 0644); @@ -408,7 +409,7 @@ read_dumphdr(void) /* * Clear valid bit so we don't complain on every invocation. */ - if (!filemode) + if (!filemode && !rflag) Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff); logprint(SC_SL_ERR | SC_EXIT_ERR, "initial dump header corrupt"); @@ -660,7 +661,7 @@ copy_crashfile(const char *corefile) * Write out the modified dump header to the dump device. * The dump device has been processed, so DF_VALID is clear. */ - if (!filemode) + if (!filemode && !rflag) Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff); (void) close(corefd); @@ -1422,7 +1423,7 @@ build_corefile(const char *namelist, const char *corefile) * Write out the modified dump headers. */ Pwrite(corefd, &corehdr, sizeof (corehdr), 0); - if (!filemode) + if (!filemode && !rflag) Pwrite(dumpfd, &dumphdr, sizeof (dumphdr), endoff); (void) close(corefd); @@ -1531,7 +1532,10 @@ stack_retrieve(char *stack) DUMP_ERPTSIZE); dumpoff -= DUMP_SUMMARYSIZE; - dumpfd = Open(dumpfile, O_RDWR | O_DSYNC, 0644); + if (rflag) + dumpfd = Open(dumpfile, O_RDONLY, 0644); + else + dumpfd = Open(dumpfile, O_RDWR | O_DSYNC, 0644); dumpoff = llseek(dumpfd, dumpoff, SEEK_END) & -DUMP_OFFSET; Pread(dumpfd, &sd, sizeof (summary_dump_t), dumpoff); @@ -1668,7 +1672,7 @@ main(int argc, char *argv[]) if (savedir != NULL) savedir = strdup(savedir); - while ((c = getopt(argc, argv, "Lvcdmf:")) != EOF) { + while ((c = getopt(argc, argv, "Lvcdmf:r")) != EOF) { switch (c) { case 'L': livedump++; @@ -1685,6 +1689,9 @@ main(int argc, char *argv[]) case 'm': mflag++; break; + case 'r': + rflag++; + break; case 'f': dumpfile = optarg; filebounds = getbounds(dumpfile); @@ -1709,6 +1716,9 @@ main(int argc, char *argv[]) if (cflag && livedump) usage(); + if (rflag && (cflag || mflag || livedump)) + usage(); + if (dumpfile == NULL || livedump) dumpfd = Open("/dev/dump", O_RDONLY, 0444); @@ -1752,7 +1762,7 @@ main(int argc, char *argv[]) * We could extend it to handle this, but there doesn't seem to be * a general need for it, so we isolate the complexity here instead. */ - if (dumphdr.dump_panicstring[0] != '\0') { + if (dumphdr.dump_panicstring[0] != '\0' && !rflag) { int logfd = Open("/dev/conslog", O_WRONLY, 0644); log_ctl_t lc; struct strbuf ctl, dat; @@ -1801,7 +1811,7 @@ main(int argc, char *argv[]) * for the same event. Also avoid raising an event for a * livedump, or when we inflating a compressed dump. */ - if (!fm_panic && !livedump && !filemode) + if (!fm_panic && !livedump && !filemode && !rflag) raise_event(SC_EVENT_DUMP_PENDING, NULL); logprint(SC_SL_WARN, "System dump time: %s", @@ -1857,7 +1867,7 @@ main(int argc, char *argv[]) * has panicked. We know a reasonable amount about the * condition at this time, but the dump is still compressed. */ - if (!livedump && !fm_panic) + if (!livedump && !fm_panic && !rflag) raise_event(SC_EVENT_DUMP_AVAILABLE, NULL); if (metrics_size > 0) { @@ -1926,7 +1936,7 @@ main(int argc, char *argv[]) build_corefile(namelist, corefile); - if (!livedump && !filemode && !fm_panic) + if (!livedump && !filemode && !fm_panic && !rflag) raise_event(SC_EVENT_DUMP_AVAILABLE, NULL); if (access(METRICSFILE, F_OK) == 0) { diff --git a/usr/src/cmd/scsi/smp/common/smp.c b/usr/src/cmd/scsi/smp/common/smp.c index 374049b845..00dd414c67 100644 --- a/usr/src/cmd/scsi/smp/common/smp.c +++ b/usr/src/cmd/scsi/smp/common/smp.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2015 PALO, Richard + * Copyright 2019, Joyent, Inc. */ #include <sys/types.h> #include <sys/scsi/generic/smp_frames.h> @@ -70,6 +71,31 @@ fatal(int err, const char *fmt, ...) _exit(err); } +/* + * Print out a buffer of SMP character array data. The data in str is guaranteed + * to be at most len bytes long. While it is supposed to be ascii, we should not + * assume as such. + */ +static void +smp_print_ascii(const char *header, const char *str, size_t len) +{ + size_t i, last = len; + + while (last > 0 && str[last - 1] == ' ') + last--; + + (void) printf("%s: ", header); + for (i = 0; i < last; i++) { + if (isascii(str[i]) != 0 && isalnum(str[i]) != 0) { + (void) putchar(str[i]); + } else { + (void) printf("\\x%x", str[i]); + } + } + + (void) putchar('\n'); +} + static char * smp_get_result(smp_result_t result) { @@ -431,6 +457,12 @@ smp_validate_args(int argc, char *argv[]) fatal(-1, "Usage: %s <device> <function> ...\n", argv[0]); switch (func) { + case SMP_FUNC_REPORT_GENERAL: + case SMP_FUNC_REPORT_MANUFACTURER_INFO: + if (argc != 3) { + fatal(-1, "Usage: %s <device> 0x%x\n", argv[0], func); + } + break; case SMP_FUNC_DISCOVER: case SMP_FUNC_REPORT_PHY_EVENT: case SMP_FUNC_REPORT_PHY_ERROR_LOG: { @@ -540,6 +572,13 @@ main(int argc, char *argv[]) } switch (func) { + case SMP_FUNC_REPORT_GENERAL: + case SMP_FUNC_REPORT_MANUFACTURER_INFO: + /* + * These functions have no additional request bytes. therefore + * there is nothing for us to get and fill in here. + */ + break; case SMP_FUNC_DISCOVER: { smp_discover_req_t *dp; @@ -615,6 +654,150 @@ main(int argc, char *argv[]) smp_get_response(B_TRUE); switch (func) { + case SMP_FUNC_REPORT_GENERAL: { + smp_report_general_resp_t *gr = + (smp_report_general_resp_t *)smp_resp; + + (void) printf("Expander Route Indexes: %u\n", + SCSI_READ16(&gr->srgr_exp_route_indexes)); + (void) printf("Long Responses: %s\n", + gr->srgr_long_response != 0 ? "Supported" : "Unsupported"); + (void) printf("Phys: %d\n", gr->srgr_number_of_phys); + (void) printf("Features:\n"); + if (gr->srgr_externally_configurable_route_table != 0) { + (void) printf("\tExternally Configurable Route " + "Table\n"); + } + if (gr->srgr_configuring != 0) { + (void) printf("\tConfiguring\n"); + } + if (gr->srgr_configures_others != 0) { + (void) printf("\tConfigures Others\n"); + } + if (gr->srgr_open_reject_retry_supported != 0) { + (void) printf("\tOpen Reject Retry\n"); + } + if (gr->srgr_stp_continue_awt != 0) { + (void) printf("\tSTP Continue AWT\n"); + } + if (gr->srgr_table_to_table_supported != 0) { + (void) printf("\tTable to Table\n"); + } + + (void) printf("Logical Identify: %016llx\n", + SCSI_READ64(&gr->srgr_enclosure_logical_identifier)); + + (void) printf("STP Bus Inactivity Time Limit: %u us\n", + SCSI_READ16(&gr->srgr_stp_bus_inactivity_time_limit) * 100); + (void) printf("STP Maximum Connect Time Limit: %u us\n", + SCSI_READ16(&gr->srgr_stp_maximum_connect_time_limit) * + 100); + (void) printf("STP SMP I_T Nexus Loss Time: "); + if (gr->srgr_stp_smp_nexus_loss_time == 0) { + (void) printf("Vendor Specific\n"); + } else if (gr->srgr_stp_smp_nexus_loss_time == UINT16_MAX) { + (void) printf("Retries Forever\n"); + } else { + (void) printf("%u ms\n", + SCSI_READ16(&gr->srgr_stp_smp_nexus_loss_time)); + } + + (void) printf("Physical Presence: %s, %s\n", + gr->srgr_physical_presence_supported ? "Supported" : + "Unsupported", + gr->srgr_physical_presence_asserted ? "Enabled" : + "Disabled"); + + (void) printf("Zoning:\n"); + if (gr->srgr_zoning_supported != 0) { + (void) printf("\tSupported\n"); + } else { + (void) printf("\tUnsupported\n"); + } + if (gr->srgr_zoning_enabled != 0) { + (void) printf("\tEnabled\n"); + } else { + (void) printf("\tDisabled\n"); + } + if (gr->srgr_zone_locked != 0) { + (void) printf("\tLocked\n"); + } else { + (void) printf("\tUnlocked\n"); + } + if (gr->srgr_saving_zoning_enabled_supported != 0) { + (void) printf("\tSaving Zoning Enabled Supported\n"); + } + if (gr->srgr_saving_zone_perm_table_supported != 0) { + (void) printf("\tSaving Zone Perm Table Supported\n"); + } + if (gr->srgr_saving_zone_phy_info_supported != 0) { + (void) printf("\tSaving Zone Phy Info Supported\n"); + } + if (gr->srgr_saving != 0) { + (void) printf("\tSaving\n"); + } + (void) printf("\tActive Zone Manager SAS Address: %016llx\n", + SCSI_READ64(&gr->srgr_active_zm_sas_addr)); + (void) printf("\tZone Lock Inactivity Limit: %u ms\n", + SCSI_READ16(&gr->srgr_zone_lock_inactivity_limit) * 100); + + (void) printf("Maximum Routed SAS Addresses: %u\n", + SCSI_READ16(&gr->srgr_max_routed_sas_addrs)); + + (void) printf("First Enclosure Connector Element Index: %u\n", + gr->srgr_first_encl_conn_elem_idx); + (void) printf("Number of Enclosure Connector Elements: %u\n", + gr->srgr_number_encl_conn_elem_idxs); + + if (gr->srgr_reduced_functionality != 0) { + (void) printf("Time to Reduced Functionality: %u ms\n", + gr->srgr_time_to_reduced_functionality * 100); + } + (void) printf("Initial Time to Reduced Functionality: %u ms\n", + gr->srgr_initial_time_to_reduced_functionality * 100); + (void) printf("Maximum Time to Reduced Functionality: %u ms\n", + gr->srgr_max_reduced_functionality_time * 100); + (void) printf("Last Self-configuration Status Index: %u\n", + SCSI_READ16(&gr->srgr_last_self_conf_status_descr_idx)); + (void) printf("Maximum Stored Self-configuration Statuses: " + "%u\n", SCSI_READ16( + &gr->srgr_max_stored_self_config_status_descrs)); + (void) printf("Last Phy Event List Descriptor Index: %u\n", + SCSI_READ16(&gr->srgr_last_phy_event_list_descr_idx)); + (void) printf("Maximum Stored Phy Event List Descriptors: " + "%u\n", SCSI_READ16( + &gr->srgr_max_stored_phy_event_list_descrs)); + (void) printf("STP Reject to Open Limit: %u us\n", + SCSI_READ16(&gr->srgr_stp_reject_to_open_limit) * 10); + break; + } + case SMP_FUNC_REPORT_MANUFACTURER_INFO: { + smp_report_manufacturer_info_resp_t *mir = + (smp_report_manufacturer_info_resp_t *)smp_resp; + + smp_print_ascii("Vendor", mir->srmir_vendor_identification, + sizeof (mir->srmir_vendor_identification)); + smp_print_ascii("Product", mir->srmir_product_identification, + sizeof (mir->srmir_product_identification)); + smp_print_ascii("Revision", mir->srmir_product_revision_level, + sizeof (mir->srmir_product_revision_level)); + /* + * The format of the following section was changed in the SAS + * 1.1 specification. If this bit is not present, it is vendor + * specific and therefore we don't print them. + */ + if (mir->srmir_sas_1_1_format == 0) { + break; + } + smp_print_ascii("Component Vendor", + mir->srmir_component_vendor_identification, + sizeof (mir->srmir_component_vendor_identification)); + (void) printf("Component ID: 0x%x\n", + SCSI_READ16(&mir->srmir_component_id)); + (void) printf("Component Revision: 0x%x\n", + mir->srmir_component_revision_level); + break; + } case SMP_FUNC_DISCOVER: { smp_discover_resp_t *rp = (smp_discover_resp_t *)smp_resp; (void) printf("Addr: %016llx Phy: %02x\n", diff --git a/usr/src/cmd/sed/main.c b/usr/src/cmd/sed/main.c index 22937d9d92..2ada22edbb 100644 --- a/usr/src/cmd/sed/main.c +++ b/usr/src/cmd/sed/main.c @@ -1,7 +1,7 @@ /* * Copyright (c) 2013 Johann 'Myrkraverk' Oskarsson <johann@myrkraverk.com> * Copyright (c) 2011 Gary Mills - * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2010 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1992 Diomidis Spinellis. * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -42,9 +42,7 @@ #include <err.h> #include <errno.h> #include <fcntl.h> -#include <getopt.h> #include <libgen.h> -#include <libintl.h> #include <limits.h> #include <locale.h> #include <regex.h> @@ -53,6 +51,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <libintl.h> #include "defs.h" #include "extern.h" @@ -107,11 +106,6 @@ static char tmpfname[PATH_MAX]; /* Temporary file name (for in-place editing) */ static const char *inplace; /* Inplace edit file extension. */ ulong_t linenum; -static const struct option lopts[] = { - {"in-place", optional_argument, NULL, 'i'}, - {NULL, 0, NULL, 0} -}; - static void add_compunit(enum e_cut, char *); static void add_file(char *); static void usage(void); @@ -133,18 +127,14 @@ main(int argc, char *argv[]) fflag = 0; inplace = NULL; - while ((c = getopt_long(argc, argv, "EI::ae:f:i::lnr", lopts, NULL)) != - -1) + while ((c = getopt(argc, argv, "EI:ae:f:i:lnr")) != -1) switch (c) { case 'r': /* Gnu sed compat */ case 'E': rflags = REG_EXTENDED; break; case 'I': - if (optarg != NULL) - inplace = optarg; - else - inplace = ""; + inplace = optarg; ispan = 1; /* span across input files */ break; case 'a': @@ -161,10 +151,7 @@ main(int argc, char *argv[]) add_compunit(CU_FILE, optarg); break; case 'i': - if (optarg != NULL) - inplace = optarg; - else - inplace = ""; + inplace = optarg; ispan = 0; /* don't span across input files */ break; case 'l': @@ -205,8 +192,8 @@ main(int argc, char *argv[]) static void usage(void) { - (void) fputs(_("usage: sed script [-Ealn] [-i[extension]] [file...]\n" - " sed [-Ealn] [-i[extension]] [-e script]... " + (void) fputs(_("usage: sed script [-Ealn] [-i extension] [file...]\n" + " sed [-Ealn] [-i extension] [-e script]... " "[-f script_file]... [file...]\n"), stderr); exit(1); diff --git a/usr/src/cmd/sendmail/src/Makefile b/usr/src/cmd/sendmail/src/Makefile index 14793754fd..9512a7d976 100644 --- a/usr/src/cmd/sendmail/src/Makefile +++ b/usr/src/cmd/sendmail/src/Makefile @@ -46,7 +46,7 @@ LDFLAGS += $(MAPFILES:%=-M%) LDLIBS += ../libsmutil/libsmutil.a ../libsm/libsm.a -lresolv -lsocket \ -lnsl ../db/libdb.a -lldap -lsldap -lwrap -lumem \ - -lssl -lcrypto -lsasl + -lsunw_ssl -lsunw_crypto -lsasl INCPATH= -I. -I../include -I../db diff --git a/usr/src/cmd/sgs/elfdump/Makefile.targ b/usr/src/cmd/sgs/elfdump/Makefile.targ index 4cbbec6bff..bef356bb28 100644 --- a/usr/src/cmd/sgs/elfdump/Makefile.targ +++ b/usr/src/cmd/sgs/elfdump/Makefile.targ @@ -79,6 +79,8 @@ delete: package \ install: all $(VAR_SGSBINPROG) $(VAR_SGSCCSLINK) + -$(RM) $(ROOTPROG) + -$(LN) $(ISAEXEC) $(ROOTPROG) include $(SRC)/cmd/Makefile.targ include $(SRC)/cmd/sgs/Makefile.targ diff --git a/usr/src/cmd/sgs/elfdump/amd64/Makefile b/usr/src/cmd/sgs/elfdump/amd64/Makefile index ec8341a69b..7c3f1eb876 100644 --- a/usr/src/cmd/sgs/elfdump/amd64/Makefile +++ b/usr/src/cmd/sgs/elfdump/amd64/Makefile @@ -39,6 +39,8 @@ CONVLIBDIR = $(CONVLIBDIR64) VAR_SGSBINPROG= $(VAR_SGSBINPROG64) VAR_SGSCCSLINK= $(VAR_SGSCCSLINK64) +install: all $(ROOTPROG64) + include ../Makefile.targ include ../../Makefile.sub.64 diff --git a/usr/src/cmd/sgs/elfdump/common/elfdump.msg b/usr/src/cmd/sgs/elfdump/common/elfdump.msg index 253ea4a788..5876b59f1f 100644 --- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg +++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg @@ -37,7 +37,7 @@ [-N name] [-O osabi] [-T type] [-p | -w outfile] \ file...\n" @ MSG_USAGE_DETAIL1 "\t[-c]\t\tdump section header information\n" -@ MSG_USAGE_DETAIL2 "\t[-C]\t\tdemangle C++ symbol names\n" +@ MSG_USAGE_DETAIL2 "\t[-C]\t\tdemangle symbol names\n" @ MSG_USAGE_DETAIL3 "\t[-d]\t\tdump the contents of the .dynamic section\n" @ MSG_USAGE_DETAIL4 "\t[-e]\t\tdump the elf header\n" @ MSG_USAGE_DETAIL5 "\t[-g]\t\tdump the contents of the .group sections\n" diff --git a/usr/src/cmd/sgs/elfdump/i386/Makefile b/usr/src/cmd/sgs/elfdump/i386/Makefile index d3cb302ac1..95390a2899 100644 --- a/usr/src/cmd/sgs/elfdump/i386/Makefile +++ b/usr/src/cmd/sgs/elfdump/i386/Makefile @@ -30,4 +30,6 @@ include ../Makefile.com ARCH = i386 +install: all $(ROOTPROG32) + include ../Makefile.targ diff --git a/usr/src/cmd/sgs/include/conv.h b/usr/src/cmd/sgs/include/conv.h index 066e215bc4..7fc4c026d5 100644 --- a/usr/src/cmd/sgs/include/conv.h +++ b/usr/src/cmd/sgs/include/conv.h @@ -283,7 +283,7 @@ typedef union { } Conv_bnd_obj_buf_t; /* conv_phdr_flags() */ -#define CONV_PHDR_FLAGS_BUFSIZE 88 +#define CONV_PHDR_FLAGS_BUFSIZE 244 typedef union { Conv_inv_buf_t inv_buf; char buf[CONV_PHDR_FLAGS_BUFSIZE]; diff --git a/usr/src/cmd/sgs/lex/common/main.c b/usr/src/cmd/sgs/lex/common/main.c index 17ba4808a4..a1fd526cf9 100644 --- a/usr/src/cmd/sgs/lex/common/main.c +++ b/usr/src/cmd/sgs/lex/common/main.c @@ -30,11 +30,15 @@ /* Copyright 1976, Bell Telephone Laboratories, Inc. */ +/* Copyright (c) 2013, joyent, Inc. All rights reserved. */ + #include <string.h> #include "once.h" #include "sgs.h" #include <locale.h> #include <limits.h> +#include <unistd.h> +#include <libgen.h> static wchar_t L_INITIAL[] = {'I', 'N', 'I', 'T', 'I', 'A', 'L', 0}; static void get1core(void); @@ -46,6 +50,25 @@ static void get3core(void); static void free3core(void); #endif +static int +lex_construct_path(char *buf, size_t size, const char *file, int type) +{ + int ret; + char origin[PATH_MAX]; + + if (type != 0) { + ret = readlink("/proc/self/path/a.out", origin, PATH_MAX - 1); + if (ret < 0) + error( + "lex: failed to read origin from /proc\n"); + origin[ret] = '\0'; + return (snprintf(buf, size, "%s/../%s/%s", dirname(origin), + NBASE, file)); + } + + return (snprintf(buf, size, "%s/%s/%s", NPREFIX, NBASE, file)); +} + int main(int argc, char **argv) { @@ -53,6 +76,7 @@ main(int argc, char **argv) int c; char *apath = NULL; char *ypath; + char pathbuf[PATH_MAX]; Boolean eoption = 0, woption = 0; sargv = argv; @@ -224,6 +248,11 @@ main(int argc, char **argv) free3core(); #endif + /* + * Try to find the file relative to $ORIGIN. Note that we don't touch + * antyhing related to -Y. In fact, unfortunately it's always been + * ignored it seems. + */ if (handleeuc) { if (ratfor) error("Ratfor is not supported by -w or -e option."); @@ -232,9 +261,19 @@ main(int argc, char **argv) else ypath = ratfor ? RATNAME : CNAME; - if (apath != NULL) - ypath = strcat(apath, strrchr(ypath, '/')); - fother = fopen(ypath, "r"); + if (apath == NULL) { + (void) lex_construct_path(pathbuf, sizeof (pathbuf), ypath, 1); + fother = fopen(pathbuf, "r"); + if (fother == NULL) { + (void) lex_construct_path(pathbuf, sizeof (pathbuf), + ypath, 0); + fother = fopen(pathbuf, "r"); + } + } else { + apath = strcat(apath, "/"); + ypath = strcat(apath, ypath); + fother = fopen(ypath, "r"); + } if (fother == NULL) error("Lex driver missing, file %s", ypath); while ((i = getc(fother)) != EOF) diff --git a/usr/src/cmd/sgs/lex/common/once.h b/usr/src/cmd/sgs/lex/common/once.h index 014ca00b17..9e4b0e5e00 100644 --- a/usr/src/cmd/sgs/lex/common/once.h +++ b/usr/src/cmd/sgs/lex/common/once.h @@ -26,11 +26,11 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +/* Copyright (c) 2013, joyent, Inc. All rights reserved. */ + #ifndef _ONCE_H #define _ONCE_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include "ldefs.h" /* once.c */ @@ -73,9 +73,11 @@ int peek = '\n'; /* next input character */ CHR *pushptr = pushc; CHR *slptr = slist; -#define CNAME "/usr/share/lib/ccs/ncform" -#define RATNAME "/usr/share/lib/ccs/nrform" -#define EUCNAME "/usr/share/lib/ccs/nceucform" +#define NPREFIX "/usr" +#define NBASE "/share/lib/ccs/" +#define CNAME "ncform" +#define RATNAME "nrform" +#define EUCNAME "nceucform" int ccount = 1; int casecount = 1; diff --git a/usr/src/cmd/sgs/libconv/common/corenote.c b/usr/src/cmd/sgs/libconv/common/corenote.c index dc9b8022f3..ce923bb039 100644 --- a/usr/src/cmd/sgs/libconv/common/corenote.c +++ b/usr/src/cmd/sgs/libconv/common/corenote.c @@ -78,7 +78,7 @@ const char * conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags, Conv_inv_buf_t *inv_buf) { - static const Msg types_0_22[] = { + static const Msg types_0_25[] = { MSG_AUXV_AT_NULL, MSG_AUXV_AT_IGNORE, MSG_AUXV_AT_EXECFD, MSG_AUXV_AT_PHDR, MSG_AUXV_AT_PHENT, MSG_AUXV_AT_PHNUM, @@ -90,10 +90,11 @@ conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags, MSG_AUXV_AT_HWCAP, MSG_AUXV_AT_CLKTCK, MSG_AUXV_AT_FPUCW, MSG_AUXV_AT_DCACHEBSIZE, MSG_AUXV_AT_ICACHEBSIZE, MSG_AUXV_AT_UCACHEBSIZE, - MSG_AUXV_AT_IGNOREPPC + MSG_AUXV_AT_IGNOREPPC, MSG_AUXV_AT_SECURE, + MSG_AUXV_AT_BASE_PLATFORM, MSG_AUXV_AT_RANDOM }; - static const conv_ds_msg_t ds_types_0_22 = { - CONV_DS_MSG_INIT(0, types_0_22) }; + static const conv_ds_msg_t ds_types_0_25 = { + CONV_DS_MSG_INIT(0, types_0_25) }; static const Msg types_2000_2011[] = { MSG_AUXV_AT_SUN_UID, MSG_AUXV_AT_SUN_RUID, @@ -112,7 +113,7 @@ conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags, MSG_AUXV_AT_SUN_EMULATOR, MSG_AUXV_AT_SUN_BRANDNAME, MSG_AUXV_AT_SUN_BRAND_AUX1, MSG_AUXV_AT_SUN_BRAND_AUX2, MSG_AUXV_AT_SUN_BRAND_AUX3, MSG_AUXV_AT_SUN_HWCAP2, - NULL, NULL, + MSG_AUXV_AT_SUN_BRAND_NROOT, MSG_AUXV_AT_SUN_BRAND_AUX4, MSG_AUXV_AT_SUN_COMMPAGE, MSG_AUXV_AT_SUN_FPTYPE, MSG_AUXV_AT_SUN_FPSIZE }; @@ -120,7 +121,7 @@ conv_cnote_auxv_type(Word type, Conv_fmt_flags_t fmt_flags, CONV_DS_MSG_INIT(2014, types_2014_2028) }; static const conv_ds_t *ds[] = { - CONV_DS_ADDR(ds_types_0_22), CONV_DS_ADDR(ds_types_2000_2011), + CONV_DS_ADDR(ds_types_0_25), CONV_DS_ADDR(ds_types_2000_2011), CONV_DS_ADDR(ds_types_2014_2028), NULL }; return (conv_map_ds(ELFOSABI_NONE, EM_NONE, type, ds, fmt_flags, diff --git a/usr/src/cmd/sgs/libconv/common/corenote.msg b/usr/src/cmd/sgs/libconv/common/corenote.msg index a36f2bddf7..78951cfb1d 100644 --- a/usr/src/cmd/sgs/libconv/common/corenote.msg +++ b/usr/src/cmd/sgs/libconv/common/corenote.msg @@ -80,6 +80,9 @@ @ MSG_AUXV_AT_ICACHEBSIZE "ICACHEBSIZE" @ MSG_AUXV_AT_UCACHEBSIZE "UCACHEBSIZE" @ MSG_AUXV_AT_IGNOREPPC "IGNOREPPC" +@ MSG_AUXV_AT_SECURE "SECURE" +@ MSG_AUXV_AT_BASE_PLATFORM "BASE_PLATFORM" +@ MSG_AUXV_AT_RANDOM "RANDOM" @ MSG_AUXV_AT_SUN_UID "SUN_UID" @ MSG_AUXV_AT_SUN_RUID "SUN_RUID" @ MSG_AUXV_AT_SUN_GID "SUN_GID" @@ -102,6 +105,8 @@ @ MSG_AUXV_AT_SUN_BRAND_AUX2 "SUN_BRAND_AUX2" @ MSG_AUXV_AT_SUN_BRAND_AUX3 "SUN_BRAND_AUX3" @ MSG_AUXV_AT_SUN_HWCAP2 "SUN_HWCAP2" +@ MSG_AUXV_AT_SUN_BRAND_NROOT "SUN_BRAND_NROOT" +@ MSG_AUXV_AT_SUN_BRAND_AUX4 "SUN_BRAND_AUX4" @ MSG_AUXV_AT_SUN_COMMPAGE "SUN_COMMPAGE" @ MSG_AUXV_AT_SUN_FPTYPE "SUN_FPTYPE" @ MSG_AUXV_AT_SUN_FPSIZE "SUN_FPSIZE" diff --git a/usr/src/cmd/sgs/libconv/common/phdr.c b/usr/src/cmd/sgs/libconv/common/phdr.c index d2b29a201f..382a1bf9f1 100644 --- a/usr/src/cmd/sgs/libconv/common/phdr.c +++ b/usr/src/cmd/sgs/libconv/common/phdr.c @@ -25,6 +25,10 @@ */ /* + * Copyright (c) 2015, Joyent, Inc. All rights reserved. + */ + +/* * String conversion routines for program header attributes. */ #include <stdio.h> @@ -95,6 +99,7 @@ error "PT_NUM has grown. Update phdrs[]" { PT_GNU_EH_FRAME, LIN, MSG_PT_GNU_EH_FRAME }, { PT_GNU_STACK, LIN, MSG_PT_GNU_STACK }, { PT_GNU_RELRO, LIN, MSG_PT_GNU_RELRO }, + { PT_PAX_FLAGS, LIN, MSG_PT_PAX_FLAGS }, { 0 } }; @@ -109,6 +114,7 @@ error "PT_NUM has grown. Update phdrs[]" { PT_GNU_EH_FRAME, LIN, MSG_PT_GNU_EH_FRAME_CF }, { PT_GNU_STACK, LIN, MSG_PT_GNU_STACK_CF }, { PT_GNU_RELRO, LIN, MSG_PT_GNU_RELRO_CF }, + { PT_PAX_FLAGS, LIN, MSG_PT_PAX_FLAGS_CF }, { 0 } }; @@ -123,6 +129,7 @@ error "PT_NUM has grown. Update phdrs[]" { PT_GNU_EH_FRAME, LIN, MSG_PT_GNU_EH_FRAME_CFNP }, { PT_GNU_STACK, LIN, MSG_PT_GNU_STACK_CFNP }, { PT_GNU_RELRO, LIN, MSG_PT_GNU_RELRO_CFNP }, + { PT_PAX_FLAGS, LIN, MSG_PT_PAX_FLAGS_CFNP }, { 0 } }; @@ -137,6 +144,7 @@ error "PT_NUM has grown. Update phdrs[]" { PT_GNU_EH_FRAME, LIN, MSG_PT_GNU_EH_FRAME_NF }, { PT_GNU_STACK, LIN, MSG_PT_GNU_STACK_NF }, { PT_GNU_RELRO, LIN, MSG_PT_GNU_RELRO_NF }, + { PT_PAX_FLAGS, LIN, MSG_PT_PAX_FLAGS_NF }, { 0 } }; @@ -214,6 +222,18 @@ conv_phdr_flags_strings(Conv_fmt_flags_t fmt_flags) MSG_PF_X_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ MSG_PF_W_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ MSG_PF_R_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_PAGEEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_NOPAGEEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_SEGMEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_NOSEGMEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_MPROTECT_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_NOMPROTECT_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_RANDEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_NORANDEXEC_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_EMUTRAMP_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_NOEMUTRAMP_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_RANDMMAP_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ + MSG_PF_NORANDMMAP_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ MSG_PF_SUNW_FAILURE_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ MSG_PF_SUNW_KILLED_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ MSG_PF_SUNW_SIGINFO_CF_SIZE + CONV_EXPN_FIELD_DEF_SEP_SIZE + \ @@ -237,11 +257,24 @@ conv_phdr_flags_strings(Conv_fmt_flags_t fmt_flags) #define ALL ELFOSABI_NONE, EM_NONE #define SOL ELFOSABI_SOLARIS, EM_NONE +#define LIN ELFOSABI_LINUX, EM_NONE static const Val_desc2 vda_cf[] = { { PF_X, ALL, MSG_PF_X_CF }, { PF_W, ALL, MSG_PF_W_CF }, { PF_R, ALL, MSG_PF_R_CF }, + { PF_PAGEEXEC, LIN, MSG_PF_PAGEEXEC_CF }, + { PF_NOPAGEEXEC, LIN, MSG_PF_NOPAGEEXEC_CF }, + { PF_SEGMEXEC, LIN, MSG_PF_SEGMEXEC_CF }, + { PF_NOSEGMEXEC, LIN, MSG_PF_NOSEGMEXEC_CF }, + { PF_MPROTECT, LIN, MSG_PF_MPROTECT_CF }, + { PF_NOMPROTECT, LIN, MSG_PF_NOMPROTECT_CF }, + { PF_RANDEXEC, LIN, MSG_PF_RANDEXEC_CF }, + { PF_NORANDEXEC, LIN, MSG_PF_NORANDEXEC_CF }, + { PF_EMUTRAMP, LIN, MSG_PF_EMUTRAMP_CF }, + { PF_NOEMUTRAMP, LIN, MSG_PF_NOEMUTRAMP_CF }, + { PF_RANDMMAP, LIN, MSG_PF_RANDMMAP_CF }, + { PF_NORANDMMAP, LIN, MSG_PF_NORANDMMAP_CF }, { PF_SUNW_FAILURE, SOL, MSG_PF_SUNW_FAILURE_CF }, { PF_SUNW_KILLED, SOL, MSG_PF_SUNW_KILLED_CF }, { PF_SUNW_SIGINFO, SOL, MSG_PF_SUNW_SIGINFO_CF }, @@ -251,6 +284,18 @@ conv_phdr_flags_strings(Conv_fmt_flags_t fmt_flags) { PF_X, ALL, MSG_PF_X_NF }, { PF_W, ALL, MSG_PF_W_NF }, { PF_R, ALL, MSG_PF_R_NF }, + { PF_PAGEEXEC, LIN, MSG_PF_PAGEEXEC_NF }, + { PF_NOPAGEEXEC, LIN, MSG_PF_NOPAGEEXEC_NF }, + { PF_SEGMEXEC, LIN, MSG_PF_SEGMEXEC_NF }, + { PF_NOSEGMEXEC, LIN, MSG_PF_NOSEGMEXEC_NF }, + { PF_MPROTECT, LIN, MSG_PF_MPROTECT_NF }, + { PF_NOMPROTECT, LIN, MSG_PF_NOMPROTECT_NF }, + { PF_RANDEXEC, LIN, MSG_PF_RANDEXEC_NF }, + { PF_NORANDEXEC, LIN, MSG_PF_NORANDEXEC_NF }, + { PF_EMUTRAMP, LIN, MSG_PF_EMUTRAMP_NF }, + { PF_NOEMUTRAMP, LIN, MSG_PF_NOEMUTRAMP_NF }, + { PF_RANDMMAP, LIN, MSG_PF_RANDMMAP_NF }, + { PF_NORANDMMAP, LIN, MSG_PF_NORANDMMAP_NF }, { PF_SUNW_FAILURE, SOL, MSG_PF_SUNW_FAILURE_NF }, { PF_SUNW_KILLED, SOL, MSG_PF_SUNW_KILLED_NF }, { PF_SUNW_SIGINFO, SOL, MSG_PF_SUNW_SIGINFO_NF }, @@ -262,6 +307,7 @@ conv_phdr_flags_strings(Conv_fmt_flags_t fmt_flags) #undef ALL #undef SOL +#undef LIN } const char * diff --git a/usr/src/cmd/sgs/libconv/common/phdr.msg b/usr/src/cmd/sgs/libconv/common/phdr.msg index 789832a16a..e84182277b 100644 --- a/usr/src/cmd/sgs/libconv/common/phdr.msg +++ b/usr/src/cmd/sgs/libconv/common/phdr.msg @@ -24,6 +24,8 @@ # Use is subject to license terms. # +# Copyright (c) 2015, Joyent, Inc. All rights reserved. + @ MSG_PT_NULL "[ PT_NULL ]" # 0 @ MSG_PT_NULL_CF "PT_NULL" @ MSG_PT_NULL_CFNP "NULL" @@ -79,6 +81,10 @@ @ MSG_PT_GNU_RELRO_CF "PT_GNU_RELRO" @ MSG_PT_GNU_RELRO_CFNP "GNU_RELRO" @ MSG_PT_GNU_RELRO_NF "gnu_relro" +@ MSG_PT_PAX_FLAGS "[ PT_PAX_FLAGS ]" # 0x65041580 +@ MSG_PT_PAX_FLAGS_CF "PT_PAX_FLAGS" +@ MSG_PT_PAX_FLAGS_CFNP "PAX_FLAGS" +@ MSG_PT_PAX_FLAGS_NF "pax_flags" @ MSG_PT_SUNWBSS "[ PT_SUNWBSS ]" # 0x6ffffffa @ MSG_PT_SUNWBSS_CF "PT_SUNWBSS" @@ -103,6 +109,30 @@ @ MSG_PF_W_NF "w" @ MSG_PF_R_CF "PF_R" # 0x4 @ MSG_PF_R_NF "r" +@ MSG_PF_PAGEEXEC_CF "PF_PAGEEXEC" # 0x00000010 +@ MSG_PF_PAGEEXEC_NF "pageexec" +@ MSG_PF_NOPAGEEXEC_CF "PF_NOPAGEEXEC" # 0x00000020 +@ MSG_PF_NOPAGEEXEC_NF "nopageexec" +@ MSG_PF_SEGMEXEC_CF "PF_SEGMEXEC" # 0x00000040 +@ MSG_PF_SEGMEXEC_NF "segmexec" +@ MSG_PF_NOSEGMEXEC_CF "PF_NOSEGMEXEC" # 0x00000080 +@ MSG_PF_NOSEGMEXEC_NF "nosegmexec" +@ MSG_PF_MPROTECT_CF "PF_MPROTECT" # 0x00000100 +@ MSG_PF_MPROTECT_NF "mprotect" +@ MSG_PF_NOMPROTECT_CF "PF_NOMPROTECT" # 0x00000200 +@ MSG_PF_NOMPROTECT_NF "nomprotect" +@ MSG_PF_RANDEXEC_CF "PF_RANDEXEC" # 0x00000400 +@ MSG_PF_RANDEXEC_NF "randexec" +@ MSG_PF_NORANDEXEC_CF "PF_NORANDEXEC" # 0x00000800 +@ MSG_PF_NORANDEXEC_NF "norandexec" +@ MSG_PF_EMUTRAMP_CF "PF_EMUTRAMP" # 0x00001000 +@ MSG_PF_EMUTRAMP_NF "emutramp" +@ MSG_PF_NOEMUTRAMP_CF "PF_NOEMUTRAMP" # 0x00002000 +@ MSG_PF_NOEMUTRAMP_NF "noemutramp" +@ MSG_PF_RANDMMAP_CF "PF_RANDMMAP" # 0x00004000 +@ MSG_PF_RANDMMAP_NF "randmmap" +@ MSG_PF_NORANDMMAP_CF "PF_NORANDMMAP" # 0x00008000 +@ MSG_PF_NORANDMMAP_NF "norandmmap" @ MSG_PF_SUNW_FAILURE_CF "PF_SUNW_FAILURE" # 0x00100000 @ MSG_PF_SUNW_FAILURE_NF "sunw_failure" @ MSG_PF_SUNW_KILLED_CF "PF_SUNW_KILLED" # 0x00200000 diff --git a/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg b/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg index fbc595f5f4..5b0ad9533a 100644 --- a/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg +++ b/usr/src/cmd/sgs/librtld_db/common/librtld_db.msg @@ -24,6 +24,10 @@ # Use is subject to license terms. # +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + # Message file for cmd/sgs/librtld_db. @ MSG_ID_LIBRTLD_DB @@ -104,7 +108,7 @@ @ MSG_DB_RDOBJPADE "rtld_db: rd_objpad_enable(padsize=0x%llx)" @ MSG_DB_64BIT_PREFIX "64/" @ MSG_DB_BRAND_HELPERPATH_PREFIX "%s/%s/%s/%s%s_librtld_db.so.1" -@ MSG_DB_BRAND_HELPERPATH "%s/%s/%s%s_librtld_db.so.1" +@ MSG_DB_BRAND_HELPERPATH "%s/%s/%s/%s%s_librtld_db.so.1" @ MSG_DB_HELPERNOOPS "rtld_db: helper lib loaded but ops not preset" @ MSG_DB_HELPERLOADED "rtld_db: helper library loaded for brand \"%s\"" @ MSG_DB_HELPERLOADFAILED "rtld_db: couldn't load brand helper library %s" diff --git a/usr/src/cmd/sgs/librtld_db/common/rd_elf.c b/usr/src/cmd/sgs/librtld_db/common/rd_elf.c index 410b819b30..b3de685b81 100644 --- a/usr/src/cmd/sgs/librtld_db/common/rd_elf.c +++ b/usr/src/cmd/sgs/librtld_db/common/rd_elf.c @@ -23,6 +23,10 @@ * Use is subject to license terms. */ +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + #include <stdlib.h> #include <stdio.h> #include <proc_service.h> @@ -38,6 +42,14 @@ #include <sys/param.h> /* + * We want to include zone.h to pull in the prototype for zone_get_nroot(), + * but we need to avoid pulling in <sys/stream.h>, which has a definition + * of M_DATA that conflicts with the ELF-related definition in machdep_*.h. + */ +#define _SYS_STREAM_H +#include <zone.h> + +/* * 64-bit builds are going to compile this module twice, the * second time with _ELF64 defined. These defines should make * all the necessary adjustments to the code. @@ -283,7 +295,9 @@ _rd_reset32(struct rd_agent *rap) * If we are debugging a branded executable, load the appropriate * helper library, and call its initialization routine. Being unable * to load the helper library is not a critical error. (Hopefully - * we'll still be able to access some objects in the target.) + * we'll still be able to access some objects in the target.) Note + * that we pull in the native root here to allow for helper libraries + * to be properly found from within the branded zone. */ ps_pbrandname = (ps_pbrandname_fp_t)dlsym(RTLD_PROBE, "ps_pbrandname"); while ((ps_pbrandname != NULL) && @@ -294,17 +308,23 @@ _rd_reset32(struct rd_agent *rap) isa = MSG_ORIG(MSG_DB_64BIT_PREFIX); #endif /* _LP64 */ - if (rtld_db_helper_path[0] != '\0') + if (rtld_db_helper_path[0] != '\0') { (void) snprintf(brandlib, MAXPATHLEN, MSG_ORIG(MSG_DB_BRAND_HELPERPATH_PREFIX), rtld_db_helper_path, MSG_ORIG(MSG_DB_HELPER_PREFIX), brandname, isa, brandname); - else + } else { + const char *nroot = zone_get_nroot(); + + if (nroot == NULL) + nroot = ""; + (void) snprintf(brandlib, MAXPATHLEN, - MSG_ORIG(MSG_DB_BRAND_HELPERPATH), + MSG_ORIG(MSG_DB_BRAND_HELPERPATH), nroot, MSG_ORIG(MSG_DB_HELPER_PREFIX), brandname, isa, brandname); + } rap->rd_helper.rh_dlhandle = dlopen(brandlib, RTLD_LAZY | RTLD_LOCAL); diff --git a/usr/src/cmd/sgs/nm/amd64/Makefile b/usr/src/cmd/sgs/nm/amd64/Makefile index 0b9d1b6992..cb2d8a5fb5 100644 --- a/usr/src/cmd/sgs/nm/amd64/Makefile +++ b/usr/src/cmd/sgs/nm/amd64/Makefile @@ -22,7 +22,7 @@ # Copyright 2010 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# Copyright (c) 2018, Joyent, Inc. +# Copyright (c) 2019, Joyent, Inc. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # @@ -44,10 +44,6 @@ INCLIST= -I../../include -I../../include/i386 \ -I$(SRCBASE)/uts/$(ARCH)/sys CPPFLAGS= $(INCLIST) $(DEFLIST) $(CPPFLAGS.master) -I$(ELFCAP) -CERRWARN += -_gcc=-Wno-uninitialized - -SMOFF += precedence,indenting - LDLIBS += $(CONVLIBDIR64) $(CONV_LIB) $(ELFLIBDIR) -lelf %.o: ../common/%.c diff --git a/usr/src/cmd/sgs/nm/common/nm.c b/usr/src/cmd/sgs/nm/common/nm.c index fc3ded721e..2e750a559b 100644 --- a/usr/src/cmd/sgs/nm/common/nm.c +++ b/usr/src/cmd/sgs/nm/common/nm.c @@ -26,6 +26,7 @@ * * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2018 Jason King + * Copyright 2019, Joyent, Inc. */ #include <stdio.h> @@ -76,7 +77,7 @@ typedef struct { /* structure to translate symbol table data */ #define REG_WEAK "R*" #define REG_LOCL "r" -#define OPTSTR ":APDoxhvnursplLCVefgRTt:" /* option string for getopt() */ +#define OPTSTR ":APDoxhvniursplLCVefgRTt:" /* option string for getopt() */ #define DATESIZE 60 @@ -116,6 +117,7 @@ static int /* flags: ?_flag corresponds to ? option */ h_flag = 0, /* suppress printing of headings */ v_flag = 0, /* sort external symbols by value */ n_flag = 0, /* sort external symbols by name */ + i_flag = 0, /* don't sort symbols */ u_flag = 0, /* print only undefined symbols */ r_flag = 0, /* prepend object file or archive name */ /* to each symbol name */ @@ -210,141 +212,185 @@ main(int argc, char *argv[], char *envp[]) while ((optchar = getopt(argc, argv, optstr)) != -1) { switch (optchar) { - case 'o': if (COMPAT_FMT_FLAG(FMT_T_OCT)) - fmt_flag = FMT_T_OCT; - else - (void) fprintf(stderr, gettext( - "%s: -x or -t set, -o ignored\n"), - prog_name); - break; - case 'x': if (COMPAT_FMT_FLAG(FMT_T_HEX)) - fmt_flag = FMT_T_HEX; - else - (void) fprintf(stderr, gettext( - "%s: -o or -t set, -x ignored\n"), - prog_name); - break; - case 'h': h_flag = 1; - break; - case 'v': if (!n_flag) - v_flag = 1; - else - (void) fprintf(stderr, gettext( - "%s: -n set, -v ignored\n"), - prog_name); - break; - case 'n': if (!v_flag) - n_flag = 1; - else - (void) fprintf(stderr, gettext( - "%s: -v set, -n ignored\n"), - prog_name); - break; - case 'u': if (!e_flag && !g_flag) - u_flag = 1; - else - (void) fprintf(stderr, gettext( - "%s: -e or -g set, -u ignored\n"), - prog_name); - break; - case 'e': if (!u_flag && !g_flag) - e_flag = 1; - else - (void) fprintf(stderr, gettext( - "%s: -u or -g set, -e ignored\n"), - prog_name); - break; - case 'g': if (!u_flag && !e_flag) - g_flag = 1; - else - (void) fprintf(stderr, gettext( - "%s: -u or -e set, -g ignored\n"), - prog_name); - break; - case 'r': if (R_flag) { - R_flag = 0; - (void) fprintf(stderr, gettext( - "%s: -r set, -R ignored\n"), - prog_name); - } - r_flag = 1; - break; - case 's': s_flag = 1; - break; - case 'p': if (P_flag == 1) { - (void) fprintf(stderr, gettext( - "nm: -P set. -p ignored\n")); - } else - p_flag = 1; - break; - case 'P': if (p_flag == 1) { - (void) fprintf(stderr, gettext( - "nm: -p set. -P ignored\n")); - } else - P_flag = 1; - break; - case 'l': l_flag = 1; - break; - case 'L': if (D_flag == 1) { - (void) fprintf(stderr, gettext( - "nm: -D set. -L ignored\n")); - } else - L_flag = 1; - break; - case 'D': if (L_flag == 1) { - (void) fprintf(stderr, gettext( - "nm: -L set. -D ignored\n")); - } else - D_flag = 1; - break; + case 'o': + if (COMPAT_FMT_FLAG(FMT_T_OCT)) { + fmt_flag = FMT_T_OCT; + } else { + (void) fprintf(stderr, gettext( + "%s: -x or -t set, -o ignored\n"), + prog_name); + } + break; + case 'x': + if (COMPAT_FMT_FLAG(FMT_T_HEX)) { + fmt_flag = FMT_T_HEX; + } else { + (void) fprintf(stderr, gettext( + "%s: -o or -t set, -x ignored\n"), + prog_name); + } + break; + case 'h': + h_flag = 1; + break; + case 'v': + if (!n_flag && !i_flag) { + v_flag = 1; + } else { + (void) fprintf(stderr, gettext( + "%s: -n or -i set, -v ignored\n"), + prog_name); + } + break; + case 'n': + if (!v_flag && !i_flag) { + n_flag = 1; + } else { + (void) fprintf(stderr, gettext( + "%s: -v or -i set, -n ignored\n"), + prog_name); + } + break; + case 'i': + if (!n_flag && !v_flag) { + i_flag = 1; + } else { + (void) fprintf(stderr, gettext( + "%s: -n or -v set, -i ignored\n"), + prog_name); + } + break; + case 'u': + if (!e_flag && !g_flag) { + u_flag = 1; + } else { + (void) fprintf(stderr, gettext( + "%s: -e or -g set, -u ignored\n"), + prog_name); + } + break; + case 'e': + if (!u_flag && !g_flag) { + e_flag = 1; + } else { + (void) fprintf(stderr, gettext( + "%s: -u or -g set, -e ignored\n"), + prog_name); + } + break; + case 'g': + if (!u_flag && !e_flag) { + g_flag = 1; + } else { + (void) fprintf(stderr, gettext( + "%s: -u or -e set, -g ignored\n"), + prog_name); + } + break; + case 'r': + if (R_flag) { + R_flag = 0; + (void) fprintf(stderr, gettext( + "%s: -r set, -R ignored\n"), + prog_name); + } + r_flag = 1; + break; + case 's': + s_flag = 1; + break; + case 'p': + if (P_flag == 1) { + (void) fprintf(stderr, gettext( + "nm: -P set. -p ignored\n")); + } else { + p_flag = 1; + } + break; + case 'P': + if (p_flag == 1) { + (void) fprintf(stderr, gettext( + "nm: -p set. -P ignored\n")); + } else { + P_flag = 1; + } + break; + case 'l': + l_flag = 1; + break; + case 'L': + if (D_flag == 1) { + (void) fprintf(stderr, gettext( + "nm: -D set. -L ignored\n")); + } else { + L_flag = 1; + } + break; + case 'D': + if (L_flag == 1) { + (void) fprintf(stderr, gettext( + "nm: -L set. -D ignored\n")); + } else { + D_flag = 1; + } + break; case 'C': - C_flag = 1; - break; - case 'A': A_flag = 1; - break; - case 'V': V_flag = 1; - (void) fprintf(stderr, "nm: %s %s\n", - (const char *)SGU_PKG, - (const char *)SGU_REL); - break; + C_flag = 1; + break; + case 'A': + A_flag = 1; + break; + case 'V': + V_flag = 1; + (void) fprintf(stderr, "nm: %s %s\n", + (const char *)SGU_PKG, + (const char *)SGU_REL); + break; case 'f': /* -f is a noop, see man page */ - break; - case 'R': if (!r_flag) - R_flag = 1; - else - (void) fprintf(stderr, gettext( - "%s: -r set, -R ignored\n"), - prog_name); - break; + break; + case 'R': + if (!r_flag) { + R_flag = 1; + } else { + (void) fprintf(stderr, gettext( + "%s: -r set, -R ignored\n"), + prog_name); + } + break; case 'T': - break; - case 't': if (strcmp(optarg, "o") == 0) { - new_fmt_flag = FMT_T_OCT; - } else if (strcmp(optarg, "d") == 0) { - new_fmt_flag = FMT_T_DEC; - } else if (strcmp(optarg, "x") == 0) { - new_fmt_flag = FMT_T_HEX; - } else { - new_fmt_flag = FMT_T_NONE; - } - if (new_fmt_flag == FMT_T_NONE) { - errflag += 1; - (void) fprintf(stderr, gettext( -"nm: -t requires radix value (d, o, x): %s\n"), optarg); - } else if (COMPAT_FMT_FLAG(new_fmt_flag)) { - fmt_flag = new_fmt_flag; - } else { - (void) fprintf(stderr, gettext( - "nm: -t or -o or -x set. -t ignored.\n")); - } - break; - case ':': errflag += 1; + break; + case 't': + if (strcmp(optarg, "o") == 0) { + new_fmt_flag = FMT_T_OCT; + } else if (strcmp(optarg, "d") == 0) { + new_fmt_flag = FMT_T_DEC; + } else if (strcmp(optarg, "x") == 0) { + new_fmt_flag = FMT_T_HEX; + } else { + new_fmt_flag = FMT_T_NONE; + } + if (new_fmt_flag == FMT_T_NONE) { + errflag += 1; + (void) fprintf(stderr, gettext( + "nm: -t requires radix value (d, o, x): " + "%s\n"), optarg); + } else if (COMPAT_FMT_FLAG(new_fmt_flag)) { + fmt_flag = new_fmt_flag; + } else { (void) fprintf(stderr, gettext( - "nm: %c requires operand\n"), optopt); - break; - case '?': errflag += 1; - break; - default: break; + "nm: -t or -o or -x set. -t ignored.\n")); + } + break; + case ':': + errflag += 1; + (void) fprintf(stderr, gettext( + "nm: %c requires operand\n"), optopt); + break; + case '?': + errflag += 1; + break; + default: + break; } } @@ -381,7 +427,7 @@ static void usage() { (void) fprintf(stderr, gettext( -"Usage: nm [-ACDhLlnPpRrsTVv] [-efox] [-g | -u] [-t d|o|x] file ...\n")); +"Usage: nm [-ACDhiLlnPpRrsTVv] [-efox] [-g | -u] [-t d|o|x] file ...\n")); } /* @@ -451,20 +497,20 @@ each_file(char *filename) (void) printf(gettext( "\n\nUndefined symbols from %s:\n\n"), filename); - } else if (!h_flag & !P_flag) + } else if ((h_flag == 0) && (P_flag == 0)) { #else - if (!h_flag & !P_flag) + if ((h_flag == 0) && (P_flag == 0)) { #endif - { - if (p_flag) + if (p_flag) { (void) printf("\n\n%s:\n", filename); - else { - if (A_flag != 0) + } else { + if (A_flag != 0) { (void) printf("\n\n%s%s:\n", A_header, filename); - else + } else { (void) printf("\n\n%s:\n", filename); + } } } archive_name = (char *)0; @@ -616,11 +662,11 @@ print_ar_files(int fd, Elf * elf_file, char *filename) continue; } - if (!h_flag & !P_flag) { - if (p_flag) + if ((h_flag == 0) && (P_flag == 0)) { + if (p_flag) { (void) printf("\n\n%s[%s]:\n", filename, p_ar->ar_name); - else { + } else { if (A_flag != 0) (void) printf("\n\n%s%s[%s]:\n", A_header, filename, p_ar->ar_name); @@ -715,8 +761,10 @@ print_symtab(Elf *elf_file, unsigned int shstrndx, prog_name, filename); return; } - qsort((char *)sym_data, count-1, sizeof (SYM), - (int (*)(const void *, const void *))compare); + if (i_flag == 0) { + qsort((char *)sym_data, count-1, sizeof (SYM), + (int (*)(const void *, const void *))compare); + } s = sym_data; while (count > 1) { #ifndef XPG4 @@ -725,18 +773,19 @@ print_symtab(Elf *elf_file, unsigned int shstrndx, * U_flag specified */ print_with_uflag(sym_data, filename); - } else if (p_flag) + } else if (p_flag) { #else - if (p_flag) + if (p_flag) { #endif print_with_pflag(ndigits, elf_file, shstrndx, sym_data, filename); - else if (P_flag) + } else if (P_flag) { print_with_Pflag(ndigits, elf_file, shstrndx, sym_data); - else + } else { print_with_otherflags(ndigits, elf_file, shstrndx, sym_data, filename); + } sym_data++; count--; } @@ -803,9 +852,9 @@ readsyms(Elf_Data * data, GElf_Sxword num, Elf *elf, buf->indx = i; /* allow to work on machines where NULL-derefs dump core */ - if (sym.st_name == 0) + if (sym.st_name == 0) { buf->name = ""; - else if (C_flag) { + } else if (C_flag) { const char *dn = NULL; char *name = (char *)elf_strptr(elf, link, sym.st_name); @@ -817,9 +866,9 @@ readsyms(Elf_Data * data, GElf_Sxword num, Elf *elf, name = FormatName(name, d_buf); } buf->name = name; - } - else + } else { buf->name = (char *)elf_strptr(elf, link, sym.st_name); + } buf->value = sym.st_value; buf->size = sym.st_size; @@ -1456,29 +1505,34 @@ parsename(char *s) void parse_fn_and_print(const char *str, char *s) { - char c, *p1, *p2; + char c = '\0', *p1, *p2; int yes = 1; - if ((p1 = p2 = strstr(s, "_c_")) == NULL) - if ((p1 = p2 = strstr(s, "_C_")) == NULL) - if ((p1 = p2 = strstr(s, "_cc_")) == NULL) - if ((p1 = p2 = strstr(s, "_cxx_")) == NULL) + if ((p1 = p2 = strstr(s, "_c_")) == NULL) { + if ((p1 = p2 = strstr(s, "_C_")) == NULL) { + if ((p1 = p2 = strstr(s, "_cc_")) == NULL) { + if ((p1 = p2 = strstr(s, "_cxx_")) == NULL) { if ((p1 = p2 = strstr(s, "_h_")) == - NULL) - yes = 0; - else + NULL) { + yes = 0; + } else { p2 += 2; - else + } + } else { p2 += 4; - else + } + } else { p2 += 3; - else + } + } else { p2 += 2; - else + } + } else { p2 += 2; + } if (yes) { - *p1 = '.'; + *p1 = '.'; c = *p2; *p2 = '\0'; } diff --git a/usr/src/cmd/sgs/nm/i386/Makefile b/usr/src/cmd/sgs/nm/i386/Makefile index c7d5bf8b0b..a6f7735af2 100644 --- a/usr/src/cmd/sgs/nm/i386/Makefile +++ b/usr/src/cmd/sgs/nm/i386/Makefile @@ -21,7 +21,7 @@ # # Copyright (c) 1993, 2010, Oracle and/or its affiliates. All rights reserved. # -# Copyright (c) 2018, Joyent, Inc. +# Copyright (c) 2019, Joyent, Inc. # Copyright 2019 OmniOS Community Edition (OmniOSce) Association. # @@ -46,10 +46,6 @@ INCLIST= -I../../include -I../../include/i386 \ DEFLIST= -DTARGET=I386 -DI386=1 -D$(ARFORMAT) -DELF CPPFLAGS= $(INCLIST) $(DEFLIST) $(CPPFLAGS.master) -I$(ELFCAP) -CERRWARN += -_gcc=-Wno-uninitialized - -SMOFF += precedence,indenting - LDLIBS += $(CONVLIBDIR) $(CONV_LIB) $(ELFLIBDIR) -lelf objs.xpg4/%.o := CPPFLAGS += -DXPG4 diff --git a/usr/src/cmd/sgs/nm/sparc/Makefile b/usr/src/cmd/sgs/nm/sparc/Makefile index 0fa774a310..a76d967545 100644 --- a/usr/src/cmd/sgs/nm/sparc/Makefile +++ b/usr/src/cmd/sgs/nm/sparc/Makefile @@ -45,7 +45,6 @@ INCLIST= -I../../include -I../../include/sparc \ -I$(SRCBASE)/uts/$(ARCH)/sys DEFLIST= -DTARGET=SPARC -DSPARC=1 -D$(ARFORMAT) -DELF CPPFLAGS= $(INCLIST) $(DEFLIST) $(CPPFLAGS.master) -I$(ELFCAP) -CERRWARN += -_gcc=-Wno-uninitialized LDLIBS += $(CONVLIBDIR) $(CONV_LIB) $(ELFLIBDIR) -lelf objs.xpg4/%.o := CPPFLAGS += -DXPG4 diff --git a/usr/src/cmd/sgs/nm/sparcv9/Makefile b/usr/src/cmd/sgs/nm/sparcv9/Makefile index 58bc8a5aff..75772f807c 100644 --- a/usr/src/cmd/sgs/nm/sparcv9/Makefile +++ b/usr/src/cmd/sgs/nm/sparcv9/Makefile @@ -43,7 +43,6 @@ INCLIST= -I../../include -I../../include/sparc \ -I$(SRCBASE)/uts/$(ARCH)/sys DEFLIST= -DTARGET=SPARC -DSPARC=1 -D$(ARFORMAT) -DELF CPPFLAGS= $(INCLIST) $(DEFLIST) $(CPPFLAGS.master) -I$(ELFCAP) -CERRWARN += -_gcc=-Wno-uninitialized LDLIBS += $(CONVLIBDIR64) $(CONV_LIB) $(ELFLIBDIR) -lelf diff --git a/usr/src/cmd/sgs/pvs/common/pvs.c b/usr/src/cmd/sgs/pvs/common/pvs.c index 4d51ce300d..4c353b887c 100644 --- a/usr/src/cmd/sgs/pvs/common/pvs.c +++ b/usr/src/cmd/sgs/pvs/common/pvs.c @@ -27,7 +27,7 @@ /* * Analyze the versioning information within a file. * - * -C demangle C++ symbol names. + * -C demangle symbol names. * * -d dump version definitions. * diff --git a/usr/src/cmd/sgs/pvs/common/pvs.msg b/usr/src/cmd/sgs/pvs/common/pvs.msg index 82a61385cd..eb888a753a 100644 --- a/usr/src/cmd/sgs/pvs/common/pvs.msg +++ b/usr/src/cmd/sgs/pvs/common/pvs.msg @@ -22,6 +22,7 @@ # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2018, Joyent, Inc. # @ _START_ @@ -34,7 +35,7 @@ # Argument usage messages. @ MSG_USAGE_BRIEF "usage: %s [-Cdlnorsv] [-I index] [-N Name] file(s)\n" -@ MSG_USAGE_DETAIL "\t[-C]\t\tdemangle C++ symbol names\n\ +@ MSG_USAGE_DETAIL "\t[-C]\t\tdemangle symbol names\n\ \t[-d]\t\tprint version definition information\n\ \t[-I index]\tqualify version with an index\n\ \t[-l]\t\tprint reduced symbols\n\ diff --git a/usr/src/cmd/sgs/rtld/common/_rtld.h b/usr/src/cmd/sgs/rtld/common/_rtld.h index ece14a855e..83b7071471 100644 --- a/usr/src/cmd/sgs/rtld/common/_rtld.h +++ b/usr/src/cmd/sgs/rtld/common/_rtld.h @@ -26,7 +26,7 @@ * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ #ifndef __RTLD_H #define __RTLD_H @@ -589,6 +589,8 @@ extern const char *rpl_ldflags; /* replaceable LD_FLAGS string */ extern const char *rpl_libpath; /* replaceable LD_LIBRARY string */ extern Alist *rpl_libdirs; /* and its associated Pdesc list */ extern const char *rpl_preload; /* replaceable LD_PRELOAD string */ +extern const char *rpl_ldtoxic; /* replaceable LD_TOXIC_PATH string */ +extern Alist *rpl_toxdirs; /* and associated Pdesc list */ extern const char *prm_audit; /* permanent LD_AUDIT string */ extern const char *prm_debug; /* permanent LD_DEBUG string */ diff --git a/usr/src/cmd/sgs/rtld/common/analyze.c b/usr/src/cmd/sgs/rtld/common/analyze.c index e14c121f07..3cae1036ae 100644 --- a/usr/src/cmd/sgs/rtld/common/analyze.c +++ b/usr/src/cmd/sgs/rtld/common/analyze.c @@ -21,6 +21,7 @@ /* * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2015, Joyent, Inc. */ /* @@ -834,6 +835,57 @@ is_so_loaded(Lm_list *lml, const char *name, int *in_nfavl) } /* + * Walk the toxic path list and determine if the object in question has violated + * the toxic path. When evaluating the toxic path we need to ensure that we + * match any path that's a subdirectory of a listed entry. In other words if + * /foo/bar is toxic, something in /foo/bar/baz/ is no good. However, we need to + * ensure that we don't mark /foo/barbaz/ as bad. + */ +static int +is_load_toxic(Lm_list *lml, Rt_map *nlmp) +{ + const char *fpath; + size_t flen; + Pdesc *pdp; + Aliste idx; + + fpath = PATHNAME(nlmp); + + /* + * If we have a NULL path name, that indicates that rtld is processing + * an in-memory shared object. For example, trying to run ldd or doing + * an LD_PRELOAD on an object file. In those cases, we'll always allow + * it. + */ + if (fpath == NULL) + return (0); + + flen = strlen(fpath); + + for (ALIST_TRAVERSE(rpl_toxdirs, idx, pdp)) { + if (pdp->pd_plen == 0) + continue; + + if (strncmp(pdp->pd_pname, fpath, pdp->pd_plen) == 0) { + if (pdp->pd_pname[pdp->pd_plen-1] != '/') { + /* + * Path didn't end in a /, make sure + * we're at a directory boundary + * nonetheless. + */ + if (flen > pdp->pd_plen && + fpath[pdp->pd_plen] == '/') + return (1); + continue; + } + return (1); + } + } + + return (0); +} + +/* * Tracing is enabled by the LD_TRACE_LOADED_OPTIONS environment variable which * is normally set from ldd(1). For each link map we load, print the load name * and the full pathname of the associated object. @@ -2169,6 +2221,17 @@ load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode, uint_t rdflags; /* + * If this dependency is associated with a toxic path, then we must + * honor the user's request to die. + */ + if (is_load_toxic(lml, nlmp) != 0) { + eprintf(lml, ERR_FATAL, MSG_INTL(MSG_TOXIC_FILE), + PATHNAME(nlmp)); + rtldexit(lml, 1); + + } + + /* * If this dependency is associated with a required version ensure that * the version is present in the loaded file. */ diff --git a/usr/src/cmd/sgs/rtld/common/external.c b/usr/src/cmd/sgs/rtld/common/external.c index 67429ac171..2476a6dbbc 100644 --- a/usr/src/cmd/sgs/rtld/common/external.c +++ b/usr/src/cmd/sgs/rtld/common/external.c @@ -22,7 +22,7 @@ /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2014 Garrett D'Amore <garrett@damore.org> - * Copyright 2016 Joyent, Inc. + * Copyright (c) 2017, Joyent, Inc. */ /* @@ -722,9 +722,9 @@ isalnum(int c) #if defined(__i386) || defined(__amd64) /* - * Instead of utilizing the comm page for clock_gettime, rtld uses the raw - * syscall instead. Doing so decreases the surface of symbols needed from libc - * for a modest performance cost. + * Instead of utilizing the comm page for clock_gettime and gettimeofday, rtld + * uses the raw syscall instead. Doing so decreases the surface of symbols + * needed from libc for a modest performance cost. */ extern int __clock_gettime_sys(clockid_t, struct timespec *); @@ -733,6 +733,22 @@ __clock_gettime(clockid_t clock_id, struct timespec *tp) { return (__clock_gettime_sys(clock_id, tp)); } + +int +gettimeofday(struct timeval *tv, void *tz) +{ + if (tv != NULL) { + /* + * Perform the same logic as the libc gettimeofday() when it + * lacks comm page support: Make the clock_gettime syscall and + * divide out the tv_usec field as required. + */ + __clock_gettime_sys(CLOCK_REALTIME, (timespec_t *)tv); + tv->tv_usec /= 1000; + } + + return (0); +} #endif /* defined(__i386) || defined(__amd64) */ /* diff --git a/usr/src/cmd/sgs/rtld/common/globals.c b/usr/src/cmd/sgs/rtld/common/globals.c index bb47b12540..45c08f8286 100644 --- a/usr/src/cmd/sgs/rtld/common/globals.c +++ b/usr/src/cmd/sgs/rtld/common/globals.c @@ -24,6 +24,7 @@ * All Rights Reserved * * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -132,6 +133,8 @@ const char *rpl_ldflags = NULL; /* replaceable LD_FLAGS string */ const char *rpl_libpath = NULL; /* replaceable LD_LIBRARY_PATH string */ Alist *rpl_libdirs = NULL; /* and associated Pdesc list */ const char *rpl_preload = NULL; /* replaceable LD_PRELOAD string */ +const char *rpl_ldtoxic = NULL; /* replaceable LD_TOXIC string */ +Alist *rpl_toxdirs = NULL; /* and associated Pdesc list */ const char *prm_audit = NULL; /* permanent LD_AUDIT string */ const char *prm_debug = NULL; /* permanent LD_DEBUG string */ diff --git a/usr/src/cmd/sgs/rtld/common/rtld.msg b/usr/src/cmd/sgs/rtld/common/rtld.msg index f629e7b64b..add19eaf80 100644 --- a/usr/src/cmd/sgs/rtld/common/rtld.msg +++ b/usr/src/cmd/sgs/rtld/common/rtld.msg @@ -21,6 +21,7 @@ # # Copyright (c) 1995, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, Joyent, Inc. All rights reserved. # @ _START_ @@ -99,9 +100,14 @@ @ MSG_SYS_MPROT "%s: mprotect failed: %s" @ MSG_SYS_MMAPANON "mmap anon failed: %s" +# Secure path failures + @ MSG_SEC_OPEN "%s: open failed: No such file in secure directories" @ MSG_SEC_ILLEGAL "%s: open failed: illegal insecure pathname" +# Toxic failures + +@ MSG_TOXIC_FILE "%s: dependency marked as toxic" # Configuration failures @@ -397,6 +403,7 @@ @ MSG_LD_PROFILE_OUTPUT "PROFILE_OUTPUT" @ MSG_LD_SFCAP "SFCAP" @ MSG_LD_SIGNAL "SIGNAL" +@ MSG_LD_TOXICPATH "TOXIC_PATH" @ MSG_LD_TRACE_OBJS "TRACE_LOADED_OBJECTS" @ MSG_LD_TRACE_OBJS_E "TRACE_LOADED_OBJECTS_E" @ MSG_LD_TRACE_OBJS_A "TRACE_LOADED_OBJECTS_A" diff --git a/usr/src/cmd/sgs/rtld/common/setup.c b/usr/src/cmd/sgs/rtld/common/setup.c index 862bb7d61f..98e3ba5d33 100644 --- a/usr/src/cmd/sgs/rtld/common/setup.c +++ b/usr/src/cmd/sgs/rtld/common/setup.c @@ -28,7 +28,7 @@ * All Rights Reserved */ /* - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ /* @@ -819,6 +819,14 @@ setup(char **envp, auxv_t *auxv, Word _flags, char *_platform, int _syspagsz, return (0); } + /* + * Initialize our toxic paths + */ + if (rpl_ldtoxic != NULL) { + (void) expand_paths(mlmp, rpl_ldtoxic, &rpl_toxdirs, + AL_CNT_SEARCH, 0, PD_TKN_CAP); + } + #if defined(_ELF64) /* * If this is a 64-bit process, determine whether this process has diff --git a/usr/src/cmd/sgs/rtld/common/util.c b/usr/src/cmd/sgs/rtld/common/util.c index 046c8297a0..f10f7a4aed 100644 --- a/usr/src/cmd/sgs/rtld/common/util.c +++ b/usr/src/cmd/sgs/rtld/common/util.c @@ -24,6 +24,7 @@ * All Rights Reserved * * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Joyent, Inc. All rights reserved. */ /* @@ -1428,6 +1429,7 @@ static u_longlong_t cmdisa = 0; /* command line (-e) ISA */ #define ENV_FLG_CAP_FILES 0x0080000000000ULL #define ENV_FLG_DEFERRED 0x0100000000000ULL #define ENV_FLG_NOENVIRON 0x0200000000000ULL +#define ENV_FLG_TOXICPATH 0x0400000000000ULL #define SEL_REPLACE 0x0001 #define SEL_PERMANT 0x0002 @@ -1601,8 +1603,7 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags, if ((len == MSG_LD_FLAGS_SIZE) && (strncmp(s1, MSG_ORIG(MSG_LD_FLAGS), MSG_LD_FLAGS_SIZE) == 0)) { select |= SEL_ACT_SPEC_1; - str = (select & SEL_REPLACE) ? &rpl_ldflags : - &prm_ldflags; + str = &rpl_ldflags; variable = ENV_FLG_FLAGS; } } @@ -1813,6 +1814,8 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags, * In case an auditor is called, which in turn might exec(2) a * subprocess, this variable is disabled, so that any subprocess * escapes ldd(1) processing. + * + * Also, look for LD_TOXIC_PATH */ else if (*s1 == 'T') { if (((len == MSG_LD_TRACE_OBJS_SIZE) && @@ -1850,7 +1853,13 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags, select |= SEL_ACT_LML; val = LML_FLG_TRC_SEARCH; variable = ENV_FLG_TRACE_PTHS; + } else if ((len == MSG_LD_TOXICPATH_SIZE) && (strncmp(s1, + MSG_ORIG(MSG_LD_TOXICPATH), MSG_LD_TOXICPATH_SIZE) == 0)) { + select |= SEL_ACT_SPEC_1; + str = &rpl_ldtoxic; + variable = ENV_FLG_TOXICPATH; } + } /* * LD_UNREF and LD_UNUSED (internal, used by ldd(1)). @@ -1974,7 +1983,8 @@ ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags, *lmtflags &= ~val; } else if (select & SEL_ACT_SPEC_1) { /* - * variable is either ENV_FLG_FLAGS or ENV_FLG_LIBPATH + * variable is either ENV_FLG_FLAGS, ENV_FLG_LIBPATH, or + * ENV_FLG_TOXICPATH */ if (env_flags & ENV_TYP_NULL) *str = NULL; diff --git a/usr/src/cmd/sgs/yacc/common/dextern.h b/usr/src/cmd/sgs/yacc/common/dextern.h index e90aa60468..54b441cac4 100644 --- a/usr/src/cmd/sgs/yacc/common/dextern.h +++ b/usr/src/cmd/sgs/yacc/common/dextern.h @@ -26,11 +26,13 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ + #ifndef _DEXTERN_H #define _DEXTERN_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <inttypes.h> #include <ctype.h> @@ -42,6 +44,7 @@ #include <unistd.h> #include <stdlib.h> #include <wctype.h> +#include <limits.h> #ifdef __cplusplus extern "C" { @@ -301,6 +304,12 @@ extern int wscmp(const wchar_t *, const wchar_t *); extern char *parser; +#ifndef PBUFSIZE +#define PBUFSIZE PATH_MAX +#endif + +extern char pbuf[PBUFSIZE]; + /* default settings for a number of macros */ /* name of yacc tempfiles */ @@ -324,7 +333,11 @@ extern char *parser; #endif #ifndef PARSER -#define PARSER "/usr/share/lib/ccs/yaccpar" +#define PARSER "/share/lib/ccs/yaccpar" +#endif + +#ifndef PARSERPREFIX +#define PARSERPREFIX "/usr" #endif /* diff --git a/usr/src/cmd/sgs/yacc/common/y1.c b/usr/src/cmd/sgs/yacc/common/y1.c index 845f82d367..0e67d9047b 100644 --- a/usr/src/cmd/sgs/yacc/common/y1.c +++ b/usr/src/cmd/sgs/yacc/common/y1.c @@ -26,7 +26,9 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include "dextern.h" #include <sys/param.h> @@ -34,6 +36,7 @@ #include <unistd.h> #include <locale.h> #include <stdarg.h> /* For error() */ +#include <libgen.h> static void mktbls(void); static void others(void); @@ -236,6 +239,25 @@ mktbls() lsetsize = INIT_LSIZE + 1; } +static int +yacc_assemble_path(char *buf, size_t size, const char *file, int type) +{ + int ret; + char origin[PATH_MAX]; + + if (type != 0) { + ret = readlink("/proc/self/path/a.out", origin, PATH_MAX - 1); + if (ret < 0) + error(gettext( + "yacc: failed to read origin from /proc\n")); + origin[ret] = '\0'; + return (snprintf(buf, size, "%s/../%s", dirname(origin), + file)); + } + + return (snprintf(buf, size, "%s/%s", PARSERPREFIX, file)); +} + /* put out other arrays, copy the parsers */ static void others() @@ -244,7 +266,17 @@ others() int c, i, j; int tmpline; - finput = fopen(parser, "r"); + if (parser == NULL) { + parser = pbuf; + (void) yacc_assemble_path(pbuf, PBUFSIZE, PARSER, 1); + finput = fopen(parser, "r"); + if (finput == NULL) { + (void) yacc_assemble_path(pbuf, PBUFSIZE, PARSER, 0); + finput = fopen(parser, "r"); + } + } else { + finput = fopen(parser, "r"); + } if (finput == NULL) /* * TRANSLATION_NOTE -- This is a message from yacc. diff --git a/usr/src/cmd/sgs/yacc/common/y2.c b/usr/src/cmd/sgs/yacc/common/y2.c index fbdaf19445..0d97f4260f 100644 --- a/usr/src/cmd/sgs/yacc/common/y2.c +++ b/usr/src/cmd/sgs/yacc/common/y2.c @@ -26,6 +26,10 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ + #include "dextern.h" #include "sgs.h" #include <stdio.h> @@ -58,7 +62,8 @@ char *infile; /* input file name */ static int numbval; /* value of an input number */ static int toksize = NAMESIZE; static wchar_t *tokname; /* input token name */ -char *parser = PARSER; /* location of common parser */ +char *parser = NULL; /* location of common parser */ +char pbuf[PBUFSIZE]; static void finact(void); static wchar_t *cstash(wchar_t *); diff --git a/usr/src/cmd/smbios/Makefile b/usr/src/cmd/smbios/Makefile index f3d7803a78..ead08c39ac 100644 --- a/usr/src/cmd/smbios/Makefile +++ b/usr/src/cmd/smbios/Makefile @@ -22,6 +22,8 @@ # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright 2018 Joyent, Inc. +# PROG = smbios OBJS = smbios.o @@ -30,11 +32,13 @@ SRCS = $(OBJS:%.o=%.c) include ../Makefile.cmd CFLAGS += $(CCVERBOSE) -LDLIBS += -lsmbios +LDLIBS += -lsmbios -ljedec FILEMODE = 0555 STRIPFLAG = +LINTFLAGS += -erroff=E_BAD_PTR_CAST_ALIGN + .KEEP_STATE: all: $(PROG) diff --git a/usr/src/cmd/smbios/smbios.c b/usr/src/cmd/smbios/smbios.c index a40e393a91..a038b00cf0 100644 --- a/usr/src/cmd/smbios/smbios.c +++ b/usr/src/cmd/smbios/smbios.c @@ -21,7 +21,7 @@ /* * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. - * Copyright (c) 2017, Joyent, Inc. + * Copyright (c) 2018, Joyent, Inc. * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -40,6 +40,7 @@ #include <fcntl.h> #include <errno.h> #include <ctype.h> +#include <libjedec.h> #define SMBIOS_SUCCESS 0 #define SMBIOS_ERROR 1 @@ -55,6 +56,17 @@ static int opt_s; static int opt_t = -1; static int opt_x; +static boolean_t +smbios_vergteq(smbios_version_t *v, uint_t major, uint_t minor) +{ + if (v->smbv_major > major) + return (B_TRUE); + if (v->smbv_major == major && + v->smbv_minor >= minor) + return (B_TRUE); + return (B_FALSE); +} + /*PRINTFLIKE2*/ static void smbios_warn(smbios_hdl_t *shp, const char *format, ...) @@ -159,6 +171,22 @@ id_printf(FILE *fp, const char *s, id_t id) } } +static void +jedec_print(FILE *fp, const char *desc, uint_t id) +{ + const char *name; + uint_t cont, vendor; + + vendor = id & 0xff; + cont = (id >> 8) & 0xff; + name = libjedec_vendor_string(cont, vendor); + if (name == NULL) { + oprintf(fp, " %s: 0x%x\n", desc, id); + } else { + oprintf(fp, " %s: 0x%x (%s)\n", desc, id, name); + } +} + static int check_oem(smbios_hdl_t *shp) { @@ -334,10 +362,30 @@ print_system(smbios_hdl_t *shp, FILE *fp) (void) smbios_info_system(shp, &s); + /* + * SMBIOS definition section 3.3.2.1 is clear that the first three + * fields are little-endian, but this utility traditionally got this + * wrong, and followed RFC 4122. We keep this old behavior, but also + * provide a corrected UUID. + */ oprintf(fp, " UUID: "); - for (i = 0; i < s.smbs_uuidlen; i++) { + oprintf(fp, "%02x%02x%02x%02x-%02x%02x-%02x%02x-", + s.smbs_uuid[0], s.smbs_uuid[1], s.smbs_uuid[2], s.smbs_uuid[3], + s.smbs_uuid[4], s.smbs_uuid[5], s.smbs_uuid[6], s.smbs_uuid[7]); + for (i = 8; i < s.smbs_uuidlen; i++) { + oprintf(fp, "%02x", s.smbs_uuid[i]); + if (i == 9) + oprintf(fp, "-"); + } + oprintf(fp, "\n"); + + oprintf(fp, " UUID (Endian-corrected): "); + oprintf(fp, "%08x-%04hx-%04hx-", *((uint_t *)&s.smbs_uuid[0]), + *((ushort_t *)&s.smbs_uuid[4]), + *((ushort_t *)&s.smbs_uuid[6])); + for (i = 8; i < s.smbs_uuidlen; i++) { oprintf(fp, "%02x", s.smbs_uuid[i]); - if (i == 3 || i == 5 || i == 7 || i == 9) + if (i == 9) oprintf(fp, "-"); } oprintf(fp, "\n"); @@ -656,12 +704,41 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) s.smbl_ch2, sizeof (s.smbl_ch2) * NBBY, smbios_slot_ch2_name, smbios_slot_ch2_desc); - if (check_oem(shp) != 0 && (v.smbv_major < 2 || v.smbv_minor < 6)) + if (check_oem(shp) != 0 && !smbios_vergteq(&v, 2, 6)) return; oprintf(fp, " Segment Group: %u\n", s.smbl_sg); oprintf(fp, " Bus Number: %u\n", s.smbl_bus); - oprintf(fp, " Device/Function Number: %u\n", s.smbl_df); + oprintf(fp, " Device/Function Number: %u/%u\n", s.smbl_df >> 3, + s.smbl_df & 0x7); + + if (s.smbl_dbw != 0) { + oprintf(fp, " Data Bus Width: %d\n", s.smbl_dbw); + } + + if (s.smbl_npeers > 0) { + smbios_slot_peer_t *peer; + uint_t i, npeers; + + if (smbios_info_slot_peers(shp, id, &npeers, &peer) != 0) { + smbios_warn(shp, "failed to read slot peer " + "information"); + return; + } + + for (i = 0; i < npeers; i++) { + oprintf(fp, " Slot Peer %u:\n", i); + oprintf(fp, " Segment group: %u\n", + peer[i].smblp_group); + oprintf(fp, " Bus/Device/Function: %u/%u/%u", + peer[i].smblp_bus, peer[i].smblp_device, + peer[i].smblp_function); + oprintf(fp, " Electrical width: %u\n", + peer[i].smblp_data_width); + } + + smbios_info_slot_peers_free(shp, npeers, peer); + } } static void @@ -931,6 +1008,68 @@ print_memdevice(smbios_hdl_t *shp, id_t id, FILE *fp) } else { oprintf(fp, " Configured Voltage: Unknown\n"); } + + if (md.smbmd_memtech != 0) { + desc_printf(smbios_memdevice_memtech_desc(md.smbmd_memtech), + fp, " Memory Technology: %u", md.smbmd_memtech); + } + + if (md.smbmd_opcap_flags != 0) { + flag_printf(fp, " Operating Mode Capabilities", + md.smbmd_opcap_flags, sizeof (md.smbmd_opcap_flags) * NBBY, + smbios_memdevice_op_capab_name, + smbios_memdevice_op_capab_desc); + } + + if (md.smbmd_firmware_rev[0] != '\0') { + oprintf(fp, " Firmware Revision: %s\n", md.smbmd_firmware_rev); + } + + if (md.smbmd_modmfg_id != 0) { + jedec_print(fp, "Module Manufacturer ID", md.smbmd_modmfg_id); + } + + if (md.smbmd_modprod_id != 0) { + jedec_print(fp, "Module Product ID", md.smbmd_modprod_id); + } + + if (md.smbmd_cntrlmfg_id != 0) { + jedec_print(fp, "Memory Subsystem Controller Manufacturer ID", + md.smbmd_cntrlmfg_id); + } + + if (md.smbmd_cntrlprod_id != 0) { + jedec_print(fp, "Memory Subsystem Controller Product ID", + md.smbmd_cntrlprod_id); + } + + if (md.smbmd_nvsize == UINT64_MAX) { + oprintf(fp, " Non-volatile Size: Unknown\n"); + } else if (md.smbmd_nvsize != 0) { + oprintf(fp, " Non-volatile Size: %llu bytes\n", + (u_longlong_t)md.smbmd_nvsize); + } + + if (md.smbmd_volatile_size == UINT64_MAX) { + oprintf(fp, " Volatile Size: Unknown\n"); + } else if (md.smbmd_volatile_size != 0) { + oprintf(fp, " Volatile Size: %llu bytes\n", + (u_longlong_t)md.smbmd_volatile_size); + } + + if (md.smbmd_cache_size == UINT64_MAX) { + oprintf(fp, " Volatile Size: Unknown\n"); + } else if (md.smbmd_cache_size != 0) { + oprintf(fp, " Volatile Size: %llu bytes\n", + (u_longlong_t)md.smbmd_cache_size); + } + + if (md.smbmd_logical_size == UINT64_MAX) { + oprintf(fp, " Volatile Size: Unknown\n"); + } else if (md.smbmd_logical_size != 0) { + oprintf(fp, " Volatile Size: %llu bytes\n", + (u_longlong_t)md.smbmd_logical_size); + } } static void diff --git a/usr/src/cmd/ssh/THIRDPARTYLICENSE.descrip b/usr/src/cmd/ssh/THIRDPARTYLICENSE.descrip deleted file mode 100644 index 7e936fffc7..0000000000 --- a/usr/src/cmd/ssh/THIRDPARTYLICENSE.descrip +++ /dev/null @@ -1 +0,0 @@ -OPENSSH SOFTWARE diff --git a/usr/src/cmd/ssh/doc/LICENCE b/usr/src/cmd/ssh/doc/LICENCE deleted file mode 100644 index 04d6fe18e3..0000000000 --- a/usr/src/cmd/ssh/doc/LICENCE +++ /dev/null @@ -1,194 +0,0 @@ -This file is part of the ssh software. - -The licences which components of this software falls under are as -follows. First, we will summarize and say that that all components -are under a BSD licence, or a licence more free than that. - -OpenSSH contains no GPL code. - -1) - * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland - * All rights reserved - * - * As far as I am concerned, the code I have written for this software - * can be used freely for any purpose. Any derived versions of this - * software must be clearly marked as such, and if the derived work is - * incompatible with the protocol description in the RFC file, it must be - * called by a name other than "ssh" or "Secure Shell". - - [Tatu continues] - * However, I am not implying to give any licenses to any patents or - * copyrights held by third parties, and the software includes parts that - * are not under my direct control. As far as I know, all included - * source code is used in accordance with the relevant license agreements - * and can be used freely for any purpose (the GNU license being the most - * restrictive); see below for details. - - [However, none of that term is relevant at this point in time. All of - these restrictively licenced software components which he talks about - have been removed from OpenSSH, ie. - - - RSA is no longer included, found in the OpenSSL library - - IDEA is no longer included, it's use is depricated - - DES is now external, in the OpenSSL library - - GMP is no longer used, and instead we call BN code from OpenSSL - - Zlib is now external, in a library - - The make-ssh-known-hosts script is no longer included - - TSS has been removed - - MD5 is now external, in the OpenSSL library - - RC4 support has been replaced with ARC4 support from OpenSSL - - Blowfish is now external, in the OpenSSL library - - [The licence continues] - - Note that any information and cryptographic algorithms used in this - software are publicly available on the Internet and at any major - bookstore, scientific library, and patent office worldwide. More - information can be found e.g. at "http://www.cs.hut.fi/crypto". - - The legal status of this program is some combination of all these - permissions and restrictions. Use only at your own responsibility. - You will be responsible for any legal consequences yourself; I am not - making any claims whether possessing or using this is legal or not in - your country, and I am not taking any responsibility on your behalf. - - - NO WARRANTY - - BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY - FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN - OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES - PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED - OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS - TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE - PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, - REPAIR OR CORRECTION. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING - WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR - REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, - INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING - OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED - TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY - YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER - PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE - POSSIBILITY OF SUCH DAMAGES. - -2) - The 32-bit CRC implementation in crc32.c is due to Gary S. Brown. - Comments in the file indicate it may be used for any purpose without - restrictions: - - * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or - * code or tables extracted from it, as desired without restriction. - -3) - The 32-bit CRC compensation attack detector in deattack.c was - contributed by CORE SDI S.A. under a BSD-style license. See - http://www.core-sdi.com/english/ssh/ for details. - - * Cryptographic attack detector for ssh - source code - * - * Copyright (c) 1998 CORE SDI S.A., Buenos Aires, Argentina. - * - * All rights reserved. Redistribution and use in source and binary - * forms, with or without modification, are permitted provided that - * this copyright notice is retained. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES ARE DISCLAIMED. IN NO EVENT SHALL CORE SDI S.A. BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR - * CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OR MISUSE OF THIS - * SOFTWARE. - * - * Ariel Futoransky <futo@core-sdi.com> - * <http://www.core-sdi.com> - -3a) - Various parts are from the University of California. - - * Copyright (c) 1983, 1987, 1989-1995 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND 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. - - * Copyright (c) 1989, 1991, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND 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. - -4) - Remaining components of the software are provided under a standard - 2-term BSD licence with the following names as copyright holders: - - Markus Friedl - Theo de Raadt - Niels Provos - Dug Song - Aaron Campbell - - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 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. diff --git a/usr/src/cmd/ssh/etc/ssh.xml b/usr/src/cmd/ssh/etc/ssh.xml deleted file mode 100644 index f5fb471669..0000000000 --- a/usr/src/cmd/ssh/etc/ssh.xml +++ /dev/null @@ -1,177 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- - CDDL HEADER START - - The contents of this file are subject to the terms of the - Common Development and Distribution License (the "License"). - You may not use this file except in compliance with the License. - - You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - or http://www.opensolaris.org/os/licensing. - See the License for the specific language governing permissions - and limitations under the License. - - When distributing Covered Code, include this CDDL HEADER in each - file and include the License file at usr/src/OPENSOLARIS.LICENSE. - If applicable, add the following below this CDDL HEADER, with the - fields enclosed by brackets "[]" replaced with your own identifying - information: Portions Copyright [yyyy] [name of copyright owner] - - CDDL HEADER END - - Copyright 2009 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> - - NOTE: This service manifest is not editable; its contents will - be overwritten by package or patch operations, including - operating system upgrade. Make customizations in a different - file. ---> - -<service_bundle type='manifest' name='SUNWsshdr:ssh'> - -<service - name='network/ssh' - type='service' - version='1'> - - <create_default_instance enabled='false' /> - - <single_instance /> - - <dependency name='fs-local' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri - value='svc:/system/filesystem/local' /> - </dependency> - - <dependency name='fs-autofs' - grouping='optional_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/system/filesystem/autofs' /> - </dependency> - - <dependency name='net-loopback' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/network/loopback' /> - </dependency> - - <dependency name='net-physical' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/network/physical' /> - </dependency> - - <dependency name='cryptosvc' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/system/cryptosvc' /> - </dependency> - - <dependency name='utmp' - grouping='require_all' - restart_on='none' - type='service'> - <service_fmri value='svc:/system/utmp' /> - </dependency> - - <dependency name='network_ipfilter' - grouping='optional_all' - restart_on='error' - type='service'> - <service_fmri value='svc:/network/ipfilter:default' /> - </dependency> - - <dependency name='config_data' - grouping='require_all' - restart_on='restart' - type='path'> - <service_fmri - value='file://localhost/etc/ssh/sshd_config' /> - </dependency> - - <dependent - name='ssh_multi-user-server' - grouping='optional_all' - restart_on='none'> - <service_fmri - value='svc:/milestone/multi-user-server' /> - </dependent> - - <exec_method - type='method' - name='start' - exec='/lib/svc/method/sshd start' - timeout_seconds='60'/> - - <exec_method - type='method' - name='stop' - exec=':kill' - timeout_seconds='60' /> - - <exec_method - type='method' - name='refresh' - exec='/lib/svc/method/sshd restart' - timeout_seconds='60' /> - - <property_group name='startd' - type='framework'> - <!-- sub-process core dumps shouldn't restart session --> - <propval name='ignore_error' - type='astring' value='core,signal' /> - </property_group> - - <property_group name='general' type='framework'> - <!-- to start stop sshd --> - <propval name='action_authorization' type='astring' - value='solaris.smf.manage.ssh' /> - </property_group> - - <property_group name='firewall_context' type='com.sun,fw_definition'> - <propval name='name' type='astring' value='ssh' /> - <propval name='ipf_method' type='astring' - value='/lib/svc/method/sshd ipfilter' /> - </property_group> - - <property_group name='firewall_config' type='com.sun,fw_configuration'> - <propval name='policy' type='astring' value='use_global' /> - <propval name='block_policy' type='astring' - value='use_global' /> - <propval name='apply_to' type='astring' value='' /> - <propval name='apply_to_6' type='astring' value='' /> - <propval name='exceptions' type='astring' value='' /> - <propval name='exceptions_6' type='astring' value='' /> - <propval name='target' type='astring' value='' /> - <propval name='target_6' type='astring' value='' /> - <propval name='value_authorization' type='astring' - value='solaris.smf.value.firewall.config' /> - </property_group> - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - SSH server - </loctext> - </common_name> - <documentation> - <manpage title='sshd' section='1M' manpath='/usr/share/man' /> - </documentation> - </template> - -</service> - -</service_bundle> diff --git a/usr/src/cmd/ssh/etc/ssh_config b/usr/src/cmd/ssh/etc/ssh_config deleted file mode 100644 index cdb9d97d45..0000000000 --- a/usr/src/cmd/ssh/etc/ssh_config +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -# ident "%Z%%M% %I% %E% SMI" -# -# This file provides defaults for ssh(1). -# The values can be changed in per-user configuration files $HOME/.ssh/config -# or on the command line of ssh(1). - -# Configuration data is parsed as follows: -# 1. command line options -# 2. user-specific file -# 3. system-wide file /etc/ssh/ssh_config -# -# Any configuration value is only changed the first time it is set. -# host-specific definitions should be at the beginning of the -# configuration file, and defaults at the end. - -# Example (matches compiled in defaults): -# -# Host * -# ForwardAgent no -# ForwardX11 no -# PubkeyAuthentication yes -# PasswordAuthentication yes -# FallBackToRsh no -# UseRsh no -# BatchMode no -# CheckHostIP yes -# StrictHostKeyChecking ask -# EscapeChar ~ diff --git a/usr/src/cmd/ssh/etc/sshd b/usr/src/cmd/ssh/etc/sshd deleted file mode 100644 index d52b1afd25..0000000000 --- a/usr/src/cmd/ssh/etc/sshd +++ /dev/null @@ -1,127 +0,0 @@ -#!/sbin/sh -# -# Copyright 2010 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# Copyright 2016 Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org> -# - -. /lib/svc/share/ipf_include.sh -. /lib/svc/share/smf_include.sh - -SSHDIR=/etc/ssh -KEYGEN="/usr/bin/ssh-keygen -q" -PIDFILE=/var/run/sshd.pid - -# Checks to see if RSA, and DSA host keys are available -# if any of these keys are not present, the respective keys are created. -create_key() -{ - keypath=$1 - keytype=$2 - - if [ ! -f $keypath ]; then - # - # HostKey keywords in sshd_config may be preceded or - # followed by a mix of any number of space or tabs, - # and optionally have an = between keyword and - # argument. We use two grep invocations such that we - # can match HostKey case insensitively but still have - # the case of the path name be significant, keeping - # the pattern somewhat more readable. - # - # The character classes below contain one literal - # space and one literal tab. - # - grep -i "^[ ]*HostKey[ ]*=\{0,1\}[ ]*$keypath" \ - $SSHDIR/sshd_config | grep "$keypath" > /dev/null 2>&1 - - if [ $? -eq 0 ]; then - echo Creating new $keytype public/private host key pair - $KEYGEN -f $keypath -t $keytype -N '' - if [ $? -ne 0 ]; then - echo "Could not create $keytype key: $keypath" - exit $SMF_EXIT_ERR_CONFIG - fi - fi - fi -} - -create_ipf_rules() -{ - FMRI=$1 - ipf_file=`fmri_to_file ${FMRI} $IPF_SUFFIX` - ipf6_file=`fmri_to_file ${FMRI} $IPF6_SUFFIX` - policy=`get_policy ${FMRI}` - - # - # Get port from /etc/ssh/sshd_config - # - tports=`grep "^Port" /etc/ssh/sshd_config 2>/dev/null | \ - awk '{print $2}'` - - echo "# $FMRI" >$ipf_file - echo "# $FMRI" >$ipf6_file - for port in $tports; do - generate_rules $FMRI $policy "tcp" $port $ipf_file - generate_rules $FMRI $policy "tcp" $port $ipf6_file _6 - done -} - -# This script is being used for two purposes: as part of an SMF -# start/stop/refresh method, and as a sysidconfig(1M)/sys-unconfig(1M) -# application. -# -# Both, the SMF methods and sysidconfig/sys-unconfig use different -# arguments.. - -case $1 in - # sysidconfig/sys-unconfig arguments (-c and -u) -'-c') - /usr/bin/ssh-keygen -A - if [ $? -ne 0 ]; then - create_key $SSHDIR/ssh_host_rsa_key rsa - create_key $SSHDIR/ssh_host_dsa_key dsa - fi - ;; - -'-u') - # sys-unconfig(1M) knows how to remove ssh host keys, so there's - # nothing to do here. - : - ;; - - # SMF arguments (start and restart [really "refresh"]) - -'ipfilter') - create_ipf_rules $2 - ;; - -'start') - # - # If host keys don't exist when the service is started, create - # them; sysidconfig is not run in every situation (such as on - # the install media). - # - /usr/bin/ssh-keygen -A - if [ $? -ne 0 ]; then - create_key $SSHDIR/ssh_host_rsa_key rsa - create_key $SSHDIR/ssh_host_dsa_key dsa - fi - - /usr/lib/ssh/sshd - ;; - -'restart') - if [ -f "$PIDFILE" ]; then - /usr/bin/kill -HUP `/usr/bin/cat $PIDFILE` - fi - ;; - -*) - echo "Usage: $0 { start | restart }" - exit 1 - ;; -esac - -exit $? diff --git a/usr/src/cmd/ssh/etc/sshd_config b/usr/src/cmd/ssh/etc/sshd_config deleted file mode 100644 index fd4aa5df46..0000000000 --- a/usr/src/cmd/ssh/etc/sshd_config +++ /dev/null @@ -1,145 +0,0 @@ -# -# Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. -# -# Configuration file for sshd(1m) (see also sshd_config(4)) -# - -# Protocol versions supported -# -# The sshd shipped in this release of Solaris has support for major versions -# 1 and 2. It is recommended due to security weaknesses in the v1 protocol -# that sites run only v2 if possible. Support for v1 is provided to help sites -# with existing ssh v1 clients/servers to transition. -# Support for v1 may not be available in a future release of Solaris. -# -# To enable support for v1 an RSA1 key must be created with ssh-keygen(1). -# RSA and DSA keys for protocol v2 are created by /etc/init.d/sshd if they -# do not already exist, RSA1 keys for protocol v1 are not automatically created. - -# Uncomment ONLY ONE of the following Protocol statements. - -# Only v2 (recommended) -Protocol 2 - -# Both v1 and v2 (not recommended) -#Protocol 2,1 - -# Only v1 (not recommended) -#Protocol 1 - -# Listen port (the IANA registered port number for ssh is 22) -Port 22 - -# The default listen address is all interfaces, this may need to be changed -# if you wish to restrict the interfaces sshd listens on for a multi homed host. -# Multiple ListenAddress entries are allowed. - -# IPv4 only -#ListenAddress 0.0.0.0 -# IPv4 & IPv6 -ListenAddress :: - -# If port forwarding is enabled (default), specify if the server can bind to -# INADDR_ANY. -# This allows the local port forwarding to work when connections are received -# from any remote host. -GatewayPorts no - -# X11 tunneling options -X11Forwarding yes -X11DisplayOffset 10 -X11UseLocalhost yes - -# The maximum number of concurrent unauthenticated connections to sshd. -# start:rate:full see sshd(1) for more information. -# The default is 10 unauthenticated clients. -#MaxStartups 10:30:60 - -# Banner to be printed before authentication starts. -#Banner /etc/issue - -# Should sshd print the /etc/motd file and check for mail. -# On Solaris it is assumed that the login shell will do these (eg /etc/profile). -PrintMotd no - -# KeepAlive specifies whether keep alive messages are sent to the client. -# See sshd(1) for detailed description of what this means. -# Note that the client may also be sending keep alive messages to the server. -KeepAlive yes - -# Syslog facility and level -SyslogFacility auth -LogLevel info - -# -# Authentication configuration -# - -# Host private key files -# Must be on a local disk and readable only by the root user (root:sys 600). -HostKey /etc/ssh/ssh_host_rsa_key -HostKey /etc/ssh/ssh_host_dsa_key - -# Length of the server key -# Default 768, Minimum 512 -ServerKeyBits 768 - -# sshd regenerates the key every KeyRegenerationInterval seconds. -# The key is never stored anywhere except the memory of sshd. -# The default is 1 hour (3600 seconds). -KeyRegenerationInterval 3600 - -# Ensure secure permissions on users .ssh directory. -StrictModes yes - -# Length of time in seconds before a client that hasn't completed -# authentication is disconnected. -# Default is 600 seconds. 0 means no time limit. -LoginGraceTime 600 - -# Maximum number of retries for authentication -# Default is 6. Default (if unset) for MaxAuthTriesLog is MaxAuthTries / 2 -MaxAuthTries 6 -MaxAuthTriesLog 3 - -# Are logins to accounts with empty passwords allowed. -# If PermitEmptyPasswords is no, pass PAM_DISALLOW_NULL_AUTHTOK -# to pam_authenticate(3PAM). -PermitEmptyPasswords no - -# To disable tunneled clear text passwords, change PasswordAuthentication to no. -PasswordAuthentication yes - -# Are root logins permitted using sshd. -# Note that sshd uses pam_authenticate(3PAM) so the root (or any other) user -# maybe denied access by a PAM module regardless of this setting. -# Valid options are yes, without-password, no. -PermitRootLogin no - -# sftp subsystem -Subsystem sftp internal-sftp - - -# SSH protocol v1 specific options -# -# The following options only apply to the v1 protocol and provide -# some form of backwards compatibility with the very weak security -# of /usr/bin/rsh. Their use is not recommended and the functionality -# will be removed when support for v1 protocol is removed. - -# Should sshd use .rhosts and .shosts for password less authentication. -IgnoreRhosts yes -RhostsAuthentication no - -# Rhosts RSA Authentication -# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts. -# If the user on the client side is not root then this won't work on -# Solaris since /usr/bin/ssh is not installed setuid. -RhostsRSAAuthentication no - -# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication. -#IgnoreUserKnownHosts yes - -# Is pure RSA authentication allowed. -# Default is yes -RSAAuthentication yes diff --git a/usr/src/cmd/stat/Makefile b/usr/src/cmd/stat/Makefile index 34149b2b37..faffc6a437 100644 --- a/usr/src/cmd/stat/Makefile +++ b/usr/src/cmd/stat/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2011, 2012, Joyent, Inc. All rights reserved. # Use is subject to license terms. # # cmd/stat/Makefile @@ -27,7 +27,14 @@ include ../Makefile.cmd -SUBDIRS= arcstat iostat mpstat vmstat fsstat kstat +SUBDIRS= arcstat \ + fsstat \ + iostat \ + kstat \ + mpstat \ + vfsstat \ + vmstat \ + ziostat all := TARGET = all install := TARGET = install diff --git a/usr/src/cmd/stat/arcstat/Makefile b/usr/src/cmd/stat/arcstat/Makefile index 6ae60a8d3d..a98e2fee7e 100644 --- a/usr/src/cmd/stat/arcstat/Makefile +++ b/usr/src/cmd/stat/arcstat/Makefile @@ -11,6 +11,7 @@ # # Copyright 2014 Adam Stevko. All rights reserved. +# Copyright (c) 2011, Joyent, Inc. All rights reserved. # include $(SRC)/cmd/Makefile.cmd diff --git a/usr/src/cmd/stat/arcstat/arcstat.pl b/usr/src/cmd/stat/arcstat/arcstat.pl index d4f12a9e1c..d4f12a9e1c 100755..100644 --- a/usr/src/cmd/stat/arcstat/arcstat.pl +++ b/usr/src/cmd/stat/arcstat/arcstat.pl diff --git a/usr/src/cmd/ssh/etc/Makefile b/usr/src/cmd/stat/vfsstat/Makefile index 66a60e0705..04b5085243 100644 --- a/usr/src/cmd/ssh/etc/Makefile +++ b/usr/src/cmd/stat/vfsstat/Makefile @@ -18,41 +18,24 @@ # # CDDL HEADER END # -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2011, Joyent, Inc. All rights reserved. # -# Copyright (c) 2018, Joyent, Inc. -MANIFEST = ssh.xml -SVCMETHOD = sshd +include $(SRC)/cmd/Makefile.cmd -include ../../Makefile.cmd +PROG= vfsstat -ETCSSHDIR= $(ROOTETC)/ssh -DIRS= $(ETCSSHDIR) +.KEEP_STATE: -FILES= sshd_config ssh_config +all: $(PROG) -ETCSSHFILES= $(FILES:%=$(ETCSSHDIR)/%) +install: all .WAIT $(ROOTPROG) -$(ETCSSHFILES) := FILEMODE= 644 +clean: -ROOTMANIFESTDIR = $(ROOTSVCNETWORK) - -$(ETCSSHDIR)/% : % +$(ROOTBINPROG): $(PROG) $(INS.file) -$(DIRS): - $(INS.dir) - -$(POFILE): - -SMOFF += signed - -all lint clean clobber _msg: - -install: all $(DIRS) $(ETCSSHFILES) $(ROOTMANIFEST) $(ROOTSVCMETHOD) - -check: $(CHKMANIFEST) +lint: -include ../../Makefile.targ +include $(SRC)/cmd/Makefile.targ diff --git a/usr/src/cmd/stat/vfsstat/vfsstat.pl b/usr/src/cmd/stat/vfsstat/vfsstat.pl new file mode 100644 index 0000000000..a3780b8e63 --- /dev/null +++ b/usr/src/cmd/stat/vfsstat/vfsstat.pl @@ -0,0 +1,227 @@ +#!/usr/perl5/bin/perl -w +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2011 Joyent, Inc. +# +# vfsstat - report VFS statistics per zone +# +# USAGE: vfsstat [-hIMrzZ] [interval [count]] +# -h # help +# -I # print results per interval (where applicable) +# -M # print results in MB/s +# -r # print data in comma-separated format +# -z # hide zones with no VFS activity +# -Z # print data for all zones +# +# eg, vfsstat # print summary since zone boot +# vfsstat 1 # print continually every 1 second +# vfsstat 1 5 # print 5 times, every 1 second +# +# NOTES: +# +# - The calculations and output fields emulate those from iostat(1M) as closely +# as possible. When only one zone is actively performing disk I/O, the +# results from iostat(1M) in the global zone and vfsstat in the local zone +# should be almost identical. Note that many VFS read operations are handled +# by the ARC, so vfsstat and iostat(1M) will be similar only when most +# requests are missing in the ARC. +# +# - As with iostat(1M), a result of 100% for VFS read and write utilization does +# not mean that the syscall layer is fully saturated. Instead, that +# measurement just shows that at least one operation was pending over the last +# quanta of time examined. Since the VFS layer can process more than one +# operation concurrently, this measurement will frequently be 100% but the VFS +# layer can still accept additional requests. +# +# - This script is based on Brendan Gregg's K9Toolkit examples: +# +# http://www.brendangregg.com/k9toolkit.html +# + +use Getopt::Std; +use Sun::Solaris::Kstat; +my $Kstat = Sun::Solaris::Kstat->new(); + +# Process command line args +usage() if defined $ARGV[0] and $ARGV[0] eq "--help"; +getopts('hIMrzZ') or usage(); +usage() if defined $main::opt_h; +$main::opt_h = 0; + +my $USE_MB = defined $main::opt_M ? $main::opt_M : 0; +my $USE_INTERVAL = defined $main::opt_I ? $main::opt_I : 0; +my $USE_COMMA = defined $main::opt_r ? $main::opt_r : 0; +my $HIDE_ZEROES = defined $main::opt_z ? $main::opt_z : 0; +my $ALL_ZONES = defined $main::opt_Z ? $main::opt_Z : 0; + +my ($interval, $count); +if ( defined($ARGV[0]) ) { + $interval = $ARGV[0]; + $count = defined ($ARGV[1]) ? $ARGV[1] : 2**32; + usage() if ($interval == 0); +} else { + $interval = 1; + $count = 1; +} + +my $HEADER_FMT = $USE_COMMA ? + "r/%s,w/%s,%sr/%s,%sw/%s,ractv,wactv,read_t,writ_t,%%r,%%w," . + "d/%s,del_t,zone\n" : + " r/%s w/%s %sr/%s %sw/%s ractv wactv read_t writ_t " . + "%%r %%w d/%s del_t zone\n"; +my $DATA_FMT = $USE_COMMA ? + "%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%.1f,%d,%d,%.1f,%.1f,%s,%d\n" : + "%5.1f %5.1f %5.1f %5.1f %5.1f %5.1f %6.1f %6.1f %3d %3d " . + "%5.1f %6.1f %s (%d)\n"; + +my $BYTES_PREFIX = $USE_MB ? "M" : "k"; +my $BYTES_DIVISOR = $USE_MB ? 1024 * 1024 : 1024; +my $INTERVAL_SUFFIX = $USE_INTERVAL ? "i" : "s"; +my $NANOSEC = 1000000000; + +my @fields = ( 'reads', 'writes', 'nread', 'nwritten', 'rtime', 'wtime', + 'rlentime', 'wlentime', 'delay_cnt', 'delay_time', 'snaptime' ); + +chomp(my $curzone = (`/sbin/zonename`)); + +my %old = (); +my $rows_printed = 0; + +for (my $ii = 0; $ii < $count; $ii++) { + # Read list of visible zones and their zone IDs + my @zones = (); + my %zoneids = (); + my $zoneadm = `zoneadm list -p | cut -d: -f1,2`; + @lines = split(/\n/, $zoneadm); + foreach $line (@lines) { + @tok = split(/:/, $line); + $zoneids->{$tok[1]} = $tok[0]; + push(@zones, $tok[1]); + } + + $Kstat->update(); + + # Print the column header every 20 rows + if ($rows_printed == 0 || $ALL_ZONES) { + printf($HEADER_FMT, $INTERVAL_SUFFIX, $INTERVAL_SUFFIX, + $BYTES_PREFIX, $INTERVAL_SUFFIX, $BYTES_PREFIX, + $INTERVAL_SUFFIX, $INTERVAL_SUFFIX); + } + + $rows_printed = $rows_printed >= 20 ? 0 : $rows_printed + 1; + + foreach $zone (@zones) { + if ((!$ALL_ZONES) && ($zone ne $curzone)) { + next; + } + + if (! defined $old->{$zone}) { + $old->{$zone} = (); + foreach $field (@fields) { $old->{$zone}->{$field} = 0; } + } + + # + # Kstats have a 30-character limit (KSTAT_STRLEN) on their + # names, so if the zone name exceeds that limit, use the first + # 30 characters. + # + my $trimmed_zone = substr($zone, 0, 30); + my $zoneid = $zoneids->{$zone}; + + print_stats($zone, $zoneid, + $Kstat->{'zone_vfs'}{$zoneid}{$trimmed_zone}, $old->{$zone}); + } + + sleep ($interval); +} + +exit(0); + +sub print_stats { + my $zone = $_[0]; + my $zoneid = $_[1]; + my $data = $_[2]; + my $old = $_[3]; + + my $etime = $data->{'snaptime'} - + ($old->{'snaptime'} > 0 ? $old->{'snaptime'} : $data->{'crtime'}); + + # Calculate basic statistics + my $rate_divisor = $USE_INTERVAL ? 1 : $etime; + my $reads = ($data->{'reads'} - $old->{'reads'}) / $rate_divisor; + my $writes = ($data->{'writes'} - $old->{'writes'}) / $rate_divisor; + my $nread = ($data->{'nread'} - $old->{'nread'}) / + $rate_divisor / $BYTES_DIVISOR; + my $nwritten = ($data->{'nwritten'} - $old->{'nwritten'}) / + $rate_divisor / $BYTES_DIVISOR; + + # Calculate transactions per second + my $r_tps = ($data->{'reads'} - $old->{'reads'}) / $etime; + my $w_tps = ($data->{'writes'} - $old->{'writes'}) / $etime; + + # Calculate average length of active queue + my $r_actv = (($data->{'rlentime'} - $old->{'rlentime'}) / $NANOSEC) / + $etime; + my $w_actv = (($data->{'wlentime'} - $old->{'wlentime'}) / $NANOSEC) / + $etime; + + # Calculate average service time + # multiply by 1000 to convert to usecs for conssistency with del_t + my $read_t = ($r_tps > 0 ? $r_actv * (1000 / $r_tps) : 0.0) * 1000; + my $writ_t = ($w_tps > 0 ? $w_actv * (1000 / $w_tps) : 0.0) * 1000; + + # Calculate I/O throttle delay metrics + my $delays = $data->{'delay_cnt'} - $old->{'delay_cnt'}; + my $d_tps = $delays / $etime; + my $del_t = $delays > 0 ? + ($data->{'delay_time'} - $old->{'delay_time'}) / $delays : 0.0; + + # Calculate the % time the VFS layer is active + my $r_b_pct = ((($data->{'rtime'} - $old->{'rtime'}) / $NANOSEC) / + $etime) * 100; + my $w_b_pct = ((($data->{'wtime'} - $old->{'wtime'}) / $NANOSEC) / + $etime) * 100; + + if (! $HIDE_ZEROES || $reads != 0.0 || $writes != 0.0 || + $nread != 0.0 || $nwritten != 0.0) { + printf($DATA_FMT, $reads, $writes, $nread, $nwritten, $r_actv, + $w_actv, $read_t, $writ_t, $r_b_pct, $w_b_pct, + $d_tps, $del_t, substr($zone, 0, 8), $zoneid); + } + + # Save current calculations for next loop + foreach (@fields) { $old->{$_} = $data->{$_}; } +} + +sub usage { + print STDERR <<END; +USAGE: vfsstat [-hIMrzZ] [interval [count]] + eg, vfsstat # print summary since zone boot + vfsstat 1 # print continually every 1 second + vfsstat 1 5 # print 5 times, every 1 second + vfsstat -I # print results per interval (where applicable) + vfsstat -M # print results in MB/s + vfsstat -r # print results in comma-separated format + vfsstat -z # hide zones with no VFS activity + vfsstat -Z # print results for all zones +END + exit 1; +} diff --git a/usr/src/cmd/ssh/Makefile b/usr/src/cmd/stat/ziostat/Makefile index c68aa94238..c338b59678 100644 --- a/usr/src/cmd/ssh/Makefile +++ b/usr/src/cmd/stat/ziostat/Makefile @@ -18,41 +18,24 @@ # # CDDL HEADER END # - -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. +# Copyright (c) 2011, Joyent, Inc. All rights reserved. # -include ../Makefile.cmd +include $(SRC)/cmd/Makefile.cmd -SUBDIRS= \ - etc - -CLOBBERFILES += $(MSGFILE) THIRDPARTYLICENSE +PROG= ziostat .KEEP_STATE: -all := TARGET= all -clean := TARGET= clean -clobber := TARGET= clobber -install := TARGET= install +all: $(PROG) -all clean install: $(SUBDIRS) +install: all .WAIT $(ROOTPROG) -lint: +clean: -clobber: $(SUBDIRS) clobber_local -clobber_local: - $(RM) $(CLOBBERFILES) +$(ROOTBINPROG): $(PROG) + $(INS.file) -all install: THIRDPARTYLICENSE - -$(SUBDIRS): FRC - cd $@; pwd; $(MAKE) $(TARGET) - -# skip the summary; just include the actual license clauses. -THIRDPARTYLICENSE: doc/LICENCE - $(SED) -n '/1)/,$$p' doc/LICENCE > $@ +lint: -FRC: +include $(SRC)/cmd/Makefile.targ diff --git a/usr/src/cmd/stat/ziostat/ziostat.pl b/usr/src/cmd/stat/ziostat/ziostat.pl new file mode 100755 index 0000000000..cf95d2f5a5 --- /dev/null +++ b/usr/src/cmd/stat/ziostat/ziostat.pl @@ -0,0 +1,204 @@ +#!/usr/perl5/bin/perl -w +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2011 Joyent, Inc. +# +# ziostat - report I/O statistics per zone +# +# USAGE: ziostat [-hIMrzZ] [interval [count]] +# -h # help +# -I # print results per interval (where applicable) +# -M # print results in MB/s +# -r # print data in comma-separated format +# -z # hide zones with no ZFS I/O activity +# -Z # print data for all zones +# +# eg, ziostat # print summary since zone boot +# ziostat 1 # print continually every 1 second +# ziostat 1 5 # print 5 times, every 1 second +# +# NOTES: +# +# - The calculations and output fields emulate those from iostat(1M) as closely +# as possible. When only one zone is actively performing disk I/O, the +# results from iostat(1M) in the global zone and ziostat in the local zone +# should be almost identical. +# +# - As with iostat(1M), a result of 100% for disk utilization does not mean that +# the disk is fully saturated. Instead, that measurement just shows that at +# least one operation was pending over the last quanta of time examined. +# Since disk devices can process more than one operation concurrently, this +# measurement will frequently be 100% but the disk can still offer higher +# performance. +# +# - This script is based on Brendan Gregg's K9Toolkit examples: +# +# http://www.brendangregg.com/k9toolkit.html +# + +use Getopt::Std; +use Sun::Solaris::Kstat; +my $Kstat = Sun::Solaris::Kstat->new(); + +# Process command line args +usage() if defined $ARGV[0] and $ARGV[0] eq "--help"; +getopts('hIMrzZ') or usage(); +usage() if defined $main::opt_h; +$main::opt_h = 0; + +my $USE_MB = defined $main::opt_M ? $main::opt_M : 0; +my $USE_INTERVAL = defined $main::opt_I ? $main::opt_I : 0; +my $USE_COMMA = defined $main::opt_r ? $main::opt_r : 0; +my $HIDE_ZEROES = defined $main::opt_z ? $main::opt_z : 0; +my $ALL_ZONES = defined $main::opt_Z ? $main::opt_Z : 0; + +my ($interval, $count); +if ( defined($ARGV[0]) ) { + $interval = $ARGV[0]; + $count = defined ($ARGV[1]) ? $ARGV[1] : 2**32; + usage() if ($interval == 0); +} else { + $interval = 1; + $count = 1; +} + +my $HEADER_FMT = $USE_COMMA ? + "r/%s,%sr/%s,actv,wsvc_t,asvc_t,%%b,zone\n" : + " r/%s %sr/%s actv wsvc_t asvc_t %%b zone\n"; +my $DATA_FMT = $USE_COMMA ? + "%.1f,%.1f,%.1f,%.1f,%.1f,%d,%s,%d\n" : + " %6.1f %6.1f %6.1f %6.1f %6.1f %3d %s (%d)\n"; + +my $BYTES_PREFIX = $USE_MB ? "M" : "k"; +my $BYTES_DIVISOR = $USE_MB ? 1024 * 1024 : 1024; +my $INTERVAL_SUFFIX = $USE_INTERVAL ? "i" : "s"; +my $NANOSEC = 1000000000; + +my @fields = ( 'reads', 'nread', 'waittime', 'rtime', 'rlentime', 'snaptime' ); + +chomp(my $curzone = (`/sbin/zonename`)); + +# Read list of visible zones and their zone IDs +my @zones = (); +my %zoneids = (); +my $zoneadm = `zoneadm list -p | cut -d: -f1,2`; +@lines = split(/\n/, $zoneadm); +foreach $line (@lines) { + @tok = split(/:/, $line); + $zoneids->{$tok[1]} = $tok[0]; + push(@zones, $tok[1]); +} + +my %old = (); +my $rows_printed = 0; + +$Kstat->update(); + +for (my $ii = 0; $ii < $count; $ii++) { + # Print the column header every 20 rows + if ($rows_printed == 0 || $ALL_ZONES) { + printf($HEADER_FMT, $INTERVAL_SUFFIX, $BYTES_PREFIX, + $INTERVAL_SUFFIX, $INTERVAL_SUFFIX); + } + + $rows_printed = $rows_printed >= 20 ? 0 : $rows_printed + 1; + + foreach $zone (@zones) { + if ((!$ALL_ZONES) && ($zone ne $curzone)) { + next; + } + + if (! defined $old->{$zone}) { + $old->{$zone} = (); + foreach $field (@fields) { $old->{$zone}->{$field} = 0; } + } + + # + # Kstats have a 30-character limit (KSTAT_STRLEN) on their + # names, so if the zone name exceeds that limit, use the first + # 30 characters. + # + my $trimmed_zone = substr($zone, 0, 30); + my $zoneid = $zoneids->{$zone}; + + print_stats($zone, $zoneid, + $Kstat->{'zone_zfs'}{$zoneid}{$trimmed_zone}, $old->{$zone}); + } + + sleep ($interval); + $Kstat->update(); +} + +sub print_stats { + my $zone = $_[0]; + my $zoneid = $_[1]; + my $data = $_[2]; + my $old = $_[3]; + + my $etime = $data->{'snaptime'} - + ($old->{'snaptime'} > 0 ? $old->{'snaptime'} : $data->{'crtime'}); + + # Calculate basic statistics + my $rate_divisor = $USE_INTERVAL ? 1 : $etime; + my $reads = ($data->{'reads'} - $old->{'reads'}) / $rate_divisor; + my $nread = ($data->{'nread'} - $old->{'nread'}) / + $rate_divisor / $BYTES_DIVISOR; + + # Calculate overall transactions per second + my $ops = $data->{'reads'} - $old->{'reads'}; + my $tps = $ops / $etime; + + # Calculate average length of disk run queue + my $actv = (($data->{'rlentime'} - $old->{'rlentime'}) / $NANOSEC) / + $etime; + + # Calculate average disk wait and service times + my $wsvc = $ops > 0 ? (($data->{'waittime'} - $old->{'waittime'}) / + 1000000) / $ops : 0.0; + my $asvc = $tps > 0 ? $actv * (1000 / $tps) : 0.0; + + # Calculate the % time the disk run queue is active + my $b_pct = ((($data->{'rtime'} - $old->{'rtime'}) / $NANOSEC) / + $etime) * 100; + + if (! $HIDE_ZEROES || $reads != 0.0 || $nread != 0.0 ) { + printf($DATA_FMT, $reads, $nread, $actv, $wsvc, $asvc, + $b_pct, substr($zone, 0, 8), $zoneid); + } + + # Save current calculations for next loop + foreach (@fields) { $old->{$_} = $data->{$_}; } +} + +sub usage { + print STDERR <<END; +USAGE: ziostat [-hIMrzZ] [interval [count]] + eg, ziostat # print summary since zone boot + ziostat 1 # print continually every 1 second + ziostat 1 5 # print 5 times, every 1 second + ziostat -I # print results per interval (where applicable) + ziostat -M # print results in MB/s + ziostat -r # print results in comma-separated format + ziostat -z # hide zones with no ZFS I/O activity + ziostat -Z # print results for all zones +END + exit 1; +} diff --git a/usr/src/cmd/svc/configd/backend.c b/usr/src/cmd/svc/configd/backend.c index b7ed400cfd..4c3a7d0816 100644 --- a/usr/src/cmd/svc/configd/backend.c +++ b/usr/src/cmd/svc/configd/backend.c @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2017 Joyent, Inc. */ /* @@ -2194,7 +2195,24 @@ backend_tx_begin(backend_type_t t, backend_tx_t **txp) UPDATE_TOTALS((*txp)->bt_be, bt_exec, ts, vts); if (r == SQLITE_FULL) (*txp)->bt_full = 1; - r = backend_error((*txp)->bt_be, r, errmsg); + /* + * We explicitly handle an ENOSPC error here for the beginning of the + * transaction, instead of in backend_error, which calls backend_panic + * for this case, resulting in the death of svc.configd. That may be + * appropriate in other cases, but in this case we would rather fail so + * that configd remains up and the caller gets an approprate error. The + * failure mode is that there is not enough swap space to open the + * non-persistent database, so there won't be enough space to restart + * configd, leaving SMF in a state requiring manual intervention. + */ + if (r == SQLITE_CANTOPEN && errno == ENOSPC && + (*txp)->bt_type == BACKEND_TYPE_NONPERSIST) { + configd_info("Warning: no space to open %s\n", + bes[BACKEND_TYPE_NONPERSIST]->be_path); + r = REP_PROTOCOL_FAIL_NO_RESOURCES; + } else { + r = backend_error((*txp)->bt_be, r, errmsg); + } if (r != REP_PROTOCOL_SUCCESS) { assert(r != REP_PROTOCOL_DONE); diff --git a/usr/src/cmd/svc/configd/rc_node.c b/usr/src/cmd/svc/configd/rc_node.c index a5b968c53c..33cb2be7a2 100644 --- a/usr/src/cmd/svc/configd/rc_node.c +++ b/usr/src/cmd/svc/configd/rc_node.c @@ -24,6 +24,9 @@ * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2016 by Delphix. All rights reserved. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ /* * rc_node.c - In-memory SCF object management diff --git a/usr/src/cmd/svc/milestone/net-routing-setup b/usr/src/cmd/svc/milestone/net-routing-setup index 6ab1a6c7f0..b4ee7d39ac 100644 --- a/usr/src/cmd/svc/milestone/net-routing-setup +++ b/usr/src/cmd/svc/milestone/net-routing-setup @@ -21,11 +21,15 @@ # # # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. +# +# Copyright (c) 2012 Joyent, Inc. All rights reserved. # This script configures IP routing. . /lib/svc/share/smf_include.sh +set -o xtrace + # # In a shared-IP zone we need this service to be up, but all of the work # it tries to do is irrelevant (and will actually lead to the service @@ -156,7 +160,8 @@ fi # however, as persistent daemon state is now controlled by SMF. # ipv4_routing_set=`/usr/bin/svcprop -p routeadm/ipv4-routing-set $SMF_FMRI` -if [ -z "$defrouters" ]; then +smartos_param=`/usr/bin/bootparams | grep "^smartos"` +if [ -z "$defrouters" ] && [ "$smartos_param" != "" ]; then # # Set default value for ipv4-routing to enabled. If routeadm -e/-d # has not yet been run by the administrator, we apply this default. @@ -210,5 +215,21 @@ if [ -f /etc/inet/static_routes ]; then done fi +# +# Read /etc/inet/static_routes.vmadm and add each route. +# +if [ -f /etc/inet/static_routes.vmadm ]; then + echo "Adding vmadm persistent routes:" + /usr/bin/egrep -v "^(#|$)" /etc/inet/static_routes.vmadm | while read line; do + /usr/sbin/route add $line + done +fi + +# +# Log the result +# +echo "Routing setup complete:" +/usr/bin/netstat -rn + # Clear exit status. exit $SMF_EXIT_OK diff --git a/usr/src/cmd/svc/milestone/network-location.xml b/usr/src/cmd/svc/milestone/network-location.xml index aad337f42f..709e9df8f3 100644 --- a/usr/src/cmd/svc/milestone/network-location.xml +++ b/usr/src/cmd/svc/milestone/network-location.xml @@ -106,7 +106,7 @@ --> <dependency name='manifest-import' - grouping='require_all' + grouping='optional_all' restart_on='none' type='service'> <service_fmri value='svc:/system/manifest-import:default' /> diff --git a/usr/src/cmd/svc/milestone/network-routing-setup.xml b/usr/src/cmd/svc/milestone/network-routing-setup.xml index b34d578e2a..85a74756da 100644 --- a/usr/src/cmd/svc/milestone/network-routing-setup.xml +++ b/usr/src/cmd/svc/milestone/network-routing-setup.xml @@ -40,11 +40,19 @@ <!-- loopback/physical network configuration is required --> <dependency - name='network' - grouping='optional_all' + name='loopback' + grouping='require_all' + restart_on='none' + type='service'> + <service_fmri value='svc:/network/loopback' /> + </dependency> + + <dependency + name='physical' + grouping='require_all' restart_on='none' type='service'> - <service_fmri value='svc:/milestone/network' /> + <service_fmri value='svc:/network/physical' /> </dependency> <!-- usr filesystem required to run routing-related commands --> diff --git a/usr/src/cmd/svc/milestone/network.xml b/usr/src/cmd/svc/milestone/network.xml index 75b5578f44..48386ebf73 100644 --- a/usr/src/cmd/svc/milestone/network.xml +++ b/usr/src/cmd/svc/milestone/network.xml @@ -54,6 +54,14 @@ <service_fmri value='svc:/network/physical' /> </dependency> + <dependency + name='routing-setup' + grouping='require_all' + restart_on='none' + type='service'> + <service_fmri value='svc:/network/routing-setup' /> + </dependency> + <exec_method type='method' name='start' diff --git a/usr/src/cmd/svc/milestone/single-user.xml b/usr/src/cmd/svc/milestone/single-user.xml index 8797f13c47..579ecb5ddd 100644 --- a/usr/src/cmd/svc/milestone/single-user.xml +++ b/usr/src/cmd/svc/milestone/single-user.xml @@ -68,7 +68,7 @@ <dependency name='manifests' - grouping='require_all' + grouping='optional_all' restart_on='none' type='service'> <service_fmri value='svc:/system/manifest-import' /> diff --git a/usr/src/cmd/svc/shell/smf_include.sh b/usr/src/cmd/svc/shell/smf_include.sh index 4acbed7d90..a5e3431d5b 100644 --- a/usr/src/cmd/svc/shell/smf_include.sh +++ b/usr/src/cmd/svc/shell/smf_include.sh @@ -22,6 +22,7 @@ # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2012 Joyent, Inc. All rights reserved. # Copyright 2015 Nexenta Systems, Inc. All rights reserved. # Copyright 2012 Joyent, Inc. All rights reserved. # diff --git a/usr/src/cmd/svc/startd/graph.c b/usr/src/cmd/svc/startd/graph.c index 0e5253a281..0361d5ae4f 100644 --- a/usr/src/cmd/svc/startd/graph.c +++ b/usr/src/cmd/svc/startd/graph.c @@ -145,6 +145,8 @@ #include <assert.h> #include <errno.h> #include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> #include <fm/libfmevent.h> #include <libscf.h> #include <libscf_priv.h> @@ -4846,6 +4848,20 @@ vertex_subgraph_dependencies_shutdown(scf_handle_t *h, graph_vertex_t *v, was_up = up_state(old_state); now_up = up_state(v->gv_state); + if (halting != -1 && old_state == RESTARTER_STATE_DISABLED && + v->gv_state != RESTARTER_STATE_DISABLED) { + /* + * We're halting and we have a svc which is transitioning to + * offline in parallel. This leads to a race condition where + * gt_enter_offline might re-enable the svc after we disabled + * it. Since we're halting, we want to ensure no svc ever + * transitions out of the disabled state. In this case, modify + * the flags to keep us on the halting path. + */ + was_up = 0; + now_up = 0; + } + if (!was_up && now_up) { ++non_subgraph_svcs; } else if (was_up && !now_up) { @@ -6802,6 +6818,9 @@ repository_event_thread(void *unused) char *fmri = startd_alloc(max_scf_fmri_size); char *pg_name = startd_alloc(max_scf_value_size); int r; + int fd; + + (void) pthread_setname_np(pthread_self(), "repository_event"); (void) pthread_setname_np(pthread_self(), "repository_event"); @@ -6826,6 +6845,14 @@ retry: goto retry; } + if ((fd = open("/etc/svc/volatile/startd.ready", O_RDONLY | O_CREAT, + S_IRUSR)) < 0) { + log_error(LOG_WARNING, "Couldn't create startd.ready file\n", + SCF_GROUP_FRAMEWORK, scf_strerror(scf_error())); + } else { + (void) close(fd); + } + /*CONSTCOND*/ while (1) { ssize_t res; diff --git a/usr/src/cmd/svc/startd/method.c b/usr/src/cmd/svc/startd/method.c index 12a64343a6..915ad42da6 100644 --- a/usr/src/cmd/svc/startd/method.c +++ b/usr/src/cmd/svc/startd/method.c @@ -100,34 +100,18 @@ static uint_t method_events[] = { * method_record_start(restarter_inst_t *) * Record a service start for rate limiting. Place the current time * in the circular array of instance starts. + * + * Save the critical_failure_period and critical_failure_allowed with either + * the defaults or the svc properties startd/critical_failure_count and + * startd/critical_failure_period. + * ri_crit_fail_allowed is capped at RINST_START_TIMES. */ static void method_record_start(restarter_inst_t *inst) { - int index = inst->ri_start_index++ % RINST_START_TIMES; - - inst->ri_start_time[index] = gethrtime(); -} - -/* - * method_rate_critical(restarter_inst_t *) - * Return true if the average start interval is less than the permitted - * interval. The implicit interval defaults to RINST_FAILURE_RATE_NS and - * RINST_START_TIMES but may be overridden with the svc properties - * startd/critical_failure_count and startd/critical_failure_period - * which represent the number of failures to consider and the amount of - * time in seconds in which that number may occur, respectively. Note that - * this time is measured as of the transition to 'enabled' rather than wall - * clock time. - * Implicit success if insufficient measurements for an average exist. - */ -int -method_rate_critical(restarter_inst_t *inst) -{ + int index; + uint_t critical_failure_allowed = RINST_START_TIMES; hrtime_t critical_failure_period; - uint_t critical_failure_count = RINST_START_TIMES; - uint_t n = inst->ri_start_index; - hrtime_t avg_ns = 0; uint64_t scf_fr, scf_st; scf_propvec_t *prop = NULL; scf_propvec_t restart_critical[] = { @@ -151,17 +135,48 @@ method_rate_critical(restarter_inst_t *inst) * in seconds but tracked in ns */ critical_failure_period = (hrtime_t)scf_fr * NANOSEC; - critical_failure_count = (uint_t)scf_st; + critical_failure_allowed = (uint_t)scf_st; + + if (critical_failure_allowed > RINST_START_TIMES) + critical_failure_allowed = RINST_START_TIMES; + if (critical_failure_allowed < 1) + critical_failure_allowed = 1; + } - if (inst->ri_start_index < critical_failure_count) + + inst->ri_crit_fail_allowed = critical_failure_allowed; + inst->ri_crit_fail_period = critical_failure_period; + + index = inst->ri_start_index++ % critical_failure_allowed; + inst->ri_start_time[index] = gethrtime(); +} + +/* + * method_rate_critical(restarter_inst_t *) + * Return true if the number of failures within the interval + * ri_crit_fail_period exceeds ri_crit_fail_allowed. The allowed failure + * count defaults to RINST_START_TIMES and the implicit interval defaults + * to RINST_FAILURE_RATE_NS but may be overridden with the svc properties + * startd/critical_failure_count and startd/critical_failure_period which + * represent the acceptable number of failures and the amount of time in + * seconds in which that number may occur, respectively. Note that this time + * is measured as of the transition to 'enabled' rather than wall clock + * time. Implicitly not critical if insufficient failures have occured. + */ +int +method_rate_critical(restarter_inst_t *inst) +{ + uint_t n = inst->ri_start_index; + uint_t fail_allowed = inst->ri_crit_fail_allowed; + hrtime_t diff_ns; + + if (n < fail_allowed) return (0); - avg_ns = - (inst->ri_start_time[(n - 1) % critical_failure_count] - - inst->ri_start_time[n % critical_failure_count]) / - (critical_failure_count - 1); + diff_ns = inst->ri_start_time[(n - 1) % fail_allowed] - + inst->ri_start_time[n % fail_allowed]; - return (avg_ns < critical_failure_period); + return (diff_ns < inst->ri_crit_fail_period); } /* diff --git a/usr/src/cmd/svc/startd/startd.h b/usr/src/cmd/svc/startd/startd.h index d230ed1490..df3e98a27b 100644 --- a/usr/src/cmd/svc/startd/startd.h +++ b/usr/src/cmd/svc/startd/startd.h @@ -398,7 +398,7 @@ typedef enum { #define RINST_RETAKE_MASK 0x0f000000 -#define RINST_START_TIMES 5 /* failures to consider */ +#define RINST_START_TIMES 10 /* up to 10 fails to consider */ #define RINST_FAILURE_RATE_NS 600000000000LL /* 1 failure/10 minutes */ #define RINST_WT_SVC_FAILURE_RATE_NS NANOSEC /* 1 failure/second */ @@ -420,6 +420,8 @@ typedef struct restarter_inst { hrtime_t ri_start_time[RINST_START_TIMES]; uint_t ri_start_index; /* times started */ + uint_t ri_crit_fail_allowed; + hrtime_t ri_crit_fail_period; uu_list_node_t ri_link; pthread_mutex_t ri_lock; diff --git a/usr/src/cmd/svc/svcadm/Makefile b/usr/src/cmd/svc/svcadm/Makefile index cc0cc160bf..1a6a0dd35c 100644 --- a/usr/src/cmd/svc/svcadm/Makefile +++ b/usr/src/cmd/svc/svcadm/Makefile @@ -21,6 +21,7 @@ # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright 2012, Joyent, Inc. All rights reserved. # PROG = svcadm @@ -49,7 +50,11 @@ $(PROG): $(OBJS) $(POFILE): $(POFILES) cat $(POFILES) > $(POFILE) -install: all $(ROOTUSRSBINPROG) +install: all $(ROOTSBINPROG) $(ROOTUSRSBINPROG) + +$(ROOTUSRSBINPROG): + -$(RM) $@ + -$(SYMLINK) ../../sbin/$(PROG) $@ clean: $(RM) $(OBJS) diff --git a/usr/src/cmd/svc/svcs/Makefile b/usr/src/cmd/svc/svcs/Makefile index 0e9fc52652..36bd39d567 100644 --- a/usr/src/cmd/svc/svcs/Makefile +++ b/usr/src/cmd/svc/svcs/Makefile @@ -21,20 +21,20 @@ # # Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. # -# Copyright (c) 2011, Joyent, Inc. All rights reserved. +# Copyright (c) 2019, Joyent, Inc. All rights reserved. # PROG = svcs OBJS = svcs.o explain.o MYOBJS = notify_params.o SRCS = $(OBJS:%.o=%.c) $(MYOBJS:%.o=../common/%.c) -POFILES = $(OBJS:.o=.po) +POFILES = $(OBJS:.o=.po) include ../../Makefile.cmd include ../../Makefile.ctf POFILE = $(PROG)_all.po -LDLIBS += -lcontract -lscf -luutil -lumem -lnvpair -lzonecfg +LDLIBS += -lcontract -lscf -luutil -lumem -lnvpair -lzonecfg -lsasl -lproc CPPFLAGS += -I ../common lint := LINTFLAGS = -mux diff --git a/usr/src/cmd/svc/svcs/explain.c b/usr/src/cmd/svc/svcs/explain.c index 533437cbee..41ba1b3b47 100644 --- a/usr/src/cmd/svc/svcs/explain.c +++ b/usr/src/cmd/svc/svcs/explain.c @@ -194,6 +194,7 @@ static char *emsg_invalid_dep; extern scf_handle_t *h; extern char *g_zonename; +extern char *g_zonealias; /* ARGSUSED */ static int @@ -1994,6 +1995,9 @@ print_service(inst_t *svcp, int verbose) if (g_zonename != NULL) (void) printf(gettext(" Zone: %s\n"), g_zonename); + if (g_zonealias != NULL) + (void) printf(gettext(" Alias: %s\n"), g_zonealias); + stime = svcp->stime.tv_sec; tmp = localtime(&stime); diff --git a/usr/src/cmd/svc/svcs/svcs.c b/usr/src/cmd/svc/svcs/svcs.c index ad88b05b37..8b322a823e 100644 --- a/usr/src/cmd/svc/svcs/svcs.c +++ b/usr/src/cmd/svc/svcs/svcs.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, Joyent, Inc. All rights reserved. + * Copyright (c) 2019, Joyent, Inc. All rights reserved. * Copyright (c) 2015, 2016 by Delphix. All rights reserved. */ @@ -60,6 +60,7 @@ #include <sys/ctfs.h> #include <sys/stat.h> +#include <sasl/saslutil.h> #include <assert.h> #include <errno.h> #include <fcntl.h> @@ -71,8 +72,8 @@ #include <libscf_priv.h> #include <libuutil.h> #include <libnvpair.h> +#include <libproc.h> #include <locale.h> -#include <procfs.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -91,6 +92,13 @@ #define EMPTY_OK 0x01 #define MULTI_OK 0x02 +/* + * Per proc(4) when pr_nlwp, pr_nzomb, and pr_lwp.pr_lwpid are all 0, + * the process is a zombie. + */ +#define IS_ZOMBIE(_psip) \ + ((_psip)->pr_nlwp == 0 && (_psip)->pr_nzomb == 0 && \ + (_psip)->pr_lwp.pr_lwpid == 0) /* * An AVL-storable node for output lines and the keys to sort them by. @@ -135,6 +143,9 @@ static int first_paragraph = 1; /* For -l mode. */ static char *common_name_buf; /* Sized for maximal length value. */ char *locale; /* Current locale. */ char *g_zonename; /* zone being operated upon */ +char *g_zonealias; /* alias for zone, if any */ +static char g_aliasdec[MAXPATHLEN / 4 * 3]; /* decoded zone alias buffer */ +static char g_aliasbuf[MAXPATHLEN]; /* base64 encoded zone alias buffer */ /* * Pathname storage for path generated from the fmri. @@ -241,7 +252,25 @@ ht_free(void) static void ht_init(void) { - assert(ht_buckets == NULL); + if (ht_buckets != NULL) { + /* + * If we already have a hash table (e.g., because we are + * processing multiple zones), destroy it before creating + * a new one. + */ + struct ht_elem *elem, *next; + int i; + + for (i = 0; i < ht_buckets_num; i++) { + for (elem = ht_buckets[i]; elem != NULL; elem = next) { + next = elem->next; + free((char *)elem->fmri); + free(elem); + } + } + + free(ht_buckets); + } ht_buckets_num = 8; ht_buckets = safe_malloc(sizeof (*ht_buckets) * ht_buckets_num); @@ -554,7 +583,7 @@ get_restarter_time_prop(scf_instance_t *inst, const char *pname, int r; r = inst_get_single_val(inst, SCF_PG_RESTARTER, pname, SCF_TYPE_TIME, - tvp, NULL, ok_if_empty ? EMPTY_OK : 0, 0, 1); + tvp, 0, ok_if_empty ? EMPTY_OK : 0, 0, 1); return (r == 0 ? 0 : -1); } @@ -939,28 +968,6 @@ instance_processes(scf_instance_t *inst, const char *fmri, return (ret); } -static int -get_psinfo(pid_t pid, psinfo_t *psip) -{ - char path[100]; - int fd; - - (void) snprintf(path, sizeof (path), "/proc/%lu/psinfo", pid); - - fd = open64(path, O_RDONLY); - if (fd < 0) - return (-1); - - if (read(fd, psip, sizeof (*psip)) < 0) - uu_die(gettext("Could not read info for process %lu"), pid); - - (void) close(fd); - - return (0); -} - - - /* * Column sprint and sortkey functions */ @@ -1651,7 +1658,7 @@ sprint_stime(char **buf, scf_walkinfo_t *wip) SCF_PROPERTY_STATE_TIMESTAMP, &tv, 0); } else { r = pg_get_single_val(wip->pg, SCF_PROPERTY_STATE_TIMESTAMP, - SCF_TYPE_TIME, &tv, NULL, 0); + SCF_TYPE_TIME, &tv, 0, 0); } if (r != 0) { @@ -1703,7 +1710,7 @@ sortkey_stime(char *buf, int reverse, scf_walkinfo_t *wip) SCF_PROPERTY_STATE_TIMESTAMP, &tv, 0); else r = pg_get_single_val(wip->pg, SCF_PROPERTY_STATE_TIMESTAMP, - SCF_TYPE_TIME, &tv, NULL, 0); + SCF_TYPE_TIME, &tv, 0, 0); if (r == 0) { int64_t sec; @@ -2057,7 +2064,7 @@ detailed_list_processes(scf_walkinfo_t *wip) (void) printf("%-*s%lu", DETAILED_WIDTH, gettext("process"), pids[i]); - if (get_psinfo(pids[i], &psi) == 0) + if (proc_get_psinfo(pids[i], &psi) == 0 && !IS_ZOMBIE(&psi)) (void) printf(" %.*s", PRARGSZ, psi.pr_psargs); (void) putchar('\n'); @@ -2517,7 +2524,7 @@ print_detailed(void *unused, scf_walkinfo_t *wip) gettext("next_state"), buf); if (pg_get_single_val(rpg, SCF_PROPERTY_STATE_TIMESTAMP, - SCF_TYPE_TIME, &tv, NULL, 0) == 0) { + SCF_TYPE_TIME, &tv, 0, 0) == 0) { stime = tv.tv_sec; tmp = localtime(&stime); for (tbsz = 50; ; tbsz *= 2) { @@ -2933,7 +2940,7 @@ add_processes(scf_walkinfo_t *wip, char *line, scf_propertygroup_t *lpg) struct tm *tm; int len = 1 + 15 + 8 + 3 + 6 + 1 + PRFNSZ; - if (get_psinfo(pids[i], &psi) != 0) + if (proc_get_psinfo(pids[i], &psi) != 0 || IS_ZOMBIE(&psi)) continue; line = realloc(line, strlen(line) + len); @@ -3665,6 +3672,24 @@ again: assert(opt_zone == NULL || zids == NULL); if (opt_zone == NULL) { + zone_status_t status; + + if (zone_getattr(zids[zent], ZONE_ATTR_STATUS, + &status, sizeof (status)) < 0 || + status != ZONE_IS_RUNNING) { + /* + * If this zone is not running or we cannot + * get its status, we do not want to attempt + * to bind an SCF handle to it, lest we + * accidentally interfere with a zone that + * is not yet running by looking up a door + * to its svc.configd (which could potentially + * block a mount with an EBUSY). + */ + zent++; + goto nextzone; + } + if (getzonenamebyid(zids[zent++], zonename, sizeof (zonename)) < 0) { uu_warn(gettext("could not get name for " @@ -3687,18 +3712,46 @@ again: uu_die(gettext("invalid zone '%s'\n"), g_zonename); scf_value_destroy(zone); + + /* + * On SmartOS, there may be a base64-encoded string attribute + * named 'alias' associated with this zone. This alias is + * useful, so we attempt to make it available when we are + * displaying -xZ output. If it's not available or not + * decodable, we just ignore it. + */ + if (g_zonename != NULL) { + unsigned len; + struct zone_attrtab zattrs; + zone_dochandle_t zhdl = zonecfg_init_handle(); + + bzero(&zattrs, sizeof (zattrs)); + (void) strcpy(zattrs.zone_attr_name, "alias"); + + if (zhdl != NULL && + zonecfg_get_handle(g_zonename, zhdl) == Z_OK && + zonecfg_lookup_attr(zhdl, &zattrs) == Z_OK && + zonecfg_get_attr_string(&zattrs, g_aliasbuf, + sizeof (g_aliasbuf)) == Z_OK && + sasl_decode64(g_aliasbuf, strlen(g_aliasbuf), + g_aliasdec, sizeof (g_aliasdec), &len) == SASL_OK) { + g_aliasdec[len] = '\0'; + g_zonealias = g_aliasdec; + } else { + g_zonealias = NULL; + } + zonecfg_fini_handle(zhdl); + } } if (scf_handle_bind(h) == -1) { if (g_zonename != NULL) { - uu_warn(gettext("Could not bind to repository " + if (show_zones) + goto nextzone; + + uu_die(gettext("Could not bind to repository " "server for zone %s: %s\n"), g_zonename, scf_strerror(scf_error())); - - if (!show_zones) - return (UU_EXIT_FATAL); - - goto nextzone; } uu_die(gettext("Could not bind to repository server: %s. " @@ -3757,7 +3810,7 @@ again: if (opt_mode == 'L') { if ((err = scf_walk_fmri(h, argc, argv, SCF_WALK_MULTIPLE, - print_log, NULL, &exit_status, uu_warn)) != 0) { + print_log, NULL, errarg, errfunc)) != 0) { uu_warn(gettext("failed to iterate over " "instances: %s\n"), scf_strerror(err)); exit_status = UU_EXIT_FATAL; diff --git a/usr/src/cmd/tail/Makefile b/usr/src/cmd/tail/Makefile index 6f50c71fb7..7afc25b187 100644 --- a/usr/src/cmd/tail/Makefile +++ b/usr/src/cmd/tail/Makefile @@ -22,6 +22,7 @@ OBJS= forward.o misc.o read.o reverse.o tail.o SRCS= $(OBJS:%.o=%.c) include ../Makefile.cmd +include ../Makefile.ctf CLOBBERFILES= $(PROG) CPPFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 @@ -46,6 +47,10 @@ $(PROG): $(OBJS) $(LINK.c) $(OBJS) -o $@ $(LDLIBS) $(POST_PROCESS) +%.o: %.c + $(COMPILE.c) $< + $(POST_PROCESS_O) + install: all .WAIT $(ROOTPROG) $(ROOTXPG4PROG) $(ROOTXPG4PROG): diff --git a/usr/src/cmd/truss/print.c b/usr/src/cmd/truss/print.c index 14472f22c3..fad3a52ecd 100644 --- a/usr/src/cmd/truss/print.c +++ b/usr/src/cmd/truss/print.c @@ -21,7 +21,7 @@ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2015, Joyent, Inc. All rights reserved. + * Copyright (c) 2017, Joyent, Inc. All rights reserved. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ @@ -874,7 +874,9 @@ prt_mc4(private_t *pri, int raw, long val) /* print memcntl() (4th) argument */ return; case MC_SYNC: - if ((val & ~(MS_SYNC|MS_ASYNC|MS_INVALIDATE)) == 0) { + if ((val & + ~(MS_SYNC|MS_ASYNC|MS_INVALIDATE|MS_INVALCURPROC)) + == 0) { *(s = pri->code_buf) = '\0'; if (val & MS_SYNC) (void) strlcat(s, "|MS_SYNC", CBSIZE); @@ -883,6 +885,9 @@ prt_mc4(private_t *pri, int raw, long val) /* print memcntl() (4th) argument */ if (val & MS_INVALIDATE) (void) strlcat(s, "|MS_INVALIDATE", CBSIZE); + if (val & MS_INVALCURPROC) + (void) strlcat(s, "|MS_INVALCURPROC", + CBSIZE); } break; @@ -2091,6 +2096,8 @@ udp_optname(private_t *pri, long val) case UDP_EXCLBIND: return ("UDP_EXCLBIND"); case UDP_RCVHDR: return ("UDP_RCVHDR"); case UDP_NAT_T_ENDPOINT: return ("UDP_NAT_T_ENDPOINT"); + case UDP_SRCPORT_HASH: return ("UDP_SRCPORT_HASH"); + case UDP_SND_TO_CONNECTED: return ("UDP_SND_TO_CONNECTED"); default: (void) snprintf(pri->code_buf, sizeof (pri->code_buf), "0x%lx", @@ -2539,7 +2546,7 @@ prt_zga(private_t *pri, int raw, long val) case ZONE_ATTR_BOOTARGS: s = "ZONE_ATTR_BOOTARGS"; break; case ZONE_ATTR_BRAND: s = "ZONE_ATTR_BRAND"; break; case ZONE_ATTR_FLAGS: s = "ZONE_ATTR_FLAGS"; break; - case ZONE_ATTR_PHYS_MCAP: s = "ZONE_ATTR_PHYS_MCAP"; break; + case ZONE_ATTR_DID: s = "ZONE_ATTR_DID"; break; } } diff --git a/usr/src/cmd/truss/systable.c b/usr/src/cmd/truss/systable.c index fb1d3f7a14..b063a6e46e 100644 --- a/usr/src/cmd/truss/systable.c +++ b/usr/src/cmd/truss/systable.c @@ -29,6 +29,9 @@ /* Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved. */ +/* + * Copyright (c) 2014, Joyent, Inc. All rights reserved. + */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> @@ -1716,9 +1719,10 @@ const char * const afcodes[] = { "POLICY", /* 29 */ "RDS", /* 30 */ "TRILL", /* 31 */ - "PACKET" /* 32 */ + "PACKET", /* 32 */ + "LX_NETLINK" /* 33 */ }; -#if MAX_AFCODES != 33 +#if MAX_AFCODES != 34 #error Need to update address-family table #endif diff --git a/usr/src/cmd/ucodeadm/Makefile b/usr/src/cmd/ucodeadm/Makefile index 1abe8bb420..fe30d02a27 100644 --- a/usr/src/cmd/ucodeadm/Makefile +++ b/usr/src/cmd/ucodeadm/Makefile @@ -39,13 +39,6 @@ include ../Makefile.cmd POFILE = ucodeadm_all.po POFILES = $(PROG_OBJS:%.o=%.po) -INTEL_UCODE_FILE = intel-ucode.txt -AMD_UCODE_FILE = amd-ucode.bin - -ROOTUCODEPATH = $(ROOT)/platform/i86pc/ucode -ROOTINTELUCODE = $(INTEL_UCODE_FILE:%=$(ROOTUCODEPATH)/%) -ROOTAMDUCODE = $(AMD_UCODE_FILE:%=$(ROOTUCODEPATH)/%) - CPPFLAGS = -I../../common -I../../uts/common CFLAGS += $(CCVERBOSE) CERRWARN += -_gcc=-Wno-uninitialized @@ -57,9 +50,6 @@ LDLIBS += -lgen DIRMODE = 0755 FILEMODE = 0555 -$(ROOTINTELUCODE) := FILEMODE = 0444 -$(ROOTAMDUCODE) := FILEMODE = 0444 - install := TARGET = install clobber := TARGET = clobber @@ -69,7 +59,7 @@ CLEANFILES += $(PROG) $(OBJS) ucode_errno.c $(POFILES) $(POFILE) all: $(PROG) -install: all $(ROOTUSRSBINPROG) $(ROOTUCODEPATH) $(ROOTINTELUCODE) $(ROOTAMDUCODE) +install: all $(ROOTUSRSBINPROG) _msg: ucodeadm_all.po @@ -81,12 +71,6 @@ $(PROG): $(OBJS) ucode_errno.c $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS) $(POST_PROCESS) -$(ROOTUCODEPATH): - $(INS.dir) - -$(ROOTUCODEPATH)/%: % - $(INS.file) - clean: -$(RM) $(CLEANFILES) diff --git a/usr/src/cmd/ucodeadm/amd-ucode.bin b/usr/src/cmd/ucodeadm/amd-ucode.bin Binary files differdeleted file mode 100644 index 365d279d2b..0000000000 --- a/usr/src/cmd/ucodeadm/amd-ucode.bin +++ /dev/null diff --git a/usr/src/cmd/ucodeadm/intel-ucode.txt b/usr/src/cmd/ucodeadm/intel-ucode.txt deleted file mode 100644 index 3c0d466d23..0000000000 --- a/usr/src/cmd/ucodeadm/intel-ucode.txt +++ /dev/null @@ -1,30272 +0,0 @@ -/+++ -/ Copyright (c) <1995-2010>, Intel Corporation. -/ All rights reserved. -/ -/ Redistribution. Redistribution and use in binary form, without modification, are -/ permitted provided that the following conditions are met: -/ .Redistributions must reproduce the above copyright notice and the following -/ disclaimer in the documentation and/or other materials provided with the -/ distribution. -/ .Neither the name of Intel Corporation nor the names of its suppliers may be used -/ to endorse or promote products derived from this software without specific prior -/ written permission. -/ .No reverse engineering, decompilation, or disassembly of this software is -/ permitted. -/ ."Binary form" includes any format commonly used for electronic conveyance -/ which is a reversible, bit-exact translation of binary representation to ASCII or -/ ISO text, for example, "uuencode." -/ -/ DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT -/ HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED -/ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -/ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -/ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -/ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -/ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -/ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -/ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -/ CAUSED AND 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. -/ -/--- -/* Tue Feb 9 12:54:50 CST 2010 */ -/* 727-MU168313.inc */ -0x00000001, 0x00000013, 0x02062001, 0x00000683, -0x2f0da1b0, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xbf5ad468, 0xc79f5237, 0xbd53889e, 0x896bfd13, -0x7adc0c8f, 0x44e9e0bc, 0x1a331fc9, 0x00b0f479, -0x53e9ceb3, 0xb14131a4, 0x39fc8310, 0x6993ee0d, -0xdb0c59b4, 0x67f24fd0, 0x63e83516, 0x0a4d411d, -0xb86a4294, 0x72c2edc5, 0xc543c5df, 0x7f3dd290, -0x2fb772ec, 0x9a2931bb, 0xefc2e759, 0x2f5939eb, -0xc37aa9d5, 0xd6d46fcf, 0xaf6ef51e, 0x5c3b48ed, -0xec51da4d, 0x6c8a6d59, 0x66ecfeb7, 0x3698ead8, -0x00ba31f3, 0x98f1a1fa, 0x2d015e7d, 0x5599cff2, -0x3106cde9, 0xdc0160f0, 0x14b213c3, 0xbd29458f, -0xa849c192, 0x2edfe235, 0x6dd8c4d5, 0xbd204f8c, -0xb4abfb0b, 0x173e7eb0, 0xf9540357, 0xd5357562, -0x680702f8, 0x7bb8d06c, 0x271009cb, 0xdbe0f120, -0x3838ab66, 0xd6baf0c6, 0xbfe956e0, 0x1de10bf6, -0xb89aa364, 0x75a4e75d, 0x8dbb1611, 0xe7ad829f, -0x7f240c7b, 0x1e7a25e1, 0x2bb32a9b, 0xa4d82b67, -0x826137cc, 0x56742108, 0xace9b137, 0x023edadb, -0x4cbf6d68, 0xfdf37a0a, 0xc376fa28, 0xe89004db, -0xc1eae782, 0xa4a9446c, 0x1b90d7b9, 0x2bfd32c1, -0x329eaff3, 0x4a718a99, 0x4ca2abf3, 0x7ba47de1, -0x18a70488, 0xf6952f0d, 0x84820198, 0x4f3c26eb, -0x5b94c8f6, 0x41f125fb, 0x5989354f, 0x7d044bf6, -0x184e2f6f, 0x341a42aa, 0xb45e5675, 0xcf50a3f6, -0x278ba361, 0x8ca26a33, 0x59135ca2, 0xca8da559, -0xfc7f5d55, 0x051e181b, 0xc625547a, 0x118fae7c, -0x2fedef02, 0x08db6c79, 0x80e1e8cf, 0xf4381bc1, -0x1f7950b0, 0xe696234e, 0x6b81a924, 0xf16adb3b, -0x9ef0b2eb, 0xcefbee01, 0xc14bc102, 0x04f53303, -0x24414c5d, 0x6de5becb, 0xfefd46a4, 0x181501d3, -0xca96281b, 0x8a5d854a, 0xd32c4217, 0xf6465a87, -0xedd6d554, 0x5af2e656, 0x25c927e7, 0x2b939e69, -0x3d8a1258, 0x0d4dff51, 0x393fe7bb, 0x053ca46f, -0xfffc4059, 0x7bad6cc0, 0x5f470b94, 0x4c3c8cc6, -0xc3979d0d, 0x79f13dac, 0xc5541810, 0xc91f8b1b, -0xdd622585, 0x089523bf, 0xfa92b3a9, 0x70297814, -0xe73f7917, 0xd6a9e6ac, 0x17808b44, 0x55067c05, -0xd624bead, 0xb1e38e74, 0x194dec06, 0xbdb4056d, -0x776ea5b2, 0x6728235c, 0xdf8d95ee, 0xcce51e11, -0x90bc5b43, 0x3cef9c3b, 0x6a16b438, 0x45f6d2bc, -0xaa75e5ed, 0x4b8af156, 0xc4f7b910, 0x26d01e03, -0x1cc57123, 0x4a944bab, 0x999a8a33, 0x2206c5c5, -0x0e98c46c, 0x9991c412, 0xd604b138, 0xd5fb4854, -0x8d6443a5, 0x9556ef42, 0xb0fa163f, 0x86711b0d, -0xce8093ec, 0x6e0d0ec8, 0x25419efb, 0xd0f63d95, -0xe6958c51, 0x2e1cf5a2, 0x2c4e7322, 0x6f85dfa9, -0x9edcdd4e, 0x5a90e4cc, 0x3490caf7, 0x6b54688c, -0x701149f7, 0x81252786, 0x94a7a283, 0x304852f1, -0x5db80731, 0x4534feca, 0xad089aee, 0xb8d3ffd9, -0x9bc94a42, 0xac307e67, 0x6990339e, 0xb2a1c6f4, -0xdad20302, 0x5b5c4292, 0xd40c8dde, 0x61de0def, -0xdb05e18c, 0x16d838ee, 0x90affbe4, 0x661ea875, -0xa5b3628a, 0x4c801759, 0xd1d3635f, 0xf52ac3bc, -0x79664739, 0xd14d049f, 0xf4417688, 0x20ac0ea5, -0xcbf03121, 0xa9adde2c, 0xcb2ef310, 0x26a34ecb, -0x166323e0, 0x8fdd8de7, 0x1c4a2440, 0x753bf563, -0x37881ad6, 0x8c2d6fc3, 0x1d324831, 0x4cb83f53, -0x07094679, 0xabb242a3, 0xb0fc5053, 0x3b4a1718, -0xc87b62c4, 0x6f4b76a0, 0xee785187, 0xe91c9908, -0xf738b92a, 0xbd5061b8, 0xead42904, 0x130b722b, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1637-m5cf4a04.inc */ -0x00000001, 0x00000004, 0x12142005, 0x00000f4a, -0x5e7996d9, 0x00000001, 0x0000005c, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x1b07bcc7, 0x229cce65, 0xe59c6d88, 0x368a8eac, -0x265a5ea8, 0x10ccc72c, 0x87320671, 0x94a92d48, -0xeb5af331, 0x0d008e26, 0x8df305da, 0x9dde4c6a, -0x8c99c77d, 0xb29cce43, 0xf878b938, 0xbe6f1c58, -0xa5642b21, 0xa235f7ed, 0x7246e088, 0x01f50007, -0x2671ee90, 0x80a25b6b, 0x4906a87b, 0x93feb435, -0x63376263, 0x2f56135e, 0x2fe6b7cb, 0x47b9e023, -0x89edd593, 0xa50ea0bd, 0x88b4c598, 0xe8049dce, -0xc3a5caef, 0x66c0c8b3, 0x23fd02d4, 0xae6b76e1, -0x367b794e, 0xe991df14, 0x99966e37, 0x8c94d969, -0x03bd493e, 0x9a668e1b, 0x8b03e862, 0x06b3d582, -0xdbe3e579, 0x8d808793, 0xb8a60a2e, 0xadadc225, -0x05005e7f, 0x29a8c4b2, 0xf88aa416, 0xa5fe8613, -0x28399122, 0xa72292cf, 0xd1a3ac3e, 0x0c1ecf12, -0x243e5147, 0x92d4b766, 0x1ac71ed9, 0x8bc3baca, -0xe610d668, 0x375b6b2d, 0x2ca4f1d6, 0x399857ca, -0xae107abb, 0x938d073d, 0x5ad00070, 0x9342bd0d, -0x536d6790, 0x15d633f0, 0xbb32795e, 0x980ab451, -0xb664a218, 0xb44415b7, 0xbeb0c093, 0xe5a9f22d, -0x5879deeb, 0xa416441d, 0x38fe769e, 0x52ea4068, -0xd5f86736, 0xc9ad814c, 0x1f41d0fe, 0xa8b13c07, -0x5665f649, 0x50a4a2d0, 0x47e60480, 0x174058f0, -0x5f9229eb, 0xa9b5c958, 0x8d722a78, 0x82504ca6, -0xa4f69e86, 0x1165831e, 0x5f3a2776, 0x9da68937, -0x5587f203, 0xa0dde401, 0xc8b18cd7, 0xd817c5be, -0x3c64d4c4, 0xb47424b8, 0xf290272d, 0x46f4e8de, -0xaed74fdb, 0xd6b21df6, 0xa8968c2e, 0xb9224f33, -0x9043df16, 0x53fe2d31, 0xb51da202, 0x083b1387, -0xdd470698, 0xb1b66ae2, 0x13cf0cdf, 0xa64ff501, -0x36baf606, 0x15a8128b, 0x41ee5a81, 0xac05e4ff, -0x7fd94e1c, 0xa8f227d7, 0x7c81ff00, 0xd8c234c0, -0xc31aa196, 0x9c9345a5, 0xeff07da3, 0x4c1d9daf, -0x5f1ce189, 0xefa826ca, 0x5123e316, 0xaad27995, -0x1e425c1e, 0x45d05042, 0x6b77ccba, 0x66b75e9d, -0x4b9c3b52, 0x85f95778, 0xb405df56, 0xe537f9df, -0x404c8e01, 0x6d8dd53c, 0x7f0f05f2, 0xbec561f9, -0x1a990e16, 0xe8b96bd5, 0x817d06e6, 0xb2001f52, -0x90c721a9, 0x8e7c8d4e, 0xf4a4cb38, 0x2714865c, -0x5a851aee, 0x8590dd73, 0x54bbc2c0, 0xaf164bad, -0xb82559e4, 0x3ec52049, 0x20ab2224, 0x1f2e35a9, -0xcd5bd10c, 0xa04c7a00, 0x42dadb32, 0x90d47c14, -0x48e98aa0, 0x0b3faebb, 0xb0d34d9d, 0x90df0308, -0x052df922, 0x9047a63e, 0x4a7e0ba9, 0x88217146, -0x0b037fb5, 0x8bcdede1, 0xdb81c283, 0x2bde05fd, -0xae2c87fb, 0xb4697173, 0x205688d7, 0x810963ae, -0x2e06be4c, 0x1abf1c0a, 0xbda9cf06, 0x31f1c55c, -0x52b4759c, 0x89f8da46, 0x41cee81a, 0xa1eeaec2, -0x4af67f8a, 0x3a20e63a, 0xa2caf5c3, 0x9c3c5779, -0x2acac8c9, 0x94409ea5, 0xead029b0, 0xb6bcd3c1, -0x7c41d8f1, 0xbfd61625, 0xe99f0e89, 0x0279bf61, -0x5d7a4c97, 0xb874dc31, 0x3def7321, 0x9717a1a3, -0x74dac81c, 0x1fc5bccd, 0x4b121ffd, 0x3c905b5e, -0x979c8f1b, 0x8db03b46, 0x088163dd, 0xbed0f9ef, -0x9dd04f9c, 0x05d2be02, 0x464ff266, 0xad2e216a, -0x6b8568ec, 0x86376635, 0x0e36e6b8, 0xf6cedcfb, -0xc634e917, 0x996c8a45, 0x2a2a7204, 0x57396ea2, -0x86e97e5c, 0xd8df2021, 0x27f1544b, 0xbee538d1, -0x854ac66e, 0x4194e6a1, 0xedca65af, 0x6a96ae01, -0x4b697f06, 0xa3393627, 0x6aaf7c45, 0xe4ce7b54, -0xbaf630e7, 0x48c5685a, 0xaf578166, 0x8b4b865f, -0x9fbe47f5, 0xe6dc5717, 0xe1e6a3f4, 0x88c713dd, -0x5e095cd9, 0xb8579da1, 0xccb0e009, 0x30893a84, -0xc9c01f0f, 0xa3afc2d7, 0x568816ef, 0x8e983bd3, -0x567362ca, 0x103e7a47, 0x504ed286, 0x05e53454, -0x160d2d34, 0xa78e0961, 0x35de2ff3, 0xb68bb128, -0x67fe80ec, 0x33f73764, 0x0424a99e, 0xba34b730, -0x85ba0e83, 0x8a159b32, 0xc3727283, 0x8d012edc, -0x6ae89a83, 0xb2cc412a, 0x792eb6ca, 0x38337d83, -0x07c1d766, 0xb5ada859, 0x17e30b6a, 0x9e634e91, -0x929c0699, 0x026f19f4, 0xa4f8fb5d, 0x9a9d424f, -0x79c30b93, 0xa3130a5d, 0x68e589c4, 0x027d4ec9, -0xeef88f03, 0x8afab3b2, 0x4dab76a8, 0x9570708f, -0xf47bf52a, 0x04d4ef9d, 0x76da08d8, 0x7dc7c531, -0x4c2d71a9, 0x9952935f, 0x6818527d, 0xdad1c25b, -0xb8eea89c, 0x7091b5f8, 0x5a333927, 0x865f794c, -0x36e0a2a6, 0xde431054, 0xe55c0a8a, 0xac41dfd1, -0x7bb905c7, 0xb19641c9, 0x10fc1be4, 0x038071f4, -0x3ffe20f4, 0x8af0fb14, 0x87da983f, 0xb6f2dcd0, -0x1baee9c0, 0x090773cf, 0x85e9fec0, 0x10a1216e, -0x3ff4c6aa, 0x98916b0e, 0x7fd1d04b, 0x9e8546e2, -0x7ed1b25b, 0x24c743a1, 0xf52610a3, 0xbe8d47fc, -0xb40a0dcf, 0xa976fed3, 0x8d6990e7, 0xc6d999bb, -0xc72b4218, 0xb5667e14, 0x800e6048, 0x559e81ec, -0x8463a8da, 0xcded36c4, 0xf8214d01, 0x8c9a5bf2, -0x04b3b511, 0x7f38337a, 0xc1ed0d56, 0x4b4fe2cb, -0x1ece884f, 0xa9d19d5a, 0x683fee1c, 0xd221e8ad, -0x328c416a, 0x756b18ee, 0x8481f60b, 0xa9f204cb, -0x620b2a31, 0xd4266217, 0xf9849baa, 0xd384d524, -0xa7c8c7a9, 0x9b7e94c3, 0xfb45e191, 0x632547ee, -0x77feb7fd, 0xd66e5dfc, 0x8d3533fb, 0x97b1f83b, -0x36c121cf, 0x5fed8787, 0x14bd43ea, 0x24acf846, -0x279bcc0d, 0x9ffda402, 0xcb0451ba, 0xa671cc89, -0x0f2ffa41, 0x2479c2f3, 0x8b99c062, 0x839a8212, -0x814eebd5, 0x8d5ac17d, 0x28ad1e99, 0xb744ee49, -0x5cc62a5f, 0xa6c2e876, 0xe93c507a, 0x0e838735, -0x01797001, 0xb6b1e47b, 0x8fcb643d, 0x87274e8b, -0xcf6ee5d2, 0x1c346645, 0xa241c408, 0x3e434b2a, -0x5c1e969e, 0xa159f09f, 0x51c24a4e, 0x9ea980d2, -0xb18a3126, 0x377f54f5, 0x5051635b, 0x88120bf5, -0x5068c53d, 0x81e91c0b, 0xddbe6afc, 0xace26a65, -0x89b39b12, 0x9203bac1, 0x30b1e081, 0x0d00f46a, -0x8dd7bf19, 0x84880bce, 0xfbebc09a, 0xadcd1fe1, -0xb92bf186, 0x3c0ce7e0, 0x9e1567bd, 0x08e93d8b, -0x5f3bc65d, 0xbd3213f2, 0x35dff336, 0xb017c028, -0xa5096cd6, 0x2ec14ded, 0x860021d3, 0x815b7994, -0x450eec66, 0xbe0468cd, 0xf023c57e, 0xba7f0632, -0x74ce6861, 0xa3300156, 0x12378195, 0x2902d080, -0x43670eec, 0xb97e140b, 0x10092553, 0x9621397b, -0xf9149286, 0x33331ea4, 0x91024d01, 0xce41fa3a, -0x65596b8e, 0xa146b772, 0x4a65b406, 0x40200f18, -0xf232bcbc, 0xfd86eb3d, 0xd4b83bfb, 0x8ec7b200, -0xa9d8490e, 0x42b9b1b0, 0x480bd06a, 0x2dd8f709, -0x762fedf8, 0xb1083b6f, 0xc7fba09a, 0xbb7a7261, -0xf624d4eb, 0x118ef882, 0x38230014, 0x8fad6b48, -0xf500b16a, 0x9116c2a2, 0x0e2a9245, 0x89f6f38d, -0x9954d6b2, 0xc6db5fcf, 0xe2d103e6, 0x534024b1, -0xf0bb00df, 0xf15ee38c, 0xa9ea9a03, 0x90597958, -0x152bdd7b, 0xb5e145da, 0xfd6c72a5, 0x5aa1748f, -0x86c58ac8, 0x603ad265, 0x5abfe039, 0x25f75b90, -0x177b6e02, 0xf2dc10fc, 0xf0d32590, 0x9c361b74, -0x54677a40, 0x5d34ad04, 0xece46599, 0x915f504c, -0x518acffc, 0x801e0592, 0x491e9bbc, 0x9ea5402f, -0xe943029b, 0xba9fc7e4, 0x4b6666d7, 0xb5504834, -0x77cddd8c, 0xbf122e96, 0x665a70e3, 0xc602ba64, -0xabedcce3, 0x56d38242, 0xeddc0b0a, 0xa8debf0b, -/* 422-MU26530b.inc */ -0x00000001, 0x0000000b, 0x05201999, 0x00000653, -0xe3f50f82, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xa4f21304, 0x1d7bf7d9, 0xb5be812c, 0x1ea46237, -0x8d811046, 0x0fe67ef6, 0x507754ff, 0x0c97d96c, -0xdce8311d, 0xe4c2cf96, 0x362d5ea1, 0xaf113121, -0xac3bde75, 0xbff45249, 0x0e132b97, 0x1401c5ad, -0xbca78b32, 0x07238147, 0xf31aa8f1, 0xa514cab2, -0x390ab9e7, 0x0019b113, 0x4d62ccc3, 0x27f077fc, -0x2fd14c9e, 0x7512326e, 0x47f43060, 0x0d2c1b03, -0x6c2ceaab, 0xcd57b37e, 0x4231a8d0, 0xa104c588, -0x1d2cecae, 0x5bdbf092, 0xce711c6a, 0x81f297b9, -0x3eb2dad7, 0xf20bda6f, 0xfb1efa44, 0xb00434be, -0x12742e89, 0x08354c21, 0x88f6f908, 0x476c66c6, -0x06eb9ded, 0xdcea60f0, 0xe0f48c3f, 0x3ea169fb, -0x15a1e00c, 0xfa7ef115, 0xa9a5d23d, 0x38da8793, -0x6b1ae52d, 0x1be30123, 0x0fb921e3, 0x87688811, -0x45b02f33, 0xa002e5ef, 0xdcf91775, 0x29fe20bb, -0x6d886079, 0x3b01080b, 0x2845931b, 0x56f0bdc0, -0xe7f97853, 0xaa51555b, 0x3fdefce6, 0x9231d0d5, -0x34695b1c, 0x7071e3c2, 0xfc1eefb6, 0x65ed91cf, -0xa30f9193, 0xa951e706, 0xf28168de, 0xea7cca1a, -0x00ad260c, 0x482dcab1, 0x7074f431, 0x82255d72, -0x52225c8a, 0xfcd447ee, 0xc8430fcb, 0xed713c21, -0xe05a800d, 0x9ffb7c19, 0x680a7a9a, 0x4ebdcfd6, -0x8e9c8c59, 0x72cce044, 0x87289c8b, 0x691ebdc2, -0x7dd25e97, 0x284a8c8e, 0x25248a91, 0xb73b016a, -0xf4780147, 0x0c870606, 0x81bf5462, 0xf2b76112, -0x896e6d44, 0xc75bf85a, 0xb1889a71, 0xe9c07ab3, -0xdd6be9cd, 0x9481207c, 0x6df36c80, 0x019c493b, -0x9664fa7c, 0xfe29655a, 0x8e3c380f, 0xe827afd8, -0x14a411e5, 0xd6ecf9cc, 0x08698f98, 0x76cdac6c, -0xca73193d, 0x3db85e3e, 0x9827cfc4, 0x7d80d459, -0xa52c24cc, 0x1b415086, 0xf732e136, 0xf121c28c, -0xee8a984b, 0x2ffa66b6, 0x028df8c1, 0x583c2a59, -0x940835cc, 0x11f3141d, 0x3f3f4ec1, 0xdee86cf0, -0xc85794d2, 0x83e377bc, 0x697d6c3a, 0x54cc8278, -0x1d0512ce, 0xafd73aad, 0x22fbe58e, 0x586d29a0, -0x7247bd99, 0x77eee287, 0x13584559, 0xc2fd6bf2, -0x310bba13, 0xf9b0a166, 0xf7d32176, 0x21426813, -0x56c2da83, 0x13e49126, 0x7a557e54, 0x4c8a8f84, -0x838f3992, 0x0ec6d554, 0x8aa5856f, 0xcd1935bf, -0x01614664, 0x54b01c3d, 0x17a7cdd6, 0xaec2cb3d, -0x4bc9c3e4, 0x6645b33c, 0xfced3b87, 0x4e5dd898, -0x45d1dbb7, 0xb60e6b5f, 0xa7e938ce, 0xe4e1bcde, -0x4f400eb1, 0x4dbdc103, 0xf1608c91, 0x5b05c4b5, -0xfecd782b, 0xe3106e25, 0xabbb7bb0, 0x0ba21681, -0xcca215e2, 0xefc41853, 0x67c969eb, 0xb8cb9dc2, -0xbd1089ed, 0x5df85c48, 0x31c7c77f, 0x3f14b936, -0x3396d664, 0xb09b91b2, 0xd2970963, 0xc97ee590, -0x6344c8c2, 0x3d999973, 0xb74e5d5e, 0xebd9eb93, -0x3d536a87, 0xda39bf3d, 0x8a899c61, 0x8cfbdf63, -0x41ee792e, 0x43a38712, 0x4851037d, 0x3ee0c77b, -0x82062189, 0x597faf60, 0xb95e3a07, 0x2a276757, -0xd52941c6, 0x2c1bdd08, 0xf9f47a55, 0x4508305a, -0x9f38c11b, 0x863b657b, 0x567be75c, 0xa5f37533, -0x05ce6cb1, 0xe29f6533, 0xaf889424, 0x8c4a9cf3, -0x159d8b70, 0x473abecb, 0x41df09f1, 0x6bd38e85, -0x65e45213, 0x04688358, 0x2e6e5f0c, 0x94335dd2, -0xec7d3761, 0x0db43819, 0x4dfae8d5, 0xd061ca76, -0x225c1d2e, 0xd5da0bd3, 0x61936693, 0xc6b7b73e, -0x6604eb97, 0x9993f5f6, 0x44f2f4ca, 0x2236e62d, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1498-m5df4a02.inc */ -0x00000001, 0x00000002, 0x06102005, 0x00000f4a, -0xdfbc9997, 0x00000001, 0x0000005d, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x1b07bcc7, 0x229cce65, 0xe3946d89, 0x368a8eaa, -0x8b8a4197, 0x2e048664, 0x48078928, 0x0aa749ae, -0x1cee9215, 0x22910485, 0x3d030824, 0x15cb61f8, -0x7fff14fa, 0x35c7b714, 0x1d489846, 0x5d8ff7da, -0xe237595f, 0x35e48e39, 0x4540e8d1, 0x45c15a5c, -0x3356fc26, 0x5d5386e8, 0x926d41b3, 0x10ca2831, -0x904bdf7f, 0x463e806b, 0xb22aa067, 0xaff8872c, -0xb5260171, 0x1b4bdd54, 0x6582202e, 0xaceff700, -0x56cfda08, 0x8a39f2a7, 0xf1c0e97f, 0x05fe76a0, -0xca6b4d0e, 0x9f33f9ea, 0x0495ba8a, 0x31380f84, -0xda4d936b, 0x2597f34c, 0x523aedf7, 0x22df0035, -0x15acc8e4, 0x23663293, 0xe869afdd, 0x1f23378d, -0x71a210f8, 0x091c942e, 0x5578f30d, 0xe4be34eb, -0xfd9927f3, 0x01200031, 0x0d76398e, 0xe46f9840, -0x8e29a1c5, 0xcfcd5407, 0xc93c0b1d, 0x3675504a, -0x49fec6a2, 0xf172670c, 0xc264f82e, 0x527393bd, -0xba750da9, 0x11bb3f31, 0x386d6943, 0x7e02c181, -0xdf1156af, 0x59bd57ca, 0x9241d631, 0x2bc328f0, -0xd7bbc782, 0x51d62827, 0x56258a65, 0xe9f0ede9, -0xa35ed86c, 0x1ffb6be0, 0x0395e246, 0xe7f35b66, -0x70be025e, 0xff1171d3, 0xae761e69, 0x2af9dce5, -0xda799a78, 0xe0bded96, 0x4d4688f0, 0xc79b0a5a, -0xd449c23a, 0x016970ba, 0xf34363b6, 0xe6e1d420, -0x79320e33, 0xcdd5afa7, 0xfe0fd414, 0x033a16e5, -0x109c7655, 0xc87a1e62, 0xd78f9c37, 0x682c1113, -0x2ae57d31, 0x09256fe2, 0x11ffc988, 0x465258dc, -0xb2dc55ce, 0x5d61a5e4, 0xaab3d80a, 0x19c93aac, -0x642c1dd3, 0x45999943, 0x46640bc6, 0xd7a6a658, -0x4a1c0ae3, 0x1ce268e9, 0x83f92440, 0xdbe37cd4, -0xf589f5a2, 0xcf8915df, 0x593f5d12, 0x3abb579a, -0xf92f9d43, 0xd32ba114, 0xc158dd67, 0x26e44425, -0x0c16231b, 0x0846ff42, 0x9a1c72ee, 0x3e7f9e9a, -0x00d036f6, 0x3a37204f, 0x3ab32667, 0x39c36227, -0x729b7436, 0x1979daac, 0x14791793, 0xe4b8d8fb, -0xfd25a4f7, 0x1d1bb5a8, 0x69f8fd39, 0xeb75da5a, -0x2c090ba5, 0xdcece5af, 0x98101e50, 0x3699a493, -0x7d8b6c58, 0xc0eac9bb, 0x93b47842, 0xbaf68e38, -0x81b9c8f5, 0x3263cddc, 0xc123e7a4, 0xaf0c43d7, -0xe080005f, 0xb7d5b466, 0x943bfb69, 0x35f75e4e, -0x979853ab, 0xa2602607, 0xdb30f012, 0x866a297e, -0x76f717d3, 0x162e026b, 0x976d9c8e, 0xbf364947, -0xc90b79fe, 0xb08b69cd, 0x8f666cd0, 0x00785cd5, -0xae0dc87a, 0xa73192d2, 0x42290c62, 0x3dc06187, -0x3a2270f3, 0x2f33ebc4, 0xb2afac90, 0x2550f035, -0x2a22a7b7, 0x209b09b6, 0x9672bff5, 0x24b1305a, -0x861a16f0, 0x24d11771, 0x58bfa270, 0xd6692269, -0x257857a3, 0x032562fc, 0x9cf4edd6, 0xfefe9d20, -0xf57a5c91, 0xd3d75b0e, 0x01c72ec4, 0x3fa13568, -0xc454a4d0, 0xc90f813b, 0xd9181420, 0x494627bb, -0x7c164810, 0x0a00ccdc, 0x3d9ab2a2, 0x4848efd3, -0x31584e6f, 0x48a0ed58, 0x0db818fb, 0x177138e1, -0x897d1cbb, 0x7244d929, 0xb3f4a431, 0xb6e60dfc, -0x8645e9ea, 0x3252a53c, 0x5964ccc9, 0xad76be63, -0x59027581, 0x83b0fa2e, 0xa5b9346c, 0x2082efd0, -0xb1bcaf19, 0xb98dfdd9, 0x45e082ca, 0x8c200986, -0xe193eaad, 0x39bef164, 0x99c468b8, 0x805bdaa7, -0x22d12bfe, 0xa90be671, 0x6f6d8506, 0x010af4e2, -0xa8759e49, 0xa3206b70, 0xe9a0be66, 0x139dfd01, -0x2291dc47, 0x0eec7d63, 0xcbee9187, 0x193b21c2, -0xffa47a38, 0x2fd0eba8, 0x955f4a43, 0x343b16d1, -0xa5d61063, 0x33533ce6, 0x4c9e7f08, 0x270ef845, -0x6252c02c, 0x04e4867c, 0xe26693b6, 0x3620ab00, -0x04371508, 0x0c2dcd08, 0xb0052ff9, 0x1f24f775, -0xaadf6a7f, 0x2cd5a94d, 0x2a4df4f0, 0xd98aa865, -0x754e7b50, 0x13f68eaf, 0x9d7489c8, 0xe7199de3, -0xda23e0e0, 0xdea52f5a, 0x2abf6046, 0x38ece5a4, -0x73c54818, 0xd56dea08, 0x859b323e, 0x217c80b9, -0x626c662b, 0x28cdd1e5, 0x0f0b167c, 0x1cc59430, -0xb479422f, 0x2dcd0493, 0x332b94da, 0x00c77995, -0x89c54496, 0x0d850c7b, 0xe053a358, 0x92f97427, -0xf125c08c, 0x21594f5f, 0x3368cc3b, 0xa2600fbf, -0xc881574c, 0xa39d7f58, 0x84470209, 0x18f6adb4, -0xed0fedf8, 0xbeec6bf8, 0x798839df, 0x20581100, -0x995ad6e6, 0x1eaaefd4, 0x004a1667, 0x2177b9ce, -0xda36efb8, 0x0ab93b96, 0x5afb7c0a, 0x23479016, -0xf104b17c, 0x01cfe9f8, 0x56281be4, 0xbaf663ff, -0xfabb9f77, 0x029a7ab4, 0xef4fa0b3, 0x83621100, -0xebbe19f9, 0xaff0c53c, 0x6595a5cd, 0x0ef6c50b, -0xa314b2b4, 0xb18e55c2, 0x4f55d25d, 0x4f6b1c08, -0x566ae376, 0x3fe466d9, 0x2fc3212c, 0x747b503d, -0xd827e8e3, 0x44a650e1, 0x84efebb5, 0x0627dd27, -0xd482b6b6, 0x7c1838e2, 0x57406963, 0x9ba188ec, -0x6bb9a021, 0x1cac0354, 0xc5204396, 0xa904294b, -0xd3cf32c7, 0xb9b0ddb8, 0xd95a73df, 0x0076a769, -0x92fbd38f, 0x88565d4e, 0x7423461b, 0x5880eef2, -0x143ec991, 0x30bd7869, 0x52b18056, 0x46dfc608, -0xbff8d798, 0x5ac07642, 0x78638c18, 0x285a786b, -0xe16c63b2, 0x577a5552, 0xe2964f27, 0xd16173de, -0xe471135b, 0x16d8cb8a, 0xf2723bf2, 0xc893d60c, -0x7479a756, 0xe2a5141d, 0xd36cf5fa, 0x3019dc20, -0x905c02f0, 0xee801166, 0x540c1adf, 0x639cbe17, -0x92fc96f1, 0x19fc363f, 0x319b5d51, 0x78a939b1, -0x8f472c1e, 0x7642bddc, 0xfc32257f, 0x07850fb3, -0xf3df106a, 0x55f29d11, 0x0f920214, 0xe2718970, -0x72f6ec29, 0x2d54fc8f, 0x2bc67fdb, 0xf3021bcb, -0x9d068426, 0xfdbf6707, 0xd66932bf, 0x1f66f54e, -0x256dad97, 0xdad0f681, 0x5ef863a0, 0x06f06efc, -0xae8c4b97, 0x20d14729, 0xd0b1cd56, 0x13847b3c, -0xbcc3719a, 0x025dc7bc, 0x90df4cbe, 0x1b1ae1f8, -0xad2951ed, 0x2b40ff4c, 0x759faaea, 0xef240c6b, -0x8e876989, 0x3847bb55, 0x00ee9bbf, 0xe2fa917b, -0x93760e59, 0xc07f19dc, 0x1671842f, 0x2b125b94, -0x61519c4f, 0xc89f48b8, 0x140e76a7, 0x7d685a3a, -0xe09c619a, 0x24f25b96, 0xf01b11ec, 0x621dbc3b, -0x5344e695, 0x55bef93f, 0xe521809b, 0x0283fba4, -0x18214b19, 0x545ede9f, 0x77c30256, 0xdef3400c, -0x15358782, 0x135239b4, 0x8c9f4e10, 0xd3785c06, -0xc8523088, 0xfdc3475a, 0x021c3b30, 0x23c63b6d, -0xf85e8681, 0xd9e8aeef, 0x30671e47, 0x70d63032, -0x9b5f73b7, 0x1073c5eb, 0x85a7cf9e, 0x61e6a62b, -0xad00cc55, 0x4e911223, 0xd564fe80, 0x06a5ae6c, -0x54021cbc, 0x65e3463d, 0x4d3415c8, 0x868e6ee9, -0xe5185dda, 0x2bfac1de, 0x5620e9f7, 0xbf461c29, -0x76cab399, 0xbec619be, 0x6dc45229, 0x1313cd52, -0x24041989, 0xa3d3876e, 0xb470eca3, 0x3427ab15, -0x1900f564, 0x02666a5a, 0x857b8bf6, 0x09949203, -0x20092549, 0x0eb9167f, 0xb6d7111f, 0x2af5715c, -0x05393ff4, 0x139a0b4a, 0xcc81065b, 0x94c4157d, -0xca738627, 0x4ab2cda9, 0x9c822455, 0xb1d07b41, -0x40f6d839, 0x86bcfd3e, 0xde9437b5, 0xfc9cb6c5, -0x46065444, 0x3cae20fb, 0x6dadbf69, 0x6b53ab8e, -0x19d8ad42, 0x100ef7f4, 0xb63eff85, 0xf916a193, -0xd39e525d, 0xaab2c818, 0x43f7fd47, 0x6bd2575a, -0x2bcd64ac, 0xef7cba74, 0xbbe75ea7, 0x58845dad, -0xf4556932, 0x513b796f, 0x05aa4a60, 0x51527120, -/* 293-mu267114.inc */ -0x00000001, 0x00000014, 0x08111998, 0x00000671, -0x83239dd8, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x2900aa36, 0xedef91d1, 0x980381b8, 0x990ac1a8, -0xce6aee27, 0xcd579679, 0x93340485, 0xb4ffaf67, -0x2a528bc7, 0x5cf526ec, 0x0ffd39bb, 0x6536a335, -0x3996f969, 0x2976103e, 0x2bf45e9c, 0x19cce6b8, -0xc3a599da, 0x41442e0c, 0x7d60efcf, 0xa0dd1e48, -0xf20be1a8, 0xe92fe8ed, 0x69246640, 0xce2b3120, -0xc5fd9aba, 0xa07b4f2e, 0xfc5ec6a8, 0xdfd7ec00, -0x1af0b9cb, 0xf84deed3, 0x6efad68e, 0xd26c28f4, -0x588c4713, 0x77b51ea7, 0x9ec83e5d, 0xeb5b880f, -0xdf8da780, 0x1f1db6ba, 0x3b8b3bd6, 0x1ae4191e, -0xb84402e0, 0x518bcdec, 0x6df4b892, 0xf447c3ab, -0x7f5f3bab, 0x57d668c6, 0xdfe3a8e5, 0x87ebe853, -0x53a3e449, 0x232a99d3, 0x1a5ee33c, 0xf4308ee4, -0x508b652e, 0xf78b7ae8, 0xbd0616ef, 0xccbd906a, -0x8cb04b06, 0xdcc54a0b, 0x97a6c4aa, 0x8b56ae1e, -0x2c81c68c, 0x2a8599d9, 0x88e05548, 0x9ee7e04e, -0x1df430f0, 0x44bbfa5b, 0x79b20b93, 0x417ca0e5, -0x8a9d9bad, 0x8d799fe2, 0x8ae5b99f, 0x08d2a3c7, -0x8fefbe33, 0x54201513, 0xcd50fdff, 0xfd26a22b, -0xc5be2281, 0x998e58d4, 0x179dbb49, 0x2d6b85c3, -0xa7c9c271, 0x865499d5, 0x69fe40b2, 0xe83a9703, -0x99298f1e, 0x4f52cca5, 0x26220fc3, 0x67bcd523, -0xd3077015, 0xaf86439f, 0x78bba2a0, 0x7e1cc676, -0x713fec96, 0xc8869986, 0xf15f758b, 0x2b2b58e1, -0x5b033918, 0x79713b3e, 0x4a08b144, 0x6b10e909, -0x22401dc7, 0x23087386, 0xc3359150, 0x0a6cde95, -0x91bd0c91, 0x99281e5a, 0x7bef0550, 0xc8f9e407, -0xbb6b33d7, 0x6cd518f0, 0x6ef572b9, 0x5a0fbd51, -0x7425def6, 0x0e50b4e7, 0x3623bb19, 0xfef635a6, -0x7539c632, 0xc86d176c, 0x80c7b5c5, 0xf5a0b5cd, -0x879cd278, 0xe26e9de4, 0xa1c6a90f, 0x65b30004, -0x678c63bc, 0xaab85112, 0x2a9851b3, 0xce3cbdf6, -0xa30dc116, 0x24bf66f0, 0xcd5d3611, 0x69cfebd6, -0x0bf03477, 0xa524f5aa, 0x474e152b, 0x93f5470c, -0xaf8332af, 0xa7162064, 0x8a1ef4a1, 0xf6c7da39, -0xae7e26c2, 0xb60fc22a, 0x099215de, 0x6431836f, -0xbced163e, 0x0957b3e0, 0xeaff67c5, 0x1d15d645, -0x531fe014, 0x47e298e3, 0x4d0a7808, 0xcb9e8bf3, -0xb0abe54f, 0x1a96651c, 0xd7b0df79, 0x79af1c18, -0x41aa459a, 0x70628bc8, 0xb200c92b, 0x0ffd7c37, -0xc16fa374, 0xdc479e08, 0x1181eacd, 0xdf795d60, -0x78834704, 0xd55485da, 0xdfd68db3, 0xadcb7932, -0x321eaf32, 0xf5447236, 0x498a525c, 0xc4e3e529, -0xe3218446, 0x27187ac8, 0xf31ef297, 0x2d2fdd03, -0x8286cc34, 0x3ec06e63, 0xe7ad6bcd, 0x1f64f92e, -0x280b07f2, 0x8794d8a0, 0x6f8ad638, 0x7910e4ee, -0x278340f6, 0xe55b228b, 0xb8dfab78, 0xdb28214b, -0x12f22905, 0xb8fcb70c, 0xce0065a4, 0x0e0c733b, -0xfcc20c16, 0xf2be1d02, 0x336a9467, 0xa07f5612, -0x43b9ca1d, 0x7c6fcdac, 0x810e98b4, 0x5ca423a0, -0x140596f6, 0xb711c0a6, 0x17b47ee7, 0x0b93143c, -0xd04b336a, 0x8b84be4c, 0xa3e77a17, 0xb0181d8e, -0x96d865c6, 0x41ea13b4, 0xe784b15c, 0xf807b39a, -0xd591fb1a, 0x4700dd5c, 0xbbc1e580, 0x43ac39e8, -0xadb3d257, 0x3157de34, 0xde366d0e, 0x9ad4248f, -0x95986f90, 0x9c6515e6, 0x854cb90b, 0xaa416bcf, -0x988d01aa, 0x08619fdb, 0xc428f67c, 0x440a6559, -0x3483d569, 0xbd561d15, 0x0bdac2e4, 0x110e1a21, -0x62bd921f, 0x7cc406e0, 0x038353b8, 0x50c165fa, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 400-MU166a0c.inc */ -0x00000001, 0x0000000c, 0x05051999, 0x0000066a, -0x1d9d265a, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x7ee84cf6, 0xdef59a0b, 0x2c39a0ba, 0xa83caa36, -0xc9b1f450, 0x388df7ac, 0xd69f91c3, 0xf7861ebf, -0x0184e389, 0xf6a6a084, 0xf4f6e81d, 0x079188a1, -0xf8d333e7, 0xd1f2d4b1, 0x5ba1ec8d, 0xecb245c8, -0x846469bc, 0x6c891841, 0xc8afb827, 0xadcd33d1, -0x4275c0fd, 0xffa3860b, 0x9c0cbbc3, 0x7fdc4c98, -0xc538b727, 0xba0f7d64, 0x48f8d69d, 0xe5da2ada, -0x88b8af10, 0x6af3e9c7, 0xe50d84f0, 0xb8058b2a, -0x2fd44bdd, 0xd92a9b06, 0xfecd2cde, 0x2400081e, -0x943b6d3f, 0xbc60f43c, 0x0faea953, 0xdbe48e6a, -0xd5817cff, 0x00da0bae, 0xd96d0612, 0xd5431cbb, -0x4547dcb2, 0xdc693998, 0x9ddb4562, 0x6b553f57, -0xd399b87c, 0xb8d58069, 0x69e549ab, 0xd01cc4e0, -0xf2fa23cd, 0x60944ee4, 0x9f86103a, 0xd7f0bdd6, -0x6a737f51, 0xbebd48fd, 0xd2d170e5, 0x651a6175, -0xf3bc9031, 0xd111c145, 0x2b571986, 0xd3595d17, -0xdc7ac14c, 0x0e3227b2, 0xdb4c417e, 0xd514c15c, -0x4f6dc212, 0xd639cda4, 0x9d4f9cd7, 0x69396105, -0xdfb2ece3, 0xbad52f1d, 0x6c5bfd60, 0xd87ed851, -0xfab9bdc2, 0x6d12697a, 0x9f0ee2c0, 0xda658c6a, -0x635cbebb, 0xbdcbd5c9, 0xd1bc6b04, 0x6c415204, -0xf0d34549, 0xddca0b2e, 0x2d43a106, 0xdcc99c8e, -0xdfdab7bc, 0x0b4a54a9, 0xd93a19b4, 0xd526d677, -0x41446f81, 0xd94b20c0, 0x9d895736, 0x62f70de9, -0xd200abad, 0xbd42c587, 0x6fad3a66, 0xd304e4a3, -0xf13ede57, 0x6a939756, 0x990b77ea, 0xd54494df, -0x6dd8f816, 0xb9271c02, 0xd7238862, 0x6c0119a4, -0xfeb583e0, 0xdef9450e, 0x23b2d340, 0xd4df2c30, -0xd1075deb, 0x0a9ddb8c, 0xd6f4c463, 0xdb5e2fe2, -0x45071dcb, 0xd814e4d9, 0x96a13be8, 0x666f23ee, -0xde297b1b, 0xb8956c64, 0x6bf48b36, 0xdfa05659, -0xfbdcec61, 0x6cb0be5b, 0x9e78bce3, 0xde94cb88, -0x6315b350, 0xb98e69cb, 0xdb532347, 0x694227ee, -0xf4f14336, 0xd1a59a01, 0x28c408bb, 0xd1f9a64a, -0xd5c00563, 0x04930cd2, 0xd0f5ccec, 0xdd4320da, -0x485b7656, 0xddd958a6, 0x9fe639c0, 0x6fe20678, -0xdcdcfdbf, 0xb09b15d9, 0x6df8c827, 0xd6b0ccde, -0xf9c3d0f6, 0x6496b15c, 0x9a91694a, 0xda644682, -0x6c1293df, 0xb2df9b38, 0xddb61da1, 0x6968a238, -0xfc6bbbb5, 0xdf19c18a, 0x2a56c306, 0xd67e52de, -0xd2290d0a, 0x04a145ad, 0xd49153e1, 0xde5b167b, -0x4848312d, 0xdddec3a8, 0x90a1f1b8, 0x6b8f4446, -0xda37eea7, 0xbbcf471c, 0x993f1cc0, 0x3f91a8af, -0xd61f988a, 0x47b6419b, 0x95657dde, 0xb2ffa26c, -0x44930f12, 0xf34ed623, 0xbc7f7fc3, 0x118b4f74, -0xf12d0c9e, 0xe81231e9, 0x1110db16, 0x1d41dffb, -0xe06619ee, 0xf32a7d08, 0x357fa00d, 0xd2e3c5eb, -0xdc38223b, 0x062d166c, 0xd182874c, 0x3b1d6a6a, -0x0142363d, 0x347bf43f, 0x3e818e62, 0xe5fff804, -0x305f3377, 0x2cdca236, 0xe1afc577, 0xeae0c285, -0x269653e8, 0xc40756ba, 0xe0d8b540, 0xc44824ab, -0xca5d4d9b, 0x0a51f0bf, 0xc8593df7, 0x3040056b, -0x09282276, 0xc2ba9356, 0x383d94a3, 0xf61535ef, -0xc65ab8bc, 0x3ee5709a, 0xcbfd2b50, 0xfe5787a1, -0x09dd6022, 0xf7ec8ee2, 0xe2b1e3b8, 0x580ec41a, -0xeaa5a2da, 0xbd800565, 0x7946c0b2, 0x76b9828b, -0x9bb28f85, 0xe3932a08, 0x7960d4db, 0xf3001b13, -0xec1e8232, 0x1f4d97dd, 0x2856139b, 0xc11609a4, -0xc69b6b22, 0x02829529, 0x0224403c, 0xcb7ee7b0, -0xe093e6a8, 0xa6841fee, 0x60c5b601, 0x2b99dd31, -0xae77ce16, 0xf6b997f0, 0x3eae0d83, 0x1299fe49, -0xef836ea8, 0xfc5fd4ea, 0x404801c9, 0x1588ce31, -0xf3136926, 0x5b2db34f, 0x2fddf729, 0x3aedff67, -0xc1198e78, 0xdd360cae, 0x81cc641e, 0xbd23f38e, -0x9521c3a9, 0xe5dd3bbc, 0x7f89f543, 0xad637f67, -0xb94d65df, 0x44ea2049, 0xd2a5314f, 0xf6b52ed0, -0xc1582e64, 0x696fa343, 0x6fc79d19, 0xc10008ce, -0x259496a3, 0xf4e1babc, 0xe1ab5f9c, 0x33ffd383, -0x3decbc22, 0xae09ede6, 0xf42b65f2, 0x9a49d828, -0x9ce3c48d, 0xd4055914, 0xbf360754, 0xe44b2727, -0xca93c1aa, 0xd14f31b5, 0x11d02919, 0x8b485bfc, -0x5fb21565, 0x4eb9ca57, 0x3d17e2bb, 0xd45be14a, -0x808855c4, 0xa66c16ae, 0x3f46a1d2, 0x737db4d1, -0xb7f5b0f2, 0xb6e5af8a, 0x4ea7ce1b, 0x8e79ab73, -0x3279d139, 0x160056e1, 0xc4a5ed68, 0x1ff6352d, -0x592640ff, 0xa3edfbbc, 0x68be47b8, 0xba69a126, -0xcca14ed1, 0x7e343e52, 0x1b860b23, 0xab2fe19c, -0xc0357151, 0x52b873f0, 0xe1adefe0, 0x7d73cfef, -0xb4b82b50, 0x12b02b0b, 0x4efc5c49, 0xdd37f0a2, -0x939b6fb3, 0x05ac2f31, 0x514e08d9, 0xda59b756, -0x29ee8585, 0x3c960d13, 0x5b9c2425, 0x8b904acc, -0x03506beb, 0x64ae1683, 0xf0f5f6e6, 0x1166c8e3, -0xa4fdbe30, 0xfa8de670, 0x8f8007f8, 0xf93f0a9d, -0x28c817bf, 0xdd2564ee, 0xfb77c058, 0x005ae81f, -0x3819f821, 0x40be4b2f, 0xea398f14, 0x36cbfca1, -0x66f826fb, 0x01f82781, 0x0d2e8d71, 0x827fea8d, -0xeefb9818, 0x58cbe155, 0x7cdfa2bd, 0x823c1f5c, -0xca57cf62, 0xeb8bbd3a, 0x83ee2876, 0xd09e17b6, -0x2ed8c4e2, 0x41dde0e9, 0xca0c0e36, 0xa716235a, -0x68dc48c2, 0x97c65728, 0xdf0b7db6, 0xe0f5a926, -0x1662e74a, 0x109a93f3, 0x25d1fecd, 0x5e5feb1f, -0xc1fb4ce1, 0x4a0c7854, 0x1f5e1b77, 0xc74f4a67, -0xddd32a11, 0x4f23d67f, 0x15c683c9, 0xae9e0b36, -0x1eae9783, 0xeb4575c0, 0x273ab1fe, 0x14f498f9, -0x36e1fa03, 0x5d26968e, 0xb1000e70, 0x4bd84a27, -0xf1656674, 0x69d7f679, 0x1a769399, 0x38a6a468, -0xacc185e5, 0xcfc3542f, 0x0016f20d, 0xf791207a, -0x3619f97d, 0x19aa7383, 0xbe6a3488, 0xdeab6e3c, -0x042a3e83, 0xd1a1a166, 0x5d1be3e5, 0xe0d338b5, -0xd2421262, 0x1420b7eb, 0xd9e9ab1a, 0x50cc69fe, -0x9b5056a2, 0x82e9a23d, 0xd3ab7b3e, 0x0424ef61, -0xf4d374ee, 0x982060b4, 0x954e2f92, 0xd64bfd36, -0xc9e9430d, 0x593e8cbc, 0x80d7b169, 0x8b87d305, -0x764466e8, 0x6a125ce8, 0xda699c3a, 0x13f3ff6b, -0x412e3a89, 0x7fc628e8, 0xf33761a4, 0x2e84242b, -0x388a3019, 0x33da6d91, 0xb493ed5a, 0x6c063a26, -0x6bd1b5e1, 0x372850cf, 0x8ae1c93d, 0x9220555a, -0x87199a47, 0xe4dfa5b2, 0xb0a1c13c, 0x5e4be8ed, -0xce0befd8, 0x358a7073, 0xd96a0778, 0xa8e18b1b, -0x76ec713c, 0x1208ea58, 0x3cebd827, 0xe8093948, -0x6592653c, 0x069405db, 0x01ea9da1, 0x12ce1bf5, -0x467402bf, 0x55ba728a, 0x0946945f, 0xe405cac2, -0x099a54d1, 0x6b662117, 0x18f3eeff, 0x7d6c106e, -0xbda99e98, 0xafda474e, 0x67067a30, 0x6a882ede, -0xcadb3f5f, 0xbaabe426, 0x849fc0d7, 0x03c0a313, -0x8e02168e, 0xe5cfc3ac, 0xa901afe4, 0x3152692b, -0x538a67b0, 0x408a0315, 0x5c83ba73, 0x8e51c069, -0xb2743e6c, 0xe27e14b0, 0x83917dbf, 0xebad6f2a, -0x475c528d, 0x9ea643ec, 0xc9b3e51c, 0x332886f7, -0xcf756bf6, 0x1650b95d, 0x6c89ce09, 0xaa5fa869, -0xa38a46b8, 0x2c23feb3, 0x66ca2c19, 0x95c7c745, -0x92fbf6f8, 0xd72602be, 0xfb41ad08, 0x3bae6e6b, -0x1ec6cd00, 0x55ae9d6e, 0x9fd7dcb2, 0x473683dc, -0x147cb939, 0xc06b93d8, 0x488bc90d, 0x8b5d8cbb, -0x894a3028, 0xfd651c2c, 0x1276262f, 0x25fa7147, -/* 1346-m10f252c.inc */ -0x00000001, 0x0000002c, 0x08262004, 0x00000f25, -0x62d062ab, 0x00000001, 0x00000010, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x017464fa, 0xd2fb3494, 0xaf1850af, 0x5af88989, -0xd3a0a9dd, 0x8e8bd3ad, 0x8c288786, 0xf15f02b0, -0x3f3c1471, 0x6c675202, 0x5094fdb0, 0xa618dc47, -0x7596d14e, 0x6ba07896, 0x2e4a12e7, 0x611c39f1, -0xf6a43a1c, 0x24fa23e1, 0x01bd8d37, 0x5a21bc1c, -0x60df739b, 0x40165459, 0x87c581fa, 0x2e850b8a, -0xcfcb5329, 0xee4152a6, 0x404753ca, 0x64ac8738, -0x2b8cd6bf, 0xbc5f4abd, 0xa8bb7b21, 0xf08d2f32, -0x1c8094c5, 0x67ceb543, 0x0cd8f368, 0x8658f400, -0x9174a58e, 0xccabf1d6, 0x899bf22e, 0x40d6d951, -0x4838f728, 0xa1ed41e5, 0x3483bccb, 0xc1c0815b, -0x1785082b, 0x255c0d8e, 0x91d5b4b4, 0xb1f4c7e9, -0x2bf5ac1c, 0x368af115, 0x66ae0e90, 0x2b95e4fa, -0xa9bf4b21, 0x9ae73e25, 0x86cecece, 0x534a6d72, -0x8200bc65, 0x83255506, 0xf4e35c0b, 0x9dc95dd7, -0x4464f3b9, 0x9112fc9f, 0xd62cfc95, 0xee0caf4a, -0x7963ed30, 0x90d3ad97, 0xee95be29, 0xbf49ec04, -0xf3287f06, 0x07d1e162, 0xd3e0755d, 0x929ea9cc, -0x0094df0b, 0x52064130, 0xce7f504d, 0x35f46c20, -0xb8fbeb98, 0x6b6362c5, 0xa03f5918, 0x5c427277, -0x55a52e2a, 0xd43118bb, 0xb5bd2642, 0x3cbdebe2, -0x2f8bd345, 0x1d7544fc, 0x4e08c4b4, 0x806aaa70, -0x99128239, 0x9e150e46, 0x8a542475, 0xec5b5756, -0x585c2a66, 0x73d03366, 0x3aaf1ab3, 0x35ae9846, -0xd8c688a4, 0xd1a11333, 0x0de4e99b, 0x3b641c51, -0x6a4e6159, 0xf84cef5a, 0xe56ab89f, 0xcd410bf9, -0xc90b1c48, 0x0b032ac1, 0x33dec98d, 0xd06c42be, -0x32028313, 0x5d819bf6, 0x04f60234, 0x21e4c303, -0x1d2ad9c2, 0x7bff3ccc, 0xd89dba83, 0x5798962e, -0xe3aba833, 0x333b4f64, 0xa7869e81, 0x68c4b245, -0x06c21e1a, 0xa1b8bdef, 0x5af37ec7, 0x289bfece, -0xd6cd123b, 0x9e0bcab3, 0x4c342945, 0xa9d7e1f0, -0x4a2498b0, 0x3bc93371, 0xda7d7384, 0x91fa2049, -0x6e1202af, 0x5cf95edc, 0x8efa1130, 0x2e7c51c1, -0x467e44b9, 0x6259f80e, 0x3ec0ae38, 0x515e28b5, -0xa5f3fdad, 0x26990f39, 0x132c1b43, 0x72b429ba, -0x74d71719, 0xaee958b6, 0xd22e6611, 0x2eb5b552, -0xe6812bb7, 0x99c839a3, 0x20e2b7d2, 0xb19cfdec, -0x947876b4, 0x2734f7d8, 0xe26b52b6, 0x8eff31db, -0x90a4081e, 0x76d3cabf, 0x712afede, 0x24fb06a5, -0xb6e19dac, 0x52d3d9a1, 0x916b0c9b, 0x76584397, -0x23d1fe57, 0x2e7badc9, 0x793b93af, 0x4bfafe0a, -0x2693b773, 0xc35d8ced, 0xbea30ce9, 0x22f8d19a, -0x389dae00, 0xeb826f93, 0x05f18a18, 0xd6fb6d38, -0x821bd354, 0x268226ce, 0x2191a9e8, 0xff137868, -0xbbb40031, 0xcac56b21, 0x64cf06f6, 0x30587346, -0x4b289baf, 0xf699e7bb, 0xc29e78ef, 0xc3b60ce5, -0xf82e2e0e, 0x34dee08c, 0x3c3a6eb6, 0xf7513f73, -0xfe4e1a98, 0x07ec1fbe, 0x12b6246d, 0x219c212f, -0x73ffba20, 0x369b69cb, 0x2671b878, 0x0d7b2c84, -0x032e56e7, 0x3d937bdd, 0xcc823a33, 0x287122cd, -0x6c488555, 0xa2e9aa31, 0xfd2dd62c, 0x2c1fe41e, -0xdced02c9, 0x895f72d8, 0xcc184fc1, 0xba0ffb0f, -0xee6589e7, 0x380773ef, 0x793bba57, 0x9314f3ad, -0x4d79bce2, 0x116f016d, 0x7db8b6cb, 0x2ed52750, -0x485ab29f, 0x23ae6001, 0x32854b85, 0x17ddafa2, -0x098d4caf, 0x3d404c83, 0xbcb8331e, 0x3bcfa653, -0x56382235, 0xc0a0c48b, 0x6f9d9f13, 0x300d782a, -0x7cf71f46, 0xe6e4b87b, 0x0791bb50, 0xdb2c4160, -0x6be9a315, 0x2165554b, 0xc3260d6a, 0xedfb0449, -0xbaed3058, 0x0f98dc31, 0x390814ef, 0x23a3e34d, -0x27d3c3a4, 0x2c19950b, 0x402871f0, 0x184dcea7, -0xde0edc2e, 0x2f98f6e9, 0xb447540f, 0x3c9a5cb3, -0x60c8a7cc, 0xe641f9f2, 0x3c56383a, 0x32cd115d, -0x92777bf0, 0xd89236b6, 0x3d25460a, 0xf893e2ad, -0xdcd5b651, 0x262c47ec, 0x872573d0, 0xc12dc29c, -0x409a6a3a, 0x9bf80c1c, 0xa735cc4e, 0x2587cc61, -0x7d6e93e4, 0xa0ea6f41, 0xd4ad42ae, 0x8daecee5, -0xc31e66a8, 0x2378d207, 0xabdddd7f, 0xbe11bb1c, -0xf38edca1, 0x513bf227, 0x5bef4b3e, 0x204feef8, -0x7bbf43ac, 0x7768b9da, 0x9b0bed2b, 0x56202483, -0x4695c0e6, 0x23d8d840, 0x82ecd4ce, 0x79748b5e, -0xcca7c892, 0x8c63470a, 0x2d7518c4, 0x2fac1b7a, -0x104c938f, 0xbf29d2f3, 0x1dffe8e0, 0x8d7ad738, -0xc83a0640, 0x2199cec4, 0x7bc07063, 0xa70c2537, -0x9e861394, 0x075d4c73, 0xa569faf6, 0x396bae73, -0x334b3c91, 0x20b95fab, 0x769b98f6, 0x0a8f4cda, -0xff9752b0, 0x309b6f0a, 0xc3071844, 0x3104c8ad, -0xbaff693c, 0xebf312eb, 0x9e25d11b, 0x25576b18, -0x4e70d78a, 0xc72dbd56, 0xec181ed8, 0xe9b6167c, -0xe099c2f2, 0x27d3aa35, 0x6ddd258e, 0xcc131a0c, -0x065dd636, 0x3cc4ff57, 0x77a63f63, 0x237c4bbf, -0x3889c6a1, 0x176b30e9, 0xfa111c8d, 0x281d9f44, -0xbd74ed05, 0x3ed21e58, 0x0490fdad, 0x15c697b4, -0xa3719ed3, 0xad0bb013, 0x66b68aa8, 0x282fe7ac, -0xfa118f06, 0x8f2a8338, 0x5c1253cc, 0xb7afeae2, -0x630a9b9b, 0x3cae83fb, 0x216b5789, 0x9cb4b049, -0xe9dcccb5, 0x2696572a, 0xe22011a5, 0x23b34429, -0xf9636a42, 0x1051094a, 0xdf3f18ad, 0x26510efc, -0xe378d21e, 0x38a6bf26, 0xace969cd, 0x1ca41996, -0xcb528e18, 0x87c088e2, 0xfd71cd99, 0x39e736e2, -0x9c64bc32, 0xbd8cecd2, 0x47a0629a, 0x85b3df38, -0xc9d64ce6, 0x32bebbe9, 0x42cb74dd, 0xab5d1e1c, -0xe55e7ac2, 0x55f8be13, 0xf430b24e, 0x2f17258b, -0xda10ca8f, 0x6eac45dc, 0xa07672a7, 0x506f676c, -0x1e8b526e, 0x33eb74e6, 0x7742492d, 0x61414e22, -0xc31291a5, 0x5b2b4e8b, 0xa315ffe6, 0x989185aa, -0x8bdf0a79, 0xc9c06f2c, 0x2f00faf8, 0xde4ef0f5, -0xa145c5a8, 0x92dd3dee, 0x727c9f7a, 0x250ed270, -0xcb1c44c2, 0xe1113cb5, 0x5bf4dbbe, 0xf4709150, -0xc21c5014, 0xf930bb0c, 0xbe4f9bd9, 0xa5862c75, -0x2230e5c9, 0x74149598, 0xe987643d, 0xa3412042, -0xbd3eb677, 0x80a41b9a, 0xaa2dc674, 0xd192a178, -0x8988967c, 0x8962ca42, 0x451c005e, 0xecde7737, -0x87f85870, 0xe98908b8, 0x265c73c7, 0xec182f7f, -0x05b3d87c, 0x1afff376, 0xf4c81a3c, 0x80f00263, -0xee63669e, 0x1d74f997, 0x183e2b6f, 0x0629519f, -0x6b27783d, 0x9916c2f5, 0xfecbc9d5, 0x7eb50141, -0xad0037e0, 0xf20f60c4, 0x374a7054, 0xf0848252, -0x19f82e03, 0x69c1f70c, 0x70961335, 0x9deb2ccf, -0xc453c78d, 0x0871df23, 0x7f83c98b, 0x407fbe9c, -0x10121b4f, 0x9044f904, 0x4ed3f7de, 0xb028f42b, -0x246f17de, 0xb855abb0, 0x071a51d8, 0xd549aad9, -0x735a39b1, 0xad2f4ab1, 0xdf90c6c4, 0xdd2761c2, -0x62036cae, 0x3c29d30e, 0x4f7f5f84, 0xab87914f, -0xc33f0b67, 0xde569d58, 0xb1e60d71, 0x8a817393, -0x906e903c, 0x4e972481, 0x4fe3e46c, 0xd48eb883, -0x6570d66c, 0x8e957776, 0x00534cbc, 0xe715ffed, -0x2678ac5d, 0xcacc7b06, 0xd4fe6915, 0x8d09aa7b, -0x5cfa9f8e, 0xfe2dced0, 0x7b64fbc0, 0x73940aec, -0xae88acb2, 0x800c6287, 0x7639d6f3, 0x28ac2dba, -0x162200b6, 0x7dcea0ee, 0xb63f1118, 0xeeb52b03, -0xd7996177, 0x32e8dc08, 0x52529d26, 0xd3773575, -0x0e8ffee2, 0xf7ee274d, 0xb6932b3f, 0x3a9aa201, -0x68c94a3c, 0xc9efee21, 0x4d432eb7, 0xe3f5a59f, -/* 965-m01f0a13.inc */ -0x00000001, 0x00000013, 0x07162002, 0x00000f0a, -0x2a2cc3cb, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x80e0e61a, 0x7cb2c607, 0xbe1e2fc9, -0xacaf1526, 0x31514e28, 0x9252d426, 0xb999ebf8, -0x8469bb8a, 0x95e72fd2, 0x5f7c5472, 0x254adcf0, -0xf706b236, 0x21ef3efb, 0x82d05526, 0x8b10bd77, -0x268ab8bd, 0x929739a5, 0x0f180e02, 0x3ad1cc5a, -0x23a10814, 0xbc4257f8, 0x026ded8d, 0x84bf45be, -0xe13e69f3, 0xbb0edf16, 0x85218fd2, 0x898af4e1, -0xcd635f26, 0x846ab0c6, 0x85a5d5cd, 0x077b4a16, -0x71514de0, 0xbff893a6, 0x47536ab0, 0x1fc4b546, -0x906f4b85, 0xc1f997d5, 0x0ba4b594, 0xa823eb50, -0x416ee239, 0x659b0dbd, 0xf240ad67, 0xe042d532, -0xce92f455, 0x9f318d9f, 0xac11fada, 0x6fc234ab, -0x18cddb76, 0x67e52b4f, 0xa6f01943, 0xba695e2a, -0x245bd123, 0xce05288f, 0x6582101b, 0x5be73a23, -0x6ab67d0e, 0x873ac6f3, 0xab4c48f2, 0xe0d64284, -0x65f33ddb, 0xd33abb56, 0x8dd411c3, 0x86f370ea, -0x1c3726b9, 0xd561edb5, 0xa0484b79, 0x63bdccd0, -0x54d42183, 0x05d9b9c2, 0xd1d2e489, 0x572f0b07, -0x6b804808, 0x9ee441c8, 0x87e1e425, 0x0d4d3c3e, -0xbb9188fd, 0xa7f1243b, 0x807be6fb, 0x8f828057, -0xfe37dd84, 0x104ef504, 0x5aa650b4, 0x2f1b611f, -0xd021e808, 0x1d4ca877, 0xdefabd4d, 0xaa0cbe35, -0xa4e89854, 0xa880cfc1, 0x08ed71f1, 0xb58e8625, -0x2f4bee9d, 0xfef8678d, 0x2868ade1, 0xcdd1c7a4, -0x2b823a15, 0x4788ea69, 0x7a1de61f, 0x24a51210, -0x4373e00c, 0x7f8e55c9, 0xb2c5092b, 0x74f9e0db, -0x2f54f62d, 0x13e3b1c8, 0x835863dc, 0x7401feb0, -0x82d9962c, 0xc321a358, 0x8db3eec1, 0x3d70aa8a, -0x9e8d115a, 0xd1f258ce, 0x3db0262c, 0xdedf4ecf, -0x2b43787d, 0x01bba4ab, 0x5533bfb0, 0xf25756a2, -0x6748ff85, 0x49a04cf9, 0x15a3fceb, 0x2b0045b1, -0x354d82dd, 0x51baaaae, 0x9cdb8826, 0x4a5e79d5, -0xc0b783a0, 0x244ee819, 0xc9d7ec82, 0x61b5df6b, -0xa3b0ab47, 0xf4201580, 0x16a9bda3, 0x2ac3fb2a, -0xf2d45287, 0xc775c470, 0xca49165e, 0xf011aa96, -0x7cc3f776, 0x128e7d4c, 0x53a7cb48, 0xc678c16a, -0x704d85ff, 0x5ac3438c, 0x22a4255f, 0x06f4eb73, -0x6d2c4918, 0x7ec8d353, 0x02f64898, 0x402caba1, -0xa2dcd74c, 0x2ec84768, 0x19aaacb3, 0x641e9f60, -0x610245fb, 0xbcde5b34, 0x5b2ad9e6, 0x26d2e619, -0x3c5f7fc3, 0x8a4644e1, 0x6cc1f8fb, 0xb2ec0e52, -0x02186480, 0x1c597a86, 0xea7cb92f, 0x8484972d, -0x90f10aef, 0x7032ba2f, 0x8d51693a, 0x075f7010, -0xef88324e, 0x5fbf378f, 0x1416ae8a, 0x5eac1f31, -0x70e65677, 0x0224e031, 0x1305f1ac, 0x53209b14, -0xb5037676, 0x99e958fb, 0xecb8fe97, 0x20fb5890, -0x568e98e9, 0x87d42ce4, 0x03de50e2, 0x89728dac, -0xdca95447, 0x36114e7b, 0x2aab8e7a, 0xa0529d9c, -0x9901c79d, 0x4ff191b5, 0x7500cebf, 0x210bcc07, -0x815fd1e8, 0x4ebd3be0, 0xbce22cf0, 0xcf2df323, -0xfffa8eb1, 0x016b1ca2, 0xf87846a6, 0xddbf1474, -0x435c41b5, 0x56245808, 0x050eace9, 0x128491f7, -0x48c6fdda, 0x5775ded7, 0x0b4775a1, 0x7ce11409, -0x0d9822a0, 0x084ca742, 0x8f2c8c8b, 0x4278fdfc, -0xe45d26c7, 0xd92793fb, 0xe963acf5, 0x346473ea, -0x28069586, 0xcd7423ab, 0xdd07fab1, 0xf2dd3f15, -0xf924720b, 0x0047adff, 0x3935bd42, 0xde1d799f, -0x03a4afd9, 0x4f0ea217, 0x5f3dd4df, 0x09f611a1, -0x8ecf894c, 0x5111dde5, 0xd79db940, 0x4e2da85d, -0x64622e3d, 0x00ed0f85, 0x192b2af6, 0x526fcc87, -0x3e233c92, 0xdfa9d04d, 0x5a8a7d19, 0x18205eef, -0x3ff5734e, 0xf3ba744e, 0xac73c051, 0xc2cf8a70, -0x3ba41433, 0x123eb210, 0xe3f05134, 0xcfd54fd8, -0x7995e0d1, 0x1760b323, 0x310a7810, 0x2706d0c8, -0x15cf732d, 0x3c0ee597, 0x83e36338, 0x272058a7, -0xff3e9fda, 0x0c22fe44, 0x11a26627, 0x061a17a0, -0xd784b930, 0xb40ed3ca, 0x014eaa98, 0x2cfd7ef7, -0xd3f700a6, 0xa2e0e5ad, 0xf6682e43, 0xbab69f7a, -0x185c3430, 0x10a4a66d, 0x41698b7a, 0x89666812, -0x1cdc431a, 0x301a8774, 0x056fa032, 0x08e5b4ac, -0xd8e66808, 0x06cb04c2, 0x086f09ef, 0x09404e44, -0x4b166a00, 0x1f244ff1, 0x096548b7, 0x3d066268, -0x11c22583, 0x87d98b53, 0x83c785d8, 0x0c295204, -0xa3693e8d, 0x8ca5c952, 0xa52c8190, 0xa9ac34de, -0xe640e56f, 0x16d5715c, 0xf40bac7c, 0x940d757e, -0x0955d322, 0xbd3e2f65, 0x6553293f, 0x0b25fcb7, -0x14875a5e, 0xb5efd0af, 0x79cf151f, 0xa74e5acb, -0x4b249263, 0x14a844ff, 0x4c547880, 0xb598f6b8, -0xe9fffbc6, 0xe983f09b, 0xa5384013, 0x36baf1e7, -0xe3a76c06, 0xde3df31a, 0x25d38aaa, 0xc19d9fa9, -0x2c05457a, 0x0a4fd8f6, 0x01086f65, 0xdf7e10b3, -0xa5f16786, 0x46d77f4a, 0x08336cd2, 0x1d06cb5f, -0xe453696c, 0x6f662a90, 0x40d33558, 0x76c640d5, -0x4e7e4c97, 0x10cb0f79, 0xb1cfbb1c, 0x4f3f0521, -0x8cda32ee, 0x84c3e958, 0xaac41cc9, 0x023e7572, -0xf3266bf6, 0xb4193d39, 0x3a31f7df, 0xbd83c248, -0xc812df3c, 0x0af7f510, 0x82bb61f9, 0x95db6415, -0xf7b12fa8, 0x7a7f4f9c, 0x2ec8f061, 0x3fa8e99c, -0xc19bea78, 0x470c4315, 0x0bcf3abe, 0x787b97b7, -0x78f992b4, 0x05a7b74c, 0x93fc4db2, 0x41094fe3, -0x3e7fe41b, 0xa367bc2d, 0x90b393db, 0x3ec58fe0, -0xb74cc79f, 0x9ed83f74, 0x10daeeae, 0xa524f1ac, -0xafcd0f29, 0x11423945, 0x52319e75, 0x9978031d, -0xa78bb8be, 0x1a8a86d8, 0xf9a5c6db, 0x15d9760b, -0x00028056, 0x2d0f7fc3, 0x7734d88a, 0x1b877e63, -0x7b1db862, 0x25037d9d, 0x5a210d59, 0x1875f3e4, -0x0299248c, 0x90ae4f18, 0x949d7d41, 0x713deba7, -0xa6ff8ffe, 0x243c5296, 0x6020828d, 0xe420ae82, -0xf02eeda6, 0x3a8090e3, 0xaef23b89, 0x40d2cb8a, -0xaaddddad, 0x220c269f, 0x288d2d4e, 0x8689e116, -0x42de5c86, 0x95ff5e35, 0xdcaabe42, 0x3fbb05e5, -0x4ade7e4b, 0xd6612d65, 0x44ad598c, 0x984eeabb, -0x218696b2, 0xf9c83206, 0x881e3b4e, 0x54844f30, -0x1f980f2a, 0x0aec3158, 0xdd92450c, 0xb8a3906d, -0x0ccc7c23, 0x196b48db, 0x08ffaef9, 0x2c44b86d, -0x05fcc149, 0x079869d4, 0x5f3f5d0b, 0x1086de9f, -0x638432c5, 0x1dbe89c0, 0x882041a8, 0x05a6756a, -0x306e76ea, 0x49ad9a0d, 0xbc24d1af, 0x2a113e7d, -0x8a333131, 0x775f70a6, 0x49629224, 0x8e089d24, -0x34e60e07, 0x280eb8c9, 0xcbf3805c, 0x528c0bdf, -0x46c79b94, 0x543c88dd, 0x2b2e55b0, 0x252bf38c, -0x0757335c, 0x56405b4d, 0x7f0894ef, 0xa2417da9, -0xf4f8c5d2, 0x2be63c2f, 0xcfb400fd, 0x4b9f4e99, -0xbed450c7, 0xbc3cdea6, 0x216f9223, 0x3d2920ad, -0x97284d1d, 0xb5b05c58, 0xa5075b63, 0x8ec8c059, -0xf9c2f270, 0x0f79cbf3, 0x71253a77, 0x66896241, -0x5cb14622, 0x8d439f45, 0x21d61b98, 0xddb46338, -0x1b2fb78d, 0x78389389, 0xe3e92811, 0xd7b0a62b, -0xeec11a6f, 0xf98e84dc, 0xe26a6dde, 0x7767cc48, -0x04f5492f, 0xcfb9fbbf, 0x4bc7fb18, 0x86e5876a, -0x6cec34b8, 0x44f1e0ac, 0xf60995fc, 0xd56fc8c1, -0x3843fa32, 0xbbb021d6, 0x8269ba6e, 0xfc91d4da, -0x092f051d, 0xcf0ecdc1, 0xec5f10a8, 0x16575ab3, -0x3b956ded, 0xeccdcf22, 0xb68dbf1d, 0x42bf3c8c, -0x0bbc80c3, 0x13b6dec2, 0xcc51edc6, 0x6b44ec54, -/* 617-MU16860c.inc */ -0x00000001, 0x0000000c, 0x05042000, 0x00000686, -0xb8f53b16, 0x00000001, 0x00000080, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x5beabe32, 0x8f316d6f, 0xe80fa8ed, 0x6986fc34, -0xa9af091c, 0xedef5922, 0x4d59bcce, 0x8528ec94, -0xea891582, 0x6d651dcf, 0x8ea713bb, 0xee588508, -0x40950b27, 0x839e687c, 0xc0950463, 0x6bb3f40b, -0x8a0f86c0, 0xe3763843, 0x69dd3be1, 0x814c91b7, -0xc5d81f77, 0x6e9b0217, 0xa4ba0a27, 0xe2b72aaa, -0x6497f53e, 0x82872e97, 0xeffa4a21, 0x6e462da7, -0xab2b6778, 0xe176f65b, 0x417dd377, 0x89bdcc75, -0xe1003982, 0x60569826, 0x89ac3387, 0xe6285345, -0x4782de3b, 0x826080d7, 0xc69b35f1, 0x6b185a03, -0x837baa3f, 0xe552ede6, 0x6f2fbc28, 0x87ce0f4e, -0xc20b6335, 0x6893000d, 0xa332a8f4, 0xef4959d8, -0x6284f62c, 0x879c0c35, 0xe9e3ad36, 0x653ed305, -0xac87e78a, 0xe7bde36a, 0x4345fd62, 0x8ab60171, -0xedbff4cb, 0x66cf93b5, 0x8376cf44, 0xedd6748b, -0x44eaf0c1, 0x88705803, 0xc6da08d9, 0x6fd543de, -0x85592c00, 0xe79d63c4, 0x6cdc2a92, 0x89bfe1c3, -0xcbba1423, 0x6dfa21a9, 0xa6a349e6, 0xed858baf, -0x6331f1a8, 0x86e75775, 0xeac0a06d, 0x62d8baa2, -0xa503d5df, 0xece1c293, 0x47c8bd55, 0x8d23e10e, -0xee204328, 0x6fdea099, 0x89a8f4ee, 0xe80cb92f, -0x41cd1474, 0x8f09874b, 0xcf9dbeb9, 0x62718244, -0x8a22623e, 0xe7a870e5, 0x6a6ba570, 0x84e31910, -0xcddede9e, 0x6e92e0ea, 0xaae489c6, 0xec82fa7f, -0x6a9167c6, 0x8994727e, 0xe680b48f, 0x6e403e62, -0xa24d01a8, 0xee5592fa, 0x4b74d177, 0x800d0508, -0xe3b72b12, 0x6b8ce9b2, 0x8d0db7e3, 0xec5317a0, -0x455d8f91, 0x82ffc429, 0xc1398d12, 0x60d0d84f, -0x8d3b8e62, 0xe84b361d, 0x630d2673, 0x8ab49818, -0xcd164321, 0x6b79c001, 0xacbab7c7, 0xed6ca4a5, -0x6b4bf372, 0x85e56ab6, 0xe911f38a, 0x62059ea4, -0xafcf2b18, 0xea0e55de, 0x46af190e, 0x8bb6cb1d, -0xe6b2288c, 0x652d788b, 0x83de4e28, 0xea2e9172, -0x45469080, 0x816aa607, 0xc5bd3be9, 0x6a02bdcc, -0x827f49bf, 0xe7dc4a54, 0x6b2b615f, 0x8f7063a7, -0xc56ef2c6, 0x69e07fcc, 0xa12bdaae, 0xe889c817, -0x6f9c2212, 0x8a1b632f, 0xec252abe, 0x675daad1, -0xa28aa0ce, 0xe745a6d7, 0x462d6496, 0x84c5c6cb, -0xe967c643, 0x68dbf356, 0x86319d98, 0xeab42313, -0x4e1f95a4, 0x81675488, 0xc7a05207, 0x6613d6d1, -0x84596988, 0xe9b56dec, 0x68953dfb, 0x8171c92d, -0xce5c1eca, 0x6e72e1b7, 0xaf894af5, 0xebb8db3b, -0x69bdd2f2, 0x826e11be, 0x710f8324, 0x6cbffa61, -0x6b2f68c7, 0x1f4b8c05, 0x74bc500e, 0xfea47e48, -0x1078bca5, 0xea7d8317, 0xfdbfb06d, 0x75a330e4, -0xe5fb5b4b, 0x9a5c4ba2, 0x7686e0be, 0x8daa9275, -0x94b31595, 0x10077168, 0x8866b4a8, 0x9015bde1, -0x18bb9900, 0x87055ab8, 0x92a07454, 0x88a11ebe, -0x85e42368, 0x00fff1c3, 0x805b4bd9, 0xa1b8dccb, -0x011da7f1, 0xa4b69986, 0xa7328e68, 0xfc7adf4e, -0xa5f8b5ce, 0x5db15603, 0xf9a719bc, 0x9528274b, -0x5368e951, 0x3e5542f9, 0x95bf32cc, 0x424f9535, -0x3349bd57, 0x87f3a3a6, 0xc645d35f, 0xed9bab75, -0x03cb5f04, 0xea113118, 0xe43af99c, 0x09662e06, -0xe3e3a200, 0xe5eb2a3e, 0xe8f9b93d, 0x4125d311, -0x06b430d0, 0x4c0c0347, 0xf75e7526, 0x883d85b2, -0xfaa35064, 0x7f7970b7, 0xa02cd247, 0x9f6a8b6e, -0x59b0a023, 0xc7cd794c, 0x871f98ca, 0xc3d34fbb, -0xd0081a27, 0x1267665a, 0x011d0713, 0x2dbbfcec, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 538-MU168111.inc */ -0x00000001, 0x00000011, 0x09211999, 0x00000681, -0xfc16538d, 0x00000001, 0x00000010, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x4de0640c, 0xc8973947, 0x5f1a48c9, 0xe647f1a2, -0xa24d2118, 0x636cab60, 0x8c470d7d, 0x916cd75f, -0x31031bd3, 0xa3c538bd, 0x9e5e54f6, 0x206378e4, -0x96583499, 0xd872c73c, 0x7780f2aa, 0xd03a37c5, -0xa75749cb, 0x6813ae73, 0xddf49382, 0xb8ff72b2, -0x59e1a409, 0xc6a4a78c, 0x90f5cfb7, 0x66ec3d57, -0xd9914756, 0xb3138c73, 0x69c01b23, 0xcb99a6f0, -0x96ebb2db, 0x55deaeeb, 0x97e60f3b, 0x96c1776d, -0x08d15554, 0xaf028e0a, 0xbdc887d4, 0x377c3fc3, -0xa73f7fce, 0x875bdb80, 0x2b2a8115, 0x855f5412, -0xc74fe60a, 0x1153038b, 0xd156fac3, 0xd32d49d9, -0x39362ff1, 0xc93951f6, 0xda6b6688, 0x050ded5d, -0xec5b05b2, 0xf3cde21b, 0x135002af, 0xf28d1e45, -0x87f8ac42, 0x1808c59b, 0xf1a9a99c, 0xa3c079b4, -0x618398ae, 0xdafd0792, 0xa1660c5a, 0x6ce2b855, -0xeffb8673, 0xba52b2c2, 0x6ea9eacf, 0xcd199498, -0x8c40ee4f, 0x4d0ef108, 0xceca369b, 0x9be2fcc8, -0x7dcf0b48, 0xc896c374, 0xa5c99fa0, 0x4e0439cd, -0xde60ed85, 0x919b4a0f, 0x42dec524, 0xc6816f32, -0xb55b5b78, 0x5b04fadc, 0xe76b74da, 0x8831a1a7, -0x4da4822c, 0xcdddd7c5, 0x871d13de, 0x407b21fe, -0xf723c517, 0x9c31f7a1, 0x6a70544c, 0xdc09b250, -0x85543abb, 0x470e242b, 0xcdd37b16, 0x96b413d5, -0x668d6a71, 0xccbdf00e, 0xb8a97064, 0x45c99ae4, -0xcbb8497c, 0x85e42264, 0x4ca5f7d0, 0xc2226431, -0xbe6e9ae3, 0x52c3942a, 0xe6d864b8, 0x95881f73, -0x4b73573d, 0xdd99bf30, 0x9e8a7486, 0x5a189375, -0xfe50ad4a, 0x95122b0d, 0x6f3cf161, 0xdc688639, -0x8adf821c, 0x53bacee5, 0xdc1bbc9e, 0x8ecaaf3f, -0x7a2e5ac3, 0xda48729f, 0xb0dfba0c, 0x4e7a9d7c, -0xda65e096, 0x88d8bb16, 0x44e67898, 0xc650ff49, -0xb9a43a9d, 0x58e53b4f, 0xf933b6a0, 0x9e9d335c, -0x578869ee, 0xd2883627, 0x8bd3ab9d, 0x5e29c348, -0xe6c5a282, 0x8e82941b, 0x7979e140, 0xdc56e429, -0x9745fd79, 0x4b950ee6, 0xd272f837, 0x9af05970, -0x7759d3e0, 0xc8ee8e0e, 0xbacb9ed5, 0x440d9114, -0xd5bc1831, 0x912e2243, 0x56af00c4, 0xc23ec9db, -0xba9e9d48, 0x5faacb65, 0xf73dbbff, 0x93836333, -0x585bbc70, 0xc0d7e190, 0x932a74aa, 0x492cb232, -0xfc36cf0f, 0x835177c1, 0x79d72f94, 0xccc718d1, -0x8f042ef7, 0x598a6fb3, 0xd13abadc, 0x9f9bd37c, -0x7dd5d78e, 0xc9dc4386, 0xbb82c5de, 0x49b3c88a, -0xcb327a3b, 0x8079a035, 0x6ceeab9a, 0xc6c94539, -0xd3e59ff3, 0xb6734f63, 0x6532095b, 0x95fbb24d, -0xb8f3d958, 0x2774b965, 0x85b787c3, 0x09829f85, -0x2dbf0048, 0x36eb1841, 0x152f6a16, 0x33fb0ebb, -0x30da5568, 0x133b5de5, 0x250ba5db, 0x239c23c4, -0x075baf9a, 0x3537b51b, 0x055d28de, 0xf6e7138a, -0x1c385d65, 0xfbabee54, 0xc9a8bccd, 0xd4b82b1d, -0xc5a641a6, 0xf1e979e5, 0xd16bc5cb, 0x3b2d7882, -0xfe16497c, 0x38501d49, 0x23b94d60, 0x1c1599c0, -0x34ed3dd9, 0xd2a70152, 0x0bd63ff1, 0x29d7c05d, -0xc9994c27, 0x1d28ae35, 0xad24c6b8, 0x903cf6de, -0x9730ee69, 0x05578fc8, 0x818ee685, 0x7dff8b27, -0x10d2f9c4, 0x7e62c1fa, 0x74caf9cd, 0xd6431b77, -0x78f4d042, 0xad1d90b7, 0xc9bc08fd, 0xc6485ea2, -0xb798605a, 0x6a2b95ac, 0xd0390295, 0xd748a646, -0x7530ded2, 0xbc2ccfff, 0xddadb60b, 0x417e02e7, -0xa7b63c65, 0xeb5d09c8, 0x4290aa24, 0xba90e59b, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1342-m02f252a.inc */ -0x00000001, 0x0000002a, 0x08112004, 0x00000f25, -0xad53035d, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x017464fa, 0xd2fb3494, 0xaf1850af, 0x5af88989, -0xd3a0a9dd, 0x8e8bd3ad, 0x8c288786, 0xf15f02b0, -0xf51c1471, 0x6c675200, 0x9c63f3e5, 0xbeb2d710, -0xbfb6d14e, 0x6ba07894, 0x4b08036d, 0x71a24d5a, -0x953125c3, 0x2cee5c1f, 0x744a15b1, 0x43a6f67c, -0x66087dce, 0x58bc5f0c, 0x09c1f187, 0x29065a8c, -0xb46dcc30, 0x597c4675, 0x2ce2fd55, 0x7329e04a, -0xe92adf75, 0x0a4f1f59, 0x6939b7e1, 0x586b6cb9, -0x9e9090f2, 0x612aeaa6, 0x908cfbac, 0x381a3a1d, -0xc0028180, 0xe7759a09, 0x9a41f6d0, 0x49004723, -0x447b0a1e, 0x84cea1bf, 0xdb6cfd61, 0xfa3fe8a1, -0x60569cec, 0x4ed55542, 0xc40d1fbb, 0x9766fe4a, -0xbffcd59e, 0xc0ec45af, 0x34da2fa6, 0x57a8f38b, -0x7cf8ab33, 0x991f0a4b, 0x83c635f3, 0xfaa6b412, -0xd6cfe7cd, 0x7eb7773c, 0xda12abb8, 0xae7f78c6, -0x0c82ad31, 0x28e15d48, 0x80a0cf1e, 0x6b8a9a75, -0x1a9aa64f, 0x4a2969ee, 0x9273d48d, 0x7179df33, -0x06fc27f8, 0x7de9a40b, 0xaaa80cac, 0x83d82561, -0xe0646103, 0xa72284fa, 0xb39b5822, 0xed08ed9d, -0x95760781, 0x2f84666f, 0xd1d45bed, 0x96a86c3a, -0xe4679e8a, 0xfa71d608, 0x86baebc4, 0xf116edb0, -0xd3a7263f, 0x237b4f06, 0x794f33e6, 0x0d783309, -0x2df3bb25, 0x02a800b8, 0x97b8ce5a, 0x2123dc61, -0xee1a5dbe, 0x185cf436, 0x84e325f6, 0x163e3ac3, -0x62288e57, 0xe5901f0f, 0xef985c3e, 0x1b9291fe, -0xb58de2b0, 0xe69eeadb, 0x42eefa7f, 0x0472359e, -0xb1fd90dc, 0x49d374d3, 0x49684482, 0x1156a2ac, -0xd0a6114a, 0x995f94a6, 0xbcf9ed4f, 0x51d161c3, -0xcc68e39f, 0x3d050ca9, 0x8cd08b93, 0x6ed69d22, -0x5fd5cc93, 0xe2783743, 0x5a1816c3, 0xda5a0ea4, -0x9b5c7903, 0xc25d6a23, 0x25cd54ee, 0xe1ab0174, -0x518ffebc, 0x28125044, 0x7ff130d8, 0xfbea3a8d, -0xe093582b, 0xf60baa3d, 0xe4674a15, 0x18a6322c, -0x21cfa3bf, 0x71a1a376, 0xdd4de139, 0xed578831, -0x0ab06a62, 0x9cee036d, 0x11ee0350, 0x62ee22d0, -0x83681acb, 0xef69ded4, 0x65000a40, 0x9ac7ab74, -0xd76792db, 0xf2e662f2, 0xdcae14a5, 0xfa39ba60, -0xf746cf70, 0x0bea4f1b, 0x9b384717, 0xf8dafd90, -0xb2ffc2ab, 0xf3fa97e4, 0x5f22e0c3, 0x04536e9d, -0x22c99598, 0x34631815, 0x9fc99bfa, 0xfe067ae7, -0x03fbd87a, 0xdc73bcd2, 0xc49a0fbc, 0x3138c419, -0x62643c63, 0xfa2597c7, 0x4c84afef, 0xdba2817e, -0xe818ed14, 0x74a5ad6b, 0x9cf3ced5, 0xf633dd12, -0x4ba39a46, 0x8b37b668, 0x65637f55, 0x67c7ce04, -0xe860a2e3, 0xf264ba03, 0x47b91726, 0x887f4d41, -0xb10685e0, 0x95958791, 0xcb835bbc, 0xf1af6594, -0x42fb5a5b, 0x78ff5368, 0xb201a575, 0x8a6b189c, -0xc3f6e3a0, 0xe2bb320e, 0xd75004dc, 0x735b0c3b, -0x70ccd09f, 0x4d157775, 0xc0663e58, 0xf2170355, -0x4d86c74b, 0xace253a3, 0x09fedbf3, 0x5288ffb6, -0xc577a648, 0xf808ffc9, 0x6f1b81ee, 0xa56d4123, -0x60626a1b, 0xc88b4d17, 0x280e44c5, 0xf56c8ddd, -0x9110c257, 0x2d65519d, 0xc96c1ad5, 0xcfdea3e5, -0xa69ea62f, 0xf3ed57ab, 0xbe725f8c, 0x2e3c86df, -0x23635626, 0x7d2607f6, 0x67fe2874, 0xe64ade4d, -0x5fe967da, 0x88cb5547, 0x468c3eb5, 0x73313404, -0x36b6cc3f, 0xf352d0fc, 0xcbd702bd, 0x969a1606, -0xead2f56d, 0xf4c93dd8, 0xd2395873, 0xe5304e3c, -0xdbe3e804, 0x1daf81c0, 0xfd6cbdac, 0xfbb07447, -0x1970d752, 0xff97a936, 0x1cf114a2, 0x03b678d5, -0x6edaacf8, 0xd4a869c9, 0x6db6f5fa, 0xe48335d1, -0x6c59f701, 0x2cd977a6, 0x02079375, 0xc573f27b, -0xd26f8f28, 0xe637b462, 0xb9ef5a9d, 0x2483a550, -0x8e020039, 0x01d2e9d0, 0x8e69c688, 0xfbf941b7, -0x86dcab40, 0xe99730b6, 0x0e57bd5d, 0x11ace616, -0x3a5c73dd, 0xe29052c6, 0x6728d6e3, 0xf5a73743, -0x6ef89691, 0xffa40f45, 0xd1a1b739, 0xf12697be, -0xfc849142, 0x1a6daa37, 0xc52c54a3, 0xe600bbb2, -0x6c90e1e9, 0xf9ba4ed6, 0x118b0436, 0x0d864deb, -0xa574b526, 0x6f2da0ae, 0x7297e467, 0xe33a4e82, -0x6e8a340f, 0x9524f758, 0xb7d9d387, 0x67ed6069, -0x3fcef9be, 0xf3684381, 0xb8012434, 0x86d3a9a9, -0xdb45b646, 0x8de08c40, 0x37a91d86, 0xfd107ef4, -0x0b1db4d3, 0x73988186, 0x74b646a5, 0x92e5a61f, -0x72239610, 0xf9b6564d, 0xce99179a, 0x61ebb35c, -0xfb2495bd, 0x36ab39d8, 0x7cca0da4, 0xec4b5d5c, -0x3210c169, 0xda27c02b, 0xd80c5c8c, 0x38518cea, -0x5daa2473, 0xf15b6134, 0x733e7412, 0xd6a5ae78, -0x3b0d4f4d, 0xc6304bb2, 0x7f6df8e6, 0xf6b0e912, -0x2da01433, 0x2cf7b1ce, 0x32e046e7, 0xcd50021d, -0xe39d167d, 0xef608f10, 0x5d96e85e, 0x38a113a7, -0x3ce761fa, 0x26a0250e, 0xa27c2468, 0xfd563262, -0x9f6f6866, 0xda194d33, 0xa5458a6c, 0x32aa53c8, -0x2517e3bb, 0xe5070380, 0x72d71801, 0xdee77333, -0x63f71503, 0xe4cc9d5a, 0x1f684f79, 0xebab1828, -0xcfdcbec2, 0x1913c83c, 0x72abfe52, 0xfcadec5a, -0x9a32da3e, 0xf730dc13, 0x529ec685, 0x1d558dfa, -0x3fb232f2, 0x041148b4, 0xd10bb0b7, 0xeb6821e2, -0x070d709f, 0xf92b67a4, 0x6d6af041, 0x1724d766, -0xf21a821d, 0xea6e49d8, 0x9d30cef2, 0xe0c055b1, -0x67901316, 0xb37f63f9, 0x5984e1b1, 0xf83466f0, -0x1404ac22, 0x4345d90c, 0xa14ef8b7, 0xa812e742, -0x62593a25, 0xf08c3643, 0x3b376203, 0x5ddf0e1a, -0x429c87d0, 0x31c7a9f9, 0x18f25314, 0xf55e9515, -0xd26dde06, 0xd07605c7, 0x51877d68, 0x31054918, -0x668e3ae2, 0xe273138d, 0xef9b9beb, 0xcf19359e, -0x7ccb675b, 0xca018219, 0x1a614824, 0xa1ac60f6, -0x512484e2, 0x249d2429, 0xa4e02fce, 0x85c52616, -0xfc3e1b33, 0x11885bef, 0xf1729589, 0x78342f7a, -0x3a115d84, 0x74698c2a, 0x59b804d6, 0x96598928, -0xeafb3b9f, 0x788556ba, 0xf956a1c4, 0x5ae7d9b0, -0xe86bc7d9, 0x7483aa3f, 0xa2126202, 0x5852027c, -0xbb2db21b, 0xdf7dcaec, 0x3eaa745c, 0x49390086, -0x60575f57, 0xba173f97, 0x90bd11ab, 0x0db322ea, -0x2a57df73, 0x89157540, 0x57bdf2fb, 0x32b0919b, -0x135b0600, 0xaaeb1076, 0x2a7b30ed, 0x73f755fe, -0x81650eb2, 0x4640b0f0, 0x6f89926c, 0x4bd8b89b, -0xb8233621, 0x24a33dcf, 0x1a6bbb68, 0xeb01530f, -0xcc259353, 0xc17c16d6, 0xbb207fb0, 0x27c1ebd4, -0xed585fe7, 0xf2edcabe, 0x859eca51, 0xc2f2d4b6, -0x3f779a7c, 0xdbdfe2eb, 0x6e7afe41, 0x875cec34, -0xa297ecdd, 0xc4593faf, 0x51764582, 0x2045ab44, -0x82c1ff7a, 0x9e654d1a, 0xef96a26e, 0xf9c5a8e2, -0x1949c1ec, 0xdb0c039e, 0x501af00f, 0x5aa5de51, -0x3020a51a, 0xe17c9fd5, 0x422906c5, 0xb768b789, -0xf0125395, 0xb5144500, 0x8ff2edf5, 0xdcba4acb, -0xf5918257, 0xb202af03, 0x1e50ed84, 0x72e3fca5, -0xf48d1811, 0x2800e62a, 0x2ed0487d, 0x4730996e, -0x55c149a1, 0x65dd8078, 0xdf3c47f3, 0x004ce5e8, -0x12d22a38, 0x56c81e58, 0x0093d696, 0xe362be3c, -0xbd7908e5, 0x1448356e, 0x72673597, 0xc94a3b8e, -0xae21f2cc, 0xf1bc2614, 0x79c1eac1, 0x16f59499, -0x008f11a5, 0xd86396c1, 0x56781c3c, 0x718694c7, -0xf6948d20, 0x164cfd4b, 0xbfead8fc, 0x6014c180, -0xb17136f8, 0x6d26d710, 0xd46ca41d, 0xaea0181b, -/* 535-MU16810e.inc */ -0x00000001, 0x0000000e, 0x09211999, 0x00000681, -0x02aa9e53, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xa3826712, 0x9971f6d9, 0x717628c3, 0x0fa17f01, -0x1ec494d0, 0x76bb865d, 0xb8ee6c03, 0x4aebbf9b, -0xf6e250e1, 0xc3e1ff78, 0xe1ca5a38, 0x01359757, -0x9d2ab268, 0xa2f0b055, 0x7f57beda, 0xcfc1c483, -0x25b50b8f, 0x5625931d, 0x32791755, 0xa7b271e4, -0x8daf1c60, 0x9add85b5, 0x1faf9968, 0x3c6b2f7e, -0xcaf36c5b, 0xd75190a5, 0x0fd8473f, 0x35a6851a, -0x80498f48, 0x922c570d, 0xd343dd3f, 0x420d68a4, -0xf3d3e34b, 0x9f8e3981, 0xd7fa629a, 0xb75ffb4d, -0xefb42deb, 0x0b21ef31, 0xa2088a34, 0xa89133e2, -0xd839caf1, 0x56be7fd9, 0xea6f3ff8, 0x97783330, -0xc6971be0, 0x1fc6fccf, 0x331cb3a5, 0x0b51943b, -0x60a7befe, 0x2815bc9c, 0x5b87374a, 0xa059d986, -0xe605bc93, 0xe64ebb70, 0xae782a6e, 0xfc78e27c, -0x6d328f53, 0x6ee07ee9, 0x3d976316, 0xa202fd83, -0x42bc93eb, 0x6011768c, 0xc0cd685b, 0xbfa44ff0, -0xb1a42d0e, 0xfba4071f, 0x84be8a4b, 0xda405846, -0xc57de4e0, 0x94c2db62, 0x5ea46276, 0x68532e48, -0x739f2061, 0xe83be5f8, 0x01512724, 0x17921d87, -0xe14df45e, 0x0d32a208, 0x762b277b, 0x36f6b74b, -0x07be0bf3, 0xf3b4181e, 0x95ea3ffa, 0x033df16a, -0x67ed2ae5, 0x989531e9, 0xdfb69578, 0x6ca56d00, -0xe2f2184b, 0x17f6a230, 0x26ec4a92, 0x9013b3e3, -0x11b5e3b4, 0x207ef9a4, 0x0ddb53cf, 0x74a168b8, -0x834453a1, 0xaa2e2e81, 0xa5c90f38, 0x5f5ae5b3, -0x0f09aa1c, 0x19929274, 0x5bb6e90b, 0x66927421, -0x952dcf70, 0x89c35f06, 0xb3050013, 0xa344a3e3, -0x3cc76dd2, 0x525c96fd, 0xdc72d098, 0x07b05407, -0x4ea1b6c6, 0xd8f5bcea, 0x7822ee01, 0x3f90c906, -0x9f2e4ec7, 0x7dc5aac4, 0xfa700502, 0x90887ff6, -0x0f8cf395, 0x9b556509, 0x183e0d1b, 0x88cc120d, -0xdf65b198, 0x991ccf57, 0xe2626f93, 0x82c758cc, -0xc250b731, 0xed87fac3, 0x5afced73, 0x1d37519a, -0x785fccad, 0xffb0d0e9, 0x88a3f327, 0x705ae1ed, -0x974e2ae9, 0xd3f8280b, 0xa13c9f52, 0xb5b9eade, -0xc9b91cde, 0x83d6ff2b, 0xc2a61865, 0xe0de9e81, -0xb1d2e242, 0x7ffa8e15, 0x98a1f351, 0x6075f89f, -0xdb1139b5, 0xff53a15f, 0x59d9498e, 0x2544a92d, -0x5e54f2a6, 0xa8dce04b, 0x80f367bd, 0xb105a1e2, -0x0dc47778, 0x5fb0a3bc, 0xc0ffb5bb, 0xb06bc1d3, -0x959776fa, 0x9c917553, 0x0b060078, 0xd1d9450f, -0xe6e8ebaa, 0xf6ba895b, 0xfef15af6, 0xaca6aeed, -0xb4eb8789, 0x76128d63, 0x9c9dc872, 0x6a4fd299, -0xa7eb1e33, 0x571674fd, 0x6073c4f3, 0x7972804f, -0x73f72358, 0x5f23a534, 0xa4cd9b93, 0x94371f63, -0xe3868a0b, 0xd5e18036, 0x683ac91a, 0xc7efadc3, -0x49530c41, 0x2dfc7378, 0xb347634c, 0x346e6cb4, -0x0614dcdc, 0x2354afa3, 0x4d5fcf18, 0xc406909f, -0x0fdc3a94, 0x17e804ad, 0x7e5d27b3, 0xf710a493, -0x735dc0d2, 0x6c82225c, 0x86b80c2e, 0xc83fa3c3, -0xddcd7f93, 0x5c7e7f80, 0xb3f739e3, 0xb027392b, -0x4d3e6ce8, 0x526fffac, 0xa783d364, 0xf6b43a19, -0x6ab12fe3, 0x72ffa066, 0x4990f0c7, 0x63c1c4f4, -0xcddeb2d8, 0x806d60cb, 0x4395d31f, 0xca3930a6, -0x1ee270b2, 0x0521e26e, 0xaad7ee7c, 0xcb5a8502, -0x63a00a64, 0x4bb5b884, 0x56db2b2c, 0x7a6b1ff3, -0xa56a10ee, 0xb3ba2efe, 0x4c5c0bbf, 0x96320c37, -0x2383cf15, 0xce011b62, 0xbf2d0e37, 0xcbfbc5fd, -0x50f83db7, 0xef633153, 0x66d62778, 0xef02ef93, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1106-m02f241f.inc */ -0x00000001, 0x0000001f, 0x06052003, 0x00000f24, -0x1f19b59b, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x5715f121, 0x440ce2fa, 0xd5d090eb, -0x70b3e977, 0x92320e8c, 0x4f989906, 0x36907442, -0xcc4b12e2, 0xb456a6ae, 0x0ad5bcf7, 0xe9f0a425, -0x70b932d2, 0xe66202c9, 0x350f8d4b, 0xd560a828, -0x763e8420, 0x4595b38a, 0xa66d6637, 0xe2adc7be, -0xc5d9515e, 0x7d6d08cd, 0xc930e826, 0x528d413f, -0xce5ac17a, 0x86b9646b, 0xe7845b29, 0x0c56e922, -0xad8a85f2, 0x8e9d478d, 0xd6faa7f5, 0xda7ac699, -0x10859ceb, 0x0c7c1cd8, 0xfd7bc59d, 0xb847dddd, -0xe545057b, 0x5af340d6, 0x1e2f8c45, 0x26c9c8c6, -0x8b6ea51c, 0x75280c65, 0xeb953366, 0x6400e75d, -0xfe0be614, 0x4b47f2ca, 0xac119100, 0x2f973c6e, -0xe3600377, 0xe234bd6c, 0x6010f6fb, 0x497c113b, -0x10824bec, 0xe897a508, 0x0de50694, 0x8202b8a6, -0x79dc657d, 0xa82cd03c, 0x6df4b693, 0xe2586379, -0xba899b59, 0xcfdfd29e, 0x207d1458, 0xd91fc2d7, -0x55ef9753, 0x6ea6860a, 0x69fe1ea1, 0xc8f4b482, -0x4796d795, 0x87f1131c, 0x3a1e5b4d, 0x57d06ed0, -0xb627f7ff, 0x0390c72b, 0x5a8794bb, 0xba43f4d0, -0x1b13f093, 0x9fcffdce, 0xb92dcf40, 0x22d7e700, -0x268be4ea, 0xec5f28bf, 0x8b9eceb1, 0xd47c7c9e, -0x2d379513, 0xfd0dc66c, 0x65da5790, 0xe51abca8, -0x3eb9df98, 0x64471d12, 0xab28627b, 0xe223a431, -0xeaae03e8, 0xe42404dc, 0x27573c06, 0x1784daf2, -0xdbdcc49e, 0x2797692c, 0x5220fd9a, 0x80d0ff11, -0xd74f16e1, 0xe65046ac, 0x681585b6, 0x33c86d05, -0xfdfb0a45, 0xc53ad831, 0x9453c37a, 0xef236977, -0x16558437, 0x21d8f503, 0xd30f65ce, 0xa1e80048, -0x841b0747, 0xac5a8d0a, 0x82cb186f, 0x57fa0ccd, -0x200de1f2, 0xa3bf1cee, 0xbdad77bf, 0xfe703486, -0x00049233, 0xef4a7506, 0xe84d309d, 0xaead661e, -0xcc185f9e, 0x18d07342, 0x7accaa17, 0xadcdf48b, -0x24ac2c5f, 0xe50cbf43, 0x08cf27ed, 0x6106b55c, -0x830a0dae, 0x2435eb4d, 0x776f15d7, 0xdc0eb92f, -0x4733331f, 0xe9a8b196, 0xfcd516fb, 0x2f17ac9a, -0x1ae63b82, 0xadb5be5b, 0x7c650339, 0xfd2ce3cd, -0x9dcf7535, 0xda1e0685, 0x3c41984b, 0x9001047b, -0x39a6808a, 0x7cd929d6, 0xbbe27a05, 0xe502919d, -0xbd0f8d68, 0x1ae3ca80, 0xa85576e2, 0x5ffd286b, -0x89bea08a, 0x8b6ccf11, 0xd8caa1c1, 0x20bc02ad, -0x0b0074f6, 0xf03d2e7a, 0x925a05f5, 0xfcfb6cdb, -0x26adbe25, 0x4bbb3d3b, 0x3e79e740, 0xa26a1af1, -0x4c81a93e, 0x1972b943, 0xa0a01b9c, 0x1da11031, -0x0c3a95e7, 0x0d7b0835, 0x813788b9, 0x3bde2fa6, -0x25bf03b7, 0x4f6939ac, 0x5174c8c0, 0x596a33a7, -0x07a9f755, 0x9171ec2b, 0xa7ba9b6d, 0x4613926f, -0xe7cf7e0f, 0xae9f8542, 0x1166b060, 0x9b742e82, -0x1f3bbb89, 0x29e8e508, 0xe99db755, 0xa75422ca, -0x21b59115, 0x5a8d61a5, 0xb34148bd, 0x28f52ce5, -0xa0eb85e1, 0x4395cd32, 0xa5d2bfde, 0x408cd485, -0x7f96b5f8, 0xd7113b26, 0xcd0df97c, 0x28af3a7b, -0xe3299dbf, 0x74ac44c4, 0x78524806, 0xce4c00d9, -0x4ca8c7eb, 0x196d4c86, 0x0302ba3c, 0x4092a270, -0xd6dc06e2, 0x0c373839, 0xafcf07fa, 0x1a7e415f, -0x18fb4cc0, 0xa99c5f02, 0x61d6d815, 0x45f219f3, -0x3a36a838, 0xea95523d, 0xfbe05004, 0xeb5cb78c, -0xdd141102, 0x486c0cf7, 0x2aa493e5, 0x9fd4bacc, -0x1bc9944a, 0x225984e5, 0xfc026ee0, 0x6d2fcc70, -0xd49bcfcc, 0x23bff82f, 0xb16855f7, 0x622e4b35, -0xd8bb11e3, 0x5fb5ca0f, 0x07201920, 0x1e810ba3, -0x251d4fed, 0xb4af51e6, 0x85e13f71, 0x181e4f28, -0x64bd7d03, 0x547f675c, 0xc227f1e7, 0xbb7a79ec, -0x02c75036, 0x8f691aa5, 0x42381ac1, 0x5e865d0d, -0xe97bf6bb, 0x70d917df, 0x91b87cb5, 0xa2b40540, -0x995beac8, 0xaddb86b3, 0x6505a561, 0x5000e8e6, -0x5ccbdbf0, 0x9cadcd0d, 0xe2cfad13, 0xa40c1f02, -0x6383e8f7, 0xd5b28b36, 0x89e279a4, 0xf62515ca, -0x1141fead, 0x7675f500, 0xf091e74c, 0xba19befe, -0x06a3bad2, 0x838d52df, 0x4f600866, 0x2c74de22, -0x9d2c0209, 0x6d1447fa, 0x6a029510, 0xfc185749, -0x2bb38280, 0xf3b753cd, 0x7e2d1c7e, 0x09b1f4cc, -0x813c4246, 0xe7de9137, 0x2a4a5e53, 0xf7462270, -0x22c8934b, 0x8c3068a5, 0x9475dfb0, 0xca3d63c5, -0x049303a9, 0x4264ff48, 0x6743887b, 0x90e39264, -0x3c283155, 0x937ab964, 0x4915ab48, 0x432e2d26, -0xc0f232a6, 0x1e2242fc, 0x4d632b13, 0xc9f83231, -0x617c0605, 0xe2e3611a, 0xcead2a98, 0x3487ab1e, -0xebbd2233, 0x89fd5fab, 0xb15023b7, 0xcc6e3add, -0x26fc7908, 0xad4eeacc, 0x32fd0f30, 0x8f2ee30d, -0x8d80ab0a, 0x6cc4dfb1, 0xa184df64, 0xec10053f, -0x316764d9, 0xa2de5bcf, 0x71e15024, 0x3577ef82, -0x1e778c21, 0x7ba95277, 0xc7ca2153, 0xc1450741, -0x1e6e0544, 0xe23afc78, 0x2c2bca85, 0x73f5e5d8, -0x143be075, 0xc8329359, 0xa2e3e11a, 0xcdce223e, -0x1bf0dc1c, 0xace3982b, 0x12bb4158, 0xe62eb96b, -0x5b457af7, 0x6c93e00f, 0x01376b8f, 0xa4a6e161, -0xfb333708, 0x9d7451c9, 0xd69ec6d4, 0x20ec9396, -0x9c8d181e, 0x555e322d, 0x8a1cfffe, 0xfdf773af, -0xf345058a, 0xbfd0ef18, 0x9f62c8ec, 0x444f1d96, -0xd24d6bd5, 0xe060264a, 0x90a09309, 0x8ca7e78d, -0xcfa08cfe, 0xe1a70200, 0xe1f46b36, 0xd2934b88, -0x8ef5384c, 0x1f8b54f4, 0x50164c32, 0xf08c1564, -0x8b217ebf, 0x91682eb2, 0x70699e3a, 0x091f32a3, -0x7b9213e3, 0x505cdcbb, 0xfd171a85, 0x8f8b7203, -0xdc2bd0cf, 0x8d9f8b1f, 0x7d66348b, 0x6d94e761, -0xf140d4c8, 0xf8377cbf, 0xa06a1b59, 0x87b4be17, -0xc349c49a, 0xbb546fdd, 0xd8386467, 0xce833bce, -0x2f37d875, 0xa939f441, 0xecf6020f, 0xb2dd210c, -0xe7234869, 0xb30a55ca, 0xd6a33c86, 0x4aa0e617, -0x4a0fbe69, 0x01196fb8, 0xc4526ae2, 0x1ede9d7c, -0xc1f93fa5, 0x5272f02f, 0x3a2d469a, 0x8434c542, -0x9bdee4df, 0x47439e5a, 0x4bcbbe3a, 0x5c0afa2a, -0x5c87d7ee, 0x3e5d40f4, 0x3ee86436, 0xac66c772, -0x373c2e07, 0x1a688ade, 0xe7f2922d, 0x4d27b3c7, -0x3af4e288, 0x139e43ec, 0xbf8c93c4, 0xdfb75db2, -0x8a83e530, 0xc04410f1, 0xd2078dbb, 0x375b20a9, -0xca4506de, 0x19bfe101, 0x676b0a36, 0xa0af8c82, -0x47e0cd27, 0x2ea6fcac, 0xbd9fc102, 0xbeedff19, -0xcff74bbb, 0x845b3c5c, 0x974e6e96, 0x53c9140c, -0xd76e5b60, 0x9064f35b, 0x02555ff0, 0x21dc8658, -0x92fa2cf6, 0xa9122e4a, 0x94de922d, 0x127f1a1d, -0xa8b72474, 0x58e76f8c, 0x363d276e, 0x315e3464, -0xb53354d2, 0x70e794f4, 0xd91f7f17, 0xd8d7322a, -0x719c7c85, 0x3bb6719a, 0x7af1b4db, 0x4a6630d5, -0xe6fc3575, 0xfbf4d5bb, 0xb4e3990a, 0x28f239ca, -0xa27ec578, 0xf360f7a9, 0xcb1b669e, 0x39809f83, -0x656bc617, 0x4db0e850, 0xab7f6043, 0x5225bb7a, -0x3a69084f, 0x2821ab20, 0x624da16b, 0x3a303af2, -0xd5c9132a, 0x1d587f13, 0x1712680a, 0x876484da, -0x57d88391, 0x52926e6b, 0x36205838, 0x569050b8, -0x9417d289, 0xe321e75c, 0x1a4cfaf2, 0x8fde123c, -0xa1f24d2c, 0x005e5dd9, 0xfce4239d, 0xa401a507, -0x556608bc, 0xbeb767c5, 0xe98daaca, 0xe8a11e58, -0x06e79615, 0xbc4dfda6, 0x9ab20d3d, 0x6e86a15b, -0xf1220acb, 0xc4ea8029, 0x336ed96b, 0x9f3dd547, -/* 1355-m206d618.inc */ -0x00000001, 0x00000018, 0x10172004, 0x000006d6, -0xb7b66d41, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x8b98468f, 0x3766ea87, 0xb09b21d3, 0x56122294, -0xc5ea11ed, 0x37f76e26, 0xc0f15ba1, 0xa1e74bba, -0xf7177ffb, 0x5182564a, 0x45910773, 0x0eda2672, -0x3657cb88, 0xdb55fdda, 0xd8318d0c, 0x3ebb142d, -0x522ac44a, 0x83ab943b, 0x61765fa9, 0xea2a1c58, -0xb5c6855e, 0x36f522c5, 0x679a3940, 0xd9a73e8a, -0x4296cf82, 0x9a9da755, 0x50632ab2, 0xd20195b5, -0x0da70fbc, 0xaa54fa84, 0x0d968f90, 0x8885f6e0, -0x5c5be87b, 0x41b3ef59, 0xd126d9bf, 0x892a09f7, -0xfe6aaaff, 0xf92fe218, 0x0820627b, 0xee58f87e, -0x4cf5d03d, 0xfa96f89d, 0x67eb2bca, 0xb9f39726, -0xffe7cbdf, 0xe306b9c6, 0x7478f683, 0xb3dba716, -0x1cc1355d, 0xd4df036a, 0x61eaeff1, 0x6db53d06, -0x9d8cdeb8, 0x3fe76f33, 0x499a5816, 0x767b66d2, -0xbe7fe0e8, 0xa12b7466, 0x11b91265, 0x399ef7cb, -0x563f2d7f, 0xb58199af, 0xbd86210c, 0x3ed97fe3, -0x2281abfa, 0x03128e49, 0x71682563, 0x7473a011, -0x5bd1eba3, 0x825db526, 0x47bb0d9b, 0xed4b0c1f, -0xd4f5ef22, 0x1ac56dc7, 0x11c39136, 0x860a45f2, -0xfa583033, 0xa4b46a27, 0x1092ddd7, 0x3b80bceb, -0xca39816c, 0xbd71827f, 0x3ec0546b, 0xeb62fa40, -0x3c90b1cf, 0x7a6f6561, 0x90732e6a, 0xae804456, -0x33872789, 0x34cc11db, 0x1cf32833, 0x19e8e8a6, -0xd8263d3e, 0x7789b962, 0x5b62a57d, 0xb82342dd, -0x2b5109af, 0x2dbf1000, 0x143f181f, 0x9701d7e1, -0xcf664358, 0xb7e12d61, 0x2d05020b, 0xe0a22ed3, -0x06d12c8c, 0x001c2b91, 0xfed1cc3e, 0xeb220962, -0x0214231b, 0xefe9d21a, 0x01c91de7, 0x442d153d, -0x586a3f62, 0xcd135df5, 0xf5695a08, 0x0882bb15, -0xb3d35f8c, 0x4c4a9889, 0x0e478731, 0xf48ee282, -0x414bc1cd, 0xe228649c, 0x6ebe67bd, 0xfb72a712, -0xf644a517, 0x657672f5, 0xdbe4f19e, 0x1a008de6, -0x5178a6bd, 0x8c123abb, 0xe922b727, 0xd166b732, -0x640f2583, 0xe6f2abf1, 0x4053736a, 0xab8e972f, -0x2f137c09, 0xf04f7151, 0x2c6f72e1, 0xf6c74f8d, -0xb8f506b3, 0x5de769ce, 0x0131cd04, 0x6cb62594, -0x4199ecaf, 0xa45b93ae, 0x45642462, 0x63ec25d3, -0xa793b3a1, 0x2b65326f, 0x4bb6e174, 0xa9ee5e36, -0xb44e3800, 0x414e7d6e, 0x649210ce, 0xf247e0c7, -0xf08379b1, 0xb1b2b5e1, 0x4f546ffb, 0xc4c3f671, -0x41ecb2e0, 0x77178934, 0xeebefb09, 0x1fad39ff, -0x1350b86f, 0xe140e8ca, 0x4eada8cb, 0x5209c265, -0x695d5f95, 0x7ad173a7, 0xcd477f42, 0x02aaa026, -0xd9d5e9c7, 0xa0935c5c, 0xc933399e, 0x33a16934, -0x65669841, 0x4f3a35d0, 0xcab795eb, 0x34e264ea, -0x65614bf6, 0x1d2bdc96, 0x4d591da7, 0x1c16d183, -0xa66ed275, 0x4a954ca9, 0x40ca4e3c, 0x8993d784, -0x67cfedcf, 0x4cd774e8, 0x81d48fdc, 0x152158f2, -0xaf252dff, 0xf805bbc3, 0x08a2a759, 0x78888b77, -0x8a5b7aa4, 0x37df8729, 0xf103811d, 0x6e4aa56f, -0x7fa87e82, 0xbe5cb863, 0x9d06ede2, 0xb01a3cde, -0x6118df90, 0xb75068cc, 0x69304bc8, 0x4c197795, -0x11de2f62, 0x810faad7, 0xac232848, 0x06edff7b, -0x71dec49b, 0x9f3e44c5, 0x0c4ce897, 0xf2e84f71, -0x7c3eba7f, 0x5afda074, 0x7c82c2ed, 0x298026a8, -0xde10e8fc, 0xdad8c483, 0xd6457f94, 0x08cb4a84, -0xc28290fc, 0x93c335a3, 0xeaf1eeb7, 0xae42c772, -0x89c88da3, 0x4bc6b949, 0x53bf510b, 0xbc154c2e, -0xc064d174, 0xc8536311, 0x527a0f13, 0x8a2802a6, -0xd71618ac, 0xc87934bd, 0xe96101d1, 0x55d1976c, -0x471c8505, 0x7a36d839, 0x5d62a9ee, 0xf3c54a8a, -0xa2be15d9, 0x244087c9, 0x042c8037, 0x23224689, -0x281c5d73, 0x2139ecfc, 0xffb8bc8a, 0x834fdd11, -0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, 0x4ae2dbda, -0x86d90089, 0x6675dfce, 0x48876262, 0xcec72538, -0x11dc5c80, 0x86a730f9, 0x313565c9, 0xe3e5be11, -0x106d7cce, 0x752b8be2, 0x3d00a5bc, 0xe6f70e95, -0x44447ac8, 0x600df30c, 0x8335ac3b, 0x8816ddee, -0x700982fe, 0xee495741, 0x48c7e81c, 0xa3d55da2, -0xb0172982, 0x70ab2158, 0xd4460621, 0x3a9e528b, -0x59b18a7b, 0xf4dabc4c, 0xa8454763, 0x70877bb6, -0x66005c97, 0xaf292c06, 0x7b843db1, 0xf343b59b, -0x25cdc7b5, 0xa41da617, 0x9e9d895e, 0xc936f475, -0x7270925a, 0x30024230, 0x8e72f53d, 0x2b6c1b6f, -0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, 0xaf377cc1, -0xbff09a78, 0x4b4e0814, 0x95a0b2c1, 0x270398de, -0x201fca94, 0x2a032a4f, 0x131542b4, 0x0d7306da, -0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, 0xa3b3a991, -0x17ee60c2, 0x852c0b8d, 0x11e5853a, 0x762002a7, -0x92c5311d, 0x0d4bf7e1, 0xfffec870, 0xe3d35e5b, -0xff6ecfb9, 0xdedae6ff, 0x0111a772, 0x9808e780, -0x29c336e8, 0xe9bc05df, 0x5bedde11, 0x945565af, -0xaff808fe, 0x87e3423d, 0x4de6f98f, 0x93b4adef, -0xbf704fa4, 0x09120e91, 0xd54f3692, 0xdf8eab1e, -0xfabbf59c, 0xe74318be, 0xaab87ffc, 0x29fa791c, -0xe3915552, 0xa652cb9b, 0xa1252e74, 0xb35b723b, -0x542aa28b, 0x12fcc5b0, 0x3941f962, 0x82bcc6cc, -0x47b11974, 0xb821611f, 0x78b34250, 0xf1be5659, -0x561b9e61, 0x6f3bd501, 0x584e6f5c, 0xd54ed547, -0xacebcd21, 0x7b5ff816, 0xb64ad233, 0x9f2f330d, -0x69fb1ece, 0xac8710dd, 0x58dc6c60, 0x9bee6139, -0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, 0xa733274f, -0x884d9b55, 0x42b08b63, 0xafa54a74, 0x1c7ccf64, -0x93a20191, 0xaaa3132e, 0xc69831d1, 0x54634889, -0xfbfe3efc, 0xd3cf68d4, 0x302e3117, 0xf5693131, -0xc3ce8c6c, 0x1f03cd89, 0x6243334c, 0xf16bc80f, -0xdca5f130, 0xcb2cd956, 0x4c1bb421, 0xe8de533c, -0x7f86703a, 0x29aa897e, 0xdd54acad, 0x76b2f2ae, -0x7ef82b71, 0x2e30970b, 0xba402597, 0x9a653ab4, -0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, 0x2363d147, -0x5327289a, 0xe89229f3, 0xd63a535c, 0x7efe9273, -0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, 0x1b9c7bfe, -0x5d14b3de, 0x54d575fb, 0x6d65db4c, 0x95648b7f, -0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, 0x8488a45f, -0x8ebc2932, 0xd4767316, 0x3e8c4b8a, 0xbab7402c, -0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, 0xc88528e9, -0x4b2e4e8f, 0xdd938b86, 0x0c964f98, 0xfc88d480, -0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, 0x4d40b3b3, -0xcf203155, 0x0d2fa621, 0x752d2c58, 0xb12bac12, -0x1e7e8c23, 0x94215d54, 0x9854a71c, 0x4de63c64, -0x7a012529, 0x9c171f8d, 0x9e71def7, 0x3bd17d50, -0x11f175d9, 0xec78abf3, 0x7b529eee, 0xd3a69fc3, -0x5b718676, 0x58214d29, 0xa8bd2c34, 0x41ea00ab, -0xa03f64d6, 0x4ee342b0, 0x32b1e444, 0x1c1801a4, -0xc8424702, 0x334a7e35, 0x50cf1543, 0x3b22b495, -0x88683776, 0x8e2e0154, 0x6155c033, 0x4e2fa6ac, -0x42ace700, 0x8d64f97c, 0xaf9ced17, 0xb2a5cb92, -0xa558582d, 0x88705de7, 0x9e528d59, 0x84bd45e4, -0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, 0x10462123, -0x30080f7d, 0xb346cd81, 0x0049c396, 0x4e24165f, -0xa7c66809, 0x2e60bdcf, 0xaad70a08, 0xa73ea713, -0xe28f97a7, 0x283a9eab, 0xd4366489, 0xe776f963, -0x64ffa8ae, 0xde717b50, 0xbd2ca2b5, 0x3bae5f6d, -0x8d2bbef1, 0x7e9181e6, 0xf06aa121, 0xd06b2d20, -0xa83ea826, 0xef935e4f, 0xdfd27456, 0xa3451468, -/* 691-MU168a04.inc */ -0x00000001, 0x00000004, 0x12072000, 0x0000068a, -0x995ec216, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x54166188, 0xe535ae13, 0xa1a6ca6c, 0x202f9eb5, -0xa49ee07b, 0xa4463ba3, 0x0bb8102d, 0x8751cb91, -0xa6b73e2d, 0x24cc7f4e, 0x821b0492, 0xa67c19c7, -0x0865af67, 0x806ab137, 0x8b7d96ba, 0x2a50d911, -0x87d749e0, 0xaadf5ac2, 0x27176ddb, 0x8b1e4c6b, -0x8247a52f, 0x2f199a4f, 0xab4a3695, 0xaa55f6d0, -0x25aa931e, 0x89580d05, 0xaae2937e, 0x22df2015, -0xa58c2053, 0xad480e1e, 0x056a3cdc, 0x8db6e960, -0xaedb93b5, 0x29fffaa7, 0x8e12d006, 0xa50e3b22, -0x09a99c8c, 0x8a96ad34, 0x87ac86ba, 0x2dfd44d4, -0x86c79529, 0xa7f97bcf, 0x222fbee9, 0x838f9436, -0x8ea6c4b6, 0x2b061994, 0xa718f6c6, 0xabeb6df9, -0x23c3d2f8, 0x8741db0f, 0xa0f5a92f, 0x287011ae, -0xaab46662, 0xa6501353, 0x06388553, 0x842f6b80, -0xaa415ed1, 0x2ba08c21, 0x8bfea0bc, 0xa07dd06f, -0x08ce70ec, 0x8b195004, 0x8f4735d8, 0x2d4cbb3d, -0x8e2d8d1b, 0xae340145, 0x29f05708, 0x880b17bf, -0x8d5459cf, 0x279e9251, 0xa8aa1e38, 0xae09e0ad, -0x2b4e17bc, 0x86de5f47, 0xac89f48b, 0x2787e6bd, -0xa2840685, 0xa991f7a3, 0x0bd79f55, 0x897d2734, -0xa8bef187, 0x2d91e9b8, 0x84a5bd7c, 0xab0ea74f, -0x09483b60, 0x87534077, 0x8fe56f74, 0x2bea0ee9, -0x8035a789, 0xa707eac6, 0x233d0de3, 0x880f2a56, -0x8b75a29f, 0x23eb9b6a, 0xa235532d, 0xa1629f77, -0x22719b57, 0x82af8ee4, 0xa654ac8d, 0x205b3cc6, -0xa635195c, 0xac653e14, 0x00aa4ba3, 0x89923f57, -0xad211654, 0x27964c24, 0x8145519a, 0xae577a1e, -0x02193c7d, 0x8371bb8f, 0x8e38144b, 0x2e2735bd, -0x820d4360, 0xa975c934, 0x2ecd7d81, 0x8eefd6af, -0x8760bc8d, 0x2f732336, 0xa96e2069, 0xadde039a, -0x2e6fc380, 0x8660772e, 0xa92fa5d3, 0x23db18d7, -0xafb1af41, 0xad12b1ae, 0x0b832d4c, 0x8c7ec7b4, -0xa2ab9d5e, 0x2c841a0a, 0x8ef54e2a, 0xa39d1a96, -0x03d05451, 0x83096867, 0x882ffa2c, 0x226ab470, -0x8b197086, 0xafe23ffe, 0x24f4b9aa, 0x8bc6470e, -0x835057b8, 0x2e9a2d6c, 0xace0be7d, 0xafd10f5a, -0x254a6dfb, 0x80535796, 0xa99f8e3e, 0x2497ad06, -0xa2da0657, 0xac34677a, 0x06a3cfb1, 0x8737e980, -0xacb80ed4, 0x215275ec, 0x87bcc694, 0xaeb189c7, -0x0e46185f, 0x8f5a6a2c, 0x8b3300ae, 0x218ad69a, -0x808475bb, 0xaa89ecee, 0x2e63d3b2, 0x8137c967, -0x85552646, 0x21fc5091, 0xaf8c06cd, 0xaa525c28, -0x21680179, 0x89c7b3e8, 0xd644786f, 0x5e9b9d1d, -0x2702fe66, 0xfda03d55, 0xd0df4c73, 0x9482b978, -0xfade6b02, 0x688fd36d, 0x952cf501, 0xfeca27fe, -0x66abc182, 0x996671b1, 0xf1b7cf4c, 0x232cfb6d, -0x968efeac, 0xb30f46ec, 0x2a1e24b4, 0x6350447b, -0xbef74dbd, 0xd1b77677, 0x6036d792, 0x94747eb8, -0xd321f5f0, 0x4732e7af, 0x9a4a0faa, 0xe38af022, -0x4e0f8444, 0xade43c54, 0xed08efc0, 0x63207e33, -0xa76d15da, 0xc189c05a, 0x616b1784, 0x55b07eeb, -0xc21f088c, 0x6cd19b19, 0x568d2424, 0x374ed20e, -0x634b7ad1, 0x5aa8cece, 0x342338db, 0x18514c13, -0x527faf4e, 0x4e30cc1d, 0xc12ae47f, 0x53dcc404, -0x980e4e30, 0xcb45cda4, 0x3a2a3e9a, 0x63a58248, -0xa25c4dc3, 0xc7f6786f, 0x6ade3de7, 0xa0b5b6e9, -0xcfe10078, 0x648ffa56, 0x75e3ad04, 0x2fc1552f, -0xb0f77ce6, 0x9797eba5, 0x25835592, 0x9f295669, -0x9518b629, 0x0f6f8490, 0xe86d585e, 0xa799a942, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 398-MU166503.inc */ -0x00000001, 0x00000003, 0x05051999, 0x00000665, -0x2b9733f1, 0x00000001, 0x00000010, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x358c92da, 0xa753eb19, 0x24588215, 0xa462f72c, -0x9ae43792, 0x393cc0d3, 0xe8f43249, 0x1bec1833, -0xd0b7e8ea, 0x135d58f1, 0x8a2e1ff9, 0xde9451b5, -0x82d2a3f6, 0x05a7c378, 0x75179336, 0xd7007b9b, -0x1683d5bb, 0xd4a252e7, 0x2f40aa9f, 0x3e83129c, -0x2c00fa9a, 0x51d02e05, 0xa1646c98, 0x87f8ac05, -0xce1aaa32, 0x4a82d045, 0x86880792, 0xe4974edd, -0x8061e878, 0xa1881b5f, 0x04e837b6, 0x2769c989, -0xe74ecda4, 0x33654340, 0x61baeeb7, 0x35c98030, -0xc8df4eec, 0x5c5bb984, 0x6e98f123, 0xf6d7dcea, -0x10dc19f9, 0x3b01a4e3, 0xafff281e, 0x6e161f3b, -0x17948731, 0xc65afafb, 0xabe182f2, 0x69955a64, -0x3a12b07a, 0xe495100d, 0x554994c5, 0xbd57e186, -0xebe0ac49, 0xe389fa05, 0xb009da9b, 0x0ff85b98, -0x809e9a10, 0x16254c1f, 0x304faeb4, 0x5d57d991, -0x11d772e5, 0xbef29e38, 0xd7a975e3, 0x9d097f71, -0x6106bb0b, 0xba8cf6b9, 0x5ace7130, 0x5031e613, -0x51a1a606, 0x9c0a1169, 0x872dcb66, 0x40f99c93, -0x7ca932d1, 0x5a6d449d, 0xe140f2c9, 0x84860c6a, -0x8af3229e, 0x4afaf036, 0x7e55d4f6, 0x46128b9d, -0xf46348a0, 0x9d95bcdf, 0x31943826, 0xf88de2e6, -0x9e44d646, 0xb3ee3161, 0xf92a68c8, 0x60f9bace, -0x7ca722a3, 0x9990bb83, 0xafb51d20, 0x07bfb960, -0x1df64349, 0xdcc1f002, 0x739aa18b, 0x38ea1e28, -0xa2dae978, 0x574c14bc, 0xc1f81ca6, 0x203c604c, -0x282967d8, 0x385855a9, 0xa1b12ee3, 0xa2109df8, -0x86e9a39f, 0x1790c5a9, 0x64804f3a, 0x7d2752d9, -0xa94f4f26, 0xa26c6a31, 0x5198ff0b, 0x5e94ce74, -0xf1077560, 0x54e98c79, 0xde5d0d82, 0xf4bfad49, -0xe7320b71, 0x856bc9a0, 0x82d0be13, 0x5ee2ba88, -0xef5d3f1a, 0x8069358d, 0x084c6414, 0x10ec7c70, -0x91d623a6, 0x74a78915, 0x8eb0321a, 0x3d80ac81, -0xe512e8fa, 0x8fb07c28, 0xb328603c, 0x0ef99b7e, -0x47ea27ec, 0x6be33ed1, 0x3f4da715, 0xabbbd675, -0x69a18bfe, 0xb128d04d, 0x043e4ba0, 0x6915ac2d, -0x042b7f54, 0x976ce0bc, 0x6d0c1f2a, 0x56bfb408, -0xbfe963c2, 0x7df8d0c0, 0xb2a7ed5b, 0x897a09b9, -0x6bd60b68, 0xcd6d9697, 0x48646873, 0xf973598e, -0x4ab445df, 0x87f8f3c6, 0x8c7ac00c, 0x0bdde45b, -0x7be6ecd2, 0xd0c6e842, 0xdd711cea, 0xeb22b612, -0xe6ab1500, 0xaad6042b, 0x2e5cae33, 0x47ec8dbb, -0xcbd123b9, 0xad6bad77, 0x0d8f347e, 0xa71a183d, -0x66fe5476, 0xebe8a076, 0xdf99392a, 0xe8f9d3cb, -0x14c99a25, 0xf6f36332, 0x2e4d9e17, 0x9f160e14, -0xe113d044, 0xec57bb4f, 0x3768415a, 0x8e76bb31, -0x1e3002c7, 0x3f34fde4, 0x63227f0c, 0x43bbe307, -0x04076f7d, 0x0508bc78, 0x1f85f189, 0xa1cc81cf, -0x86542205, 0xebaedc53, 0xe2c3c19b, 0x909eff45, -0xa069f9da, 0xbc6b88b0, 0xc525d56a, 0xa17fa1ec, -0x72ceb073, 0x79763bba, 0xd6c220b9, 0x850cd04d, -0x036fb53f, 0xb56d501d, 0x79ce6c72, 0x6f257e0a, -0xdf5b0c82, 0x4cfbe232, 0xfb6dc8e1, 0x70fda82a, -0xca25fe30, 0xbec9ae31, 0x519816a5, 0x41edeeeb, -0xd5cea131, 0xb6906cb9, 0xb8972484, 0x867b1154, -0x666a8484, 0x3f32c15b, 0xf41e4c2b, 0x96204780, -0x3e5bbc2f, 0x3b7ca3be, 0x06174d9d, 0xee03e984, -0xec331aec, 0xdb3c13ce, 0x3a8ab1a3, 0x9e4b50b1, -0xe15b5adc, 0x17470f1b, 0x208a3d17, 0xbb455669, -0x7aad5d15, 0x78a9e932, 0x74bb450e, 0xdc2ce482, -0x471e52d9, 0xd8b193ae, 0xb9036a57, 0x77e42d3a, -0x27ec2977, 0x06169fe7, 0x2d2bdb69, 0x869a5b44, -0x9f799f33, 0x3a64040f, 0xc3cfd2c0, 0x98a3a439, -0xb3b8101c, 0x38d8bd22, 0xd12bdc7c, 0x466e5b9f, -0x9fee2968, 0x95ce4e32, 0xdc57c7de, 0xf2fb9d1e, -0x27bded67, 0xc1ad6483, 0x223deb45, 0x86e63082, -0x4a203789, 0x7403fb65, 0x78a3e835, 0x8b61edb2, -0x5463c05d, 0x766c0055, 0x9125ef4a, 0xa539a0b7, -0x5534a196, 0xcf9f76e8, 0x9c37844d, 0x6fce6dbc, -0xef915a04, 0x4e6a1cdf, 0x4c29c215, 0xb81bb506, -0x8dd4519a, 0x74b38e0b, 0x381e1eab, 0x17b67703, -0xf4abdd68, 0xc27be868, 0x9f0faf2f, 0xefc53838, -0x3622c3a0, 0x60d7f011, 0x8ad7ebdc, 0xc40d6551, -0x04983f91, 0x2cf8b33a, 0x531ff419, 0xf5e93714, -0x65c885aa, 0x2320ae43, 0x806c5268, 0xdf4e166c, -0xc5bdc782, 0x29b46f9d, 0x0f1c4065, 0x4dc28062, -0x69e7b7c7, 0x3c26bbe8, 0x12646ad3, 0x5d6a6a1e, -0x44048e46, 0xf60531d8, 0xb74e3592, 0xb40024ea, -0x252a8bf9, 0x7dfc6e4a, 0xa7bf7fa9, 0x1bdac22f, -0x50cdfee7, 0xd0c5b034, 0xcd79e72e, 0x7eddf775, -0x6fb3c649, 0x6c3bfcaf, 0x750b8d6d, 0x41928264, -0xe301566a, 0x5a49c2f5, 0xd0e55ac1, 0xfe0f0cc8, -0x772e3cc0, 0x9bf80060, 0xdc49c2ac, 0x9f099089, -0x770823d8, 0xf463e468, 0x9e5807d0, 0xdacb3baf, -0x1eba5767, 0x13c5f4a9, 0xcd01ffec, 0x0e36d465, -0x6ec3c83b, 0x226eb0d5, 0xd01557e5, 0x77c79cef, -0x5efe9046, 0xabbfb6c8, 0x243a57b7, 0xd28db7bc, -0x719bf699, 0xe93b667e, 0x1de82685, 0x51380b53, -0xa623f364, 0x6d780611, 0x0c768e91, 0xf907a65a, -0xcc7733f9, 0x2f2465b3, 0xbd12413a, 0x5cd5a39f, -0x37d09ec8, 0xf40603c2, 0x5dbe9b04, 0xb8178e07, -0xd1bb5765, 0x1bfeb0b7, 0xc059e78c, 0x69d6449c, -0x8d28427a, 0xcbffb328, 0xfd972598, 0xcfb55e89, -0x395009e3, 0x791e6bd2, 0x78064b04, 0x80ee0f16, -0xb4cfa086, 0xd37b798a, 0x3f0808d7, 0xe95589aa, -0x8098467a, 0x115a5d4f, 0xd1dc0f2a, 0x4453e5d1, -0xb2f20cf0, 0x9a0f9e31, 0x4295d145, 0xf7ef8330, -0x4a7bda37, 0x110a6d71, 0xb923c984, 0x4fbfed95, -0xe12fedc2, 0xc0cfca64, 0x56483d6d, 0x97f840e6, -0xbf5fe41e, 0x66022685, 0x76a0819c, 0x98640d2c, -0x4eb43b01, 0x5a54896c, 0x55a1bdd7, 0x6f65ba91, -0xed2b5538, 0x1f9834d1, 0x109a30fb, 0xccf76d5e, -0x201ffeb9, 0x4ab1c88f, 0x09acf508, 0x8dae69fa, -0x2744708f, 0xcea1e69e, 0xaad64322, 0xb5b1f8f2, -0xef9bd4ee, 0xa7805716, 0x88ec378a, 0xcbc7caea, -0x668e4b26, 0xe577ac32, 0xe69a15a2, 0x9447dcb0, -0x2cce6bad, 0x17d2664b, 0x97660be8, 0x2c27db29, -0xa9724c0a, 0x17ee97d7, 0x42ac77ff, 0x83f2075e, -0x7cde02f9, 0x34420971, 0x06a2aaa7, 0x3ac69a7c, -0x53d3ac43, 0xbb5bddd2, 0x7b542bbe, 0xd961a9ca, -0x1a6decdb, 0xe6e1b5d4, 0x15a67e4d, 0x6d188aae, -0x8f19f6d6, 0x26945471, 0xea55646c, 0x82d1b6b5, -0x35a40d61, 0xcb49c2bc, 0xd0f5a364, 0x82122f86, -0xaa2b88cb, 0x11eff3f5, 0xe6f54792, 0x67f462ec, -0x542a5a8a, 0x8e8fe970, 0x729a6876, 0xe22b8ecc, -0x7970112a, 0xf74356aa, 0x25fe6cb3, 0xca01a532, -0xb1235c63, 0x4f47c539, 0xc217ce08, 0xff59b048, -0xb6ca10fe, 0x71e838d6, 0x19b45d57, 0xa3adb657, -0x9d37acf3, 0xfd89535e, 0x747406a5, 0xb5141dc2, -0x61a05b4c, 0x9eaff8c4, 0x51da150b, 0x0932911b, -0xde897842, 0xbaed7325, 0x8c35f6d0, 0xa84d6305, -0x1eda951f, 0x7bf216b8, 0xdbb78152, 0x88427248, -0x10c3fc59, 0x3a8465db, 0xb963b514, 0xa77f8dd3, -0x98dbb57d, 0x4984b500, 0xa21601b6, 0x881258aa, -0x0508093f, 0x20e84ec3, 0xb98409fa, 0x0a9eadf9, -0xdf8b856c, 0xe8bd17dd, 0xcd37e7c0, 0xa95b8505, -/* 402-MU166d07.inc */ -0x00000001, 0x00000007, 0x05051999, 0x0000066d, -0x35ba5e6e, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x5e56252c, 0x4f0fc459, 0x0dda7564, 0x89df7fe8, -0xc1985cef, 0x196e2272, 0xf4673aca, 0xfcb4c8d7, -0x260334ef, 0xd745755a, 0xf26f8cbc, 0x28c29161, -0xdc0d9885, 0xd470cec7, 0x771e836a, 0xceffe4e2, -0x8442e471, 0x4d6acd9f, 0xe0355eba, 0xac9da82d, -0x6dd914ff, 0xd4221e41, 0x909effc1, 0x58cd3b0b, -0xe1479a6d, 0xb5ef2a86, 0x63693ab6, 0xc2f046cc, -0x8adbf768, 0x4c57d2e2, 0xca5aa305, 0xb3106fbc, -0x06603d00, 0xf8c94ed8, 0xf69d93af, 0x059aca0e, -0xbcd57674, 0xb72b359a, 0x260152ed, 0xfe40d0e0, -0xdcfc0d55, 0x2ff005a0, 0xf509b0fd, 0xd214bccc, -0x630bcf58, 0xf8cfbe29, 0x92002aba, 0x4ca1f743, -0xfc65a494, 0xb9fc0c5b, 0x487580f4, 0xffcee67b, -0xf5f92e08, 0x47e81f3c, 0xbd252485, 0xd0c23904, -0x4000c37d, 0x9f6833f5, 0xdeca61bc, 0x404d81e7, -0xd72db92f, 0xd58aacd4, 0x068f4951, 0xf08a13de, -0xd053146e, 0x2fd1f26c, 0xf5c81ca1, 0xd25ae1e2, -0x66f007f0, 0xfba6eeac, 0x99bcc45a, 0x4666a0bb, -0xf03ff585, 0xb32bc3bd, 0x4ebd2cad, 0xf60c2303, -0xf5644201, 0x4cbec874, 0xbd2f4b21, 0xdb73feb4, -0x44442781, 0x9a36bb55, 0xd5ef6337, 0x41f78df4, -0xd9045692, 0xd4fdda07, 0x03361727, 0xf031b248, -0xde253f06, 0x270a6b41, 0xfabee114, 0xd44db762, -0x6f6e7d0b, 0xf3aa07dc, 0x9f784b10, 0x49628bde, -0xfee63a21, 0xba75f2f7, 0x4936344c, 0xfbf2abef, -0xf5f80b10, 0x449ba636, 0xbb45c68c, 0xd5e90822, -0x4411803a, 0x909026db, 0xdb9c09dd, 0x49da46d8, -0xd0920f17, 0xd75eeeea, 0x0a481e97, 0xfa0aed77, -0xdcb2d33c, 0x2668c527, 0xf69e1af7, 0xdb258690, -0x6789ce72, 0xf9255b26, 0x950c1bdd, 0x4dd4d88a, -0xffa406fc, 0xb4a02bb5, 0x46db6c15, 0xfb60e40f, -0xf813df80, 0x4b684e51, 0xb13bc892, 0xdad679b0, -0x44d0e6b8, 0x986dbc15, 0xdb39a619, 0x40e2dfd1, -0xd98d6cc5, 0xd2d46188, 0x09918e75, 0xf10f8b27, -0xd0762674, 0x238338f3, 0xfe1fde17, 0xd5322a2e, -0x65a842bc, 0xfb313c5c, 0x9264995e, 0x4ae7a364, -0xf82fec15, 0xb988a3c4, 0x408bf6ca, 0xf8291760, -0xfa087dd2, 0x4fc95069, 0xbf0c517e, 0xdbdab8d2, -0x4e0dc819, 0x955d89b9, 0xd57c93f3, 0x445c0771, -0xd7df5deb, 0xd499e424, 0x01a24a0f, 0xf6f249fa, -0xd790a20d, 0x2d78aa5c, 0xf2891b04, 0xdc212d68, -0x6ea2d816, 0xf81db2c5, 0x95f9716f, 0x4b09451b, -0xf91d11d6, 0xb01920bd, 0xfab65a11, 0x6cb5e00f, -0xf2c998f0, 0x007116c1, 0xfdac4ae7, 0x24a2cd9b, -0x073c27cb, 0x2cfeffbb, 0x23998e30, 0x11fbf8b6, -0x24a3acc0, 0x352fdfbd, 0x1e4b3aac, 0x15820bb1, -0x3f02c3e3, 0x25eb76a0, 0x3e1c9a8d, 0x00b9e149, -0x0d8a9e7a, 0x07d85c98, 0x04bae543, 0x26b7fd43, -0x03d5b79e, 0x2946001d, 0x2dea0cf8, 0x43b4610e, -0x2506bb04, 0x9ac11105, 0x4edb0263, 0xfb327e1b, -0x93448267, 0x66c4f588, 0xf48d483a, 0x113d6078, -0x61e5eefb, 0x768e81cc, 0x12daba21, 0xfc5f39c5, -0x731b6ba4, 0x770a963f, 0xfc148bd3, 0x6b04e3d5, -0x735eea30, 0x1793f64a, 0xa2d6e850, 0x7cb00909, -0xd858cbfe, 0xa3f24121, 0x4c994609, 0xdfcbff3f, -0x9725e9fc, 0x4f3543fe, 0x59c0c1a1, 0x18cb9e57, -0xc1c3562a, 0xdacd316b, 0x26490ed3, 0x9d8fe37a, -0xe90e7a6a, 0x79ed9044, 0xabb894d5, 0xa0374350, -0x47ced1f5, 0xe85f29ed, 0x0e54c3fa, 0xa0f907e9, -0xc1755fcf, 0x4cc7bd45, 0x7f08499c, 0xc6d36e55, -0x7e2612b4, 0xc4c9891e, 0x3b5408e7, 0x710f9c03, -0xb4ddd9b0, 0xd2558968, 0x7a3bdb65, 0x06acc5d7, -0x58e1c843, 0x181e5813, 0xfe930ba6, 0x82c7bb45, -0x694bc111, 0x046ec31f, 0x7c83855b, 0xcd97a1ec, -0x941639d2, 0xac2630bc, 0x6c8bd957, 0x476c9982, -0x39087f73, 0x05c6832f, 0x3e85c189, 0xb3abdfde, -0xccc779ec, 0x84597ce5, 0xeca12503, 0x83d674fc, -0x9bd3f064, 0x1292a463, 0xee679bf6, 0x82823ef4, -0xed7f4d18, 0x6dafa853, 0x8bba73b2, 0xde5badfe, -0x86f9e16b, 0xe08b4380, 0x8fd032aa, 0x952be076, -0x8e43a9dd, 0x5e9ca0d0, 0x5c3a9c6e, 0x3ed246d3, -0xcd3d920c, 0xfee73f4e, 0x5be235af, 0x3842c7ac, -0x549a38c1, 0xd7155622, 0xd609483d, 0x2e8c63c1, -0x7ee633d4, 0x365cb896, 0x21486709, 0x09da59e1, -0x5385d44f, 0x40923a13, 0x368e7227, 0x3865cb0b, -0x49b86a4b, 0xe91d9222, 0xa4261ac2, 0x5987de57, -0x6b90090d, 0x4e07c06b, 0xe0ade732, 0x48b064ff, -0xd8fbcaf4, 0x72e5f0b7, 0xfe1fb6e4, 0x8865fe58, -0xaabd9585, 0x5bebdeef, 0xbccdc668, 0x0d44bbe3, -0x35745d5d, 0x88e5bb1f, 0xfe5d3374, 0x69064530, -0xac93ea3e, 0xd0358d6a, 0x98d400d4, 0x55767bfe, -0x256a1b09, 0x99d61a1e, 0x89879a7b, 0x9f7fa025, -0xfa19a9c0, 0x7a5a45a4, 0x8827d97b, 0x721df39b, -0x8ca26f82, 0x2debf883, 0xf9bf8802, 0x0168de7d, -0x69d62893, 0xf34f8364, 0x43b06563, 0x958f92ff, -0xcc61b852, 0x46de8312, 0x7eadaa11, 0xf5d7317e, -0x7fcbed41, 0xfd8b4472, 0x89ce0b98, 0x33a26c73, -0x2372c4fc, 0xbfe3a890, 0x7d7840ac, 0xd561ac76, -0xcd84304e, 0xe5058896, 0x7e6c051e, 0x61a9b441, -0x0e14570f, 0xadaf99cb, 0xf0c39de0, 0x4a1dc4ab, -0x52045c44, 0xdf33d196, 0x0af0dd01, 0x368040ad, -0xa611a20d, 0xbe7b4987, 0xc8b7a5b2, 0xafa1d162, -0xd9cf8dac, 0x6b09a341, 0x3e3df047, 0x2a780a01, -0x02b0cb81, 0x99f9ec8c, 0x4afa4e2d, 0x73048be6, -0x5ef2130d, 0xb1000354, 0xacbbedf6, 0x7767aa87, -0x98b36af1, 0x416479a5, 0x72b01f54, 0x72d98f7d, -0x68e9ecef, 0xe309f9a2, 0xd051571b, 0x78a5de85, -0x9a6409e6, 0x6f6c2998, 0x507db337, 0x5f37d973, -0x6cc44dd8, 0x9ca00fec, 0x6865feb9, 0x0b0a0443, -0x5786a3ea, 0xf84bf72c, 0x6a8e35d4, 0x19b6490b, -0x2d021a57, 0x42b5d1fd, 0xd9d989da, 0xece79c06, -0x9d622680, 0x29b81f2b, 0x1c83e53b, 0x156a1f8f, -0x19aa68ed, 0x63c44d9a, 0x8f17ef88, 0x1e18c81c, -0x16b9f137, 0x2ae4a05d, 0xf7839170, 0xb6e98047, -0xb0460222, 0x17be9291, 0x5805f8c9, 0x3fedccc9, -0xabd75591, 0x5c89bb87, 0x22361c7f, 0xb449f07c, -0xdbd7e082, 0x601c32a5, 0xca07c0a2, 0xf53f9056, -0xe2801718, 0xb8dd7373, 0xb8c1fa68, 0x7521d777, -0x54e7b093, 0x87d1c19f, 0xa0043422, 0x42641b0d, -0x3df7eb55, 0x33960ceb, 0x2ccab13c, 0x7289fe79, -0x017a50dd, 0x83585544, 0x1a62924b, 0xed311733, -0x9f07f9ce, 0x19e88eb3, 0xa57658fe, 0x971210d4, -0x551651e9, 0x50a40561, 0x5f05ec29, 0xdcfb5112, -0xa3f15c0d, 0x728a4196, 0x5f6c1bb9, 0x9ed61bc8, -0xb0c1763d, 0x572a6bbc, 0xd957a4be, 0x7a9e36ee, -0x08809d99, 0x5db2305d, 0x0cd2b571, 0x776a0ea1, -0xc3023262, 0xc7e2241e, 0x9a3bf11a, 0x10685917, -0x05f63bf9, 0x7515a7cd, 0x354df431, 0x9fe23aa6, -0xe7dd2ce1, 0xfd3f4c4e, 0xb8175841, 0x2a33e9cd, -0xb31a26b8, 0x2becb6ae, 0x960637fe, 0x88d5d321, -0x88dbbe41, 0xdb3c0412, 0xaed4333a, 0xf5553d5a, -0x64323f5a, 0x2eeaadca, 0x819df2e5, 0xf45b6d56, -0x7d027108, 0x2f49ed39, 0xbfd62d0c, 0xa0a64a08, -0x0b06d96b, 0xc4459fe8, 0x404028e9, 0x560a808e, -0x68d481c2, 0x1062ab83, 0x51ffc2c7, 0xbc762820, -/* 983-m02f0a15.inc */ -0x00000001, 0x00000015, 0x08212002, 0x00000f0a, -0x63e49a0c, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x80e0e61a, 0x7cb2c607, 0xbe1e2fc9, -0xacaf1526, 0x31514e28, 0x9252d426, 0xb999ebf8, -0x8469bb8a, 0x95e72fd2, 0x5f7c5472, 0x254adcf0, -0xf706b236, 0x21ef3efb, 0x82d05526, 0x8b10bd77, -0x268ab8bd, 0x929739a5, 0x0f180e02, 0x3ad1cc5a, -0x23a10814, 0xbc4257f8, 0x026ded8d, 0x84bf45be, -0xe13e69f3, 0xbb0edf16, 0x85218fd2, 0x898af4e1, -0xcd635f26, 0x846ab0c6, 0x85a5d5cd, 0x077b4a16, -0x71514de0, 0xbff893a6, 0x47536ab0, 0x1fc4b546, -0x906f4b85, 0xc1f997d5, 0x0ba4b594, 0xa823eb50, -0x416ee239, 0x659b0dbd, 0xf240ad67, 0xe042d532, -0xce92f455, 0x9f318d9f, 0xac11fada, 0x6fc234ab, -0x18cddb76, 0x67e52b4f, 0xa6f01943, 0xba695e2a, -0x245bd123, 0xce05288f, 0x6582101b, 0x5be73a23, -0x6ab67d0e, 0x873ac6f3, 0xab4c48f2, 0xe0d64284, -0x65f33ddb, 0xd33abb56, 0x8dd411c3, 0x86f370ea, -0x1c3726b9, 0xd561edb5, 0xa0484b79, 0x63bdccd0, -0x54d42183, 0x05d9b9c2, 0xd1d2e489, 0x572f0b07, -0x6b804808, 0x9ee441c8, 0x87e1e425, 0x0d4d3c3e, -0xbb9188fd, 0xa7f1243b, 0x807be6fb, 0x8f828057, -0xfe37dd84, 0x104ef504, 0x5aa650b4, 0x2f1b611f, -0xd021e808, 0x1d4ca877, 0xdefabd4d, 0xaa0cbe35, -0xa4e89854, 0xa880cfc1, 0x08ed71f1, 0xb58e8625, -0x2f4bee9d, 0xfef8678d, 0x2868ade1, 0xcdd1c7a4, -0x2b823a15, 0x4788ea69, 0x7a1de61f, 0x24a51210, -0x4373e00c, 0x7f8e55c9, 0xb2c5092b, 0x74f9e0db, -0x2f54f62d, 0x13e3b1c8, 0x835863dc, 0x7401feb0, -0x82d9962c, 0xc321a358, 0x8db3eec1, 0x3d70aa8a, -0x9e8d115a, 0xd1f258ce, 0x3db0262c, 0xdedf4ecf, -0x2b43787d, 0x01bba4ab, 0x5533bfb0, 0xf25756a2, -0x6748ff85, 0x49a04cf9, 0x15a3fceb, 0x2b0045b1, -0x354d82dd, 0x51baaaae, 0x9cdb8826, 0x4a5e79d5, -0xc0b783a0, 0x244ee819, 0xc9d7ec82, 0x61b5df6b, -0xa3b0ab47, 0xf4201580, 0x16a9bda3, 0x2ac3fb2a, -0xf2d45287, 0xc775c470, 0xca49165e, 0xf011aa96, -0x7cc3f776, 0x128e7d4c, 0x53a7cb48, 0xc678c16a, -0x704d85ff, 0x5ac3438c, 0x22a4255f, 0x06f4eb73, -0x6d2c4918, 0x7ec8d353, 0x02f64898, 0x402caba1, -0xa2dcd74c, 0x2ec84768, 0x19aaacb3, 0x641e9f60, -0x610245fb, 0xbcde5b34, 0x5b2ad9e6, 0x26d2e619, -0x3c5f7fc3, 0x8a4644e1, 0x6cc1f8fb, 0xb2ec0e52, -0x02186480, 0x1c597a86, 0xea7cb92f, 0x8484972d, -0x90f10aef, 0x7032ba2f, 0x8d51693a, 0x075f7010, -0xef88324e, 0x5fbf378f, 0x1416ae8a, 0x5eac1f31, -0x70e65677, 0x0224e031, 0x1305f1ac, 0x53209b14, -0xb5037676, 0x99e958fb, 0xecb8fe97, 0x20fb5890, -0x568e98e9, 0x87d42ce4, 0x03de50e2, 0x89728dac, -0xdca95447, 0x36114e7b, 0x2aab8e7a, 0xa0529d9c, -0x9901c79d, 0x4ff191b5, 0x7500cebf, 0x210bcc07, -0x815fd1e8, 0x4ebd3be0, 0xbce22cf0, 0xcf2df323, -0xfffa8eb1, 0x016b1ca2, 0xf87846a6, 0xddbf1474, -0x435c41b5, 0x56245808, 0x050eace9, 0x128491f7, -0x48c6fdda, 0x5775ded7, 0x0b4775a1, 0x7ce11409, -0x0d9822a0, 0x084ca742, 0x8f2c8c8b, 0x4278fdfc, -0xe45d26c7, 0xd92793fb, 0xe963acf5, 0x346473ea, -0x28069586, 0xcd7423ab, 0xdd07fab1, 0xf2dd3f15, -0xf924720b, 0x0047adff, 0x3935bd42, 0xde1d799f, -0x03a4afd9, 0x4f0ea217, 0x5f3dd4df, 0x09f611a1, -0x8ecf894c, 0x5111dde5, 0xd79db940, 0x4e2da85d, -0x64622e3d, 0x00ed0f85, 0x192b2af6, 0x526fcc87, -0x3e233c92, 0xdfa9d04d, 0x5a8a7d19, 0x18205eef, -0x3ff5734e, 0xf3ba744e, 0xac73c051, 0xc2cf8a70, -0x3ba41433, 0x123eb210, 0xe3f05134, 0xcfd54fd8, -0x7995e0d1, 0x1760b323, 0x310a7810, 0x2706d0c8, -0x15cf732d, 0x3c0ee597, 0x83e36338, 0x272058a7, -0xff3e9fda, 0x0c22fe44, 0x11a26627, 0x061a17a0, -0xd784b930, 0xb40ed3ca, 0x014eaa98, 0x2cfd7ef7, -0xd3f700a6, 0xa2e0e5ad, 0xf6682e43, 0xbab69f7a, -0x185c3430, 0x10a4a66d, 0x41698b7a, 0x89666812, -0x1cdc431a, 0x301a8774, 0x056fa032, 0x08e5b4ac, -0xd8e66808, 0x06cb04c2, 0x086f09ef, 0x09404e44, -0x4b166a00, 0x1f244ff1, 0x096548b7, 0x3d066268, -0x11c22583, 0x87d98b53, 0x83c785d8, 0x0c295204, -0xa3693e8d, 0x8ca5c952, 0xa52c8190, 0xa9ac34de, -0xe640e56f, 0x16d5715c, 0xf40bac7c, 0x940d757e, -0x0955d322, 0xbd3e2f65, 0x6553293f, 0x0b25fcb7, -0x14875a5e, 0xb5efd0af, 0x79cf151f, 0xa74e5acb, -0x4b249263, 0x14a844ff, 0x4c547880, 0xb598f6b8, -0xe9fffbc6, 0xe983f09b, 0xa5384013, 0x36baf1e7, -0xe3a76c06, 0xde3df31a, 0x25d38aaa, 0xc19d9fa9, -0x2c05457a, 0x0a4fd8f6, 0x01086f65, 0xdf7e10b3, -0xa5f16786, 0x46d77f4a, 0x08336cd2, 0x1d06cb5f, -0xe453696c, 0x6f662a90, 0x40d33558, 0x76c640d5, -0x4e7e4c97, 0x10cb0f79, 0xb1cfbb1c, 0x4f3f0521, -0x8cda32ee, 0x84c3e958, 0xaac41cc9, 0x023e7572, -0xf3266bf6, 0xb4193d39, 0x3a31f7df, 0xbd83c248, -0xc812df3c, 0x0af7f510, 0x82bb61f9, 0x95db6415, -0xf7b12fa8, 0x7a7f4f9c, 0x2ec8f061, 0x3fa8e99c, -0xc19bea78, 0x470c4315, 0x0bcf3abe, 0x787b97b7, -0x78f992b4, 0x05a7b74c, 0x93fc4db2, 0x41094fe3, -0x3e7fe41b, 0xa367bc2d, 0x90b393db, 0x3ec58fe0, -0xb74cc79f, 0x9ed83f74, 0x10daeeae, 0xa524f1ac, -0xafcd0f29, 0x11423945, 0x52319e75, 0x9978031d, -0xa78bb8be, 0x1a8a86d8, 0xf9a5c6db, 0x15d9760b, -0x00028056, 0x2d0f7fc3, 0x7734d88a, 0x1b877e63, -0x7b1db862, 0x25037d9d, 0x5a210d59, 0x1875f3e4, -0x0299248c, 0x90ae4f18, 0x949d7d41, 0x713deba7, -0xa6ff8ffe, 0x243c5296, 0x6020828d, 0xe420ae82, -0xf02eeda6, 0x3a8090e3, 0xaef23b89, 0x40d2cb8a, -0xaaddddad, 0x220c269f, 0x288d2d4e, 0x8689e116, -0x42de5c86, 0x95ff5e35, 0xdcaabe42, 0x3fbb05e5, -0x4ade7e4b, 0xd6612d65, 0x44ad598c, 0x984eeabb, -0x218696b2, 0xf9c83206, 0x881e3b4e, 0x54844f30, -0x1f980f2a, 0x0aec3158, 0xdd92450c, 0xb8a3906d, -0x0ccc7c23, 0x196b48db, 0x08ffaef9, 0x2c44b86d, -0x05fcc149, 0x079869d4, 0x5f3f5d0b, 0x1086de9f, -0x638432c5, 0x1dbe89c0, 0x882041a8, 0x05a6756a, -0x306e76ea, 0x49ad9a0d, 0xbc24d1a9, 0x2a113e7d, -0x75f3c2fd, 0x48a08a9f, 0x49629224, 0x78bc1e06, -0x6cf37a29, 0x350cf5be, 0x44139fa4, 0x8d46fe52, -0xab806472, 0x942992a6, 0xd17e2f91, 0xe2141f73, -0xfa427c43, 0x8faa955f, 0x1a46e5e1, 0x3565549d, -0x614a5a2f, 0xce97ff83, 0x11c7054c, 0x079587e3, -0x08c226bb, 0x33d4dfc4, 0x01e29a03, 0xfe8383f7, -0x4896c322, 0xc2b8bf34, 0xeb519cd8, 0x87a369b6, -0x2896c199, 0xf31cda89, 0x95882efc, 0xcf69e53c, -0x27fbdd3b, 0x8491be72, 0x866ba50e, 0xf63845c1, -0x74862a52, 0xd27ee1ad, 0xa20b324c, 0x34481857, -0x7d154913, 0xcdfaf533, 0x86c43d02, 0x84a53719, -0xc686aeaa, 0x3b1c1991, 0xd2757700, 0x7c0300e5, -0x9a79cf8b, 0xb5cf5135, 0xa515be91, 0xde62d956, -0x15075fe1, 0x50e9c78e, 0x4b411050, 0x03e28d50, -0xe86bf955, 0xc760da3c, 0x9c1645d7, 0x29f8de00, -0xe2905e2f, 0x3755c59e, 0x2c2a0a58, 0xd4f48945, -0x78f6c3c5, 0x3d7ca7ef, 0xf3bf6b34, 0x6a42e9df, -/* 359-MU166d06.inc */ -0x00000001, 0x00000006, 0x03121999, 0x0000066d, -0x5a11f8b1, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x5438e02a, 0xac0baef5, 0xf9af9ee5, 0x7daa9469, -0xc72a2473, 0xed1bc9f3, 0x0a5b4dfd, 0xf04f2cfd, -0xd6c32dc9, 0x23309edb, 0xf3afb18c, 0xdbc53f4c, -0x29db6ed7, 0xdff96f41, 0x8ce7acb8, 0x3d2bfd5e, -0x8beb4597, 0xb91f261e, 0x1faef98c, 0xa1c19c06, -0x9d0ba2f2, 0x21f025c1, 0x946df216, 0xaf4cdaeb, -0x18548806, 0xbfc15b01, 0x95fae116, 0x3dfbd428, -0x8843cbe6, 0xb1dc2df7, 0x36a6d1ee, 0xb5334ca4, -0xfda770fc, 0x0cbca559, 0xf48e7cc2, 0xf54eb67e, -0x4024db53, 0xbf714641, 0xd4975b91, 0x0e0f66da, -0xd0b27e7f, 0xd8563c7c, 0x0758ffcc, 0xd876e9c8, -0x9a3f0365, 0x0a6b995d, 0x980275f6, 0xb181ab45, -0x06cb2f41, 0xb001af81, 0xbd6bcee5, 0x09bc6806, -0xf9e3f297, 0xb352816b, 0x462611ca, 0xdc6d5552, -0xbdb5af42, 0x6689779f, 0xd1e348f7, 0xbe74550e, -0x2d19da39, 0xdd1f8553, 0xf3baaa2d, 0x0907706c, -0xdc8fb8a3, 0xdba419ed, 0x0086c036, 0xd5d3ae68, -0x93c55fcd, 0x04a1ae8d, 0x9afe94eb, 0xb96489ac, -0x09a60b6c, 0xb3d0c99b, 0xb4e1072f, 0x0afad454, -0xfa453558, 0xb09ee184, 0x4a31efeb, 0xdfcd940d, -0xb13cde6c, 0x64962b75, 0xd47bd3d1, 0xbd963b9e, -0x2219d435, 0xd244d090, 0xf21378af, 0x0faf36f8, -0xd2794a73, 0xd5318695, 0x0ec5272a, 0xd22a3506, -0x91a9ad03, 0x0d59901c, 0x9e57c7e7, 0xb55e7c49, -0x0925b26d, 0xb95d2a8c, 0xbdc13885, 0x035bf2db, -0xfead6a85, 0xbcac5c7e, 0x4fe8bf18, 0xd847f308, -0xb4eff243, 0x6e82abea, 0xd174e54a, 0xbac0865b, -0x28e70f71, 0xde040c76, 0xfb529490, 0x084911ed, -0xd2f91422, 0xdaa64854, 0x0c7eaf9e, 0xdefdbaac, -0x9132b630, 0x0a9b6342, 0x9de92427, 0xbed14ecd, -0x090fc874, 0xbc6a926e, 0xb19d1dd0, 0x0c7c92b5, -0xfd9a9fb9, 0xb688faf8, 0x4c848221, 0xd2c427bf, -0xbf128678, 0x6c185794, 0xd07a1ee3, 0xb966f436, -0x2f741a19, 0xd3de45c4, 0xf65148fe, 0x0f4e7e86, -0xd2e39990, 0xdd7556b8, 0x04392416, 0xd47f4676, -0x97107c76, 0x05e43678, 0x9b25ef6a, 0xb7aa1e88, -0x0c6afeec, 0xb9255789, 0xb2b414cd, 0x0a22b967, -0xf095af1a, 0xb854fa48, 0x42f3a9bd, 0xd0fa341c, -0xbcf0ca66, 0x6aba8362, 0xdb58dba7, 0xba6ddb6d, -0x23d32744, 0xd3eec90e, 0xf1c62281, 0x038fa057, -0xd66aacd5, 0xd05d164a, 0x061ff1a1, 0xd928d8bc, -0x96588418, 0x02c45cb6, 0x9dcb3ea1, 0xb3b9ce27, -0x08b10dab, 0xb01dfe0e, 0xa2f4cb9e, 0x8eb386f9, -0x0e6e8abb, 0xae9f10a1, 0xa8f3102c, 0x9b7550fc, -0xa56f673c, 0x38f6bcb5, 0x93b14bb8, 0xe586077f, -0x321cee2c, 0xd6aef87b, 0xe707d1d2, 0x32354de0, -0xd0ebeabe, 0xe5c5458d, 0x1b203412, 0x8ef41355, -0xc755edd0, 0x4546df73, 0x8c9145f4, 0x6065fcf2, -0x491779ac, 0x26a4c7cb, 0x65ba6bc5, 0x191cef28, -0x2f8d1fc5, 0xc259a55c, 0x19b8cd78, 0xd90b3d5b, -0xc78d366a, 0x10ad9c8a, 0xd61a969e, 0x268b96a5, -0x125232e3, 0x38224f2c, 0x2fa6b4fd, 0x1db52ece, -0x3c86b9c7, 0x2048a10b, 0xe7ca7b91, 0x17f5aeb1, -0xdd8dcc96, 0xc9c71faa, 0xefd34be3, 0xd4f4dac8, -0x37b10389, 0xe015ce04, 0xd1db5065, 0x05418033, -0xed8b22e1, 0xe242b352, 0x51f4d0c1, 0xac0cae18, -0xbbb5d914, 0x1f755f53, 0x7b4c7d10, 0xefefa07a, -0xcd461f2a, 0x2d464311, 0xe8ccc9e3, 0xf3a14b4b, -0x2942e286, 0xd6490328, 0x46201fae, 0xa0792235, -0xc5517483, 0x1022100d, 0x7e4a2c0c, 0x7acbd787, -0xd0b803e2, 0xe57d5e6e, 0xf06d89f0, 0xe2cf8b74, -0xf9738fb2, 0x724bd029, 0xfddbd156, 0x9e05f522, -0x191feedf, 0x59b48812, 0x60f5d73f, 0x3b420bf7, -0x0baac57d, 0x24f20b27, 0xa3f7efce, 0x78ee2b7e, -0xa25e08ba, 0xee5f647c, 0x43f8b240, 0xa00b7761, -0xf6da02ec, 0x6c69c94f, 0x33e43cfb, 0x3f3abf64, -0x1e1ad77e, 0x5c99bcf1, 0xbf7ff97a, 0x45a5e379, -0x3b6c8705, 0x4e8bb4e3, 0xce65e064, 0x7e1fb79f, -0xf3797330, 0xcef73cbb, 0x87103d74, 0x6a066804, -0x3f4462d3, 0xf2ab9a30, 0x51c5f393, 0x7c565cf2, -0x9f2405da, 0x418ff11f, 0x3bae40bb, 0xb49f9ed0, -0xadc9f958, 0x01a0e781, 0xb9c8020e, 0x9a11ba27, -0x133e4b83, 0xe1f5c968, 0xcbe377ce, 0x966c23a2, -0xd7e17fa4, 0x05c02d15, 0x7fb1895f, 0xb10a1c06, -0x176e1233, 0x6f4216df, 0xd3b3893e, 0xa9de1442, -0x13f47cbb, 0xcadd9d3c, 0xfa49790c, 0x74739159, -0xa8d9b9f0, 0x9a0a0cc8, 0xfca5cd8c, 0x12ee9077, -0x1de249a5, 0xbe558c3a, 0xbdd5b2a0, 0xd1056ae4, -0x5a27b4c5, 0x6464406e, 0x5dbdcf47, 0xdf0f3a0d, -0x77179167, 0x4ef7f05b, 0xfc1b89a0, 0x4cf5bb75, -0xb37c06ba, 0x81e62916, 0xdb83caf0, 0x653bb4c5, -0xc677d10e, 0x4d1de1e1, 0xe4634396, 0x67f9d7cd, -0x927fc5d7, 0xb7a3a00e, 0x87fe2f14, 0xa5e6266e, -0x3867d7a1, 0x4a9c1b17, 0x03729809, 0xfb49d6b4, -0x8a559a23, 0x3c386097, 0x02b21c37, 0xab05b6cc, -0xdecd4628, 0xfac77846, 0xa38c3080, 0x999810fa, -0x43a83da5, 0x17b487fd, 0xd8a3e4e4, 0xe8120fa8, -0x11120fa9, 0x927977b5, 0x2c782885, 0xef1ba162, -0xdc97fc66, 0x83b01586, 0xe45b8da2, 0x99fddcca, -0xcc19f92c, 0x2804b9ae, 0x837b8d9f, 0x218de4b1, -0x48ce346f, 0x4b406a7e, 0xadde4cfa, 0x27404bfd, -0x124a19bb, 0x13428075, 0x6b5ddf57, 0x301ff9b5, -0xb171d5c4, 0x2afeca28, 0xcab20b74, 0x7fcf8d05, -0x4b885a5d, 0x4d843055, 0xe4658f32, 0x538c4131, -0xd525e274, 0x30fbd9d1, 0x3ddde395, 0x7d2451a8, -0xa53bf61a, 0xd1a3cf94, 0x8c5780bb, 0x5e03ddf1, -0x6811ee83, 0x1cd220bb, 0xd7e5a1e8, 0x42304db3, -0x7249f9fb, 0xfbf5867c, 0xfe79897a, 0x1b4234b9, -0x73db9ff7, 0xbf958830, 0x96d444f2, 0x9b6bb6ed, -0x8b17c507, 0xea4f1f55, 0x3391f0f5, 0xb0796c55, -0xb7aa2eda, 0x5bdddb7d, 0x06287d43, 0x5ecbc51d, -0xad8d8847, 0xdc098664, 0xe1e5f0b6, 0xfc5fed8a, -0x0820e537, 0x05be47e5, 0x9eee2d56, 0xcbc83208, -0xdd11c6be, 0x91f849f4, 0xdd3d3443, 0xf72de322, -0xaf679f11, 0x02cedcaf, 0x27a7e9bf, 0xeb55b97c, -0xc285d57c, 0xae701a4c, 0x76dc5928, 0x1298b9e3, -0xcd254a73, 0x2a240b27, 0x145e78ff, 0xefe9993c, -0x0c565b83, 0x154a49b5, 0xdd896ee6, 0x99d3a097, -0xb67d6763, 0x44562693, 0xe69353a2, 0x957a1116, -0xce61d1e0, 0x4bda4c75, 0x7d8c770c, 0x11980805, -0x561a87ea, 0x6b79e439, 0x8d54242a, 0x817de2cd, -0xe2140396, 0xd8f538d7, 0x60a7e51f, 0x981a22f4, -0x8c1bd013, 0x6b23db67, 0xc51f4727, 0xa2ebd226, -0x46528dae, 0xa4f44720, 0x8e241ea6, 0x4510662f, -0x8e2d75df, 0x206c055f, 0x77fe4b1c, 0x923824f2, -0x7f805f32, 0x59ac5198, 0x6ac7fb2b, 0x89b0087a, -0x4772415d, 0xd9e73d6b, 0x1d767093, 0xf15922f2, -0xf783392a, 0xc2715489, 0x18d84435, 0x90af82a1, -0xb8900c90, 0xb7adc0d2, 0x1a8e2a13, 0xcbc595f0, -0x5dc62e9f, 0x2c1bee3b, 0xd817354d, 0x9e460f6a, -0x57ae4385, 0x0b54aedd, 0x21cc9c23, 0xf67349b4, -0x072a2495, 0xc501def4, 0x65d1fbf9, 0x70282b9c, -0x7072643e, 0xb7ed88d7, 0x93341d4c, 0x6fd88c08, -0x4e185215, 0xfcf788fc, 0x5ccc37c1, 0x9d8c1602, -0x84017ec9, 0x9213b205, 0xdc4db616, 0xbfe9acb0, -/* 662-MU168a01.inc */ -0x00000001, 0x00000001, 0x11022000, 0x0000068a, -0x80fc9e3b, 0x00000001, 0x00000010, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x4efad552, 0x58a399f1, 0xf144f845, 0xfdb9117d, -0xb230677d, 0x1136f756, 0x8298a1b2, 0xb0c9cffc, -0x1e77875e, 0x2ea286ab, 0x6943a0b5, 0x41e37874, -0xfad4205d, 0xbc2d4993, 0xe5ac11e8, 0xa81a4aa8, -0x977a1e24, 0xd78cb1a7, 0xea9b7600, 0x280582ee, -0x04779e3e, 0x4af7afda, 0xeba0b976, 0x40f8ed1c, -0x9801c81d, 0xf500eb15, 0x74eb0918, 0x9b17c81f, -0x9d5dd38f, 0x17410757, 0xf843bed3, 0x2c401670, -0x6a428a9d, 0x28640d65, 0x35840c58, 0xcae15773, -0xcad83b47, 0x304765ea, 0x36da3de4, 0xaca34c0f, -0x61950b2a, 0x13ff21a5, 0x0817c1bb, 0x7e68e7a3, -0x89d484f7, 0xa2c84945, 0xbdd500eb, 0x0f7aaaef, -0x43b3cc4d, 0x55aaf9b2, 0xb8e9831f, 0xf093b0b9, -0x8266e028, 0x5242bbd4, 0xccd1f798, 0x385ee185, -0x15b897df, 0xedcc4e3e, 0x5028068b, 0xe3fc6555, -0x24c2ded3, 0xf9ddf6aa, 0x1256f316, 0x21829113, -0x17bd6a35, 0x252bdbdf, 0x9d356e62, 0xe02c900a, -0xa3f04a7d, 0xd607feeb, 0xb2938296, 0x63192310, -0x0aa601be, 0xe75ba498, 0xe844f6cc, 0xd9016ef6, -0x0ee53a7b, 0x4109ef16, 0x06f14b3a, 0x28185283, -0x97abaed9, 0xb6aaf076, 0xdb485b2d, 0x64213aa4, -0xd95491d1, 0x79495ede, 0x0f6d13d2, 0x409172b3, -0x71ff4426, 0x39482f22, 0x7411a8a8, 0x1d33b47f, -0xd1b42e84, 0xec7754cf, 0x89116c0f, 0x2c09c658, -0x99c8564f, 0x6b901f71, 0x83a077bd, 0xd50ac9fe, -0x53427f66, 0x93447a6a, 0xa72bfaf2, 0x33e743e8, -0x240588c1, 0xd74f75fb, 0xbf90f7a5, 0x75c3c8a2, -0x9d0c5193, 0x43b92dd1, 0x2c00a47a, 0xfffce742, -0x5d3ac1fa, 0xcdc46584, 0x712af8c7, 0x3733fe09, -0xbb301419, 0x2bb6a944, 0x3edd7c53, 0x31157d4a, -0xba14f3a0, 0xa385a286, 0xa6ac6f44, 0xb09ee00a, -0x4fb68608, 0x5eba43d6, 0xeddde198, 0x688e46eb, -0x4f4cef08, 0xd3dd5f9d, 0x8c0d995b, 0xb1688d6d, -0x40f050f3, 0x064f8c26, 0x2acbc04b, 0xe3be1052, -0x81765ee9, 0x38ec4036, 0x4aebe9e4, 0x700aee4d, -0x0ddee69f, 0x32a8240c, 0xf1aadda5, 0x79d64bf0, -0x79bca80b, 0x42ba8186, 0x5093b355, 0xc6bc148a, -0x60bbbcf0, 0x58843416, 0x68fe124e, 0x551551b5, -0x2ee3310b, 0x3fe684e4, 0xd2669d2f, 0x6d32a6ec, -0x3c038661, 0xdfce797f, 0xb44f91b9, 0x6b054e2c, -0x6c8a55b0, 0x53d4f5cf, 0xa9ef5cc9, 0x6a1497e3, -0xdad943af, 0x7ac80ff7, 0x0a233ada, 0xdd162f79, -0x654e8707, 0x6e0d72dc, 0xa7f16610, 0x64af2199, -0x43cbc05a, 0xa082d85a, 0xa0ecc319, 0xed5fb102, -0x50e03123, 0x1e691374, 0x76cca719, 0x96a54140, -0xe637f7ac, 0x0bdceb2c, 0x2509562e, 0xdc493727, -0x9ae44e2b, 0xbe7c82e6, 0xdd903312, 0x16182680, -0xab131706, 0x00753d5a, 0x4f018f8a, 0x768bbd06, -0xda089985, 0x9ec0bf68, 0xcf0ca6d6, 0xef21a479, -0x10f990bb, 0x976257b1, 0x448acbd0, 0xd6a49e41, -0x146a9f84, 0x1c462ffe, 0xc1e13fc2, 0x33a89da1, -0xefe418ba, 0x2157e31e, 0xc9dab388, 0x7a5175f7, -0x8fca565c, 0x3badf7fa, 0xb6b3ad3c, 0xcdc7c3db, -0x75c1db40, 0x9f93463f, 0x869e7c18, 0xe3841a98, -0x47f4b382, 0x5b708e12, 0xb704f263, 0x0977410d, -0x510dad8c, 0x6e6e5abb, 0x523171ed, 0x0641bebd, -0x03f8ab45, 0xffb1561a, 0xbac7c413, 0x893143e7, -0x78f8702e, 0xf3a1a5dc, 0x154f9e24, 0xecee7df8, -0x887b465c, 0x31ea2f2d, 0x58e06b7f, 0x3e53c9d3, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1069-m04f122e.inc */ -0x00000001, 0x0000002e, 0x05022003, 0x00000f12, -0xb2548d0a, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0xe6b36263, 0x6f9eaf78, 0x632770bd, -0xb11f8920, 0xbc42e776, 0xbd797134, 0x9768e716, -0x1dce3da1, 0xe0dbe21b, 0x30349ee3, 0xb0aae4c6, -0x1591358e, 0x6646707a, 0x147f6ddc, 0x639c59e3, -0xed11c0d6, 0x2707c252, 0x8053be8a, 0xb432051c, -0x941732da, 0x80e55dca, 0xf389d8f4, 0x738a68e3, -0x85f7042d, 0xe1904f35, 0x1e2e7f3d, 0xf1d4b55d, -0xf9829802, 0x0b8d6394, 0x252d74ca, 0x7b6a0be4, -0x13ec2030, 0x7d8c3429, 0x32380fdb, 0xb595854c, -0x6ab18d3b, 0xfe241438, 0x79ee3c90, 0xf7c80ed2, -0x9735dffb, 0xbba18676, 0x2687be0c, 0x9fb2e5ef, -0x28f85fb1, 0xea0b3223, 0xf1e3f263, 0xffd47414, -0x86a09efc, 0x3b23b61f, 0x03600e24, 0x0f59519b, -0x8868d3b5, 0x1cd3ddcd, 0x174364a6, 0xced7c4ea, -0x637cf55d, 0xab80c838, 0xb2ccd05c, 0x968f8d6f, -0x77f66b77, 0xdf34ebcb, 0xfece6f5e, 0xb819e030, -0x1d73c1d0, 0xf6d86e15, 0xfed82c81, 0x4ac93249, -0x4358711e, 0xe558a942, 0xc19f602c, 0x3d51db79, -0xbc5b9f59, 0x1dcbf598, 0x09326724, 0xae712704, -0x686bb2d8, 0x8cb848bf, 0xd1f00d90, 0x6cebdd80, -0xe9827e3b, 0x7ffc9a62, 0x52851c33, 0xd9f6d8b7, -0x89294625, 0x5cc9e522, 0x416df615, 0x7b4b8c1d, -0xa819df83, 0x458483f8, 0x12c2a1c8, 0x3219f4be, -0x20a99f23, 0x30c8cb2b, 0x0284107f, 0xcaf74794, -0x3b8408e5, 0xe3915f05, 0xfe89b7f1, 0x3b30f859, -0xf6c214a4, 0x53ea7021, 0xf1ae6ce6, 0x300771c2, -0x7c769103, 0x59c4f9ec, 0x954321c1, 0x0010217c, -0x60f87712, 0x9531a33c, 0x6516e8b2, 0x7e6af0e1, -0x159c0a30, 0x5c0df59b, 0x2763d9c5, 0xc5c08122, -0x80be5172, 0x96d9c015, 0x227f4d84, 0x104ad707, -0x7cd7de50, 0xc58e569a, 0xd2129ffd, 0xe9afedf3, -0x61e19908, 0xecd27e20, 0x36ef4ae8, 0xcda53aff, -0xdfbd8a65, 0xaad6eef6, 0x3720e8cb, 0x061f85c6, -0x60643ad4, 0x0e3cd18c, 0x9d19ec4f, 0xec94bb30, -0x9f53ebe5, 0x3f591c58, 0xdb015450, 0xade7e0c7, -0x305be3b2, 0x4cb29bc5, 0x7b57cbb4, 0x3aa89078, -0xfbe6e43d, 0x0b761e6e, 0xed8b5baf, 0x3b4e756d, -0x6a148c9f, 0x1a3a01a8, 0x1d33ac7a, 0x3e3dd3e2, -0xbfb4392c, 0xca1ce690, 0xd1af4a34, 0xa931d9c3, -0xa86836be, 0x34d86f8a, 0x21cb75f0, 0x37c152a4, -0x95b9c9a4, 0xc30f3c29, 0x1b821c8e, 0x637851df, -0x069cc4f8, 0xd88ead11, 0xf5f5728d, 0x1b0ffed7, -0xfd846742, 0xf76f607d, 0x5d8a4740, 0xad48d963, -0x6a9ffcc0, 0x1b320e79, 0xc49b22c3, 0xde2c0048, -0x5fcaddfe, 0x708e63ca, 0x294d5d69, 0xa3dce328, -0xb847b4d2, 0x611c0a2b, 0xcd4513c8, 0xfa1bfa75, -0x45ca8ca2, 0x3681b381, 0xc27f6c94, 0xcd958d01, -0x7b55386f, 0xa4b2c59c, 0xaa58ef1f, 0x752c6c71, -0xdd97125c, 0xdfc2881a, 0xb9d5036e, 0x5148d9ff, -0x24e6b06d, 0x8390116a, 0xea6d4d44, 0x7378ffef, -0xd1833cf6, 0x3415528c, 0xcf3622fe, 0x76729d17, -0xcd1ba4ad, 0x1885ed72, 0xde02375a, 0xa49131ff, -0x3be6df31, 0x6cf2c534, 0x90aacc16, 0xa2eda106, -0xa7aaecef, 0x5831a9fd, 0x5f142437, 0xaf30f7fc, -0xc8f6cdab, 0xda69d12d, 0x5871249f, 0xc011e372, -0x33c8e75d, 0x8087d9fb, 0xc595c587, 0x9cc36c3e, -0x676b2c58, 0x4f242c1b, 0x6b77d07c, 0xa1c8543b, -0x2824e9c7, 0x84be15a4, 0xc0b4a308, 0x0e41511b, -0xfaf3dbbe, 0xc1777e7b, 0x199d042b, 0xb0b35558, -0x9bf8cb58, 0xf68d5c43, 0xf359b550, 0x993d82d1, -0xa8388458, 0x56d3c256, 0x11cbc33f, 0x3c28a56f, -0xe6aa09f9, 0xd41f6c39, 0x11020cd2, 0x985c89db, -0x3705b46f, 0xaf90c2dc, 0xf7ecfc96, 0x355eee96, -0x078e9048, 0x2fd05bf1, 0x48eab9e0, 0xafaab712, -0xcf0c3e12, 0x8095ae6d, 0x8364131e, 0x7221ba38, -0xad0e42d6, 0x20741356, 0x8698ad29, 0x024d1baf, -0xb87c4a77, 0xa4169a47, 0xa487c4c8, 0x966a2b68, -0x9821bace, 0xe64b1014, 0x22eda535, 0x4cc48e4e, -0xb1a80833, 0x0e9ec179, 0xf6bb1c55, 0x95489311, -0xefe8a663, 0xc4cf14f9, 0xe3591c5d, 0x86c3c61b, -0x9fe18d90, 0x3b75ff1b, 0x5ca3d992, 0x8c072f42, -0xecf16b8e, 0x672b72c7, 0x4603e497, 0x45e015d4, -0xd918406b, 0x4f25a635, 0x5feb56b4, 0xf9f94d06, -0x7bd31a73, 0x1ab03fc0, 0xb85fdbd8, 0x4c3e81d9, -0xefc2c666, 0x59a7afcd, 0x8a02428a, 0x73af7adb, -0xd8ea36e0, 0x991a6fd9, 0x7f9c2019, 0x2d3a85d6, -0x8f3295c0, 0x93809471, 0xa5d313f5, 0x8cd5ea3b, -0x7b982971, 0x5e4f0172, 0xcedcb6e6, 0xea24e209, -0x8a46f8b2, 0x74331527, 0xd77ed523, 0xaba69d6a, -0xebd38b4b, 0x04c01b27, 0xcf51542c, 0x25e75d87, -0x69f4e24a, 0xeb1c3f81, 0xdd4508da, 0x0cc85856, -0xd006d573, 0x79a7c5cb, 0x1cc2e951, 0xd1ac0710, -0xa78fbeba, 0x90877b5f, 0x7972ab18, 0xd866ac15, -0xc287620f, 0x54fdeb69, 0x9c2d264f, 0x6c2e6ff9, -0xa12c2962, 0x87f99490, 0x5a9f5f5c, 0x5fd88f09, -0xf6b7e966, 0x02abc4f2, 0xde5eddd1, 0x6ccd06e7, -0x7747ee88, 0x9bc9622a, 0xb807d839, 0x1d14fe6b, -0x1c4676e8, 0xb9add7e1, 0x5a84fc84, 0xa0d232ab, -0xf09b95a0, 0xbd7481db, 0x9f68639a, 0x4870d114, -0x60ebc8a5, 0x42d4d24b, 0xf64d2815, 0xaab0da5f, -0xcba7f41c, 0x44dcd89b, 0x613d50e6, 0x180e700c, -0x18a6bdad, 0x54883f08, 0xa0a9fc4b, 0x9af3ec0b, -0xba3f74f2, 0x9469aa23, 0xc89de01e, 0xe7963adb, -0x8cb13661, 0xdbbd276c, 0x42e113df, 0x4947dfd7, -0x513cc410, 0x57c6db1c, 0x8911377d, 0x01405fa9, -0x7163e406, 0x995a0db3, 0x2e9b208b, 0x4c77dfbc, -0x33f30f4c, 0x5aad99da, 0xcca61b32, 0x027fa2ce, -0x2b5387aa, 0xafca9d2b, 0x7fbe4c67, 0xee92fc72, -0xc3857c05, 0x5e425769, 0x4ae6558f, 0x499427f8, -0x15900b70, 0x3aae1260, 0xa7bfc2a1, 0xdfa73e71, -0x8b79b206, 0x6552c432, 0x56b81866, 0x86d6e834, -0x91685add, 0x7c34051c, 0x4ef8db74, 0xbab855ee, -0x083ab156, 0xc82a579d, 0xec1e3ae3, 0xdfea24a6, -0x9554ee6e, 0xd53b8bd1, 0x9a4bda63, 0x884e86e5, -0x9acf4763, 0x540b9ded, 0x5fde4bca, 0x541d2dd4, -0xc5637486, 0x5fdfc527, 0x6cc50628, 0xc701a605, -0x7fba696e, 0x053a6cd0, 0x3796571c, 0xd11ec6f6, -0x2a653ec1, 0x69a1ade5, 0x16171235, 0x3aa406c1, -0x825d106f, 0xb2f62dd2, 0x5aa895d9, 0xac55d308, -0x3f01278d, 0xb6153d8a, 0x98cc1fa3, 0x65327e2d, -0x7dd8e033, 0x9c399398, 0x94a8f0ba, 0x4336f0e7, -0x87f425fd, 0x8f1d3e0d, 0x05ff65d4, 0xe4a1a06a, -0xf5dd16e6, 0xc4bcdc31, 0x363f2b98, 0xcd01dfec, -0x442c1d49, 0x3a5cb899, 0x0ea2945e, 0xa91470dd, -0xb629ae00, 0x2a25ffd7, 0xaf24dcea, 0x4bf22512, -0x2f4c1a13, 0x9d76a33e, 0x28a3e7b7, 0x17ea3463, -0x0a831542, 0x1ae4a98a, 0xcc8066c9, 0x51b4e2a1, -0xa030bf19, 0xa19596da, 0xe0e5af95, 0x86a6f7a4, -0x6f51d56f, 0xed2d0511, 0x31a1430c, 0x6a9fd0d7, -0x481515f9, 0x423cb82a, 0x3811455c, 0x475610cb, -0xdecb5b82, 0x52bd1ebe, 0x3373db79, 0xdc7c458d, -0x462cf8cc, 0xfe353c25, 0x91dc7f41, 0x60b84709, -0xc29de95b, 0x97acf20e, 0xdba91f15, 0xbb26e2cd, -0xbb150856, 0x5683c1cf, 0x6bc7ffbf, 0xa00deea3, -0x5a1c103d, 0x2b0d6b33, 0x241c3306, 0xf86d7e81, -/* 531-mu26732e.inc */ -0x00000001, 0x0000002e, 0x09101999, 0x00000673, -0xa5945abf, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x608ab600, 0x7653aba3, 0x90cf06df, 0x2cb405de, -0xe4c59cfb, 0xe6c669e7, 0x3aa728ba, 0x83d3111f, -0x892fc321, 0x2566fbdb, 0x8c37ee68, 0xbfbe902e, -0x58c979b3, 0xe18b8acb, 0x8d0d319d, 0x4b0ed465, -0xf4f644f7, 0x847da89c, 0x587df5fd, 0xa3aed418, -0xb8b811cb, 0x0330bc99, 0xe8167486, 0xa00d6d3a, -0x77bfa90d, 0xbaa76e96, 0xf9098d1c, 0x3320799a, -0xcf8409f1, 0xe176caa8, 0x4f0319a8, 0xb4952500, -0x967781c1, 0x63834cab, 0xc6e650d3, 0xed9dd97c, -0x3007ef9a, 0xa4fe2c6e, 0xf45fe99e, 0x6b3e6506, -0xf2cdd2f3, 0xb59c79c9, 0x14c6ed40, 0xa5148f5d, -0xf5fde82e, 0x3bcfe380, 0xd4530539, 0xf29c478b, -0x0783cd9f, 0x804ce845, 0xb9f62a6c, 0x2ae018f8, -0xd7c42c7d, 0xe2106e84, 0x0954ef6e, 0xbdf3275f, -0x96d8f3a3, 0x127c0bfc, 0x9b459637, 0xae1c6dbc, -0x52986367, 0x8ce39f67, 0x9460054a, 0x012da826, -0xe6a663f5, 0x9b7d890e, 0x7954aa8e, 0xc92ef63b, -0xbfe64a51, 0x7ad32697, 0xa42480dc, 0xd904d833, -0x7e8fc827, 0xeab91ad0, 0x869b7a18, 0x496c1157, -0xd07db5d6, 0xc4befd10, 0x692303f2, 0xb7219baf, -0xaf54123f, 0x7def51a2, 0xb284536c, 0xd67c0f8f, -0x02b5ed18, 0xbccb127d, 0x92139fc2, 0x1e70a3fb, -0x84fde186, 0xe3e678e4, 0x3f04793d, 0xefbfd6e5, -0xce8eb13f, 0x60c77646, 0x966d3b7b, 0xc3e7a620, -0x4447e93c, 0x8f604fc1, 0x91c17b22, 0x7f232650, -0xb5efc2da, 0xb2280f8d, 0x519fcedc, 0xaec0722a, -0xf0d35d60, 0x63c82715, 0x9cfaacb5, 0xf57e3bd3, -0x4a7ea75d, 0xc228bac7, 0xa1e89e6c, 0x58c8a391, -0xdaee8c6e, 0xabc21b13, 0x341e7a59, 0x9ad9d0b9, -0x85d4e8fb, 0x25d0c528, 0xeb4a572a, 0xf95a39ac, -0x3a409cf8, 0xde9db56f, 0x9782b8d2, 0x664b82cc, -0xf070e3ad, 0xa4231202, 0x01c2423a, 0x9855d0bf, -0xc2af813a, 0x4cc77c96, 0xd5d25658, 0x960a18ae, -0x59ead120, 0xb07bb96a, 0x8a95ab68, 0x3026dafa, -0xc4ba3959, 0x92ab62c2, 0x75b4328c, 0x9fb9fbbe, -0x8baf8268, 0x6d18e002, 0x87fe6aa8, 0x8bbaa231, -0x09c2001d, 0x80e8353c, 0x821a39a8, 0x08b46ff9, -0xd6caf0ae, 0xa59e0122, 0x6493d7fc, 0xa5121d9c, -0x9906b736, 0x361c9427, 0xb9fdc3f8, 0xad0575be, -0x08b6f080, 0xc46399a9, 0x85013609, 0x066ecc06, -0x878870a9, 0xc2d8b6cd, 0x529b03c3, 0xaaa98ba2, -0xfd7d4381, 0x0651145b, 0xb3a5ef25, 0xfb2d55b5, -0x29f7c000, 0xc6cf8717, 0x32ea5099, 0xaab306df, -0x3657ef2c, 0x20a16efa, 0x51ac482a, 0xd6a62e1d, -0x47742893, 0xb3b3e105, 0xbfdfc488, 0x015f4adf, -0xbf6842aa, 0xed18f4df, 0x3c4ccaa2, 0x4923ec46, -0xa77a5258, 0xea143daf, 0x6c2915cc, 0x87c99911, -0xb54207f5, 0x676a7ae4, 0xf54539db, 0xba8530d9, -0x4a92a4d0, 0xa16b254c, 0xfde1b3c5, 0x0f39e80a, -0x8f091bc5, 0x9c3256ca, 0x32b2e9c1, 0x3e6f0d8f, -0xc747f7e3, 0x97425a47, 0x53155de3, 0xda67575c, -0xd918d8e1, 0x54a36761, 0xe3dd3bcb, 0x6c50eb67, -0x6083a5f8, 0x6f23b175, 0x175539b8, 0xd1033c16, -0x4b1cb096, 0x5e251620, 0xc9982976, 0xa5f08673, -0x6d5cb971, 0x7c7dca0b, 0x952f1155, 0xdc82a0e3, -0x06cd25cd, 0x3a46effd, 0x0fc83360, 0x88713e82, -0x9ecaae82, 0x9363878d, 0xd1ab7241, 0x8444f2f6, -0xdc440056, 0xb4ad62c5, 0x9f5f5897, 0xf1f3a779, -0xbae6be03, 0x3086cd06, 0x9d828a06, 0x4b45af5f, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 737-MU16b11c.inc */ -0x00000001, 0x0000001c, 0x02152001, 0x000006b1, -0x6506e1cf, 0x00000001, 0x00000010, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x3ff8d1ac, 0x6ad5a5d7, 0x41bc1a2f, 0xc0cfcf98, -0xae80b685, 0x4e7fdba5, 0xee70aae6, 0x857f82df, -0x4c12ad1c, 0xc6eab058, 0x849e97b8, 0x4b425e5a, -0xe6819908, 0x8134a945, 0x601aea2a, 0xc633b991, -0x8f9e395f, 0x4699cb55, 0xcbc3795e, 0x85561846, -0x6f4f5e1f, 0xcf0cf38f, 0xac133e0c, 0x4bbe51fc, -0xc340f285, 0x8c63f67d, 0x45160027, 0xc85a74bb, -0xaeb95e32, 0x4f4fc61d, 0xe5033858, 0x8e4e090f, -0x4b5acb2a, 0xc75bc00c, 0x880daabb, 0x43d6f6af, -0xefd1d4e8, 0x87575a65, 0x6ef3afc2, 0xc8062d96, -0x8945ca80, 0x41c583c3, 0xcbb2f0a7, 0x8661bdce, -0x6d21f128, 0xc24acdc4, 0xaeaf43d5, 0x46dcbcd3, -0xcf544779, 0x82ea3983, 0x4b1656e2, 0xc3a0de21, -0xa14ded06, 0x4e779174, 0xe01de86d, 0x80c33ba8, -0x44762085, 0xc74f0d93, 0x85ca1cfa, 0x4dc7752f, -0xe0c2bfd0, 0x853e48b1, 0x67f42503, 0xcfed157c, -0x8d33cb2f, 0x43eb149b, 0xc71e279a, 0x82561424, -0x60cc4578, 0xce0d779d, 0xa6254192, 0x43e5a2cf, -0xcaee4715, 0x857afd44, 0x45ad93fa, 0xc6043ebf, -0xa98f3eee, 0x4f8e481c, 0xee5d3fe4, 0x84e30c80, -0x464de23b, 0xc76af7c3, 0x8155a3cb, 0x4a425a2f, -0xe3fd06a4, 0x8b51c2ec, 0x61bda6b9, 0xc71d76c2, -0x8bd436d3, 0x4e4a5c77, 0xc2cffcfd, 0x833c6a3c, -0x65d4f768, 0xcbfe0635, 0xa9bd7c0a, 0x49d3018a, -0xca646403, 0x8776d3d2, 0x426a93f7, 0xc03b8393, -0xa8e7690c, 0x46d7b40c, 0xe6a47d18, 0x8b927811, -0x4febdfe3, 0xc38a9d51, 0x8f76a603, 0x49d5cc1c, -0xe79861ed, 0x8d4c5baa, 0x6c7da6df, 0xc157063a, -0x87dbd994, 0x472dff09, 0xcc1742f2, 0x8de8e9c7, -0x641ab500, 0xc437013a, 0xaeaedc04, 0x492e9f4e, -0xc3de047e, 0x8dbd801d, 0x4cfd2f32, 0xcc34102c, -0xac06dbb4, 0x4ac3f30b, 0xe83b3458, 0x8634b95b, -0x444079d2, 0xc807d487, 0x8da4cd9e, 0x4760f318, -0xec62523f, 0x816240b9, 0x6cba09ce, 0xca86a264, -0x863f14ca, 0x49b9d4a1, 0xc6bd9715, 0x87edeb98, -0x6fa1a092, 0xcb36670f, 0xa2edb3a7, 0x43545378, -0xc3c35ad7, 0x8e2d1255, 0x4a06377c, 0xcd1b61d4, -0xa83a9bc7, 0x4c48d28d, 0xe8a27b8a, 0x8a47665c, -0x49a35371, 0xc8a8fb0a, 0x830dc900, 0x4c01d1bc, -0xee2ffff4, 0x83243d8d, 0x61ead599, 0xc82c0451, -0x8c19b0ec, 0x465ee1d4, 0xc52df943, 0x8490687c, -0x68474c0d, 0xcc495773, 0xa04396d5, 0x4824c02c, -0xceb15f4d, 0x80a78140, 0x4de85a0b, 0x8945e8c5, -0xc981ea75, 0x7ff89629, 0x4e4ce4e2, 0x6e9ceb88, -0x7f0b4dff, 0x165e46c8, 0xcf59bf6c, 0x9c430db4, -0xb55a941c, 0x277a73f1, 0x6dbffb22, 0xb3081fe8, -0xdebe60c6, 0x691d8c9e, 0x330333a2, 0x0b024599, -0xe358aa28, 0xe70334b3, 0xe48d7707, 0x16318df8, -0x0e34f491, 0x1c0d6223, 0x54315b5f, 0x040fcc96, -0x5557f1d2, 0x5ccf28f6, 0xc0004404, 0x2f7a5fef, -0x95b65ddd, 0xbaa1a873, 0x077783d4, 0x3f24b63b, -0x9ae679fe, 0xaf11d97e, 0x51391564, 0xb3247855, -0xcd10e6dc, 0x704e147c, 0xcc15de9d, 0xa5adf161, -0x0179c9a6, 0xa579d74c, 0x28704a4d, 0x3e7a2d92, -0x253437c4, 0x1162b521, 0x14a9c51d, 0x2129abbe, -0x3b2d07c4, 0x1d84f76a, 0x016cd356, 0x3fd03cad, -0x3f82ee67, 0x0275b51e, 0x5dd38dae, 0xdd022704, -0x6b6d2f56, 0xbdb25b55, 0xe4188d73, 0xc03a6c98, -0x8a303586, 0x4999d605, 0x82c9e7e8, 0x8169c654, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 615-MU16860a.inc */ -0x00000001, 0x0000000a, 0x05042000, 0x00000686, -0xf3bb1079, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc6586232, 0x277d54d5, 0x4f7ef8fb, 0xcef7ac22, -0xafee0e72, 0x4a9e0934, 0xe7695725, 0x8e285007, -0x43a4a8d1, 0xca144dd9, 0x8da2b518, 0x4c6d74d3, -0xee363815, 0x8dda7522, 0x6369e4b9, 0xc7c48080, -0x86ecc6af, 0x44076855, 0xc9135988, 0x80b2a4a6, -0x654cbe11, 0xc314db83, 0xa04e60d8, 0x4434829a, -0xca630037, 0x863dba4b, 0x456b3656, 0xc81b5036, -0xa757768c, 0x42657f3e, 0xee28655e, 0x8acb7fc2, -0x4d3f1153, 0xc727c830, 0x8d83dadf, 0x4337ed65, -0xea82a648, 0x8b0ed272, 0x6e1d5d2d, 0xc89ca234, -0x88162543, 0x4509f20b, 0xc4246893, 0x897c8837, -0x6ce85470, 0xc289a8b6, 0xa7b752d9, 0x44740264, -0xc338d34d, 0x840cd712, 0x4d254023, 0xc9bd3b4c, -0xaec6fe45, 0x46a93c90, 0xeba68ac4, 0x8661a9bf, -0x4ceabe79, 0xc306abe8, 0x85063cf1, 0x4bc76d54, -0xeae61c29, 0x8d44a15b, 0x66237e93, 0xcd3d3258, -0x8ac002d2, 0x40ec33d2, 0xc1e9e690, 0x85ba7ab9, -0x6dcb9946, 0xcd8e5656, 0xa4574bee, 0x4618c900, -0xced94234, 0x8fa66dc2, 0x43674822, 0xccadd163, -0xaee4a680, 0x473f1952, 0xee0b507b, 0x826c5327, -0x4f1b2e4a, 0xc5545ee4, 0x81491d47, 0x4ac38596, -0xe89e1b72, 0x81521383, 0x6b81f877, 0xcbf08fef, -0x8b650447, 0x45f055aa, 0xc9486656, 0x85578a8b, -0x63654c15, 0xc2af788c, 0xa233a356, 0x4c8d3793, -0xc064bed5, 0x87ff0732, 0x4b5dc58d, 0xc0c6c854, -0xac243f64, 0x4da1178b, 0xe7afc726, 0x83d3db2f, -0x4ffb7e67, 0xc99377ab, 0x8c41ac2f, 0x47fe29e9, -0xed122282, 0x838f214b, 0x6e5e72ea, 0xc1f608f0, -0x86a943f6, 0x47145486, 0xcf3c8179, 0x81052692, -0x635b3226, 0xcc85c969, 0xaa5ce1eb, 0x47e6fcf9, -0xc5cc35c4, 0x89ac6258, 0x479fac3a, 0xc973764a, -0xa016e339, 0x4c1b7a87, 0xee98daae, 0x8edc812f, -0x412b4bee, 0xc25c289d, 0x8046a1c6, 0x488629e4, -0xe91c1a3c, 0x8fb3f214, 0x651e4ec9, 0xc74eac7e, -0x8524b474, 0x4030530f, 0xcb056d74, 0x8c0ac837, -0x6a40ec66, 0xc74d14ad, 0xab9f4dd1, 0x459394be, -0xcfa36a50, 0x8e3cbebe, 0x4c5ee2fb, 0xc98e93b1, -0xa9931b6b, 0x4d7e4737, 0xedd1f9a0, 0x8416989d, -0x465230dc, 0xc53d307d, 0x88081eb6, 0x450cc861, -0xec50e8f4, 0x813ebc03, 0x60c24916, 0xc054909e, -0x8e9a180f, 0x49733b4c, 0xcdefdaa6, 0x83d68d71, -0x6242222e, 0xc9dba65d, 0xa3cccfc5, 0x4e4a1f40, -0xcc900c57, 0x8ff2de70, 0x48e12407, 0x5de722dd, -0xcce5593d, 0x808ee900, 0x418756c9, 0x47de05b7, -0x85d9207c, 0xc21bc623, 0x44cebac0, 0xde933434, -0xcfaa4ccb, 0x1b56dcfe, 0xd9b94c1c, 0x30ee76ed, -0x1fc5ee45, 0x25ec6f82, 0x31faa1b4, 0x56adf5d2, -0x2aded395, 0x7248b2d4, 0x57c8710c, 0xa08f21da, -0x71284cb3, 0xde2154a2, 0xa2604dbf, 0x19d224f3, -0xdf868867, 0xc7856703, 0x149f27ba, 0xe9c687c4, -0xc1003175, 0x22d08b5a, 0xe6e67fc6, 0x357a7981, -0x2d83592e, 0xeca25638, 0x38dfd98a, 0xf1116012, -0xefebfd17, 0xe1fe908a, 0x7a9a518b, 0xc7174264, -0x6dfc5c6f, 0xacbf3bcd, 0xcbcf1983, 0x8dd961dc, -0xa1ea4015, 0x22886fed, 0x426bef9c, 0x89976657, -0xeff39b00, 0x6403ca75, 0x27dd4d41, 0x1a7e4e6e, -0xcd8db1cc, 0xd0534459, 0x8d784b83, 0x990e1efa, -0x4183683a, 0xd8a1cac2, 0x1b04d7d1, 0x8a53f9ae, -0x5af9a50e, 0xdf0f6d46, 0xc307f2ec, 0xcb272d1d, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 412-MU16530d.inc */ -0x00000001, 0x0000000d, 0x05181999, 0x00000653, -0xc28f9258, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xfcfae324, 0x355315ed, 0xc89ef542, 0x63841659, -0x3c7c348e, 0x72c60a98, 0xabf29b87, 0x3bcf46b2, -0x85c9c5fd, 0x99e2bbf8, 0xa7e7803a, 0x32ae3caf, -0x7591a794, 0x408861ae, 0x14b31bd0, 0x06bece05, -0x20ad4eff, 0x2e4b7bfe, 0x82c1a02a, 0x1c19b338, -0x8c3078a2, 0x8da2bbbb, 0x395ac3fb, 0x879e34d0, -0x61f4384e, 0x399b3f11, 0x4e27b881, 0xbed3ce7b, -0xe385bb3d, 0x36616016, 0xb701b47c, 0x3b5e632d, -0x31470408, 0xd0b588c1, 0x2ef42409, 0xe272ffa8, -0xfadb8d9e, 0xa02391cb, 0x278bf424, 0x0487391f, -0x2a1fbf75, 0xbf9e565b, 0xdc04f70f, 0x205e3b9c, -0x26503a0c, 0x4ed040bd, 0xcb7e1985, 0x5d057e57, -0x8e22af97, 0xf0de9058, 0x44e78e45, 0x2447cf34, -0x8372f0f0, 0x2a52c75c, 0x6bff4c35, 0xbcffce46, -0x07ef2734, 0xb5cee8e6, 0x4ede7dab, 0x49f5d0b5, -0x4f25b91d, 0x51148c59, 0x6ad97fb4, 0x366d1763, -0x7e52600a, 0xfa3ac4bf, 0x91ab7601, 0x743211ab, -0x52196684, 0x0b2e1efd, 0xad54278d, 0x1a824f50, -0x90c09495, 0xd9cb86d1, 0x2c4e5005, 0x0aef93f6, -0x2ffd9ca7, 0x0a09a406, 0x1cdb4d4b, 0x4a873b20, -0x9c85c6ab, 0x9e1220d3, 0x1fc343b6, 0xbea0c2c1, -0xf8a24157, 0x541ff346, 0x280c3d6a, 0xe8459a8b, -0xa9f6430b, 0x0c6e5ba1, 0xe7da7b03, 0xac7a218c, -0x9108cb65, 0xec79380e, 0xec3bb1c7, 0xaf0c4bbb, -0x866eb11d, 0x16d6f13b, 0xe1ee4d0e, 0x74df8063, -0xbcbb0fc6, 0x0f6cb60c, 0xb446bdda, 0x1c129ad1, -0xfc3b9f9c, 0xce0672f9, 0x720d1665, 0x99217438, -0x80a6d584, 0xd07e188a, 0x64d53940, 0x5928d1fa, -0xd5b24c6c, 0x8cb04a04, 0xac747437, 0xa7a20909, -0x0b57768b, 0x6c4437e8, 0x72ea1c95, 0x2aea4e76, -0x96c9f8aa, 0x8917d477, 0xab747d6e, 0xc2c12858, -0xaec4035a, 0xb641abed, 0x89637037, 0xc4c2394b, -0x251f679d, 0xb9d0d6f8, 0x06da24d1, 0x2ad6c123, -0x16324a11, 0x9fb6e487, 0x67885199, 0xbf3f7eed, -0x22847933, 0x5d2ec8f4, 0x4a08914c, 0x7ed70790, -0x5d6709a6, 0xfd73a3a0, 0x78295ddc, 0x67a4f723, -0xd0fc4363, 0xda50249d, 0x4c8586e8, 0x001aefe8, -0x4ddb0a45, 0xe19ad425, 0x51eff9f3, 0xd6c3ee2d, -0x45bd8490, 0xca34b967, 0x46e68112, 0x98e08fe7, -0x5ead54e9, 0x1f12298e, 0x82a1e421, 0x4826f80c, -0x2e488608, 0xe103caf6, 0xc8be1e00, 0xd69ce416, -0xa791a5c7, 0xfccad928, 0xa15ce378, 0xd5890d56, -0xbfe7b822, 0x8e33f92a, 0x1847193d, 0x06619365, -0xbf12a9f9, 0x9c1dbff3, 0xf70fe13f, 0x73267ae6, -0xbf73df95, 0x2067879b, 0x7323b730, 0x8c28f88a, -0x49769dfb, 0xebdbd925, 0x44f1d0bd, 0x2f379983, -0x76eac858, 0xfd6f8777, 0xed431ae3, 0xf656af10, -0xb245e033, 0x91c45641, 0x3ceb2809, 0xefe9f9c3, -0xae156659, 0x4e11a25e, 0xd96bceae, 0xd03e9342, -0x966300d4, 0x2763c143, 0x6d7cb136, 0x30013a68, -0x99c07c40, 0x7c53ba71, 0x0e034e01, 0x78974bdd, -0x5793f65b, 0x27bde07c, 0x84ccc31e, 0x8169d813, -0x1477c316, 0x2da18290, 0x64b686d4, 0x6bc7d9ff, -0x73b2c749, 0xa97f8161, 0x189bc202, 0xee2ace64, -0xadb6a179, 0x4c13950c, 0x69f7c438, 0xc1265fe7, -0xe7b7d517, 0x48ebf4c6, 0x76528cf4, 0x18f820d6, -0xa3eaf9da, 0x1de7d37a, 0xe27ba2c6, 0x48fe45e1, -0xf110770d, 0x4caab774, 0xce2990ac, 0xe7878e0b, -0x5b9764cd, 0x6706217f, 0xf2121426, 0xcb5a9df1, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 692-MU168a05.inc */ -0x00000001, 0x00000005, 0x12072000, 0x0000068a, -0xb82bbbc1, 0x00000001, 0x00000080, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x41347bd8, 0x911d1af5, 0xbf990226, 0x21c0248e, -0xae9c9087, 0x8ae67595, 0x04e0310d, 0xa3e9215a, -0xafbc70f4, 0x1042c1bc, 0x96d7567d, 0xb056e38f, -0x12e3b314, 0x8671b0bb, 0xb8280b8e, 0x17c0582a, -0x864bef4e, 0x898fffe2, 0x02210693, 0x93159cea, -0xa7e2f15d, 0x3cfa0fdc, 0xa7423ecf, 0xbf0a256d, -0x3e69431a, 0xb5fb1776, 0x99be8001, 0x05b07adc, -0xb394b1a6, 0xa674d032, 0x07e83a6a, 0xa6ab4c4e, -0x8af11f6e, 0x20286de7, 0xbd9bbc1f, 0x8c6a09e0, -0x342e30a5, 0x9d4cb289, 0x908edce5, 0x39aeafa3, -0xb34ba5ac, 0xaca163d8, 0x37588926, 0xbc5e56a7, -0x8459e3c2, 0x0b3b9ff9, 0xae97715d, 0x88969d8c, -0x3e75d4f3, 0x9498328f, 0xb6f537c2, 0x018c631e, -0xae215c90, 0xbdd6b8a0, 0x09857c7d, 0xa9836d89, -0x940c13b6, 0x25e44062, 0xbc9e2608, 0x99c96188, -0x2eac1954, 0x85874d2a, 0x970ecbde, 0x192fc565, -0x8abc734f, 0x80bd71ce, 0x01dc441c, 0xbf71b84a, -0x9e736705, 0x2dadd0ef, 0x8ba9a609, 0xa00f9d9a, -0x0abc4362, 0xb816f372, 0x8db28c8c, 0x35bcdaea, -0xbdd153c3, 0xa42c5de5, 0x2935db78, 0x8aba1a25, -0xaed0899b, 0x354b0560, 0xa5819406, 0xbee34a2b, -0x1442293c, 0x89853e8d, 0x87360b9d, 0x1a965d79, -0x8388a852, 0xaeb2903a, 0x1bb2212e, 0x89083e53, -0xa640f91c, 0x086e68a7, 0xb15460a3, 0x83476357, -0x1d240330, 0xb86cc2a7, 0xb76e5b61, 0x1730c3be, -0x92b5494b, 0xb2feab3e, 0x129f6107, 0xbbf8b20c, -0xa73c326b, 0x3aa98258, 0xae3195ac, 0x91e12887, -0x3c06eee4, 0xa9e8c42c, 0x8c6be8e5, 0x25a315c9, -0xa14d1cfa, 0x87bd5cb1, 0x08674a93, 0x917ed650, -0x8f2aa2dd, 0x2f45fe2b, 0xab9480cd, 0xb4935ed1, -0x212f60f9, 0xb8ec56b4, 0x8d0e7f5a, 0x2c3f8cea, -0x86961452, 0x9ccdae56, 0x159818e6, 0xb96b4352, -0xb7cd6212, 0x3f2d6c56, 0x8825661b, 0xbc9172af, -0x2e3a93a2, 0xaeade4a7, 0x9ec4c420, 0x10c6b354, -0x95bc6ad4, 0x8dda8b59, 0x0cf1d120, 0x9d89ec8d, -0x8c4c5d61, 0x310352af, 0xae1a306e, 0xbdc79b88, -0x1973679e, 0xbbfc21e4, 0x82210224, 0x1f5e405b, -0x97947e94, 0xb050f500, 0x21e01c36, 0xacf12a75, -0x9ddefc1b, 0x26127f57, 0xbdd5a967, 0xbad4c987, -0x12a6f074, 0xaba8f359, 0xac21deb9, 0x10a11f38, -0x88ed207c, 0xb9314cb9, 0x034c2c2a, 0xadf14cb5, -0xa4d24fe3, 0x39f571fd, 0x8c3d9ec4, 0x8f7f8e7c, -0x03381979, 0xae96a1d0, 0xc838a487, 0x851b445d, -0x12423402, 0xc5ba17c8, 0xc6c3f5af, 0xf1d8bba3, -0xcf9e5715, 0x2b98c03c, 0xc7d43a12, 0x04b5c31e, -0x0f177aea, 0x0e40ed42, 0x2481d35b, 0x0c9d57fa, -0x284d6c07, 0x14c680bb, 0x380af49d, 0xaa351008, -0x04f24363, 0xb6382b7a, 0xad315d2b, 0x490d6a3f, -0x8ba682dd, 0xd2cd8f95, 0x6270d114, 0x0a114a39, -0xf0882611, 0xe1711220, 0x20921556, 0x01469a6a, -0xe5ee16d0, 0xf3565705, 0x01786889, 0x7e5198c8, -0xdf188aff, 0x631c25ca, 0x73d2953c, 0x56f7eb7f, -0x6946d516, 0x1ecf52c6, 0x7080c634, 0x978d321c, -0x0f112244, 0x90a5c4d9, 0xba85c68c, 0xda699171, -0x9cc834d3, 0x7836026a, 0xf455ee1a, 0x5e6868c0, -0x5ec93697, 0x0641249c, 0x1305fc1c, 0x62ff2eb5, -0x7cd7299e, 0x1e12a8b4, 0x67ea1393, 0xeccd8544, -0x2df22cd2, 0xf3862164, 0x40c38c62, 0x6f983460, -0x59238962, 0x27384d47, 0xd2b26031, 0x951fb69b, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 550-MU168307.inc */ -0x00000001, 0x00000007, 0x10151999, 0x00000683, -0x1c5efd4b, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x1a7821a0, 0x5c7f704b, 0x8e78e37b, 0x50c22d14, -0xd7937431, 0x51820d98, 0x5cad6308, 0xec5e3721, -0xd41ee66d, 0xb01a24c5, 0x5ff960ce, 0x3c922ad2, -0x709ab11a, 0xebb95fab, 0x2db73b5a, 0x20945fd3, -0xa81b0257, 0xbf8155d0, 0x04fd273f, 0xc077c5ae, -0x1da50ba8, 0x307bda81, 0x5923ff70, 0x103828c6, -0xaf83cdca, 0x2f3c561c, 0xd5cb85b8, 0x1a807114, -0xc241322b, 0x4e401582, 0xe2567b0e, 0xad093555, -0x4c182287, 0x14ac0b2d, 0x90cf1541, 0xedce3c25, -0x05da049b, 0x0985b6a0, 0x1f9e9be4, 0x994b2d6d, -0x68d04ab3, 0xe2aa006a, 0xeecb3773, 0x5a7c271a, -0x0ac949d2, 0xa3668ff0, 0x97c326c6, 0xc05d483c, -0xbddd9812, 0x9b823a6f, 0xb3b94ebd, 0x00ba7054, -0x7f96f49c, 0xfe29574a, 0xcc79bed8, 0xebbd89a2, -0x6a0f4007, 0xc3ba70bd, 0x92ed4aba, 0xeb17fcd7, -0x8c65dc38, 0x538035a3, 0x1f16c77a, 0xd816d9fe, -0xc9054761, 0xb2867d05, 0x8a3cefa0, 0xebd91eb2, -0xbb43e990, 0x193bc028, 0xdccdc90b, 0x5e76a8fd, -0xa80a4aca, 0xe370a88f, 0xb4981ab9, 0x7cae2227, -0x8e3052e1, 0x1784fe28, 0xc4007b0b, 0x4871dd0d, -0xa606e0aa, 0x2e9e19e5, 0x770a64e0, 0x8e173235, -0x2452fa0d, 0xd8ca8e56, 0x912ae38b, 0x713a1325, -0xc8cee2c6, 0xc728742f, 0xc6571e00, 0x2b1b3cdb, -0x358965d4, 0x19357f16, 0xdcd504b9, 0xfb35fadd, -0x9d511335, 0x7642b9c1, 0x47f1226d, 0x6e5c9b37, -0x37cf651c, 0x694bb058, 0x110004c6, 0x351dc396, -0xca6828a8, 0xe477af88, 0x97bb399a, 0x60b23e3b, -0x02bcde6d, 0x67f48e58, 0x09cdb6c6, 0x231ab666, -0xc46482c8, 0x29991ee2, 0x542947c3, 0x920b2e29, -0xa8de7681, 0xa8bafe26, 0x5ce72e46, 0x1a51784e, -0xaaac80a4, 0xc02f7328, 0xe5743d23, 0x370720c7, -0xb905e958, 0x69450f66, 0x1118c974, 0x905e91b6, -0xff337157, 0x7145bec6, 0x64d2014e, 0x7240872b, -0xbb43e990, 0x193bc028, 0xdccdc90b, 0x5e76a8fd, -0xa80a4aca, 0xe370a88f, 0xb4981ab9, 0x7cae2227, -0x8e3052e1, 0x1784fe28, 0xc4007b0b, 0x4871dd0d, -0xa606e0aa, 0x2e9e19e5, 0x770a64e0, 0x8e173235, -0x2452fa0d, 0xd8ca8e56, 0x912ae38b, 0x713a1325, -0xc8cee2c6, 0xc728742f, 0xc6571e00, 0x2b1b3cdb, -0x358965d4, 0x19357f16, 0xdcd504b9, 0xfb35fadd, -0x9d511335, 0x7642b9c1, 0x47f1226d, 0x6e5c9b37, -0x37cf651c, 0x694bb058, 0x110004c6, 0x351dc396, -0xca6828a8, 0xe477af88, 0x69c96661, 0xd3298179, -0xbe41ad76, 0xb3397e64, 0xede18b2f, 0xc9d46419, -0xb1f0487c, 0xc1957106, 0x6a1544c2, 0xbd8c9352, -0xbe63dbd6, 0x56032dab, 0x3afc824e, 0xd2b9bd8e, -0x3cdf7aa8, 0x05a65e2b, 0xf5754a4c, 0x3686c208, -0xaf304450, 0x6fe2b358, 0xb24b9535, 0xbc7c85bc, -0x090fe7dc, 0x1f6f78ee, 0xf620e00c, 0x4c723c90, -0xa68330e1, 0x3f6d625e, 0x3e70e19a, 0x1a4c4273, -0x67658f78, 0xcf51048b, 0x41a50d62, 0x59dbd4da, -0x50b3f115, 0x14590456, 0xbb3a3f9e, 0xb56b5947, -0x3c774967, 0xce1de1f7, 0x6123b871, 0x317cbf4c, -0x8730d79b, 0xa56d2631, 0xab312243, 0x29ddc7e9, -0x9fb56d0c, 0xf58cefc9, 0xf13bd652, 0xc31b5ee5, -0x29e957b0, 0x93152de5, 0xc44ccf17, 0xe13c8e66, -0x882d583e, 0x44b2993a, 0x9274016f, 0x767f7670, -0x233ae532, 0x6ef6694b, 0x89800e05, 0xc479ac7c, -0x8f5b4d18, 0xffab875d, 0xc1e6cf41, 0x9222f8e4, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1068-m01f122d.inc */ -0x00000001, 0x0000002d, 0x05022003, 0x00000f12, -0x22ba6824, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0xe6b36263, 0x6f9eaf78, 0x632770bd, -0xb11f8920, 0xbc42e776, 0xbd797134, 0x9768e716, -0x1dce3da1, 0xe0dbe21b, 0x30349ee3, 0xb0aae4c6, -0x1591358e, 0x6646707a, 0x147f6ddc, 0x639c59e3, -0xed11c0d6, 0x2707c252, 0x8053be8a, 0xb432051c, -0x941732da, 0x80e55dca, 0xf389d8f4, 0x738a68e3, -0x85f7042d, 0xe1904f35, 0x1e2e7f3d, 0xf1d4b55d, -0xf9829802, 0x0b8d6394, 0x252d74ca, 0x7b6a0be4, -0x13ec2030, 0x7d8c3429, 0x32380fdb, 0xb595854c, -0x6ab18d3b, 0xfe241438, 0x79ee3c90, 0xf7c80ed2, -0x9735dffb, 0xbba18676, 0x2687be0c, 0x9fb2e5ef, -0x28f85fb1, 0xea0b3223, 0xf1e3f263, 0xffd47414, -0x86a09efc, 0x3b23b61f, 0x03600e24, 0x0f59519b, -0x8868d3b5, 0x1cd3ddcd, 0x174364a6, 0xced7c4ea, -0x637cf55d, 0xab80c838, 0xb2ccd05c, 0x968f8d6f, -0x77f66b77, 0xdf34ebcb, 0xfece6f5e, 0xb819e030, -0x1d73c1d0, 0xf6d86e15, 0xfed82c81, 0x4ac93249, -0x4358711e, 0xe558a942, 0xc19f602c, 0x3d51db79, -0xbc5b9f59, 0x1dcbf598, 0x09326724, 0xae712704, -0x686bb2d8, 0x8cb848bf, 0xd1f00d90, 0x6cebdd80, -0xe9827e3b, 0x7ffc9a62, 0x52851c33, 0xd9f6d8b7, -0x89294625, 0x5cc9e522, 0x416df615, 0x7b4b8c1d, -0xa819df83, 0x458483f8, 0x12c2a1c8, 0x3219f4be, -0x20a99f23, 0x30c8cb2b, 0x0284107f, 0xcaf74794, -0x3b8408e5, 0xe3915f05, 0xfe89b7f1, 0x3b30f859, -0xf6c214a4, 0x53ea7021, 0xf1ae6ce6, 0x300771c2, -0x7c769103, 0x59c4f9ec, 0x954321c1, 0x0010217c, -0x60f87712, 0x9531a33c, 0x6516e8b2, 0x7e6af0e1, -0x159c0a30, 0x5c0df59b, 0x2763d9c5, 0xc5c08122, -0x80be5172, 0x96d9c015, 0x227f4d84, 0x104ad707, -0x7cd7de50, 0xc58e569a, 0xd2129ffd, 0xe9afedf3, -0x61e19908, 0xecd27e20, 0x36ef4ae8, 0xcda53aff, -0xdfbd8a65, 0xaad6eef6, 0x3720e8cb, 0x061f85c6, -0x60643ad4, 0x0e3cd18c, 0x9d19ec4f, 0xec94bb30, -0x9f53ebe5, 0x3f591c58, 0xdb015450, 0xade7e0c7, -0x305be3b2, 0x4cb29bc5, 0x7b57cbb4, 0x3aa89078, -0xfbe6e43d, 0x0b761e6e, 0xed8b5baf, 0x3b4e756d, -0x6a148c9f, 0x1a3a01a8, 0x1d33ac7a, 0x3e3dd3e2, -0xbfb4392c, 0xca1ce690, 0xd1af4a34, 0xa931d9c3, -0xa86836be, 0x34d86f8a, 0x21cb75f0, 0x37c152a4, -0x95b9c9a4, 0xc30f3c29, 0x1b821c8e, 0x637851df, -0x069cc4f8, 0xd88ead11, 0xf5f5728d, 0x1b0ffed7, -0xfd846742, 0xf76f607d, 0x5d8a4740, 0xad48d963, -0x6a9ffcc0, 0x1b320e79, 0xc49b22c3, 0xde2c0048, -0x5fcaddfe, 0x708e63ca, 0x294d5d69, 0xa3dce328, -0xb847b4d2, 0x611c0a2b, 0xcd4513c8, 0xfa1bfa75, -0x45ca8ca2, 0x3681b381, 0xc27f6c94, 0xcd958d01, -0x7b55386f, 0xa4b2c59c, 0xaa58ef1f, 0x752c6c71, -0xdd97125c, 0xdfc2881a, 0xb9d5036e, 0x5148d9ff, -0x24e6b06d, 0x8390116a, 0xea6d4d44, 0x7378ffef, -0xd1833cf6, 0x3415528c, 0xcf3622fe, 0x76729d17, -0xcd1ba4ad, 0x1885ed72, 0xde02375a, 0xa49131ff, -0x3be6df31, 0x6cf2c534, 0x90aacc16, 0xa2eda106, -0xa7aaecef, 0x5831a9fd, 0x5f142437, 0xaf30f7fc, -0xc8f6cdab, 0xda69d12d, 0x5871249f, 0xc011e372, -0x33c8e75d, 0x8087d9fb, 0xc595c587, 0x9cc36c3e, -0x676b2c58, 0x4f242c1b, 0x6b77d07c, 0xa1c8543b, -0x2824e9c7, 0x84be15a4, 0xc0b4a308, 0x0e41511b, -0xfaf3dbbe, 0xc1777e7b, 0x199d042b, 0xb0b35558, -0x9bf8cb58, 0xf68d5c43, 0xf359b550, 0x993d82d1, -0xa8388458, 0x56d3c256, 0x11cbc33f, 0x3c28a56f, -0xe6aa09f9, 0xd41f6c39, 0x11020cd2, 0x985c89db, -0x3705b46f, 0xaf90c2dc, 0xf7ecfc96, 0x355eee96, -0x078e9048, 0x2fd05bf1, 0x48eab9e0, 0xafaab712, -0xcf0c3e12, 0x8095ae6d, 0x8364131e, 0x7221ba38, -0xad0e42d6, 0x20741356, 0x8698ad29, 0x024d1baf, -0xb87c4a77, 0xa4169a47, 0xa487c4c8, 0x966a2b68, -0x9821bace, 0xe64b1014, 0x22eda535, 0x4cc48e4e, -0xb1a80833, 0x0e9ec179, 0xf6bb1c55, 0x95489311, -0xefe8a663, 0xc4cf14f9, 0xe3591c5d, 0x86c3c61b, -0x9fe18d90, 0x3b75ff1b, 0x5ca3d992, 0x8c072f42, -0xecf16b8e, 0x672b72c7, 0x4603e497, 0x45e015d4, -0xd918406b, 0x4f25a635, 0x5feb56b4, 0xf9f94d06, -0x7bd31a73, 0x1ab03fc0, 0xb85fdbd8, 0x4c3e81d9, -0xefc2c666, 0x59a7afcd, 0x8a02428a, 0x73af7adb, -0xd8ea36e0, 0x991a6fd9, 0x7f9c2019, 0x2d3a85d6, -0x8f3295c0, 0x93809471, 0xa5d313f5, 0x8cd5ea3b, -0x7b982971, 0x5e4f0172, 0xcedcb6e6, 0xea24e209, -0x8a46f8b2, 0x74331527, 0xd77ed523, 0xaba69d6a, -0xebd38b4b, 0x04c01b27, 0xcf51542c, 0x25e75d87, -0x69f4e24a, 0xeb1c3f81, 0xdd4508da, 0x0cc85856, -0xd006d573, 0x79a7c5cb, 0x1cc2e951, 0xd1ac0710, -0xa78fbeba, 0x90877b5f, 0x7972ab18, 0xd866ac15, -0xc287620f, 0x54fdeb69, 0x9c2d264f, 0x6c2e6ff9, -0xa12c2962, 0x87f99490, 0x5a9f5f5c, 0x5fd88f09, -0xf6b7e966, 0x02abc4f2, 0xde5eddd1, 0x6ccd06e7, -0x7747ee88, 0x9bc9622a, 0xb807d839, 0x1d14fe6b, -0x1c4676e8, 0xb9add7e1, 0x5a84fc84, 0xa0d232ab, -0xf09b95a0, 0xbd7481db, 0x9f68639a, 0x4870d114, -0x60ebc8a5, 0x42d4d24b, 0xf64d2815, 0xaab0da5f, -0xcba7f41c, 0x44dcd89b, 0x613d50e6, 0x180e700c, -0x18a6bdad, 0x54883f08, 0xa0a9fc4b, 0x9af3ec0b, -0xba3f74f2, 0x9469aa23, 0xc89de01e, 0xe7963adb, -0x8cb13661, 0xdbbd276c, 0x42e113df, 0x4947dfd7, -0x513cc410, 0x57c6db1c, 0x8911377d, 0x01405fa9, -0x7163e406, 0x995a0db3, 0x2e9b208b, 0x4c77dfbc, -0x33f30f4c, 0x5aad99da, 0xcca61b32, 0x027fa2ce, -0x2b5387aa, 0xafca9d2b, 0x7fbe4c67, 0xee92fc72, -0xc3857c05, 0x5e425769, 0x4ae6558f, 0x499427f8, -0x15900b70, 0x3aae1260, 0xa7bfc2a1, 0xdfa73e71, -0x8b79b206, 0x6552c432, 0x56b81866, 0x86d6e834, -0x91685add, 0x7c34051c, 0x4ef8db74, 0xbab855ee, -0x083ab156, 0xc82a579d, 0xec1e3ae3, 0xdfea24a6, -0x9554ee6e, 0xd53b8bd1, 0x9a4bda63, 0x884e86e5, -0x9acf4763, 0x540b9ded, 0x5fde4bca, 0x541d2dd4, -0xc5637486, 0x5fdfc527, 0x6cc50628, 0xc701a605, -0x7fba696e, 0x053a6cd0, 0x3796571c, 0xd11ec6f6, -0x2a653ec1, 0x69a1ade5, 0x16171236, 0x3aa406c1, -0x506e343a, 0x3a0e8bf4, 0x5aa895d9, 0x0c775b47, -0x4e28dec5, 0x1bda09ce, 0x1c9e840d, 0x6dce833a, -0x22465428, 0xd371150f, 0x8567e8cb, 0xca82a9f1, -0xbb870830, 0xb97bd7c3, 0x9d47f4da, 0x320a7f4a, -0x615904da, 0x5a1afaef, 0x8db2a274, 0x25c6cc0b, -0x77b25e1b, 0xc9b16b2a, 0x85f83b19, 0xe0ded88d, -0x5c5fe541, 0x4701f3ef, 0x951546d9, 0x27ad1bee, -0xfca8fb12, 0x82d4b9ed, 0xa2213f6d, 0x7d9d78f5, -0x427f9be7, 0xbadb7c7a, 0x4d96ad1f, 0x38ab11db, -0x39afac6a, 0x1d1f122b, 0x8809f762, 0xe4d45952, -0x47d8e7f5, 0x454c13cb, 0x3f786535, 0x379cc67c, -0xec8ee189, 0x1be38d4a, 0x6bd926d6, 0xf0d25114, -0x1167e82d, 0xa54c9af1, 0xad7ba68c, 0x6f59b719, -0x801e27bd, 0xf038f9b7, 0x3a0ab320, 0xeeb2465f, -0xb3a99e7e, 0x6c2fc613, 0xb341b38c, 0xe7e64850, -0xa91b0475, 0xcd46e686, 0xe8915130, 0x3d7a326f, -0x3e9b9c26, 0x581d98c3, 0x84e6b5c3, 0x90b1d2fd, -/* 309-MU163437.inc */ -0x00000001, 0x00000037, 0x09231998, 0x00000634, -0x02c55597, 0x00000001, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xb9725de0, 0x6311cc57, 0xc0c08f3a, 0x0f9579b6, -0x91b9a5fd, 0xe7a0d5d6, 0x44afb34b, 0x88402bd9, -0xfd14eeb1, 0x689409f6, 0xe61da9dc, 0xbd52db17, -0x741fd636, 0xe7148292, 0xf0f6d187, 0x68553ad8, -0xd94fec1c, 0x8a4744d6, 0x6485ed16, 0xb5577cb3, -0xdc642e23, 0x40a00b58, 0x90182b9c, 0xedb37e03, -0x32f4e0d1, 0xa53ad183, 0xf8d5f840, 0x354ab66d, -0xc7923da7, 0xe97a69f6, 0x231fcbde, 0xb5979fca, -0x90e57d0d, 0x6ff9cc93, 0x838a19e4, 0x9c96d833, -0x440a03ad, 0xb8e2b5a3, 0xe475de70, 0x3dca60b4, -0x93b8a77b, 0xede1a465, 0x4b5d64e7, 0xd1ed9008, -0x872de386, 0x707baea9, 0x8f1618a8, 0xb844e46f, -0x7bff46c7, 0xb9d7ee49, 0xc1bd24ac, 0x2e88a8ef, -0xa8d79f00, 0xe8895a77, 0x38436327, 0xb0fa076e, -0xafc4af33, 0x1c40e574, 0xcadd42c0, 0xf6b620c4, -0x3c1eeb06, 0xbb228015, 0xdbc6c9fd, 0x3054c2d1, -0xa1007ade, 0xe5999e2b, 0x1574da4f, 0x9ddd9233, -0x8cb964b1, 0x07fa6cdd, 0xc87b8f03, 0x8a78b160, -0x510b1db0, 0xd0062833, 0xf22d87cd, 0x00387de1, -0xd0bea504, 0xe76bbe3e, 0x63516873, 0xf303a522, -0x84fcc4b9, 0x63715883, 0x8a47d1e8, 0x85b5bd6c, -0x0d2c8b4a, 0xe178a673, 0xeeac92ef, 0x23862fa9, -0xe45e93de, 0xd5a22c96, 0x7ac26e43, 0xb69621a5, -0xfc2d746a, 0x1b67a2d2, 0xa0d1acf4, 0xfb7dc534, -0x69ea7ef8, 0xe0b452cf, 0xda397364, 0x05992d50, -0xd84d1762, 0xbd2837ee, 0x2b4396c1, 0x86323aad, -0xf2adc36b, 0x4abd4872, 0xe11f0d66, 0xebbf9666, -0x6392b987, 0x9ad21e5a, 0xc5f7617a, 0x6d65a8d7, -0x9407e87e, 0xcca7da78, 0x73e6bedf, 0xf497f577, -0xcdb872e7, 0x7ec37786, 0x8ce79cc8, 0xb72e2d97, -0x01f4898b, 0xb6f168e2, 0xa57f145b, 0x16cf215c, -0x836d7958, 0xcea95f34, 0x02f723ff, 0xb673ff4d, -0x9232c461, 0x160eef3e, 0x8ddbdb79, 0xa23d3e40, -0x005fca75, 0xa64a04a4, 0xcf639c0f, 0x25a6fa5a, -0x9c7b4656, 0xdad1c90f, 0x0941974a, 0xfe7e4a6e, -0x92a2f906, 0x32953b90, 0xd79b4025, 0xa24837aa, -0x7d1abad8, 0xd518ddd9, 0xaa87cd14, 0x4192f1c3, -0xe537f5c7, 0xc9686588, 0x0166144c, 0xece72901, -0x82646372, 0x1fdd3b34, 0xde9ed104, 0x907bc18e, -0x046d1fb9, 0x9f0229b8, 0xb8830517, 0x3b9b8255, -0xbdca285a, 0xce3d6258, 0x306c11b9, 0xe291c557, -0xb5ad6e96, 0x2c26d197, 0xbf3d19a4, 0x828c6e43, -0x124679da, 0xb94feed5, 0x0028dfd2, 0x40a7b67b, -0x4e35e50e, 0x6c8f4415, 0x8ee725b0, 0x4941bff5, -0x973f67bf, 0xd1b60674, 0x4fe0175a, 0x31e4430b, -0xe007cb2c, 0xc87147fb, 0x22412543, 0x8219eb26, -0xab2bee20, 0x3bd82f1b, 0xf6eca253, 0xf8c99394, -0x3b1ac6cf, 0xd23cd4f3, 0x84f807db, 0x399efee6, -0xe3d29459, 0xd09bdf45, 0x66f0fba7, 0xc7d955de, -0xc980cf99, 0x3e6da774, 0x8805856f, 0x48b16b36, -0x71241b9c, 0xf76eb493, 0xe04e8a5e, 0xfe44ab34, -0x11076cc0, 0x5b1bd217, 0x8f7a6572, 0x9e1f7de0, -0x23be7914, 0xb7fc8fc1, 0xee21eb58, 0xee55fbe7, -0x9935288e, 0x0b42af7f, 0xc87b01b2, 0xaed052e8, -0x6950ecc1, 0xd2d38b75, 0x1b0a9b47, 0xab934dc7, -0x4edab76f, 0xdf67944e, 0x491037d3, 0x26a4d2fa, -0x60ffedae, 0x2fe107e3, 0x104ea8c3, 0xb506e130, -0x06102a1d, 0x96a7c9a1, 0xa23fd47e, 0x406eb0a9, -0xdb151849, 0x9afb562f, 0x7d22ab67, 0xbeae4ace, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 536-MU16810f.inc */ -0x00000001, 0x0000000f, 0x09211999, 0x00000681, -0x73f2cca2, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x78021ec2, 0x1b1b6d8b, 0x6bb53ed4, 0xd36c5ad1, -0xbf6f3c59, 0x4c97e2fb, 0xadbe12d3, 0xa6998d5d, -0x327a1a64, 0x84a0f599, 0xb75eee4e, 0x2da4f396, -0xbceafc7a, 0xce54ed0c, 0x6f4276cf, 0xec5393e7, -0x8235b282, 0x5c60204d, 0xf44af88f, 0xab0e81d5, -0x5c6631de, 0xd60e5d01, 0xb9a1a5b1, 0x672f570b, -0xfe8d296d, 0xbe304563, 0x6a4ef0a3, 0xc6b22b69, -0x92a1406c, 0x66562aea, 0x9ac8a28e, 0x95c31acf, -0x3dfaaeb2, 0x949f1129, 0x8bd271ad, 0x1ecb6dd9, -0xad22be72, 0x8308f8db, 0x3d3d5ab2, 0x97c412c6, -0xd83161cb, 0x2edd3832, 0xe3a6a21b, 0xc888a0c6, -0x16dfbcd3, 0xfcadc2fe, 0xd85d71ec, 0x358bce2c, -0xe87d2d81, 0xf10dfb9e, 0x296c32cd, 0xfbb12b01, -0xb521c0dc, 0x0135a8e2, 0xc014d67e, 0x82301d9d, -0x7a506b07, 0xd627731f, 0x938e12ea, 0x60fb36ad, -0xc2121315, 0xb3a40ef2, 0x501a4463, 0xca53a7e2, -0x8905d202, 0x56f04dde, 0xdf6d6db2, 0x99668508, -0x73fcc401, 0xebb098d0, 0x8ab8cf4c, 0x65495bd0, -0xc5dc6126, 0xbfa3738f, 0x40e269b5, 0xe7c065b0, -0xafa8f722, 0x610005e5, 0xe1efd3ea, 0x9f52c4a6, -0x6fe5e4c4, 0xca7b2d93, 0x9a487d3d, 0x7150e2a9, -0xd597acc8, 0xb0892a96, 0x556a0e0b, 0xc75a6dda, -0xb1cce67d, 0x70576a5e, 0xd5d9f4cb, 0xa323dc2a, -0x7984f913, 0xd44fbda1, 0xb6eb13bf, 0x5282b867, -0xf7b50028, 0x8ab18c60, 0x706c63a3, 0xfdc16223, -0xa0de6a16, 0x5be19bd6, 0xec5dfbf2, 0xa49b0124, -0x6bf7b85e, 0xd9a2bf9c, 0xb92a235e, 0x4531115d, -0xf449984a, 0x8ada6365, 0x454ff6ce, 0xcda5e072, -0x966da5e9, 0x4e0ffc35, 0xef46600b, 0x9cb0d898, -0x59652b89, 0xdb79de7b, 0x92ff99ad, 0x6aee17f4, -0xd8f79930, 0x89b5c1fa, 0x66223270, 0xcd70ceb8, -0x9239e6ff, 0x768f9775, 0xd301ef77, 0x9be7283d, -0x4133ce34, 0xf64ea6a6, 0xb813aeec, 0x7356bce2, -0xe0eba825, 0x93ba38e3, 0x4853cd1f, 0xf22774ac, -0x8c5896e0, 0x59fb292a, 0xf3af2c19, 0xa8a3d0d6, -0x43d676fe, 0xe1f30726, 0x9da64a3b, 0x4bd03774, -0xf544baa7, 0xb2400406, 0x7391da22, 0xc15eb93e, -0xa0994a39, 0x444ca24a, 0xfe8762c6, 0x90b5f5b2, -0x5ecc0a28, 0xe81b735c, 0xba6bfdc2, 0x5165cfb1, -0xce117215, 0xa1a3c7c3, 0x47284431, 0xc0db0ba1, -0xb5d29293, 0x5c92a346, 0xee7f3017, 0x84299ee1, -0x5315374a, 0xd9a9320d, 0x95e25cac, 0x53fbd980, -0xfc075892, 0x9d160ae3, 0xfa59aa1c, 0x68a14dd3, -0xdb68489d, 0x28b10918, 0xfc4c5c55, 0xca7ccc8d, -0x29343574, 0xf72e46d2, 0xc4bd67fb, 0x9c860395, -0xc615810e, 0x7ab9b008, 0xb557ceba, 0x7f40312d, -0x7514ff0f, 0x0ccde8c3, 0x40c2f374, 0xf591f29d, -0x39703a56, 0xd65b3aef, 0xc9d0ef94, 0x14e6df58, -0xda4fa9f6, 0xe2a84104, 0x2c0056b5, 0x46dd13f6, -0xeb5e2c1a, 0x65247396, 0x57daa392, 0xd2bf33ed, -0x573252ef, 0x6ef7ce92, 0xc7567e90, 0x316102be, -0x45d869e2, 0xaa59ec71, 0x1b8d9393, 0xd8e818ca, -0x8fdb774e, 0x947f5af4, 0x5e52c4b1, 0xa3fb36d5, -0x1742fa22, 0xb8e27fbc, 0xa3791a5f, 0xe38e05a6, -0x9fb62dd5, 0x720310b5, 0xf473e100, 0x146348e0, -0x589ca309, 0x6e64c75a, 0x3a956b4b, 0xa80c0dca, -0x6d16fff0, 0xfab7a74c, 0x8ac8a2a8, 0x7e4b5bea, -0xfcb2ff29, 0xa007c2a7, 0x42cb7df9, 0x2af79938, -0x9c80c69b, 0xa66945ae, 0xe7efde80, 0xe6061c57, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 530-mu16730e.inc */ -0x00000001, 0x0000000e, 0x09101999, 0x00000673, -0xf64116d1, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xd008ea9a, 0x90d1fc1b, 0x08e139ca, 0x3f54f83b, -0x6985ceca, 0xa832ab46, 0x5f54c319, 0x2a2aad6a, -0x82af41e6, 0xb946820b, 0x273d0f0b, 0x5f2b4860, -0x22fb8bf0, 0x09d64919, 0xe5ef5108, 0xd5be0718, -0xc20c175c, 0x90849d77, 0x9cb5ae2c, 0x7e8a04cc, -0x3f83be6e, 0x27f7342a, 0x54a541ac, 0x48c251fe, -0x4e7d2cbb, 0x7cb0e179, 0x3dac5cef, 0x2f17cff1, -0x8b9b17fb, 0x8eaa9a4f, 0x1671f162, 0xf4057322, -0xf1dc3423, 0x5f627c7b, 0xc7f41536, 0x0471b71f, -0x2a2662ce, 0x7627fa85, 0x30092087, 0xd6e23bab, -0x18135f41, 0xa5a5b59b, 0xcd9a0ae0, 0xed38fda2, -0xa7344d65, 0x89e51ba1, 0x178878f5, 0x752e82e4, -0xa7a46885, 0xc95e6a43, 0xe6a18eaf, 0x586db392, -0x79eb538d, 0x7ab046a8, 0xd8878ada, 0x49863242, -0x59563f59, 0xd3530ce5, 0x62001d03, 0xeab34c28, -0xe44590d4, 0x3bad8f1a, 0x5e0c9e1a, 0xb9c67b05, -0x4b28ac69, 0x75070de2, 0x2f2da3fe, 0xc91e536b, -0xe66ecbfd, 0x8d482c4c, 0x5c6d055f, 0xb538d7b8, -0x0b9fb684, 0x30491bec, 0x08f9324f, 0xef9591c5, -0x96922bd1, 0xb43524cb, 0x5de2d5ee, 0xecff2573, -0xc4a14e45, 0x762b7aea, 0xabff7517, 0x25513c1c, -0xd41ff45c, 0x97cb1887, 0x1ffee480, 0x2cbccbfd, -0x27691474, 0xf8f07595, 0x0c724a47, 0x85550ea5, -0x4963f521, 0x1758187d, 0x829f6ea2, 0xf0db59fb, -0x9ce0a900, 0x714a0191, 0xc2899de0, 0x8fde5bd6, -0x05279f03, 0x04e7d5a0, 0x19bda9aa, 0x3b530e2e, -0x65b312c8, 0x78063dfe, 0xd0092057, 0xe9a483d3, -0xd5eb2248, 0xc6a17a9d, 0x2c2a8112, 0x37405433, -0x43931206, 0x6961f1cb, 0x300b0904, 0x0ddc1480, -0xc7e0da70, 0x9ecefed6, 0x076150f7, 0x20e0194c, -0x408a2585, 0x63999df8, 0x072378e3, 0xc8e5b1c5, -0x06f80c0c, 0xe539a928, 0x103df509, 0x005ceda1, -0x55193245, 0x49fc8e90, 0xfaa5be5f, 0xec2cef0c, -0x29b21e2a, 0x81cc923e, 0x21bc19cd, 0x1edfb15e, -0xd3fe97c1, 0x907f6e4b, 0x40a2e3be, 0x8edf9a0b, -0xd87da422, 0xa4d6a135, 0x860a49be, 0x9d1fb3fc, -0xe0b05e9f, 0xfb6bc8b7, 0x2cdcb076, 0x70b1cb29, -0x6057aafe, 0x3aed90c0, 0x7aa970bf, 0x9bedf020, -0x1d141253, 0x5de04fa1, 0x6fe5e080, 0x5ee5f311, -0xfbc3177b, 0xcce67a85, 0xb96578ce, 0xc907c8da, -0x8a771092, 0xffc45b16, 0xcaee0517, 0x063d07a4, -0x7d1cd75d, 0x23c993fe, 0x1780edee, 0x7eadf2e1, -0x085bd3ae, 0xf6da6cec, 0x288cab1a, 0xc17d3e73, -0x41d7a752, 0x0cd66538, 0xa03db177, 0xf7f832ca, -0x670eab04, 0x3116aecd, 0x7f8f7f84, 0x87d034d5, -0x04033827, 0xcb63dc4e, 0xbc599cb9, 0xecf6ea45, -0x0f65ac32, 0xafa30136, 0x8133e580, 0xac6a49f8, -0x1d9aa390, 0x78439835, 0xb6bfe265, 0x7c47f347, -0x2393146d, 0x40216fb5, 0xd2aaa6b0, 0xbe1274aa, -0xbff433fe, 0xeecc4826, 0x01e245b6, 0xf766dabe, -0x22debab9, 0xde5d70b8, 0x7fe3041f, 0x8605c41a, -0x1d6b1a13, 0xffd9efd6, 0x37df74bc, 0xbe7045e5, -0x751e4b1f, 0xff7b6bec, 0x4bf15bbd, 0x9eb49f9a, -0xb17acad0, 0x40811eb5, 0x10e148e0, 0x3b8a4981, -0x97115eb0, 0x7c2c62b8, 0xfc8258da, 0xa761cee2, -0x25faab65, 0xf4b26c2f, 0x071c2e0f, 0xec732edc, -0x9877857b, 0x18419321, 0x609948cb, 0xf8729755, -0x1afc2813, 0x6e255d8e, 0x78892422, 0x085d177c, -0xbff60f4a, 0xbb1729f1, 0x3b08f81f, 0x02e8a9c7, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 240-MU163202.inc */ -0x00000001, 0x00000002, 0x06101998, 0x00001632, -0x6aae5598, 0x00000001, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x5086687e, 0x183fe71b, 0xc2cef2c2, 0x35812eda, -0x9daec1bc, 0xc8c7e9c0, 0x13b2bf9f, 0x09d2aabc, -0x56565a53, 0x051b7f55, 0x8989821c, 0xae9e02bb, -0x3503ffd3, 0x74b8cd0c, 0x12f922ca, 0x7d8a5113, -0x8ffed0d3, 0x200264f0, 0xe6687b81, 0x9f5fcc5a, -0x5e2ea862, 0x20728629, 0xd3d6e566, 0xe1d31f12, -0x0383dcf9, 0xf7c86872, 0x47bf87e7, 0x9a2f162b, -0xf2ea80c1, 0xf9e6be4a, 0x9f292114, 0xe765ea9e, -0x89f6b013, 0x8e11d077, 0xab12527c, 0xdc58898a, -0x77e6861c, 0xe6bc8da9, 0x9786f39d, 0xeae9b1e9, -0xdc5b6348, 0xf5f10ccf, 0x5c878a54, 0x739e873f, -0x103078b7, 0x4f192063, 0x2e2479e0, 0x77b726b6, -0x461a8fa7, 0x28ece47c, 0x4c8e3752, 0xa52b7632, -0x57f238de, 0xc4076eb2, 0x4cfed721, 0x446325aa, -0x1c4a3bdc, 0x7c55c9dc, 0xe607cab6, 0x4ca18774, -0x4d473db9, 0x935ba067, 0x8f9688dd, 0xc8e9c959, -0x82e13cb4, 0x6c8def39, 0x2ec2326c, 0xcf86973a, -0xfb9176f8, 0x028c8607, 0x80ba26f8, 0x0bf14a7e, -0xbbde7e3e, 0x1da9453c, 0x41453d74, 0xda576c83, -0xe47214d0, 0x1287d537, 0x65278ea8, 0x91cec3ad, -0x2526c847, 0x071cf3a7, 0xf0483b3d, 0x8c1ce5bb, -0x6655cfb4, 0xbbfe3e76, 0xe19a6999, 0x2c2b9990, -0x7b85dc5c, 0x2a5ffde1, 0x5cc9761e, 0x2fbe2be3, -0x15fcc7d8, 0x4054c02f, 0x4cef63f4, 0x055be9a1, -0x01814164, 0x814f1a22, 0xc2ba59f7, 0xe0a5da65, -0x1413e4d6, 0xbdbec99b, 0x929751d3, 0xad078350, -0x764a1033, 0xc7296867, 0x02db88e4, 0x23f326b6, -0x298eee24, 0x4a2d93df, 0x461bbdbe, 0x7496dc93, -0xea0b385b, 0x085f9754, 0x837f9a48, 0xb2a2c8bc, -0x5e9d4535, 0xdf130ddb, 0x56090512, 0x1ce18bbc, -0xe09c38e5, 0x1ef76900, 0x837458d4, 0x2454d6b8, -0xe2e1f9a3, 0x96db5d54, 0x5d22eb54, 0xe0e5b026, -0x9bf9a05f, 0x780f0192, 0xb30ad5c6, 0x2a9c6e7a, -0x5a3748b8, 0xe2b4cd09, 0xd8ab9dba, 0x18d24d71, -0xb1852d2a, 0x0d23e380, 0x405e1144, 0x7f6df64d, -0x7bc57e7c, 0x2343affc, 0x50e9c07c, 0x48cd5abc, -0xf16e92ed, 0xfbb3c2c1, 0x2d2ef623, 0x4f09fa01, -0x6fe58d54, 0xbce01e8a, 0xcdfbf33a, 0x92105d9c, -0x1a3ca378, 0xbbac1aa1, 0xea832aa3, 0x15da2b56, -0x7aa01fad, 0x358d0fd1, 0x11b4f750, 0xfc2707e6, -0x2725a273, 0x312d9bca, 0xfe87333d, 0xec0bb542, -0xbf4224cb, 0xd1eb9564, 0x0d65d477, 0xddfd1783, -0x8ccc9b3f, 0x4e8c20c1, 0x5c8960d4, 0x2dddbb65, -0x7a7089d3, 0x90ca6eda, 0x96b46eb9, 0xb5af69f8, -0x2d4f6699, 0xf2244819, 0x9ae48370, 0x4b24b76f, -0x199e29ad, 0x744eda36, 0x9347f3b0, 0x39188477, -0x90f9c71e, 0x40617767, 0x5c331047, 0xe19896fc, -0x6788bae4, 0xa2df7b78, 0x4a6d1887, 0x6a73a662, -0x6798c344, 0xd02bec78, 0x240c0dea, 0xab4bb468, -0x2654f504, 0xe93a9817, 0xc9ab8765, 0x12a60586, -0x69694bbd, 0x9f09e92e, 0xe66445ed, 0x044e028b, -0xa6256764, 0x1c663bf6, 0x0e7d4235, 0xaa1b5a60, -0x662909e1, 0x1725160e, 0x8056f057, 0x9922d580, -0xec768eb6, 0x0c7a1ceb, 0xaf111dbc, 0x22559bd8, -0x4d7487aa, 0xa5021cd2, 0x86692aa1, 0x3c1804e7, -0x2e4a4d85, 0xfc7d0089, 0x728f8bc8, 0xdf9b4e44, -0xad46b9f2, 0xe97af88c, 0x52e49bc6, 0x2e8c0af9, -0x1aa59dad, 0xe92bfea1, 0xe4dbaa3c, 0x9e2a15a0, -0x98e52da3, 0x79ac126e, 0x8f8a61f4, 0x76da41f9, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1105-m08f2420.inc */ -0x00000001, 0x00000020, 0x06052003, 0x00000f24, -0x828598c7, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x5715f121, 0x440ce2fa, 0xd5d090eb, -0x70b3e977, 0x92320e8c, 0x4f989906, 0x36907442, -0xcc4b12e2, 0xb456a6ae, 0x0ad5bcf7, 0xe9f0a425, -0x70b932d2, 0xe66202c9, 0x350f884b, 0xd560a828, -0x5c4c5cb4, 0x7b142329, 0xd9e25719, 0x98b1dbb0, -0xb11af93f, 0xe83b07eb, 0x9b6d35a1, 0x0df761c2, -0x1a5e6da5, 0x3c978798, 0x08a7acd8, 0xd20a3b15, -0x0aaeef40, 0xa4ed3a47, 0xb8d15785, 0x2ac39380, -0x153a5ad7, 0xeddc8222, 0xc02510f4, 0xc7cdc21c, -0x09adfdce, 0xf4dc290a, 0xc6e2f5bc, 0x8e60359b, -0xf097f2fd, 0x24ac2ac0, 0x770ecf17, 0x9f80b3f0, -0xf250a757, 0xad071b7e, 0x51d432ef, 0x3c095fc8, -0x3574394a, 0x23e0e092, 0x8c9e2505, 0x927dc9fb, -0x3bfcface, 0xb93be3de, 0x46c03521, 0x00192a46, -0xc6a53c55, 0xfcdbb872, 0xb56349f6, 0xf0bf598e, -0xe86afccc, 0xef930d0a, 0x905ada75, 0x9508c261, -0x8a8cb340, 0x5010a4fa, 0x92437678, 0xa7799056, -0xedd0ea8d, 0x3c25bdc8, 0x914f3f08, 0x27ff4d02, -0xd104ca12, 0x972d1570, 0xadb4a6f9, 0x34f31516, -0xb0aca99e, 0xd05b7382, 0x5fcaeecd, 0x83edf7c4, -0x1b15099f, 0x14146a3c, 0x6150ae4a, 0xd8715907, -0x6d405215, 0x307ebd9a, 0x248fcdf4, 0x1650a34e, -0xa8070739, 0x5fde05cc, 0x1a9433c3, 0x3f5770d9, -0xcedfa47f, 0x1f3c7660, 0xa3bdf9f6, 0x3a2d9d3b, -0x01833189, 0xfebaa041, 0xbc4bf2c8, 0x50c5f238, -0xb132e653, 0xd301e92a, 0x2b094386, 0xfdb557b3, -0xd4ed60d6, 0x75da1146, 0xfedf34fe, 0xa21665bb, -0xd6b6d496, 0x46d9c114, 0x20f26f66, 0x5ee354c2, -0x801aba92, 0x0973251a, 0x63748328, 0x01b293f4, -0x1a13ec73, 0xf17ea3dc, 0xcaf6a499, 0x1cd356e3, -0xa6b450be, 0x6200d2b7, 0xc4b88872, 0xf6aa6f70, -0xdbc917f9, 0x1cf3d760, 0x5d60d15b, 0x48c2407e, -0x9210b35a, 0x171df657, 0xfb14733d, 0x1c837746, -0x6df3dd50, 0xc096efa2, 0xa9202472, 0x56917067, -0x40620e92, 0xd739c7d4, 0x89cce286, 0x8882ee44, -0x2362cb14, 0x3e03d986, 0x6519adee, 0xd7aec296, -0x23a91210, 0x77229af4, 0x97fd4c79, 0x422707b5, -0xbea05034, 0x2ef3b3a4, 0xe3291146, 0x40a0cc32, -0x96b557c6, 0x5aa836bf, 0x9dff3965, 0x31e80540, -0xa0556e13, 0xc08b88ca, 0x3f3e1144, 0x4f093862, -0x96bc622c, 0x497ec377, 0x992d7899, 0xf881becb, -0xc65d3299, 0x827a9be4, 0x78b851b6, 0x8314b5d1, -0xeda31b10, 0x471764db, 0x905d2df0, 0x19e376c0, -0xcf6af8a5, 0x4355d3d3, 0xb2033a88, 0x00f2c0d6, -0x537a95be, 0x6938a3c7, 0x8d85a10e, 0x19f996f8, -0xe5334524, 0xec2cc18b, 0xc540afec, 0x14206bbe, -0x89601729, 0xf21d5916, 0x11c39ad0, 0x93a73d2f, -0xbd8a681e, 0x3d62394c, 0xe43d9c1a, 0xb1b85b09, -0x48e87b21, 0x3dc66cb4, 0xad066e73, 0x745fb4b0, -0x47f5cdd2, 0x28e9dc7c, 0x94515ceb, 0x3a94e085, -0x0fcdb0e4, 0x55cdbb93, 0x38d990f1, 0xa8f13bff, -0x497471f6, 0x4e74b9f0, 0x6212615b, 0xec6ed687, -0xc984443e, 0xd3852197, 0x35ee920a, 0x690a7b44, -0x4c2ad071, 0x8b9e3890, 0x4114aba9, 0xea796a19, -0x0d968acc, 0x97709071, 0x20274074, 0xcecfce72, -0xbfdde5ee, 0x4d694e1e, 0x800d6bfa, 0x969027a0, -0x9417fe60, 0x9cadfc0e, 0x6a103bda, 0x375fc4e8, -0xf309280c, 0x945f197b, 0x5cb77b5d, 0xdf5d5708, -0xced4272d, 0x6b04b696, 0x78e44dc2, 0x8c41f9d4, -0x92650f39, 0xae3d250a, 0x07c91401, 0x1ca1360b, -0x2078a46e, 0x7e0b1a9d, 0x5a667dd3, 0xefdd072c, -0xeee2f749, 0xc1115ebd, 0x743c2890, 0x525d7fa8, -0x4d86d130, 0xc4470f2f, 0xcbd9dc73, 0x88230f84, -0x7476f692, 0xbcdeb696, 0x981f3fd4, 0xba7f6c3a, -0xe073e123, 0x1dfb3790, 0x6ab7fc48, 0xc519cc6e, -0x5383ddda, 0x964da863, 0x1d041e19, 0x5f2288d4, -0x5ff7c34d, 0x73a197c1, 0xd086d7c9, 0xb0314861, -0xbc63a785, 0xe072a384, 0xf37e9d90, 0x63a7a4ac, -0xa33622ab, 0x802471f9, 0x0841f065, 0xff4ea8fd, -0x343caaaa, 0xcb8594f5, 0xf5756925, 0xcc946e7e, -0x9043d824, 0x49812185, 0x1f555515, 0xb62ffebf, -0xa27e379d, 0xa2386704, 0xaf19ccbd, 0x644130f0, -0x29abc386, 0x7d044e0f, 0x5274c8e1, 0xc8298400, -0xc08a2e85, 0x8f13dec2, 0x79f40342, 0x10ed42a2, -0x75541795, 0x9c9608c5, 0x11798ba6, 0x9a7e40ff, -0x4e44f869, 0xb0e0ac45, 0x9865be8d, 0xc361cdf1, -0x88cf2cf2, 0x5cb47192, 0xceaeb1a6, 0xd6c4b77e, -0x567e8aae, 0xd0eaf865, 0x30a9e8f4, 0x049e1005, -0x96c4842e, 0x4d97f912, 0x2837581a, 0x8dd154c0, -0xe88f85e3, 0xd5b8c4bd, 0xf6ae181c, 0x524a4d74, -0x17e15bed, 0xa200218f, 0x241d1c1b, 0x9efc70a7, -0x9e1adbae, 0xf115df9e, 0xda54c448, 0x8fe3ebc3, -0x0b312745, 0x4f0075d9, 0xc2867e55, 0xa19131db, -0xc244a076, 0xbfd954bc, 0x65a49f64, 0x3e99ece9, -0x80940945, 0x626f0b5f, 0x683bb192, 0x9fbb14c6, -0xe4136229, 0xd76f54e7, 0xd8b2b363, 0x049f372e, -0x5f391828, 0xbf27f2b8, 0xc9ba89f6, 0x83047de6, -0x6b9816c7, 0xa37232c5, 0xe86bda74, 0x8c426e07, -0xfca755b4, 0x5d7f53d6, 0x6a123e2e, 0xbef86cef, -0x0ff79e5c, 0xc160e69f, 0x3d9332ee, 0x14b3246c, -0xb1ee9faa, 0x72827d5c, 0x825683a2, 0xbf3143f4, -0x501cad6c, 0xbb872e29, 0x086f7851, 0x392df63f, -0x0013ae33, 0xd643c1ff, 0x5dc4b349, 0xcdf75234, -0x206f8869, 0x9cc8c8b2, 0x872c6d84, 0xc518e0a6, -0x2bdbed94, 0x2cea60cd, 0xd4542cd2, 0xbf5f7c4a, -0x03fd6694, 0x857030b4, 0x932ce1f7, 0x1b24d617, -0x8342fbb9, 0x2484a61e, 0xa76945b6, 0x39c08823, -0xcc4e48b9, 0x31b73d47, 0xe2699dfb, 0x3f43284f, -0xce602dfb, 0x0b50541c, 0x5ecb56d1, 0xefc75a88, -0xdba5beb3, 0xe0e80051, 0x11360a93, 0x27cc6d6a, -0x884a2e79, 0x4c5c9256, 0xe2c4c758, 0xf2422d67, -0x2736306d, 0x60f34846, 0xf41738eb, 0x9286cbe5, -0x27f5c292, 0x410fae37, 0x980f0a33, 0x2522d4db, -0x5c5b5beb, 0xdbd795c2, 0x2fcf3eb9, 0xf13709fc, -0xc76339cc, 0xfef3cf76, 0x152585dc, 0xc321c271, -0x2731085e, 0x676bce0a, 0x93299b87, 0x76e24635, -0x2dad2f9f, 0x4ee82851, 0x45f18669, 0x85a46c9c, -0x430f4c5e, 0xa95cbcc9, 0x42f64729, 0x532ec8ec, -0x25bd2204, 0xc9c7a3fe, 0x211fa366, 0xf26d8e5c, -0x9fa1c330, 0x5544d6f7, 0xdb8ee6c8, 0x9ea78f2d, -0xb9d20793, 0x7e21097d, 0x9a1b224a, 0x5c04b9eb, -0x33644b1a, 0xc87dbf35, 0xcfd8587f, 0xf14aac0e, -0x4e3241bc, 0x07f0d75b, 0x7eb18848, 0xf369e75e, -0x236de9b9, 0xee3eacf7, 0x1de6b3b2, 0x5b00c435, -0x550394d6, 0xb93456ce, 0xf888d226, 0x787c955b, -0x318dd4d6, 0xa167b3bc, 0x550dccb4, 0x95e7b95e, -0x3a5c8801, 0x707226ff, 0x05fd98b6, 0xfabcac46, -0x28e3aa66, 0xb336a36b, 0x77e82e0b, 0xf8756e97, -0x84c7df37, 0xd840bc47, 0x33606de4, 0x4bdc8365, -0x22302646, 0xcc36c496, 0x7dccdd49, 0x5ec61feb, -0x573d0210, 0x0ff3deb6, 0x92cc42ca, 0x63660a1c, -0x9ab6f544, 0x3436edd8, 0x3d9f21c0, 0x62aed963, -0x4293df8a, 0x51db6516, 0x0ee30026, 0xfc0a9525, -0x10f7988a, 0x161882c2, 0x0b3f4670, 0xbe6722db, -0x009a440a, 0xd0141edf, 0xfc45c36e, 0xac58ab1c, -/* 566-mu26a003.inc */ -0x00000001, 0x00000003, 0x01102000, 0x000006a0, -0xdff45617, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x3178fc44, 0xfd2d6c5b, 0x28009450, 0x947b9751, -0xd6a28dec, 0x5e09fb62, 0xf044b3ff, 0x843a9280, -0x6aade48d, 0x801ae197, 0xf259ccd2, 0x771a35d1, -0xabb20a93, 0xc7f266a6, 0x31cffc14, 0xffdf0618, -0xbfb77be4, 0x26fd9509, 0x9ae8c81b, 0xc2635165, -0x7ac26cc4, 0x976b8074, 0xd8d4a3a3, 0x6d4664f9, -0xe66a36b4, 0x9741da01, 0x356eb9a9, 0xf6742e78, -0xa88cf726, 0x74bb245e, 0x8baaf4bc, 0xf6fc71a0, -0x5b3bb726, 0xcf9f8902, 0xb89da8f4, 0x65b345a0, -0x938c67a6, 0xe4aae8d1, 0x7d69421f, 0xc01dd8d0, -0x88ec622a, 0x0beca3b7, 0x9daed2d4, 0xc0609133, -0x26706b8a, 0xb4408beb, 0xe0dceb6f, 0x2c352416, -0xdc35aea6, 0xd69cd883, 0x0ca7500c, 0x83914075, -0xc82b76d3, 0x155990a5, 0xff91c631, 0xd5bbbfc8, -0x2b80f306, 0xd7b89878, 0xf2501891, 0x2a98f0d3, -0xa86be9e0, 0xe58aab32, 0x364ffe79, 0x873fe5d0, -0x972b765c, 0x33605773, 0xe507a817, 0x9cc1b237, -0x730c85bc, 0x9ea45b18, 0xd2d2ba23, 0x4aa64ebb, -0xc3c02974, 0xe2c678d3, 0x5fddc66f, 0xd392ab7b, -0xe625b2bb, 0x6fa1bf87, 0xadb819f2, 0xbffc438d, -0x29a75a42, 0x8273bb3d, 0xa2ebbbaf, 0x44751af3, -0xd1336dc9, 0xb8ea2a01, 0x507c00b5, 0xbc5d1ae2, -0xec3d52dd, 0x3b420cfa, 0xb5903c32, 0xe27e323f, -0x635fcc3a, 0x837a737c, 0xe0a93c8b, 0x49c32b2c, -0xa2b28a0c, 0xc4910f2d, 0x7823090f, 0xdd207b5e, -0xace44b45, 0x6b07aebb, 0xf1de2791, 0x9b43ed2c, -0x2a290c51, 0xd846b2a3, 0xcd082cc2, 0x593253a9, -0xa71a8bfc, 0xe84ebaea, 0x7a1dbc25, 0xa8ed8941, -0xbad427df, 0x24ea60d9, 0x8bb91a75, 0xaf896799, -0x42edd33a, 0xcdda6c02, 0x855e1351, 0x2f9a8925, -0x9de00122, 0xbfdcdd31, 0x3adaad66, 0x95b46ddd, -0xef100e3b, 0x42c8f68a, 0xa0e8c87e, 0x964e792c, -0x2f95bc90, 0x8c072bd7, 0xcc21c070, 0x0c266694, -0x85c49295, 0xd120e46c, 0x1dc291d7, 0x9e857b79, -0xd6e85535, 0x692671b1, 0xe8fc9aa5, 0xf79cdf25, -0x3b703fbe, 0xb09ae23e, 0x948b08e9, 0x4a49df51, -0xb903210d, 0x8fb8b6f6, 0x0e9503c5, 0x970ca0e3, -0xc4a1d8fb, 0x772a97b3, 0xcdeeef55, 0xa9bbd8d3, -0x4980089f, 0xbeec79a4, 0xc47571eb, 0x71c7b097, -0xe597f149, 0xe2640676, 0x23d49990, 0xbe334a4a, -0xd8918d52, 0x677fdbb4, 0xb83811cc, 0xe2516308, -0x2e959c61, 0xd49eccff, 0xd362bb93, 0x734b6342, -0x9ad68a98, 0xb645ea96, 0xda4164dc, 0xe9a108e9, -0xfc0f2aba, 0x1771bdac, 0xd2a20f4d, 0xebc4a613, -0x16dbc8b9, 0xb7216f3e, 0x86226957, 0x64ac2fd8, -0x8dcf6c5d, 0xc7650467, 0x3dd5eb2a, 0xaab71dee, -0xa84d32a9, 0x0c302583, 0xbcfe09a1, 0xab924a16, -0x155e7a1f, 0xe7fae2f9, 0xca1b2b22, 0x56ef5e84, -0x948dbc62, 0xd924664b, 0x40ef5230, 0xfc806b91, -0xddc257f0, 0x13b601b6, 0xcd076bce, 0xa403b0ed, -0x687b7197, 0x8c43494f, 0xb1656423, 0x3608cde7, -0xb1fc13f2, 0xde76b60c, 0x2707c239, 0xf8800625, -0x9a01f190, 0x16bad602, 0x91e499b9, 0xa66a5f6a, -0x53ebe018, 0x2fb101ac, 0xf7375808, 0x9f389ac9, -0x02731d5b, 0x4332c74e, 0xa88298cc, 0x0915f8ed, -0x72cbccc0, 0xaefe2a36, 0xb9462942, 0xb96c3734, -0x5ebc9539, 0x2233e83a, 0xbc061e53, 0xcec70013, -0x2fdf4e90, 0xcb3922cd, 0xbb18ac4d, 0xbeacb4f9, -0xc244558d, 0x7eaf183b, 0xa26e73b5, 0xa43ed7c5, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 537-MU268110.inc */ -0x00000001, 0x00000010, 0x09211999, 0x00000681, -0x04387de5, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x4be8aea8, 0xd011c071, 0x2a691f13, 0xd89f633e, -0x14e47ca9, 0xf25e7d3e, 0x0517055c, 0xb27eb3e4, -0xadf16268, 0x1b8191ab, 0x112ca6a0, 0x49430934, -0x17a305b0, 0xad00ad6f, 0x00e6974a, 0x8951b04d, -0x99dbff9c, 0x10888ff1, 0x1da8fa08, 0xf7144700, -0xb505b499, 0x7142bd12, 0x0d1493b6, 0x2136a4fd, -0x5899d436, 0x15828940, 0x081ef5c7, 0x75077358, -0xa620a5e2, 0x89c640ca, 0xe3f85a5a, 0xc029fc66, -0xf80f5032, 0x8f951f5f, 0x9fa70a3a, 0xdb254c57, -0xc6d62e3a, 0xb50c3264, 0xdd0b50b5, 0xbe3afae4, -0x0682077d, 0x7c60a795, 0x9916f56d, 0x68aa7525, -0x2a9a5235, 0x490a38bf, 0x3a42c9de, 0x6e2e5b42, -0x4878ebde, 0xce48d89d, 0x04f6688a, 0x4e1c326c, -0x757b9b5f, 0x7752f735, 0x8b4db81c, 0x2c33a81f, -0x13ca01ef, 0xab71cb68, 0x420caa16, 0x1ffbee7e, -0xf3174461, 0x7508ac44, 0xf318209a, 0xc99842e7, -0x87ccd230, 0x53d05be4, 0x29f3de9a, 0x36a65d67, -0x2d7a9dd9, 0x88ad51ef, 0x25b7fdbb, 0x2b8ca261, -0xf6e85e6c, 0x1ecf9ed1, 0xc63593f9, 0x8ac9d629, -0x135d680e, 0xd200f572, 0x207623a5, 0x51b8aa3b, -0x31b5be82, 0xf3979e00, 0x57784998, 0x7dde484b, -0x3abccf17, 0x223285bc, 0x79f52876, 0x74c53f13, -0xce16fe96, 0x2893f18d, 0xd0235541, 0xe7ea5aa5, -0xb1f4a0ec, 0x7c7da02a, 0xf496b043, 0x7426394a, -0x02654a4b, 0x32016d19, 0x80a03a11, 0x2b068325, -0x7c8cb2ba, 0x633b0572, 0x2b850332, 0x1d74c0d6, -0x2b2d934a, 0xb220186c, 0xb123a130, 0x04075222, -0x25b47e62, 0xb9b2f4f6, 0xf40dd666, 0x46c90809, -0xaacdbc09, 0x00481902, 0x124fa0c6, 0xf8b98698, -0x56ee7359, 0xa9c82490, 0x9b650054, 0x92f037e6, -0x77f3ea42, 0x4f9aa420, 0x3756a81e, 0x54954b2e, -0xee31604a, 0x642d998f, 0x0163fd0b, 0x794b452b, -0xd6819422, 0x11887658, 0xaa2b44ad, 0x484f36c2, -0xe354ff29, 0x6393ee5e, 0x8642ab8b, 0xb83d39fa, -0x481f04e3, 0x1ec27310, 0xb0d68b33, 0x844c0d92, -0x758ee6e8, 0xf7db3d42, 0x9af4d118, 0x7294b5f3, -0xbe309bfb, 0x63ee1f13, 0x9a734a9b, 0x47241805, -0xc9b2887f, 0x76e37669, 0xa2ddf49a, 0xc605fa9e, -0xcd6420d4, 0x46f39785, 0xa0246d51, 0xab10ad59, -0xbcdddd37, 0x0362abf3, 0xdf85c4e2, 0xd32dfa5e, -0x7bb483ba, 0xd22c3e77, 0x16e9f835, 0x7b228d06, -0x22e4a405, 0xd92596df, 0x03653ee5, 0x1d982e39, -0xb344edc6, 0x25163d17, 0x8fce2be5, 0x0a0183b3, -0x1006e059, 0xb1cd9f3b, 0x8da1f83d, 0xbd6f26e7, -0x1a11defb, 0x7102209f, 0x4936f369, 0x429ec072, -0xfedb6040, 0x9f59ba31, 0x3c6aecd3, 0x38fb1c21, -0xc93fb52b, 0xa5ab3b8a, 0xacff84b4, 0x64b36e8d, -0x328fac01, 0x39f8ef94, 0x7999fd1f, 0xf9aa181f, -0x9b039dcc, 0x10a01aa9, 0x437eb2ea, 0x2a2ddf7d, -0xc6f8bebe, 0x865e2275, 0x7a987e18, 0xd3b7b1fd, -0xd9351c1f, 0x16016358, 0xd903741c, 0xc870ebb8, -0x3af4033b, 0x004ac482, 0xd445896d, 0xad6536af, -0x80c333fb, 0x1b7caa83, 0x357345c3, 0x934c2630, -0x1f9a45f6, 0x9729e354, 0x32fdaba8, 0x9cafb4b9, -0x8e9dda39, 0xa9700b6c, 0xbea0c131, 0xe5a55806, -0x1b0e2f71, 0x615fa421, 0xce8420ca, 0x893bac43, -0x0b95b949, 0x9260ab02, 0x31c9a79b, 0xf2a4da18, -0x73ca1c12, 0xb41c7210, 0xa3908679, 0x2208e3d8, -0x3797b08e, 0xbfa6a55c, 0x5a8be539, 0xbd9e623a, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 875-MU16b401.inc */ -0x00000001, 0x00000001, 0x01102002, 0x000006b4, -0x58213e6a, 0x00000001, 0x00000010, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x1016aa4c, 0xba6d2007, 0x139b094a, 0x8d5cd4f5, -0xece206e4, 0xfac0aa68, 0x26674533, 0x9464601b, -0x4b3f7f76, 0x64133194, 0x37c151ed, 0x3ee0e278, -0x7cffc9c4, 0x562be2dc, 0xd1067021, 0xaf8f1728, -0xbad0534c, 0xf7a67cca, 0xdd34e969, 0x774bb723, -0x5635256e, 0xd23cce15, 0x3c7c50ce, 0xa5faaecc, -0x1c717607, 0xcc1e6f3e, 0x16a4c6a7, 0x58bd5816, -0x0a2e73b3, 0xd65104e4, 0xb873ec1a, 0xe6cdd62e, -0xcd278f3c, 0x2e081c41, 0xf43f4439, 0xbcdfa892, -0xbb20c46f, 0xe0c8f8e1, 0xa619c4cc, 0x48eea22e, -0xcfdf4bc4, 0xefaf4494, 0xa7cac511, 0x783c367e, -0x6fc43ebc, 0x67e32786, 0xf0c1fbb1, 0xf93d5b0d, -0x36e9b7e8, 0xc3b4dc36, 0x4beec4fb, 0x88382c9d, -0x735dd739, 0xc5e23b67, 0x0d325dd4, 0xfe8bd98b, -0xa0f294f9, 0x1916bcd9, 0x7b73f066, 0x26758acb, -0xf10be125, 0x5aee77d0, 0xa005f65a, 0xd4d88c84, -0x02340625, 0x687da1c4, 0x29906f8c, 0x20ca4e9c, -0xcad37ebf, 0x15ae02ef, 0x06ac0241, 0x60c210b8, -0x07bb359b, 0x970ada27, 0xd15463c5, 0xb1df482a, -0x32c0386e, 0x72719013, 0xbe45b1da, 0xda807e08, -0xe1340a36, 0x9bbc789b, 0x71ae0eb2, 0xa7b0e639, -0x12948517, 0x8bd37587, 0x083273be, 0x1a73a3be, -0x2e0cf9a6, 0x3c401aa6, 0xc74c77f8, 0xe6ee9da6, -0x3188f408, 0xcdfe98ff, 0x71369d02, 0x032e20b7, -0xb9083418, 0xe5ef65a8, 0x3a9317d2, 0x23117ad6, -0x6c303cfc, 0xe6aed513, 0x97b7af1e, 0xe277f5aa, -0xd1f788a7, 0x72305569, 0x2a241259, 0x7f786fa4, -0xeba79f99, 0x740b14fa, 0x2a8e8a3c, 0x7824a0f2, -0xb1b4588e, 0xc775677d, 0xbc2372a6, 0xd485e398, -0x8a989d5d, 0x960199ba, 0xe5dca6a2, 0x818b5c9c, -0x655f760d, 0x8a75081a, 0x86a6d67a, 0x05e74583, -0x160d2e9b, 0xecf3f2b6, 0xb0e5f342, 0x162dcc4b, -0x95d05b92, 0xec736eb1, 0xad367c81, 0x6b98845e, -0xaea10969, 0x32a923cc, 0x0e20e511, 0x11f1d80d, -0xa80bff0c, 0xdee5c142, 0x5618820b, 0x9ab1530f, -0xeb2e5aad, 0x71986a78, 0x4b9f79ab, 0xdcb38492, -0x5d1df5ee, 0xa6947ea5, 0x4b81b7aa, 0x4fd1194a, -0x809256af, 0x2d7d2c85, 0xc3a3d15b, 0x4e4dde55, -0xa275c268, 0xe584005b, 0xe7975491, 0xed9d3d06, -0x6aaf4acf, 0xf4e3f967, 0x7c04ded2, 0x9fefbb0c, -0xff806dc8, 0xbe36d1ce, 0xdc9e4a45, 0xe54a5b71, -0xea53d6aa, 0xf0e13f21, 0x250f7e77, 0x09429ec2, -0xb34360be, 0xdf249256, 0x4b6b8d57, 0x6f3b9f7d, -0x1dd4d988, 0x6a68c719, 0x82d171e5, 0x04de6517, -0xd2628f0d, 0xfe6fd4e1, 0x8f3cbd0b, 0xd8517c88, -0x7993bb4f, 0x9487f25f, 0x493ad1f1, 0x781b2745, -0xd25de9ed, 0x63fe8ffa, 0x83be8468, 0x5955efd3, -0xd07886cb, 0x3cbbf313, 0x10255dcf, 0x4fe6e5df, -0x2afbe5ce, 0x2731cea5, 0x3ca3a0b4, 0x9a73e5b3, -0x7022f776, 0x43f0062b, 0xac060c7c, 0x89c88761, -0xdf86c5be, 0x0f705bcc, 0x811d31cd, 0x56e72be7, -0x473becc1, 0x74d511a7, 0x7f44e656, 0xc04d3763, -0x487e15a7, 0x851f93bd, 0xc0cfdff8, 0x11b62ba1, -0x45ebf606, 0x5ae10f89, 0xcfd063cf, 0x25b52d80, -0x03b35a1a, 0x7e5be251, 0x643e69b1, 0xe50e0a26, -0x73a3be25, 0x7bd17fb9, 0x72ac0b0e, 0x2f04ee8b, -0x8e614214, 0x73fbbb40, 0x6c87f572, 0xc2cca0b1, -0x3a575557, 0xe38b025c, 0x57d61954, 0x5a77769b, -0x123d2893, 0xd21f163e, 0xef617597, 0xbfd67b8c, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 452-MU165310.inc */ -0x00000001, 0x00000010, 0x06281999, 0x00000653, -0x4b6dfc5e, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xa9f6b598, 0xec73f4eb, 0xffce329e, 0x6c5e06dd, -0xce5188bb, 0xe94f7930, 0x15eedaa4, 0xf18757d4, -0xd70c827d, 0x31455e24, 0xf5b4bbcb, 0x9998ca1f, -0x2ec1d583, 0xaca650ad, 0x8df19fa7, 0x166dcc31, -0xf4322404, 0xa03f61f8, 0x5944ee81, 0xfc83e22b, -0xbbddfdb7, 0x58347247, 0xd2469409, 0x827198e8, -0x3400aa4f, 0xedd3d882, 0xdc966e7d, 0x3e30b255, -0xa9b45d4e, 0xc78f0810, 0x5fc7c407, 0xb1a289bb, -0xfb0657ec, 0x476c2047, 0xbc5f1574, 0xa711c231, -0x164daa0b, 0xbd96098f, 0x84d29406, 0x5b6f6564, -0xcda8e7b0, 0x8b75723b, 0x4482d30c, 0x9f2a8e06, -0xdacef785, 0x54313eb6, 0xaf86cbb6, 0x9821df5a, -0x32b22218, 0xb7eec0a2, 0xb11f02be, 0x36f4df12, -0x9dae899e, 0xa449a294, 0x49cc03ea, 0xa80e5d89, -0xde78ee40, 0x67548fce, 0xbaf8ca83, 0xd8c19acb, -0x78e71346, 0xb4507a69, 0xce0adbfc, 0x5aad67b1, -0xe3132110, 0xe4f3d82d, 0x0fbd379c, 0xb2b5f05c, -0xed0a9a6f, 0x4ad8ddb1, 0xe2cff1b0, 0xc30d2a98, -0x4b7f0d4a, 0xd61d5eab, 0x87c986b6, 0x00a7d89f, -0xc19a7241, 0xdeeb64a6, 0x0dd96c74, 0xf5037a54, -0x95b1f67d, 0x206c6c4c, 0xa92d9eea, 0x94b019eb, -0x735c9247, 0x800b3eb2, 0xb47accac, 0x4359700b, -0xe904733a, 0xba962336, 0x4d53775a, 0xf977eb8a, -0xe1431b72, 0x4fab02d8, 0x912c42a2, 0xd5b58a8d, -0x7a7caa9f, 0xaf26015a, 0xc7434abc, 0x61cc5746, -0xe7103ec9, 0xc3450e0c, 0x39e65a43, 0xc51d998d, -0xc7d74311, 0x1bc02a8e, 0xcde79dce, 0xcdfa8a67, -0x4fe6b49a, 0xd79c38ba, 0x9066cb70, 0x7c0835b6, -0xca2f447f, 0xb707beb6, 0x7f6c9230, 0xc82d1275, -0xea2546b1, 0x7424db79, 0x8cf638af, 0xdb930706, -0x6433cd97, 0xa312fc98, 0xc4fd9859, 0x6a2f6d72, -0xea0dc261, 0xd143ea78, 0x2e42e415, 0xdec0b3b6, -0xc28dd5ba, 0x071bc9af, 0xd4d5d5e4, 0xda3cfdb0, -0x58d5d6e4, 0xc182d491, 0x91201b02, 0x7aea0079, -0xc5e32789, 0xbf9508d9, 0x616e6741, 0xcb2c8d6b, -0xe5dafc14, 0x78d5dfb4, 0x9318c3d4, 0xcfe1f2e1, -0x600efeca, 0xa401d5be, 0xc6d9cd4f, 0x7dfb0134, -0xf1da7e7a, 0xd2b4dd4d, 0x2bd041fe, 0xce3aaf95, -0xc0f5d723, 0x03c769a8, 0xd6ab8b78, 0xd3aedb57, -0x4bca8a12, 0xdaf9939d, 0x99b55331, 0x62f7b086, -0xdbe96aae, 0xb308ebf5, 0x7cd9c4d7, 0xd84f11bd, -0xe47185d0, 0x67f29f82, 0x8866d29c, 0xddf9681d, -0x6f934e37, 0xb4753e8e, 0xfe060bab, 0xbae582f3, -0x7ecfd0f4, 0x9a894f8a, 0xe97d6672, 0x3487f699, -0x8f8adb39, 0xb6037e80, 0x2d1fd356, 0x2f38ba4a, -0xaf1befaf, 0x808839f3, 0x2fafe10b, 0xa1a277b7, -0x98a496bd, 0xdcd885a7, 0xa1d07540, 0x4157997d, -0xdd40d57e, 0x89bf057e, 0x41a32725, 0x5c7bc8f2, -0x9ce6b8ae, 0xc83ac484, 0x51507007, 0x3c785978, -0xd79539d5, 0xfa36aea6, 0x3f47b6ee, 0xf2ca21e6, -0xee752fc4, 0x11cd24df, 0xf948d935, 0x0b9cf56f, -0x1286f53a, 0x11d5fb21, 0x177308b8, 0x08f9048a, -0x1703ba64, 0x0ce282f3, 0x10e51cce, 0x73f2895c, -0x032c9e05, 0x85121701, 0x6c47c71d, 0xfdca9c87, -0x8ac1cd10, 0x892b0cf3, 0xe61155f2, 0x1d127feb, -0x90aabf12, 0x8ded9c74, 0x2d5895c4, 0xb6880c5f, -0xaaf4ef4d, 0x1144f331, 0x7a3fd2f9, 0x9e1ca270, -0xc538d5d6, 0x534c21fa, 0x859930c9, 0x1f486800, -0x46c3746f, 0x4a8fb4f5, 0x06b1666d, 0x96aec81b, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 430-MU165041.inc */ -0x00000001, 0x00000041, 0x05251999, 0x00000650, -0xbc120ef5, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x7e76519e, 0xe3f74799, 0x3af64fe9, 0xa7d62bb9, -0xbb89ca97, 0x3d0dbae6, 0x893aefcb, 0x87225797, -0x360ecae7, 0x98055f79, 0xbafb6168, 0x47b4b45d, -0xfee0e965, 0xcb1412f0, 0x30f49e5e, 0xcbd9a334, -0x86ad899a, 0x0b77df32, 0xa6a92a8d, 0xddc09b3b, -0x470d70e4, 0x9b7f9f70, 0xa698053a, 0x28e892a8, -0xf0444ac1, 0x83db3cc1, 0x4f5ef1b8, 0xf7c5e1e0, -0xe2e9d7ee, 0x1bffc291, 0x846c4754, 0x969086de, -0x386a0c4d, 0x9d7ed4ff, 0x863f6638, 0x66bd6bb5, -0x8b27bdd7, 0xe8b31939, 0x53badccc, 0x8a3609f0, -0xa4abd8a5, 0x57e361f2, 0xe8a620f1, 0xaedb6c10, -0x64cb41a3, 0xcae3f75a, 0xebd6c20d, 0x70441f38, -0x81baa0f0, 0xda741b2b, 0x71928a31, 0xe0c2a8b1, -0xf5ec92fd, 0x3d0106fb, 0xc9213fa1, 0xd18dfcad, -0x745aa758, 0xd6756497, 0xb0d0edca, 0x3b82cae9, -0xa11a3cbb, 0xef0ccae1, 0x1c3dde9d, 0x9c51b887, -0xb492e30d, 0x08cc3fa9, 0x88540d5b, 0xd534d068, -0x46310617, 0xb09f621d, 0xb35b272d, 0x0d6ade93, -0xc8ea5e48, 0x9910fc17, 0x405ae2a5, 0xeabe75f6, -0xe30d44c7, 0x54d998a7, 0x8be13a9e, 0xee749ea9, -0x4ee14c60, 0xb97f33bf, 0xdfa4d3a1, 0x72138db2, -0xc0e2a9de, 0xfa51201a, 0x2a66908c, 0xf00413a6, -0xcda476c2, 0x349ef9ca, 0xd9cc5827, 0xcfd42c2b, -0x6e43c59f, 0xe6488442, 0x8e6b5128, 0x5c342d58, -0xcd93d18c, 0xa0338ab9, 0x50a109e2, 0xce1fdfb6, -0xe156fd23, 0x5a8ab4f2, 0xfd877e15, 0xe27f7c42, -0x023b791e, 0xf7a3576b, 0xf2e85a4c, 0x152c3077, -0xbc8bf1be, 0xcb8ce737, 0x1a3ef077, 0xbe674ac0, -0xbb58a8e8, 0x0b5efc96, 0xaa70c36a, 0xbf232d8f, -0x4a173ad5, 0xbf2d5f44, 0xfbe55d39, 0x6d34c5c8, -0xb5a5395a, 0xf09c85c6, 0x59fa5bfb, 0xa3a88e24, -0x8baba56d, 0x6e7a2b4d, 0xd6dc185d, 0xa2928bcc, -0x7ad3b0ec, 0xc10b640e, 0xbf0c3bef, 0x497506c9, -0x8a916b56, 0xbce57d43, 0x2005fc34, 0xbceb8c26, -0x9eed6b54, 0x1f980a86, 0x93a742b0, 0x9bb3cd72, -0x45b04f20, 0x87f23d21, 0xce9dc199, 0x4213d168, -0x81960d1f, 0xeadaa7e5, 0x7b6ebd42, 0x9f31ab27, -0x9ae749c0, 0x49be575d, 0xf8afb238, 0x8bb905b4, -0x74842213, 0xd2e5c154, 0x87054f04, 0x62ce0156, -0xb6caab1d, 0xa693348a, 0x1057003e, 0xa3c5203b, -0x8af21d88, 0x23619382, 0x9c065f7a, 0xb51f3d1a, -0x7b90340f, 0x9d69951d, 0xc8f1c2f1, 0x6ba8da99, -0x8ef51252, 0xcc36317e, 0x7aed3ce7, 0xde1b9d47, -0x9c860b63, 0xe06cfbd4, 0x6dc6929a, 0xc75313b5, -0xc1ef067f, 0x1b887719, 0x2e1a2dc3, 0xd01815d6, -0xe657f6e1, 0x1f947b53, 0xdfd30cd4, 0x3cf4fd2b, -0x01ac6ac5, 0x0cee5d2e, 0x0e4c5354, 0xb4e7e3c6, -0x334e4bf2, 0xbd24ed1a, 0xa6240eed, 0xc1106c93, -0xa22c3237, 0x77803217, 0xd4487c3d, 0x999f7c88, -0x72e4cff9, 0xe15f44d2, 0x93a3e254, 0xaed5d723, -0xff7e2b22, 0x56c82c9f, 0xbcd60726, 0x343d7d03, -0x5d02a7ec, 0x7f3b10cb, 0x1f58a60f, 0x362ad6ab, -0x51e4ef3f, 0x4bf657a1, 0x01046a8d, 0x3aff1983, -0x5eaaa3d3, 0x947b35a0, 0x225ed134, 0xc91d61d2, -0x98b7a545, 0x8310dcb5, 0xd085a7d4, 0xdd85e8c2, -0x97a873d1, 0x7faee475, 0x4cf26f63, 0x4bd7aa27, -0xe2664a65, 0x97e96c2f, 0xb88267f7, 0x4fb40f0d, -0x43cd3450, 0x0e160efc, 0x9c0b4f19, 0x2c5e5fb1, -0xdc5e7d64, 0xc3da5a8d, 0x6ffe0dbc, 0xc330555e, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 429-MU165040.inc */ -0x00000001, 0x00000040, 0x05251999, 0x00000650, -0xb6a8b9b9, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x601e3c82, 0xe5a7e267, 0xbac45110, 0xf789f850, -0xba6aba81, 0x2afebde2, 0x21a7efcb, 0x2c955f52, -0x6fc277b1, 0xcc2e99c5, 0x26ebf8e1, 0xc0b5fe1c, -0x4e879083, 0xa9264124, 0xf468ff13, 0x0bb4db3f, -0xf741017f, 0x59e89ef5, 0x749f5029, 0x75eae17e, -0xb173d6fc, 0xa1aa6c88, 0x989b3c2f, 0x61acd68b, -0xacc61f2f, 0x573d81a9, 0x48dcd515, 0x5804c273, -0x1cac96f9, 0xf0fb741f, 0x31ffa59f, 0xa14a8b31, -0x82ff639b, 0x5e9a7e4e, 0xa081483a, 0x234a57ec, -0xe468eb19, 0x79b183d1, 0xbd3c1114, 0x0ad767be, -0xe8422277, 0x893322b5, 0x16b54d35, 0x16f4baf4, -0xdf12aa92, 0x9f1716cd, 0x6ce23144, 0x85524280, -0x76c31610, 0xe86bdee7, 0x8cf04199, 0x98d99747, -0x53c209d4, 0xacc2aa48, 0x342d454c, 0xe9327a0c, -0xfc57b773, 0x055732dd, 0x279b60b3, 0xd9fc24e0, -0x0d327b77, 0xdcdfd4c2, 0xe23250d4, 0x0a5d96a0, -0x47b108d2, 0x0adab0b3, 0xb41f6699, 0x28a5398b, -0xef3f4303, 0x35be207c, 0x4e6f9e76, 0x3f7834a9, -0xb50796ab, 0x3185e1ad, 0x0a38fb5d, 0xe5464beb, -0x751c4e5e, 0x482d4169, 0xc56047fb, 0xf616f12f, -0x743decdc, 0xdfe401b9, 0x612c7cf4, 0xf8304c02, -0x2885c3b6, 0x2d961bc7, 0x9f6a38f7, 0x97f6f1f4, -0x5ca2ee99, 0x0e94f902, 0xd10a1ac9, 0xb36c2107, -0x015fecbc, 0x02a2a183, 0x716daf36, 0x4990aa8e, -0x06bfb540, 0xf4a407f5, 0x689fa6a8, 0xcd05353f, -0x3c598553, 0x026cb343, 0xb85e95ca, 0xf5d1c7bd, -0x363c740a, 0x89ef13a4, 0x3afba31d, 0xf02bc3a7, -0x80d889df, 0x489c54f7, 0x99a2b71d, 0x88f4dd0a, -0x6b3f6384, 0x65e14382, 0x02d40f2f, 0x2f46ef94, -0xc5c715cb, 0x60ea1752, 0x4e238f77, 0xde0a1049, -0xd75774bc, 0x58faacf8, 0x81ed4268, 0xe9d387d1, -0x9d638a9e, 0xe0a27ad1, 0x6e94dca1, 0x7ee5fcc3, -0x819a7d58, 0x85c258ac, 0x14f2b0b1, 0x65f4c7f7, -0xe1c9aa7d, 0x714e6201, 0x990ff117, 0x5d7af3dd, -0x41fb4988, 0x1cdfa982, 0xf1fc11b7, 0x60e7a309, -0xb6a789c5, 0x70737ff3, 0xc2fa3fe3, 0xbd407b3f, -0x39ad84de, 0x76b8d442, 0x2a778268, 0x5d1d390a, -0x77ac2c16, 0xa4cec96f, 0x8c7a6045, 0x8b258bfb, -0x5a6a3154, 0xb0d0fc87, 0xe63a160d, 0x3dc8b9ea, -0x62c373f2, 0x0681a8fa, 0xd5eb4033, 0xdbf53e00, -0xb6863aec, 0xb3310839, 0xd8f994f2, 0x59d656d4, -0x02db8c87, 0xcfa1529a, 0x6c4bb4c1, 0xd6097838, -0x60b1e0d3, 0x33afe51c, 0x8e57c238, 0xeab39da5, -0x133b7741, 0x7b031f5e, 0x8b4ff0c8, 0xa8e779bd, -0x8676a9de, 0x6c133026, 0x37f3ea88, 0xdf864b39, -0x6b7e9022, 0x213ca570, 0xb9aa6a56, 0x746208cc, -0x677d2980, 0xc7e19363, 0xb5c89ecf, 0xa513c816, -0x5f76f49d, 0x0b250ddb, 0xefc3f81f, 0x9fd57e7a, -0x75386d0d, 0xa78b1410, 0x64f86f55, 0x50f9c555, -0x7cad7829, 0xd0a4e891, 0xa2df6517, 0x128751d6, -0xb29d7543, 0x9915052e, 0x8e32a38f, 0x17b1bb9a, -0x6fe77ff1, 0x65cc92a1, 0x5fcb90da, 0x60565207, -0x45e5f86a, 0xada512e7, 0x9bd77ad3, 0x8203292b, -0x24598065, 0xa8029582, 0x486b4e11, 0x7041340f, -0x763bafa2, 0x14f408a4, 0x71b784bb, 0xa4c11a9a, -0x9f872d6a, 0x946251ae, 0x6fcf6747, 0x1e354c9f, -0x82316b09, 0xcc8f682e, 0xce89240c, 0xfa2057b1, -0x4ec8ed87, 0x32ab439a, 0xbbf6f7b1, 0x0c55ebda, -0x04590c3b, 0x94aae71c, 0x41263f82, 0xd4a0fd58, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 966-m04f0a14.inc */ -0x00000001, 0x00000014, 0x07162002, 0x00000f0a, -0x64731550, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x80e0e61a, 0x7cb2c607, 0xbe1e2fc9, -0xacaf1526, 0x31514e28, 0x9252d426, 0xb999ebf8, -0x8469bb8a, 0x95e72fd2, 0x5f7c5472, 0x254adcf0, -0xf706b236, 0x21ef3efb, 0x82d05526, 0x8b10bd77, -0x268ab8bd, 0x929739a5, 0x0f180e02, 0x3ad1cc5a, -0x23a10814, 0xbc4257f8, 0x026ded8d, 0x84bf45be, -0xe13e69f3, 0xbb0edf16, 0x85218fd2, 0x898af4e1, -0xcd635f26, 0x846ab0c6, 0x85a5d5cd, 0x077b4a16, -0x71514de0, 0xbff893a6, 0x47536ab0, 0x1fc4b546, -0x906f4b85, 0xc1f997d5, 0x0ba4b594, 0xa823eb50, -0x416ee239, 0x659b0dbd, 0xf240ad67, 0xe042d532, -0xce92f455, 0x9f318d9f, 0xac11fada, 0x6fc234ab, -0x18cddb76, 0x67e52b4f, 0xa6f01943, 0xba695e2a, -0x245bd123, 0xce05288f, 0x6582101b, 0x5be73a23, -0x6ab67d0e, 0x873ac6f3, 0xab4c48f2, 0xe0d64284, -0x65f33ddb, 0xd33abb56, 0x8dd411c3, 0x86f370ea, -0x1c3726b9, 0xd561edb5, 0xa0484b79, 0x63bdccd0, -0x54d42183, 0x05d9b9c2, 0xd1d2e489, 0x572f0b07, -0x6b804808, 0x9ee441c8, 0x87e1e425, 0x0d4d3c3e, -0xbb9188fd, 0xa7f1243b, 0x807be6fb, 0x8f828057, -0xfe37dd84, 0x104ef504, 0x5aa650b4, 0x2f1b611f, -0xd021e808, 0x1d4ca877, 0xdefabd4d, 0xaa0cbe35, -0xa4e89854, 0xa880cfc1, 0x08ed71f1, 0xb58e8625, -0x2f4bee9d, 0xfef8678d, 0x2868ade1, 0xcdd1c7a4, -0x2b823a15, 0x4788ea69, 0x7a1de61f, 0x24a51210, -0x4373e00c, 0x7f8e55c9, 0xb2c5092b, 0x74f9e0db, -0x2f54f62d, 0x13e3b1c8, 0x835863dc, 0x7401feb0, -0x82d9962c, 0xc321a358, 0x8db3eec1, 0x3d70aa8a, -0x9e8d115a, 0xd1f258ce, 0x3db0262c, 0xdedf4ecf, -0x2b43787d, 0x01bba4ab, 0x5533bfb0, 0xf25756a2, -0x6748ff85, 0x49a04cf9, 0x15a3fceb, 0x2b0045b1, -0x354d82dd, 0x51baaaae, 0x9cdb8826, 0x4a5e79d5, -0xc0b783a0, 0x244ee819, 0xc9d7ec82, 0x61b5df6b, -0xa3b0ab47, 0xf4201580, 0x16a9bda3, 0x2ac3fb2a, -0xf2d45287, 0xc775c470, 0xca49165e, 0xf011aa96, -0x7cc3f776, 0x128e7d4c, 0x53a7cb48, 0xc678c16a, -0x704d85ff, 0x5ac3438c, 0x22a4255f, 0x06f4eb73, -0x6d2c4918, 0x7ec8d353, 0x02f64898, 0x402caba1, -0xa2dcd74c, 0x2ec84768, 0x19aaacb3, 0x641e9f60, -0x610245fb, 0xbcde5b34, 0x5b2ad9e6, 0x26d2e619, -0x3c5f7fc3, 0x8a4644e1, 0x6cc1f8fb, 0xb2ec0e52, -0x02186480, 0x1c597a86, 0xea7cb92f, 0x8484972d, -0x90f10aef, 0x7032ba2f, 0x8d51693a, 0x075f7010, -0xef88324e, 0x5fbf378f, 0x1416ae8a, 0x5eac1f31, -0x70e65677, 0x0224e031, 0x1305f1ac, 0x53209b14, -0xb5037676, 0x99e958fb, 0xecb8fe97, 0x20fb5890, -0x568e98e9, 0x87d42ce4, 0x03de50e2, 0x89728dac, -0xdca95447, 0x36114e7b, 0x2aab8e7a, 0xa0529d9c, -0x9901c79d, 0x4ff191b5, 0x7500cebf, 0x210bcc07, -0x815fd1e8, 0x4ebd3be0, 0xbce22cf0, 0xcf2df323, -0xfffa8eb1, 0x016b1ca2, 0xf87846a6, 0xddbf1474, -0x435c41b5, 0x56245808, 0x050eace9, 0x128491f7, -0x48c6fdda, 0x5775ded7, 0x0b4775a1, 0x7ce11409, -0x0d9822a0, 0x084ca742, 0x8f2c8c8b, 0x4278fdfc, -0xe45d26c7, 0xd92793fb, 0xe963acf5, 0x346473ea, -0x28069586, 0xcd7423ab, 0xdd07fab1, 0xf2dd3f15, -0xf924720b, 0x0047adff, 0x3935bd42, 0xde1d799f, -0x03a4afd9, 0x4f0ea217, 0x5f3dd4df, 0x09f611a1, -0x8ecf894c, 0x5111dde5, 0xd79db940, 0x4e2da85d, -0x64622e3d, 0x00ed0f85, 0x192b2af6, 0x526fcc87, -0x3e233c92, 0xdfa9d04d, 0x5a8a7d19, 0x18205eef, -0x3ff5734e, 0xf3ba744e, 0xac73c051, 0xc2cf8a70, -0x3ba41433, 0x123eb210, 0xe3f05134, 0xcfd54fd8, -0x7995e0d1, 0x1760b323, 0x310a7810, 0x2706d0c8, -0x15cf732d, 0x3c0ee597, 0x83e36338, 0x272058a7, -0xff3e9fda, 0x0c22fe44, 0x11a26627, 0x061a17a0, -0xd784b930, 0xb40ed3ca, 0x014eaa98, 0x2cfd7ef7, -0xd3f700a6, 0xa2e0e5ad, 0xf6682e43, 0xbab69f7a, -0x185c3430, 0x10a4a66d, 0x41698b7a, 0x89666812, -0x1cdc431a, 0x301a8774, 0x056fa032, 0x08e5b4ac, -0xd8e66808, 0x06cb04c2, 0x086f09ef, 0x09404e44, -0x4b166a00, 0x1f244ff1, 0x096548b7, 0x3d066268, -0x11c22583, 0x87d98b53, 0x83c785d8, 0x0c295204, -0xa3693e8d, 0x8ca5c952, 0xa52c8190, 0xa9ac34de, -0xe640e56f, 0x16d5715c, 0xf40bac7c, 0x940d757e, -0x0955d322, 0xbd3e2f65, 0x6553293f, 0x0b25fcb7, -0x14875a5e, 0xb5efd0af, 0x79cf151f, 0xa74e5acb, -0x4b249263, 0x14a844ff, 0x4c547880, 0xb598f6b8, -0xe9fffbc6, 0xe983f09b, 0xa5384013, 0x36baf1e7, -0xe3a76c06, 0xde3df31a, 0x25d38aaa, 0xc19d9fa9, -0x2c05457a, 0x0a4fd8f6, 0x01086f65, 0xdf7e10b3, -0xa5f16786, 0x46d77f4a, 0x08336cd2, 0x1d06cb5f, -0xe453696c, 0x6f662a90, 0x40d33558, 0x76c640d5, -0x4e7e4c97, 0x10cb0f79, 0xb1cfbb1c, 0x4f3f0521, -0x8cda32ee, 0x84c3e958, 0xaac41cc9, 0x023e7572, -0xf3266bf6, 0xb4193d39, 0x3a31f7df, 0xbd83c248, -0xc812df3c, 0x0af7f510, 0x82bb61f9, 0x95db6415, -0xf7b12fa8, 0x7a7f4f9c, 0x2ec8f061, 0x3fa8e99c, -0xc19bea78, 0x470c4315, 0x0bcf3abe, 0x787b97b7, -0x78f992b4, 0x05a7b74c, 0x93fc4db2, 0x41094fe3, -0x3e7fe41b, 0xa367bc2d, 0x90b393db, 0x3ec58fe0, -0xb74cc79f, 0x9ed83f74, 0x10daeeae, 0xa524f1ac, -0xafcd0f29, 0x11423945, 0x52319e75, 0x9978031d, -0xa78bb8be, 0x1a8a86d8, 0xf9a5c6db, 0x15d9760b, -0x00028056, 0x2d0f7fc3, 0x7734d88a, 0x1b877e63, -0x7b1db862, 0x25037d9d, 0x5a210d59, 0x1875f3e4, -0x0299248c, 0x90ae4f18, 0x949d7d41, 0x713deba7, -0xa6ff8ffe, 0x243c5296, 0x6020828d, 0xe420ae82, -0xf02eeda6, 0x3a8090e3, 0xaef23b89, 0x40d2cb8a, -0xaaddddad, 0x220c269f, 0x288d2d4e, 0x8689e116, -0x42de5c86, 0x95ff5e35, 0xdcaabe42, 0x3fbb05e5, -0x4ade7e4b, 0xd6612d65, 0x44ad598c, 0x984eeabb, -0x218696b2, 0xf9c83206, 0x881e3b4e, 0x54844f30, -0x1f980f2a, 0x0aec3158, 0xdd92450c, 0xb8a3906d, -0x0ccc7c23, 0x196b48db, 0x08ffaef9, 0x2c44b86d, -0x05fcc149, 0x079869d4, 0x5f3f5d0b, 0x1086de9f, -0x638432c5, 0x1dbe89c0, 0x882041a8, 0x05a6756a, -0x306e76ea, 0x49ad9a0d, 0xbc24d1a8, 0x2a113e7d, -0xdf53ea5f, 0x420a2194, 0x49629224, 0xb9bb75e9, -0x72258daf, 0x1eb90fe8, 0xf9439af0, 0x402b7c8f, -0x4994bf4f, 0x70620662, 0x9a6981d3, 0xcd5e28e3, -0xadd1673c, 0x4914c072, 0xc7173eaf, 0x6027e504, -0x2398e683, 0xd095d218, 0xca775065, 0x019f8a00, -0x4a0eea46, 0x7b31d964, 0xdf392c14, 0x8ce173c6, -0x6395a8a4, 0xcc11282e, 0xbaca1acd, 0x810a079d, -0x3a3d48c6, 0x8368b975, 0x35d4f800, 0x1144a108, -0x2bce5a1b, 0x8b5fd002, 0xd9240882, 0xba73d873, -0xdb3c7feb, 0x1d8755c3, 0x5933a76f, 0x309afa30, -0x2b4c22e3, 0xa283f4de, 0xb1702590, 0x7e644fc1, -0xd5510885, 0x0e14fb98, 0x91e3912d, 0x32d33a71, -0x4665a82c, 0x5c1ff27b, 0xf44a1fbe, 0x58af67ec, -0x1a448167, 0x2384ef77, 0xfa605bb2, 0x125db403, -0x73ca61a9, 0x5cab2971, 0x7c8d471e, 0x0425bdd8, -0x1f5a3268, 0x0f512485, 0x5b27cc48, 0x0e2839bd, -0x056fda54, 0x383a2b7c, 0xa5e6f401, 0x5773b15d, -/* 308-MU163336.inc */ -0x00000001, 0x00000036, 0x09231998, 0x00000633, -0xe92faa0c, 0x00000001, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x09a4d328, 0x97fd940f, 0xcb089376, 0x252ba980, -0x0b7d25b3, 0xe14f99f5, 0x6d964b06, 0x0cde5626, -0xae74d42d, 0x586409de, 0xe12a9af7, 0x6c4acc82, -0x42b77be0, 0xc830f1c0, 0x7055b2cd, 0xf24f8c5d, -0x6c66d2b6, 0x8cbbef3e, 0xa747e953, 0x0be25e1b, -0x94c06e36, 0x28bb97f6, 0x03dfe8b8, 0x7ee89287, -0xcac63462, 0x5bdf25ed, 0x722be3e0, 0x67ddd349, -0xb1645d41, 0x40415ea2, 0x32db2da2, 0x81b7c244, -0x25cbc92b, 0x2ee952da, 0x83c34607, 0x82c2fd4f, -0x0e9c7971, 0xe248462a, 0xd255458f, 0xc2366852, -0x329933d7, 0x5edf55d8, 0xf21e16b5, 0xbcc35b05, -0x316b91de, 0xa0126e04, 0xd81f0292, 0x26e1d666, -0x9fedb267, 0x91508fde, 0x45d90efb, 0xd61ce050, -0x2fb89f2d, 0xa241bb5f, 0x7c07578b, 0xea1c04c8, -0x68f87fee, 0x5323f4c8, 0xa222ce71, 0xf1a3e35c, -0x3acb66fd, 0xf688cffc, 0x36e6633d, 0x9c42ffa6, -0xdea22740, 0x4b675829, 0xe72ce874, 0x3621cff1, -0x05be5e7a, 0x3b548b7f, 0x2f534068, 0x2aafd034, -0xda75c851, 0x177b5662, 0xe4381e1f, 0x442a95f7, -0xee7c105a, 0x2b884bf8, 0xc0c02083, 0x67ebe266, -0x4d6af53d, 0x583ad957, 0xe9e914a3, 0x5a2b0711, -0xcb2d8915, 0x8ec9c7b0, 0x0267fb78, 0xd93005d2, -0xf12c4bb6, 0xf0c5af50, 0x782345be, 0x878e06ed, -0x4b36d1d5, 0xb994488d, 0x607d3d37, 0xc80fc120, -0x84c5423e, 0xede72a5b, 0x4cbc1c25, 0xf21b85a8, -0x663a5da4, 0x9881512a, 0x6fa52c6b, 0xd514b064, -0x6f53e439, 0x6af2890c, 0xd5bfc0be, 0x136736c2, -0x40226505, 0xf916164d, 0xf4918f38, 0x58c6a6ed, -0xbd79a3c8, 0xe7bf1f66, 0xa893ef78, 0x7dee2ce0, -0x491e0b01, 0x7ec10464, 0x89b5b0ff, 0x3d9b68ec, -0x221851fd, 0xa6fb18ca, 0x15d8ac0f, 0xac2b0b03, -0xc01a3140, 0x5c03abfa, 0xb091d90a, 0x7e7c035b, -0x743e5fca, 0xed4c34f2, 0x8a587a57, 0xfbaae37e, -0x4aae42a0, 0xee0dea30, 0xa9ab383d, 0x7f209bad, -0xf1a3a21d, 0xe488dbd0, 0x24bfc203, 0xc320c802, -0x655b5040, 0xa28c26cc, 0x12c6550f, 0x8e23bfcc, -0x32694573, 0x33884234, 0x4528be86, 0xb97aadb7, -0xc6ee97b1, 0x071da830, 0x823c7c87, 0xa6ec20b1, -0xd07ab8ab, 0x32335521, 0x8b2967c3, 0xc93d5aec, -0x9d690021, 0xbe7787e8, 0x995071cc, 0x90eee6fe, -0xfc088273, 0x2c606d29, 0xb75dec26, 0x2b130260, -0x61f8656d, 0xe1e1ab2f, 0x96b048c6, 0x1a64322c, -0x73c8ca10, 0xad4a396d, 0x97fbc79d, 0xb0550ac3, -0xeaf60280, 0x8765b69f, 0xcd556f93, 0xb137bec4, -0xf043f1d2, 0x6d5df75a, 0x0e37f7a4, 0xf40608a8, -0x2f7cf255, 0x3d961072, 0xbd05316f, 0x984dd94e, -0xf2485088, 0x20342cf5, 0xd8deb71a, 0xf294c5a9, -0x209b0839, 0x1aacb3cd, 0x0845b8ba, 0x9b856306, -0x06c9d03b, 0xd53913d3, 0xe0bc9db1, 0x163a2e99, -0x429f2a27, 0x109abfcc, 0xc20cae08, 0xa9ddd207, -0xb0fb829b, 0x0d135e5d, 0x31a689bc, 0xc1b3176d, -0xda2e1d3c, 0x1340d866, 0xb9fa41bf, 0xabd43270, -0x3822120f, 0x8a1c6c07, 0x458a067b, 0xea8d379e, -0x5ed3fc7b, 0xe124189b, 0x8d4af958, 0xa668c998, -0xb92ad776, 0x3412b9b1, 0x038fb0b6, 0xb9b1f3b3, -0xead0cc71, 0x4414f713, 0xc479b4f5, 0x4cc0096e, -0x3b995d59, 0x583d7a1f, 0x43f53eba, 0x7f72ffd9, -0xd789a520, 0xfa45e8d0, 0xb54e34ac, 0x0b2d0924, -0xae28d7b2, 0x42533c97, 0x92d21570, 0x83ce99b3, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 147-MU16502f.inc */ -0x00000001, 0x0000002f, 0x02111998, 0x00000650, -0xac6d02e6, 0x00000001, 0x00000080, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x0be4c352, 0xcebd6517, 0x7648a0d2, 0xf922cbc1, -0x9feb0ef0, 0xb662770a, 0x735b1659, 0xb24ad415, -0x63c4c03e, 0x4f6682d5, 0x9558581e, 0x535c8785, -0xb05b3caa, 0xd84d9eca, 0x6b65b5cf, 0x9e9b31a1, -0x5a3aa5ee, 0xd795cf0a, 0x37aa738e, 0x4f01c8e9, -0x4a5b75df, 0x72749f7f, 0xa3b74020, 0xb48b81d8, -0xc36fcb8e, 0x3fe2ea50, 0x88376865, 0xb499dfbd, -0x6f28b1c5, 0xa89385aa, 0x828031f4, 0x2538470d, -0x1d9cd637, 0x0e234565, 0x983c0144, 0x583e3c4d, -0xb40f71d4, 0xdc29646a, 0x192f6d07, 0x44bcc784, -0x1046a0d8, 0x7bf6bb2e, 0xcf5e24fd, 0xfcb3b5b9, -0x1a0bba7b, 0x08012499, 0x331049a5, 0xf52f3f65, -0x77f565d3, 0x142c5c41, 0x531afd34, 0xb43f9f86, -0x5a1d59d7, 0xb96d46c3, 0x63369c2a, 0x33260f91, -0x9fe551f5, 0xf7775d5b, 0x560cf1d7, 0xc4526fba, -0x5cec0335, 0x3d262906, 0xe10d0017, 0xc318b7b9, -0xa9c7db32, 0x7e839e12, 0x5f380130, 0xd84ee227, -0xc193553e, 0xc4a2ca27, 0xa349dcca, 0xd2270321, -0xbe5a660b, 0x22c5b673, 0x872e8010, 0xb72c6831, -0xd0eab8bd, 0x17725102, 0x43150624, 0x32181119, -0xb82502e7, 0x92d69e2e, 0x01835234, 0x12e93ead, -0xe79dc82b, 0xd1f88e84, 0xb1d500bd, 0x699a5685, -0x3bd89d48, 0xc49eac1d, 0xec7b8746, 0xc295bf8a, -0xcbfe99bd, 0xaed69f4a, 0x0f9272f2, 0x0c03108a, -0x0871bf1b, 0x72a35982, 0xe14dd2fe, 0x09994d09, -0x092e9636, 0x591a12f8, 0x694ff32a, 0xf1290365, -0xb48092da, 0x729a94f6, 0x94365195, 0x7bf0449c, -0x88e52cb1, 0xa3a87212, 0x01385f6a, 0x7c4bac73, -0xc18fde2d, 0x42ebbfba, 0x764f541d, 0x2e8a2dcb, -0x912109c7, 0xea91f222, 0xd3832ae8, 0x8268e703, -0xf2cfef75, 0x3b231bc1, 0x002ef2d3, 0x98a21a28, -0xd01e6c58, 0xe3b2947e, 0xd7406ec8, 0x99fa5c05, -0xc8b97094, 0x5aab71e5, 0xeb742ed0, 0xaa8e5efe, -0x61c48851, 0x81e97fb6, 0xa134151a, 0xc4b620ac, -0x96805e58, 0x710f5a3e, 0xf022918c, 0xfc9c4851, -0x060a5d76, 0xb7d9b521, 0x6e98f5f4, 0x1779be01, -0xed68f150, 0x81de9851, 0xdf6e24ab, 0x19152d3c, -0xbeb8aeed, 0x1c1e01b6, 0xa6df199f, 0x26f7df0c, -0x35bd43d7, 0x61c0ed2b, 0x73fcecc6, 0xe10e5d15, -0x6dbc7c51, 0x7a0f92bd, 0x4970ded5, 0x8da483ca, -0x1028044e, 0x3fe5ef17, 0xa8446bce, 0x3dcd84af, -0xf6113ded, 0xfca45298, 0x1cc7eb22, 0x7813f13b, -0xf8e416fd, 0x38f7f32f, 0x4ba78048, 0x08e9e40d, -0xf70db936, 0x0355d939, 0x12c420c2, 0xc99306f4, -0xc6c307c4, 0x8df2f76f, 0x22830fc5, 0xb88f4246, -0xdf60e0da, 0x15e54917, 0x35d2cd82, 0x07d8dd67, -0x38611c80, 0xf58a500e, 0xc5541ded, 0xf164d334, -0xcca2e2ba, 0x233e2700, 0xe0926cfd, 0x9c9d7f59, -0x42c2efcd, 0x262c5a3d, 0x838a2585, 0xa09d6a83, -0x0fd02750, 0xfbb75e02, 0xcf81f559, 0x983ad57f, -0x99bcb5e8, 0x0f510f38, 0x18b1be82, 0x7226b587, -0x56ddd60c, 0xcbad3c46, 0xf18d8a77, 0xb0c35569, -0xb2d69796, 0x1a6ea88a, 0xd085822a, 0xb395deb8, -0x49116573, 0xfb7562bf, 0xabb58f30, 0x24c45d69, -0x6c32c60f, 0x5c88eec1, 0xbb01ab04, 0x607ca37c, -0x7a3397e6, 0x5f465017, 0xf2efdb91, 0x4b7f7342, -0x16ab0839, 0x6583880c, 0x95dd3476, 0x6595e6f6, -0xc48ded13, 0x9af53fca, 0xccd09e81, 0xd755b817, -0xa0fd710f, 0xa7c73d39, 0xb0b55de2, 0x451e63d5, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1290-m0df320a.inc */ -0x00000001, 0x0000000a, 0x05112004, 0x00000f32, -0x2538ef0a, 0x00000001, 0x0000000d, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x74843747, 0x4501ebc2, 0xe5e57c08, 0x461ce659, -0x40a6701e, 0x5582170b, 0x74b21ac7, 0x20a81192, -0xae8f27e3, 0x62327b97, 0xc79394a9, 0x59bffa64, -0x5cd54499, 0x661609a9, 0xf3aeb795, 0x998555be, -0xafd3506d, 0x3af3bb2b, 0x80a7c09e, 0x88f4a103, -0xf61cc915, 0xc1d9b375, 0xb9f62306, 0x1f60aa5f, -0x4159c8bc, 0xedd0db19, 0x36f955b6, 0xa15d4ebd, -0xea1d8948, 0x58acf084, 0x53fc1a4e, 0xe76de3aa, -0xb9ce6bd6, 0xd99002d5, 0x797c8dcb, 0x7500ca7a, -0x5e1e5da5, 0xe2637e41, 0x1f281cc4, 0x1c0a2110, -0x9db83c8f, 0x7a256180, 0x804644c4, 0x3e1c625a, -0xb6c356f2, 0x35ccc6ba, 0xa24b20c0, 0x00dbf282, -0x76ca6755, 0x7831808f, 0x2075ec65, 0xea0b5fbf, -0x3ee5b1cf, 0x5a7b9a89, 0xf9d75ffc, 0xa2c11d5d, -0x73daaa86, 0xfa11274a, 0xfdcfb3c1, 0x051cc6c6, -0x9c6c53de, 0x992527ca, 0xa2dce7db, 0x4f3efdd2, -0x20d65f2a, 0x6c8eeb78, 0xcdb9e581, 0x345a2ca8, -0xb45e9a7f, 0x1f79bcb0, 0x0e2061ba, 0x6d7a5d55, -0x6c1e3cf5, 0x24ade036, 0x3d08860d, 0x8a3ea3a9, -0xc30f43b9, 0x1de4237c, 0xfb3b8f85, 0xa4e44587, -0x4ed26579, 0x92c37b5c, 0x04136287, 0x53d1c29f, -0xca821100, 0xbc8d89f2, 0xa11646b6, 0x501b8bb6, -0x83ed9eed, 0x1881fd4b, 0xa6014a24, 0x0330abbe, -0x635845f6, 0x450b0067, 0x4db70e3a, 0x4d7a01eb, -0xd498799b, 0x23741823, 0x8129458f, 0xae00e50c, -0x5a1c5acb, 0x27b06938, 0x847ff9d0, 0xb1dc5e10, -0x344d81f7, 0x835f0ab7, 0x0b186ccf, 0x2e2b0b0c, -0x91bec1a7, 0xfb5bfefe, 0x0d108725, 0x791fcb89, -0xa72d7393, 0x2e746000, 0xa9a904b1, 0x2907d414, -0xd344c14c, 0x1dac323f, 0x3b5944f9, 0x6e384d17, -0x9049bdb0, 0x63d46346, 0x01841ada, 0x806bd62e, -0x81b3da6d, 0x5feb969c, 0xbc4881a4, 0xae4568d5, -0x850bfbaf, 0xc5ec4d7e, 0x3592c8a6, 0x19debd00, -0x70f730be, 0xe46fc21f, 0x52edbb6c, 0x1f6c59de, -0x8e861d34, 0x1e056e10, 0x0aa4a2c0, 0x26648b05, -0x7b1b2cba, 0x15d8530b, 0x15ac9e35, 0x63fc4785, -0x4ee0e843, 0x749fc4f7, 0x9078d2e6, 0x922d7725, -0x012d3350, 0x1432be40, 0x1cfb013e, 0xe1c3b425, -0x0757f6ca, 0x96ac2827, 0xbbb1607e, 0x4d7796f1, -0x373635d5, 0xb3995af3, 0xd282686d, 0x57846e0c, -0xc10a1b7b, 0x0531aa26, 0x401a2d3b, 0x6293979a, -0x3256b584, 0x7037f5bd, 0x1a55346a, 0x4d72f65f, -0xcb831ed7, 0x78858956, 0x7534b9a9, 0x0300a497, -0x87786fe1, 0x0038e678, 0x234a22b0, 0x3a254e87, -0xae8e8c7c, 0x2a38cb9c, 0xf75e4df6, 0x124f6e10, -0xc313cb74, 0x403b85c2, 0x8b282eed, 0xe4088cb4, -0x6d3f2750, 0x44772ac5, 0xf261542e, 0xe8cf1b64, -0x701779aa, 0xeee56421, 0xf12a99ea, 0x20e83201, -0x5443f258, 0x9413ef4a, 0xc42546bd, 0x71446205, -0x846f1149, 0x69ad3ce5, 0x1d0c21d7, 0x7e732b32, -0x607080b6, 0x554fd99e, 0x0e636882, 0x516e3657, -0x83816c0c, 0x14e8634f, 0xedf4c65b, 0xf8f8eb9b, -0xdfe9a6cf, 0x68213b6a, 0xc3b08d7f, 0x90e95140, -0xd534836e, 0x8978e5aa, 0x2fbebe6e, 0x46c24c92, -0xa77f97c4, 0xfd1fc442, 0xe6e43c67, 0x4d1ba554, -0xf9468738, 0x6bd2f2cb, 0xec33883f, 0x2bba5bc4, -0x88e7e1a2, 0x3c4a7640, 0x2d2a4111, 0x237ceaca, -0xb1648b8d, 0x7b32f695, 0x7d7804d0, 0xb425cfc4, -0x167c62e1, 0x36289bf5, 0x3cdda149, 0xe499f59e, -0x74940089, 0xe17cdd2d, 0x58ef7744, 0x4a8df6ff, -0xf2f6f5ee, 0xf8ce1e0a, 0xa0797758, 0xa73b236c, -0xe0fce34d, 0x0e5301a8, 0x11afd174, 0xffd409ea, -0xc515f1ef, 0x90be8027, 0xdf7bd90f, 0x2e128305, -0x9fe0e89d, 0xc96c4158, 0x56e4f034, 0x144f5874, -0x34428f4a, 0x56b1b800, 0x42c1fd6b, 0x09e343bd, -0x0c5f0cfd, 0x6b6b8b00, 0xdab284a3, 0x5a01b6aa, -0xcdd04c97, 0x1145a1d6, 0x444c41c8, 0xb776a994, -0x58ef29b9, 0x472c2b2b, 0x60843b9e, 0xd8b82279, -0x2d4abd14, 0xd060acf7, 0xa0f409a8, 0x4a8e4099, -0x17ae573d, 0x91a5522d, 0x1c551c52, 0x49848522, -0x873bc54e, 0x1a2ec2fe, 0x5677af78, 0x1dd5d008, -0x73c9b7a4, 0xf3457a09, 0x8fef1cc1, 0x7b845cac, -0xb989248b, 0xf2921ec9, 0x71431fb0, 0x4697b928, -0x2068f116, 0x4756ae0b, 0x7f2315a6, 0x3075ee51, -0x93808fe3, 0x0a8bf0a2, 0x41ae68db, 0x7c7aea79, -0x8a036c77, 0x3bd26e9f, 0x938760ad, 0xc16aa948, -0x48cee353, 0x110c296a, 0xb0562141, 0xaadefff2, -0x39107bdb, 0xf2fdcb94, 0xedaa4ef8, 0x39b68d06, -0x66207561, 0xec544b74, 0xfd5ea699, 0x456c18ce, -0x226a54d2, 0x07b36341, 0xc771e69c, 0x6610ea78, -0x84cc8973, 0x0dd3cfff, 0x2deeb148, 0x6b3da83a, -0x8b3d6854, 0x7423712a, 0x4ebcf2d0, 0xe45b0b68, -0x20d1141f, 0x4a4ed962, 0x2cc7993e, 0xe249c851, -0xa60dff79, 0xcd3727ba, 0x5e91d1ab, 0x3b6d4523, -0xd2d7509e, 0xd5ea5ef6, 0x8fbf4006, 0x3c771673, -0x6f500446, 0x6ac41dea, 0x1c9846bd, 0x65b13f62, -0x75da9fd7, 0x6f8a5ec0, 0x19e384c2, 0x7bb6fa3c, -0x22942d91, 0x7933fcc9, 0x0613dbe8, 0x8d806e31, -0xd590e7d9, 0x64e55f3b, 0xc33585f8, 0xd7f69cb8, -0xa74dd834, 0x973ce207, 0x78c53ab6, 0x1262fc4c, -0xb210abf7, 0xd549d530, 0x9220b3ae, 0x03c5bdcb, -0x72eeb0e4, 0x50af734b, 0xb0bc88a5, 0x6077acc9, -0x9d51caf9, 0x63fb8670, 0x059b7f9d, 0x23c62f4a, -0x3efb3f4d, 0x152a02ba, 0x3c9c683a, 0xed323f23, -0x514d4bcf, 0x3b4724ea, 0x5adf550b, 0x88ff2a3a, -0xf513dfc3, 0xbc067894, 0xb8ace8ee, 0x4ea08413, -0x564a0211, 0xec08d000, 0x88f2d8b9, 0x633c232e, -0xfc369c98, 0x681f6d49, 0x40478b0c, 0x257f8ccb, -0x255710b6, 0x2d7f96fd, 0x7a0a05db, 0x3f22b6c3, -0x747b954c, 0x0223dfd4, 0x92b82a50, 0xb64b14d9, -0x638c2425, 0x7ecf3aa4, 0x1d6c828e, 0xe599d5ad, -0x9c5962ef, 0x0c65309c, 0x3fe9197f, 0x6eb20295, -0xa79c902e, 0xc09b9706, 0x30e0adf4, 0x328663c1, -0x710582d4, 0x66c659ab, 0x8b5f4623, 0xe61ab1eb, -0x98261cab, 0x8424f2b4, 0x87bbb44a, 0x5da9bf94, -0x275e692d, 0x8d45c932, 0x1e385788, 0xf6dd16cb, -0xf0098202, 0x182fb640, 0x33223503, 0xf0c2ba9a, -0x6d14a05d, 0x7e779788, 0x3dd2d827, 0x9722eca2, -0xb1dd3b68, 0xddc4ddab, 0x89372403, 0x0fc61fe5, -0xe87a3daf, 0x32c80bd9, 0x10c0ee6f, 0xf5a634af, -0x8f8206b7, 0xfc310d18, 0xc6e2bc5f, 0x55961d3c, -0x57f95fec, 0x0aca8531, 0x3d0f1e03, 0xcb429bf0, -0x94e83c04, 0xd22253a5, 0x6dc84e0c, 0xe413bfdf, -0x60f01c7e, 0xa59bc63a, 0x6e1ca5de, 0x81db7447, -0x2962a9de, 0x473a78d6, 0xc78f4b60, 0x7223f019, -0x46a89934, 0x958b2dc0, 0x39d21b92, 0x7c41a788, -0x1918ddf7, 0x03b03d8e, 0x1c83347d, 0x8a2c1d01, -0xcf0e2b36, 0xe395b75c, 0x16011525, 0xc01f1c8c, -0x28492afb, 0xdeda3005, 0x3d01c55d, 0x57c7b0bd, -0xe7f20980, 0x9af93f48, 0x2d2ef7d8, 0x82588e29, -0xb0249a6d, 0x21d7bbf4, 0xfc0bdceb, 0x78eda904, -0x332d405a, 0xc13dbf8a, 0x4b146e31, 0x1f438eea, -0x31cab96b, 0x0b5e9a77, 0x2814260d, 0x0efcebf0, -0xa44c1bda, 0xc215fdda, 0xd5b90fa0, 0x7afb0842, -0x9bab7428, 0x24678dfb, 0xe244616a, 0x71a8177e, -/* 1319-m206d820.inc */ -0x00000001, 0x00000020, 0x07222004, 0x000006d8, -0x2f6d5732, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x62c99ff7, 0x7a6b2b26, 0x588bdafa, 0xbe02d9bd, -0xef4646d4, 0xdfe7950f, 0x8882585b, 0x2b28e450, -0xbc0e5103, 0xb992ad63, 0x7b7ddc4a, 0x2b4ad8df, -0x69f9c34c, 0x254f62ac, 0x8e212d1e, 0x453cc958, -0x3fd54660, 0xa12430df, 0x2a3c7590, 0x6bf08407, -0x7f8ec244, 0xaab71e67, 0x372d7036, 0x2ea8f629, -0x47d02f32, 0x71b668ba, 0x5d105058, 0xe748702c, -0x97d18075, 0x70c92a53, 0x14f1cbbe, 0x98392132, -0xf6e9afa4, 0x9513f52b, 0x919d4df4, 0x3a49c80a, -0x67f781c7, 0x937423eb, 0x50955017, 0xbb95bd89, -0xf695c995, 0x3ea2c5c0, 0x1a3fcf39, 0x0a3e0d3f, -0xfc9680e0, 0xdf2f7f29, 0x30523ce2, 0x74781436, -0xe92db344, 0x8894130c, 0xa63a9b3e, 0x683da47e, -0x91e46f79, 0x54f49303, 0x8ed553ab, 0xf548c98f, -0xb258504f, 0xbabfeaf0, 0xfc85a922, 0x029a3c04, -0x9df03d20, 0x6d8d89f7, 0xf1be9fd2, 0x9b08c747, -0x80bff569, 0xf6c1009e, 0x7192fd37, 0x734569ab, -0x98a63684, 0x64e21152, 0x029862cd, 0xa1da74c4, -0x662432e5, 0xaf970a41, 0xcd44ba9f, 0xd6209998, -0xe7cbf9e2, 0xf1e25077, 0x7ba43611, 0x73b0ebd6, -0xa481b44a, 0x4d2453e9, 0xae2db98b, 0xb0712835, -0x569a277b, 0x756ced12, 0xe68d76cc, 0xe7302113, -0x04e289df, 0x0e08c8f1, 0x47b49858, 0x962ed31b, -0xd0ee9b92, 0xe4f96ee9, 0x09db6272, 0xacf2a059, -0x3ef41cee, 0x51632a67, 0xdfa6b20b, 0xef87ce7d, -0xcc146a5d, 0x5ea85cfd, 0xfdd57a79, 0x812d8333, -0x638ca286, 0x9719378f, 0xa17655ce, 0x18cf5988, -0xd58740e3, 0x121b472c, 0x4856a2ab, 0x5267727f, -0x2e8af107, 0x82a7136b, 0xfcaf2e53, 0x1b1af8b0, -0xfdb5aa1b, 0x356ad59c, 0x554b6397, 0xc693cb07, -0x66d593bf, 0xb00c32d2, 0x7af9baea, 0xe5623f16, -0x3c6fb0b9, 0x31269c04, 0x81371ad2, 0xc44d566a, -0x2b727011, 0xe0a06f7f, 0x66629d50, 0x7f38e494, -0x6a7e1f28, 0xe14673f6, 0xf68f6679, 0x84557020, -0x987b7eaa, 0x985d9e8d, 0x7cb50310, 0xeb334e65, -0x5d54f97d, 0xe9c0d1cb, 0xf5a084db, 0x6c199928, -0xd4442a69, 0x2eedea5b, 0xacdfef61, 0x1e2e12b3, -0x662fa232, 0x26d848a4, 0xeb9dc73f, 0x1b6d84e2, -0xc34be2c3, 0xc7c35214, 0x83d8f14d, 0x8d127305, -0x0229f7b5, 0x087ff7cf, 0x96332a09, 0x2a44bb95, -0x81e212ca, 0x9a86a1df, 0xe596589c, 0x773980ef, -0xbf860f3b, 0x75c2ad29, 0x4dd4e787, 0x522ca0c2, -0x25acf966, 0x60b59fbd, 0x6bca1f29, 0x79aff232, -0xa10c79be, 0xf07a4e76, 0x4158e659, 0x865be623, -0xf3c104c5, 0x879fdfae, 0x93b9847f, 0x578a8459, -0x648d9c34, 0xa7ae2bfb, 0x3f5a1985, 0x787eabfb, -0x57d55448, 0x7d8828cb, 0x54c9d9c2, 0x061b0a93, -0x9bbf974b, 0xb3fa4035, 0xf68f100c, 0x7bbc058e, -0xc1ae7a06, 0xa21d06a4, 0x4f92f229, 0xf0c76b24, -0x4e2c3781, 0x2eeab3d0, 0xf8994c49, 0x7e9d0b13, -0x355db607, 0xbc7a3ad0, 0x12bb75f2, 0x6080de16, -0x0b16e777, 0x32b59aa7, 0xc2f4f7f9, 0x60cb4ddd, -0xa95e0193, 0xe310d2d7, 0xfe5587b3, 0x56936f67, -0x01199707, 0xed8e7cd7, 0x51d6ff0b, 0xf6d9bdf3, -0x029ea85d, 0xd97aba88, 0x76cd57e2, 0x996a18c7, -0xa3d9e60a, 0x1404e61f, 0x40ab2be2, 0x54041917, -0xc358788f, 0x6e46b7a4, 0xfb67915d, 0x671aa938, -0x627f1e91, 0x31824cb5, 0x482f3e22, 0xd8c439ec, -0x128667db, 0x8b5dcefe, 0xc810fb4c, 0x7edf847e, -0xd71618ac, 0xc87934bd, 0xe96101d1, 0x55d1976c, -0x471c8505, 0x7a36d839, 0x5d62a9ee, 0xf3c54a8a, -0xa2be15d9, 0x244087c9, 0x042c8037, 0x23224689, -0x281c5d73, 0x2139ecfc, 0xffb8bc8a, 0x834fdd11, -0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, 0x4ae2dbda, -0x86d90089, 0x6675dfce, 0x48876262, 0xcec72538, -0x11dc5c80, 0x86a730f9, 0x313565c9, 0xe3e5be11, -0x106d7cce, 0x752b8be2, 0x3d00a5bc, 0xe6f70e95, -0x44447ac8, 0x600df30c, 0x8335ac3b, 0x8816ddee, -0x700982fe, 0xee495741, 0x48c7e81c, 0xa3d55da2, -0xb0172982, 0x70ab2158, 0xd4460621, 0x3a9e528b, -0x59b18a7b, 0xf4dabc4c, 0xa8454763, 0x70877bb6, -0x66005c97, 0xaf292c06, 0x7b843db1, 0xf343b59b, -0x25cdc7b5, 0xa41da617, 0x9e9d895e, 0xc936f475, -0x7270925a, 0x30024230, 0x8e72f53d, 0x2b6c1b6f, -0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, 0xaf377cc1, -0xbff09a78, 0x4b4e0814, 0x95a0b2c1, 0x270398de, -0x201fca94, 0x2a032a4f, 0x131542b4, 0x0d7306da, -0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, 0xa3b3a991, -0x17ee60c2, 0x852c0b8d, 0x11e5853a, 0x762002a7, -0x92c5311d, 0x0d4bf7e1, 0xfffec870, 0xe3d35e5b, -0xff6ecfb9, 0xdedae6ff, 0x0111a772, 0x9808e780, -0x29c336e8, 0xe9bc05df, 0x5bedde11, 0x945565af, -0xaff808fe, 0x87e3423d, 0x4de6f98f, 0x93b4adef, -0xbf704fa4, 0x09120e91, 0xd54f3692, 0xdf8eab1e, -0xfabbf59c, 0xe74318be, 0xaab87ffc, 0x29fa791c, -0xe3915552, 0xa652cb9b, 0xa1252e74, 0xb35b723b, -0x542aa28b, 0x12fcc5b0, 0x3941f962, 0x82bcc6cc, -0x47b11974, 0xb821611f, 0x78b34250, 0xf1be5659, -0x561b9e61, 0x6f3bd501, 0x584e6f5c, 0xd54ed547, -0xacebcd21, 0x7b5ff816, 0xb64ad233, 0x9f2f330d, -0x69fb1ece, 0xac8710dd, 0x58dc6c60, 0x9bee6139, -0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, 0xa733274f, -0x884d9b55, 0x42b08b63, 0xafa54a74, 0x1c7ccf64, -0x93a20191, 0xaaa3132e, 0xc69831d1, 0x54634889, -0xfbfe3efc, 0xd3cf68d4, 0x302e3117, 0xf5693131, -0xc3ce8c6c, 0x1f03cd89, 0x6243334c, 0xf16bc80f, -0xdca5f130, 0xcb2cd956, 0x4c1bb421, 0xe8de533c, -0x7f86703a, 0x29aa897e, 0xdd54acad, 0x76b2f2ae, -0x7ef82b71, 0x2e30970b, 0xba402597, 0x9a653ab4, -0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, 0x2363d147, -0x5327289a, 0xe89229f3, 0xd63a535c, 0x7efe9273, -0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, 0x1b9c7bfe, -0x5d14b3de, 0x54d575fb, 0x6d65db4c, 0x95648b7f, -0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, 0x8488a45f, -0x8ebc2932, 0xd4767316, 0x3e8c4b8a, 0xbab7402c, -0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, 0xc88528e9, -0x4b2e4e8f, 0xdd938b86, 0x0c964f98, 0xfc88d480, -0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, 0x4d40b3b3, -0xcf203155, 0x0d2fa621, 0x752d2c58, 0xb12bac12, -0x1e7e8c23, 0x94215d54, 0x9854a71c, 0x4de63c64, -0x7a012529, 0x9c171f8d, 0x9e71def7, 0x3bd17d50, -0x11f175d9, 0xec78abf3, 0x7b529eee, 0xd3a69fc3, -0x5b718676, 0x58214d29, 0xa8bd2c34, 0x41ea00ab, -0xa03f64d6, 0x4ee342b0, 0x32b1e444, 0x1c1801a4, -0xc8424702, 0x334a7e35, 0x50cf1543, 0x3b22b495, -0x88683776, 0x8e2e0154, 0x6155c033, 0x4e2fa6ac, -0x42ace700, 0x8d64f97c, 0xaf9ced17, 0xb2a5cb92, -0xa558582d, 0x88705de7, 0x9e528d59, 0x84bd45e4, -0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, 0x10462123, -0x30080f7d, 0xb346cd81, 0x0049c396, 0x4e24165f, -0xa7c66809, 0x2e60bdcf, 0xaad70a08, 0xa73ea713, -0xe28f97a7, 0x283a9eab, 0xd4366489, 0xe776f963, -0x64ffa8ae, 0xde717b50, 0xbd2ca2b5, 0x3bae5f6d, -0x8d2bbef1, 0x7e9181e6, 0xf06aa121, 0xd06b2d20, -0xa83ea826, 0xef935e4f, 0xdfd27456, 0xa3451468, -/* 611-MU168607.inc */ -0x00000001, 0x00000007, 0x05052000, 0x00000686, -0x87aa303f, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x6624c5b2, 0x098bab85, 0xd7cb9fd8, 0x2ad2c3e5, -0xb024689e, 0x030082ce, 0x87544b9b, 0x50a47302, -0x34508a4a, 0x42eac716, 0xfb29145f, 0xa89d38cf, -0x1595afcb, 0x7151404b, 0xd87466cb, 0xfbb7616c, -0x912ba3ae, 0x43848a53, 0x7f5b7bd9, 0x770c3d91, -0xd579a19a, 0xcd45be4f, 0x11f83af2, 0xec7a7162, -0xa31769fb, 0xb872d8b0, 0xed21b052, 0xa9757f0b, -0xd93fbb9e, 0xe4755de4, 0xde0b505f, 0xfaec9b1d, -0x7e379d2b, 0x77cd8d54, 0xd884d9a5, 0xc856674b, -0xd48fad7c, 0x79c380ef, 0xeac7311a, 0xf345ae9b, -0xe6641e8a, 0xd0e02365, 0xf95219d1, 0x5ef40f4c, -0xfb46254a, 0xa79b9c00, 0x33ff5502, 0x90a4ffc7, -0x5b61dea5, 0xee2da1a4, 0x2d33a250, 0x970e8b65, -0x61fa9e4a, 0xbf7a110e, 0x9cbe1302, 0x4489e932, -0x273d2ac7, 0xbf0576ad, 0xb11796be, 0x100c4eb8, -0x9f48c79b, 0xf43e6390, 0x07f19aa4, 0x0438d6ad, -0xd073b3e6, 0x758caefe, 0x44695821, 0x0aa2560b, -0x926f1676, 0x25c0d98c, 0x652b9701, 0xf1103ca1, -0x3838b324, 0xe86c1a56, 0xcaadd270, 0xe2655064, -0xc12e9397, 0x269a7069, 0x2c8431ef, 0xf123bff2, -0x9d72d45d, 0xcde8c983, 0x9bd75039, 0xaaae7612, -0x73f647ed, 0x96c2dfec, 0xf3c78dfd, 0x43386b24, -0xa54c9fc9, 0xe5f902ea, 0xcf895610, 0xffbd67d8, -0x88f26c51, 0x3af4baa6, 0x853803ce, 0x06a2c772, -0x58dfbaf2, 0x854db965, 0x9d99817d, 0xb8fe256c, -0xba4728ee, 0x0c4311b2, 0xb725f711, 0x332ec9d0, -0xba328c24, 0xe97255e4, 0xe0fefbf2, 0xc90b8e05, -0xdf3a9869, 0x29a5ead4, 0x8ffc234c, 0x1df04450, -0x53ea2f3c, 0x2f27e401, 0x17267310, 0x12230316, -0x4495bfc3, 0x6300281f, 0x6f1229ea, 0x987a8a03, -0xfd00f044, 0xb4119ea5, 0x08921ba9, 0x512b7a0d, -0x51baec70, 0xf456605d, 0x00d8a15c, 0x67838a1a, -0x662ef9a3, 0xcc306d52, 0x4693878b, 0x2d0e5d8e, -0x743cbcd2, 0xa6a7a050, 0x7a943e8f, 0x2e52c6a6, -0x317b8d12, 0xac83eba9, 0x59a647a5, 0x158c0cc2, -0x11af9e25, 0x6809f3ab, 0x4e59d047, 0x281ffa25, -0xd3290e4c, 0x3f876c53, 0x58562bc3, 0x3a17709e, -0x29e591d8, 0xc842e16c, 0x71620b18, 0x88680e85, -0x31bb0bbf, 0xe408d90d, 0xfc2870f2, 0x40a8e770, -0xbd7f322b, 0x00727a75, 0x12de5772, 0xca6a1790, -0x7f3170ce, 0xb29b3c80, 0x96d58bd7, 0x197d7dcd, -0xa793ec3b, 0x330d1496, 0x696788bf, 0x5e7895de, -0x4548fe46, 0x9c061b57, 0x130f9b26, 0xbc11df79, -0x1b0f6fc3, 0xa154182e, 0x568ab60a, 0x9aa45739, -0x7ebb7352, 0xe6c82d4e, 0x2626170f, 0x6484ec37, -0x8ade49d3, 0xe3608320, 0x43572189, 0x7b0b6733, -0x518bb91a, 0x9da00229, 0xc1e449cb, 0x8ff922ba, -0x7a523623, 0x615cc16d, 0x42e38cd9, 0x1253134d, -0xa3fa6f02, 0x623b38cf, 0x86ab89cf, 0x1443acb0, -0x8e21a201, 0xf111cfe6, 0xd02a9132, 0xb1d1a8d2, -0xe177664e, 0x231603ff, 0x711075e7, 0x1d18d937, -0x5b6e1cbe, 0xf6aa6105, 0x21d4847f, 0xfdf8e049, -0x397d3ffd, 0x50142e73, 0xb3bcb17a, 0xe6d9c88a, -0x9a757f51, 0xd8f22a49, 0x3bc7d8dc, 0xe337cd53, -0x097fc575, 0x3e7b9ca4, 0x0f240073, 0x3746b51b, -0x42de4d17, 0xbb2e58ab, 0x4b17f3d7, 0x8d0e06c7, -0x4dd1c929, 0x60de42b6, 0xffdd1ce9, 0xcdee1401, -0x9153da16, 0x74cc8c18, 0xed1d6841, 0x111a4964, -0xbd86a589, 0xe1bf2ad4, 0x02fa8ce7, 0xcce8b286, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 399-MU166a0b.inc */ -0x00000001, 0x0000000b, 0x05051999, 0x0000066a, -0x5320efc2, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xf164feae, 0x70f1545b, 0xee75139a, 0xdb7fca71, -0x48ba7994, 0x996e84b6, 0x6830ad5a, 0x38a129e1, -0x323ac914, 0xc779a51d, 0x1d7c40fb, 0x36adafee, -0xee2d4f67, 0x086d4fe2, 0x8f8d65d7, 0x801e7fcd, -0xef612579, 0xf4806ed7, 0xe7617b53, 0x4c5ee9a4, -0x967f5a46, 0x5a10ec0c, 0x12513274, 0xc71b9991, -0xfc32bc01, 0x8f671aad, 0xb0e538eb, 0xb02838de, -0xe999bcdf, 0x4ca0bdda, 0x4278da2c, 0x9f0a03d3, -0xd29ae2e6, 0xb035934b, 0x3e0019da, 0xd1f07ee9, -0x19852922, 0x38ba3efb, 0x29097d22, 0x208c367b, -0x573ff3a4, 0x62eb70cd, 0x14ae776d, 0x300117d2, -0x16cbcea4, 0x5e9c61ca, 0x09869e23, 0x28468eb9, -0x66b5973a, 0xf7991cbb, 0xf9cac013, 0xbe478a7c, -0x17a95a20, 0x9646dd8d, 0xdd0138d4, 0xf87e407f, -0xa99cdaa6, 0x4987bfdf, 0x8e75e743, 0x9d6cfb25, -0x2eec08a9, 0xc5e6dddf, 0x4a45c31c, 0xae85c0eb, -0x0c875f17, 0xfcb911d0, 0x064197d2, 0x8bc57376, -0xbcc472ec, 0xd12f07ec, 0xa868540e, 0x9a7c9efb, -0x8d36c3df, 0x00865944, 0x7ec588af, 0x0efd17fe, -0xbb5b2af3, 0xd7b06dc5, 0x38db16da, 0xaaff291f, -0xcdd2f6ea, 0x9f70cd4b, 0x93ebefc3, 0x6e90b1f1, -0x64b6b7b3, 0x89cd79e4, 0x4c62692e, 0x144e9e9f, -0x98063595, 0x7f835929, 0xfa447038, 0xe981b269, -0x4067c432, 0x2d2f5e5f, 0x5642fbf5, 0xe2b8f7bc, -0x2c82dd3d, 0x8bb61d10, 0x0b0e0a20, 0xffeddd78, -0xeff7b857, 0xe11a2323, 0x48b657d8, 0x56000020, -0xe65844fe, 0x5231e1b9, 0x50a84875, 0x8cafb679, -0x06cfce7c, 0xf37089a9, 0x4db86f6b, 0xa63d0376, -0x72227dee, 0x30933db5, 0xda329301, 0x2dff90cc, -0x43d5e2d6, 0x3e19da42, 0x220fdc3d, 0x85b47386, -0x649e61bd, 0x5c1c72f5, 0x2fd4c456, 0x585388b4, -0x4c12229d, 0x618fc4a8, 0x5db2f8d6, 0xd30ce359, -0xbbb6a155, 0x807e7b29, 0x587dc9d8, 0xfda6fdc3, -0x55bc6b34, 0xfc231424, 0x90b2ed33, 0xefdcbd79, -0x5f82e9ff, 0x0646a8ad, 0x3cb3c86a, 0xfe19fc8a, -0xe8c2485e, 0x0dc0f5d6, 0xb80b9c65, 0xedfb28b0, -0x4c56c7c6, 0x2cc2fcc0, 0x223d0e54, 0x5352e027, -0xfcc3527e, 0x2c6426ff, 0x46fb21cf, 0xb9a78245, -0xab4b1ec5, 0xa40ac11c, 0x671db533, 0x31410024, -0x66671b38, 0xe51ac22f, 0x39e40aa7, 0xc7e7311d, -0x28b64fca, 0xf450fa23, 0xfa7ec04c, 0xaf43495f, -0x0fdd7af3, 0xc9f94232, 0x9ee4f700, 0x6e669c5a, -0xdb6d0c3c, 0xe2bee5ac, 0xab2a3699, 0x127347e3, -0x2830b102, 0xa24bba08, 0x5e341110, 0x2f56ed4c, -0xd0387126, 0x76b07220, 0x15829272, 0x46bebe97, -0x64f7b851, 0x4ce007dd, 0x3a3022fd, 0xc2570ed3, -0x9a5b66d3, 0x8abb4abe, 0x92165dae, 0x80c23f24, -0xf8244059, 0xf240d2e2, 0x0853c211, 0x1bace652, -0xd682f3dd, 0x8e14f139, 0x68800f29, 0x0ef3a910, -0x2ac47b34, 0xdb4fbe5e, 0x9020e7c2, 0x036e4b1f, -0x8d6d3b46, 0x934cd045, 0x29fc2721, 0x08f275fa, -0x4a0320c8, 0xaf7261fa, 0x6ab8b9cb, 0x0ec88462, -0xfbd1eefd, 0x468ab905, 0x9e1a18f6, 0x4012ffc4, -0xe30a12bb, 0x6fca14c1, 0xb42b0ba8, 0xdbeb3652, -0x1fbbc466, 0x0d504189, 0x7c644ce9, 0x77877afd, -0xcea6f7c7, 0x7f5381dd, 0x905e0569, 0xd757cbac, -0x0fd855e9, 0xbc8c2690, 0x1bdbb85b, 0x5b479eed, -0x090e7c3b, 0x17484ec2, 0xc320e0d3, 0x969cbbe3, -0x792f3c3a, 0x3c5fb90e, 0x1ed121be, 0x29c3abd6, -0xd9075f20, 0xeb4806b8, 0x3cf8b650, 0x0cc4a95d, -0x6b37d4db, 0xa4d965cf, 0x8f6ba7cf, 0xddb966de, -0x62f431cb, 0x30048443, 0x12bc521b, 0x98682eaa, -0xaa95dde0, 0x8eadfdf0, 0xde0f2b31, 0x56600129, -0x86ce2e2e, 0xc0d5f0cc, 0xb0644830, 0xf8cf62dc, -0x89a5e8e5, 0x6f9220f4, 0x138a2161, 0x8377c077, -0xe57b4954, 0xf8119c9e, 0xdf31d61e, 0xd7b552b8, -0x200a83f1, 0xd69be026, 0x1bdff0eb, 0xcf778290, -0x2562ca46, 0x718e7a02, 0x45f0ab66, 0xb84bcd06, -0xbaebcf08, 0x44622ecb, 0xf095b256, 0x2e542743, -0x5265ca0d, 0x6aa19d3d, 0xc8df6999, 0x574be28f, -0x3cedfc3b, 0x8af8622c, 0xf8b3b02a, 0x7d841052, -0x3df0b3ac, 0x2222bc96, 0xe9cb2435, 0x0aea6617, -0x7e37cf8d, 0x2df6b192, 0x68bfe6f1, 0xe3fda186, -0xdee3c430, 0x3864b05a, 0x27f7e0c7, 0x22da6c6d, -0xac701f04, 0xc271b644, 0xa2bd8531, 0x3234c0ac, -0xb1a98a9f, 0x0f3ff2cd, 0x602c16d3, 0x4855cc53, -0xaabc52ac, 0x4f01eb8b, 0x96356b71, 0x42225587, -0x18266801, 0x2a082039, 0x2caa2fe7, 0xde119e92, -0x71c1e48b, 0xabba2eae, 0x202cac3b, 0x5739c9df, -0xb9c00f5c, 0x8d9576e5, 0x453c0787, 0x6043bdf5, -0x6fa7e0a7, 0xe2333ef2, 0x6b2a0c15, 0x7e71897f, -0xe35c05ba, 0x20405717, 0xdf236b3e, 0xc4a14743, -0xe813650a, 0x8d823da6, 0x4f328186, 0xee43822a, -0xe75f2227, 0x09dac319, 0x0d2c9a93, 0xda621940, -0x542a21c1, 0x3a3c2e0d, 0xb1c9b51c, 0x669fa3af, -0x7db40da4, 0x13badf34, 0x1f98c70a, 0xaa3a54b8, -0xc293d8ca, 0xc677756e, 0xe5fb8158, 0x91005fce, -0x23bcc33e, 0x08b671b1, 0x0430942f, 0xd65fdc74, -0x3773de35, 0xc1c95b17, 0x0c4a72c9, 0x605a2a55, -0x7c600ffa, 0x152462d7, 0xa6359789, 0xfa89d53a, -0x0c749805, 0xcd4b8848, 0x72ba47f2, 0x7121f90b, -0xb00412e2, 0x26dc3ceb, 0x4e73d8a1, 0x0bee25d1, -0x50b5fe45, 0xfb8f884e, 0xf4d57158, 0x694fc3b7, -0xcc8dbcfc, 0x4d32ac36, 0x032e50fd, 0xb941f702, -0x28e41afb, 0x30ae4873, 0x5ba0918c, 0x58580421, -0x25665153, 0x18fdff01, 0xe8276c28, 0xcabe3394, -0x2f208a33, 0x823997fb, 0xbd9dfd10, 0x17323611, -0xb36fe4ec, 0xfc93a594, 0x9ead87a5, 0x82140854, -0xd311f9f0, 0x974da82f, 0xded93a6d, 0xa854574c, -0x7513ded1, 0xabc9b23a, 0xa57f7303, 0xfa7b6404, -0xb9dfaa3c, 0x087c8c57, 0x90d58229, 0x97b267a0, -0xce357806, 0x7bf65936, 0xb8e5efc4, 0x88ad776d, -0x1e2fed21, 0xbfdbb9ba, 0x12983ed1, 0x5ac1e8d3, -0xe83d3b98, 0xc3ef70d3, 0x32a83173, 0x1adc355b, -0x3028a6a2, 0x590487a0, 0x70aa8ce8, 0xb07d5eab, -0x1210868f, 0x3c0bf159, 0x6a0a5d94, 0x98bfd28e, -0x756dcccd, 0x8109af55, 0xe50dbaf8, 0x0156cef1, -0x201207f1, 0x5e20750e, 0x13d20bb7, 0x438c45d9, -0x2927e7a5, 0x5683cc1d, 0x374bc98b, 0xbf43416f, -0xcc2b40c3, 0xc581b83c, 0xa245c55c, 0x15fac7fb, -0x9bf99137, 0xc985db40, 0x1c67eb27, 0xc5bd3fe9, -0x15c20413, 0x8f0a1928, 0xa52b860f, 0x243c53bf, -0x940df584, 0xfba7bc08, 0x96ea0452, 0xb9b75629, -0xa1bbf6e4, 0xb90c181e, 0x29cc3b57, 0xfc0b25ec, -0xad06529c, 0x9fffafbd, 0x56d82b99, 0x69aa91f6, -0x1a7e1041, 0x835fd763, 0x1aea44bb, 0x049e3d4f, -0xb80b7881, 0x5b23d9a5, 0x19b6297f, 0x2d8a031b, -0x8ff01930, 0xcf599b40, 0xa0c9f3c6, 0xdea7daa8, -0x1bc2493f, 0x2328bf0a, 0x0a8bf88f, 0x46ca3b61, -0xd7752cbb, 0x7fd049fe, 0x81360bfe, 0xc45e00c6, -0x345038db, 0x9fa3c734, 0x21e04551, 0x4065ce89, -0xebf537ea, 0xd917ebe4, 0x7f7442e8, 0xe979f46e, -0xb35dcd5c, 0x89afbb69, 0x85b5ee4b, 0x4ecfd25f, -0x4dd879c4, 0xe1092b39, 0xbc45c012, 0xdb2fbc66, -0x000e1ecf, 0x0bdc46f3, 0xe9958406, 0xafff5eab, -/* 411-MU16530c.inc */ -0x00000001, 0x0000000c, 0x05181999, 0x00000653, -0x810fe1ab, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x70f0e122, 0xff8bdd97, 0x3c8f6086, 0x9795839d, -0xbcec5e8a, 0x86d79f5c, 0x8a7eba1f, 0x6ec298ea, -0xdcbdea5a, 0x6df32e3c, 0xfe7b03a1, 0x1fb340f4, -0xf8ccf55e, 0xcc895669, 0x61feb2c3, 0xab4b47b8, -0xe7a4a809, 0xda5aee3a, 0xc063db2b, 0x2a3a37f9, -0xda6620db, 0x1a9d74e6, 0x69cdf24f, 0xcf84d7e3, -0xe1e91b0a, 0xd6b4524f, 0x11cb964a, 0x558bed59, -0xdc6a7037, 0x82f49abc, 0x4a7b2b02, 0x08a54751, -0x94848d50, 0x24a41d05, 0x66cd0fca, 0xdeca2bab, -0x0fc94efb, 0x3d870e54, 0x15d83204, 0x8786e666, -0x7cd9658d, 0x5a2a6bc7, 0x0728db3f, 0xe619d19b, -0x8cc8cf68, 0x16da1fba, 0x1c9dcc2f, 0x4810e99c, -0xad7b1c9e, 0x0e54555e, 0x7aaaecbc, 0xc75499d3, -0x0918055e, 0xa9ddb6af, 0x343cffda, 0x46a2def7, -0x3644376a, 0xa855ce79, 0xdb34da5d, 0x701039ce, -0xc1ef8291, 0x9a3a8b14, 0x0c383a31, 0x5b6b1cd7, -0x5a8ea284, 0x0e2b517b, 0x83fb239b, 0x12e3bbf1, -0x99cdbda8, 0xcce3ff3b, 0xabe88eb5, 0xc9c39921, -0x5d7e0f42, 0x6616c514, 0x461b4aba, 0x197e296e, -0x25fe8129, 0x8dfcdccf, 0x3e32335b, 0x70429113, -0x0a0f9efb, 0x3af19b8c, 0x9075c62e, 0x88e71557, -0x8dd4d5de, 0x08ed7495, 0x5c8d3fad, 0xbc85f573, -0xc73ac54c, 0x4b1ed289, 0x12e3145a, 0xcee63e6b, -0x35e21802, 0xf7c82dd1, 0xa3bb53f2, 0x0159b02d, -0xf9c1d59a, 0xb8ae1aa6, 0xa0f7356f, 0x25e861d2, -0x294edcd9, 0xf56e6b70, 0xed89984e, 0x5670ade3, -0x07c139c1, 0xc9825411, 0x96cd9e09, 0x7c00c1ce, -0x548f761f, 0xffd1dfb3, 0x14dd9eaa, 0x9fefccba, -0xe24e53c9, 0x90884598, 0x1c9454e2, 0x8993be4c, -0x5257183d, 0xf7e5f329, 0x65156ca7, 0x9bd171b7, -0x1d7a7430, 0x16d52022, 0x0144079f, 0xc0fa6a1c, -0xefa5baf6, 0x8761237e, 0xcbb8ca36, 0x1738b2dc, -0x9cd7f5af, 0x4dc1433c, 0xbde3ca0f, 0xe56ed03d, -0x407d8de8, 0xf112be05, 0xdc3e12af, 0xe586e503, -0x7d067e61, 0x4b9a3075, 0xcc5e88c4, 0xb5b719ae, -0xc235198b, 0x82e68914, 0xc26af071, 0xa75d5123, -0xd9c53cb0, 0xd7da2486, 0xe50307a4, 0x249f9b3b, -0x2081a6fa, 0x8f3b0668, 0x20f90ba6, 0xa24c9cbf, -0x314e3257, 0xee1e8ce8, 0xd17992e4, 0xeb667948, -0x65912e6e, 0x25683578, 0x6db17325, 0xffa874a4, -0xd417e80f, 0xe6129a2f, 0xbd0ad511, 0x87f41146, -0x9ec4c1be, 0x2606e66e, 0xf5df093e, 0x116e20ba, -0x0c8989a7, 0xf870d4c1, 0xf83b6ee8, 0x4dd7acbf, -0x9a4496d4, 0xaa80f40c, 0x47f4f668, 0xcd4708de, -0x9aee2116, 0x99f7564d, 0x6b05b918, 0x64ccb01e, -0x505dcf82, 0x50467e3c, 0xe2e053a6, 0x8ffdcc1b, -0xaddfc662, 0x6f9beee0, 0xccea8166, 0x745ae5ad, -0x1a4841b4, 0x5c9c8d0d, 0x6d34804b, 0xa1a1168f, -0x34bd6ca8, 0xc971daad, 0x57e80c5e, 0x7a67dc4d, -0x302369c9, 0x824f478d, 0xf0b041af, 0x6b6133c2, -0xba5afe3d, 0xa7ba18c4, 0xcf363d17, 0x90a2419c, -0x17d1b6cb, 0xe760bf73, 0xf7e60431, 0x6820ae47, -0x1cea1e8f, 0x349c1eaa, 0xfd35592d, 0x41263d61, -0xefbc5ea3, 0x13b634d0, 0x7b414a1b, 0xbfedbbca, -0x16e9afc0, 0x54262b9c, 0x659c9795, 0x0dbf38e2, -0xf9d87667, 0x3788ead2, 0x36efcae2, 0x6f107cfd, -0x9b4eab95, 0xcf29e1ae, 0xb65461df, 0x21e9125a, -0x4e71d0c8, 0xedcba601, 0x8016d03c, 0x92cf5b98, -0x6db3bfef, 0x087ee378, 0x8e52f7c8, 0x69e3ab9c, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 43-B_c6_617.inc */ -0x00000001, 0x000000c6, 0x12101996, 0x00000617, -0x3371797e, 0x00000001, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x10ae4204, 0x7a759c51, 0xf7cca534, 0x9d78b93c, -0x90745514, 0x83bf4995, 0x5262b38a, 0x021369cb, -0xc94a310d, 0x4f9cb983, 0x4b3fe4ce, 0xd80aa41f, -0xba1f9fd2, 0xe9916766, 0x69ef0ae4, 0x0b38b9fb, -0xa4e9c77a, 0x8a55c68c, 0x331b53b9, 0xed09d30b, -0x06198c27, 0x997ea121, 0x6138eaa8, 0xff36326d, -0x3d97e7d8, 0xed8d479a, 0x3997175c, 0xbc55ed5c, -0x174afb79, 0x7424af12, 0xb7959530, 0xaa116231, -0x995da61c, 0x06a48d64, 0x2e20a822, 0x990d8968, -0x07dae08e, 0x15cd8dbd, 0xe5faab09, 0xc6a9e802, -0xc71afd62, 0x095ac753, 0x633d3e2f, 0xc1d14895, -0xa98eaea0, 0x909d2f66, 0xc8fe0fed, 0xd9e19ef6, -0xafe41bcf, 0x0d29c0ce, 0xda036076, 0xd91e9e15, -0x819c7382, 0x7c2b057f, 0x7d5c7099, 0x7931c9c7, -0x05e436e5, 0x41c47269, 0xd692a355, 0xeddc7df8, -0x990e41ab, 0x4047ce2a, 0x7b9ce684, 0x4427a413, -0x7b8d9361, 0xec29de72, 0x7744ca39, 0xc9438681, -0xd546020a, 0x7e14e508, 0x0cafea15, 0x885ae74b, -0xbf07a64e, 0x9ad83612, 0x381cf376, 0x4b313629, -0xe6b15a73, 0xab9caec8, 0xfda2bfbf, 0xb71f9935, -0x915b31a3, 0x958db25e, 0x080cb4f3, 0xcc2280d6, -0x977afcf1, 0x43d26f23, 0x84625ffa, 0xb26c1bf2, -0x22adf88f, 0xf2835d29, 0xca277501, 0xc4557829, -0xabb2a280, 0x35b6b40d, 0xec3e551b, 0x622e0c48, -0xa9c18623, 0x6ddc2969, 0xeab9876a, 0x7c021a29, -0xe8b48860, 0x03a893cb, 0xf9c2772e, 0x99a131c2, -0x7fb1b9c8, 0x7588562b, 0x330c3ca1, 0xddf79e26, -0x102871f0, 0x46b59c1b, 0x5be784b2, 0xa13472df, -0xf77a699d, 0x1e19cf47, 0x2df8c51e, 0x3c92be60, -0x0e4c4edd, 0x5809d864, 0x78305a32, 0x2d8d80a6, -0x5f6693e2, 0x384ca99b, 0xbe5dca8e, 0xce7fbe66, -0x4e64135d, 0x979ee9c9, 0x61700566, 0xff20c623, -0x4b1ccbf9, 0x2f507b1c, 0x5c021650, 0x7844f2a9, -0x0528f939, 0xcd9f945f, 0x7a362c85, 0x7a76da60, -0x5738ca7b, 0x4828eecc, 0x2d9ac738, 0x0912a9b4, -0x15775709, 0xb719ff07, 0x9578abf6, 0xf9f85ff4, -0x30621b30, 0x1746c5be, 0xef339736, 0x641da556, -0x54b09e20, 0x4d5785fa, 0x619656d0, 0x0d0dc731, -0x79c63339, 0xb4396838, 0xafae5935, 0xacafa08c, -0xfc3bae80, 0xe324c4a2, 0x6e883362, 0x72ba13ea, -0x1baaa3c7, 0x0403a063, 0x54cc43fa, 0x70a4f3c1, -0x93b1b519, 0x4e4be8a6, 0xf273929d, 0xe6e95077, -0xb9354f62, 0x6026576d, 0x42eca8c0, 0xe811cb1d, -0x88051a86, 0xaf60322f, 0x74c1234a, 0x152dcec4, -0xc46603dc, 0x0826d833, 0x6610ba94, 0xbdb15d54, -0xd351f73a, 0x8f665ef8, 0xd352611f, 0x57ea12fc, -0x9e7865cc, 0x44a6afd9, 0xe7cf2546, 0x152d3a4a, -0xa9f3227c, 0x5a6b083b, 0xe9a760ca, 0xfacd5b6c, -0xdfead584, 0x37bdd3e1, 0xa16024a1, 0x81642637, -0x1fceca59, 0x83a6266c, 0xe18c21ae, 0x8588db23, -0xc857b0e7, 0x3a4cda5e, 0x2997ab21, 0x91ae1c25, -0xf480650d, 0xc55e3b7b, 0x2fb4a5d5, 0x8a666356, -0x49ef5393, 0x6f6a6451, 0xe4397937, 0x60ad57f8, -0x9c85560d, 0xcbe6d3e5, 0x7ea9bfc6, 0x1913e322, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -0x278cb2c0, 0xf41d6be8, 0x839b9b57, 0xde7df900, -0xa6d05386, 0xf79d8944, 0x24d4273d, 0x878456fe, -0xbc0006e2, 0x4cbc49c5, 0x16684d87, 0x1f2c79a5, -0x847dc8fb, 0xe873c43a, 0xc92223f2, 0xc9c193d4, -0x8f43d21d, 0xc723f894, 0xa0ed9e53, 0xd0693391, -/* 2185-m04f650b.inc */ -0x00000001, 0x0000000b, 0x05102007, 0x00000f65, -0x69b15bba, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x2a54c7a9, 0x18ecc912, 0x7358b4aa, 0x6c06e153, -0xb5f59e8c, 0x5f0a4af0, 0x6d268037, 0x1e392e7e, -0x5ca39c5c, 0x70fe95e4, 0x869d12af, 0x54556b68, -0x4576a7b2, 0x0ea27e20, 0xe6e118cc, 0x83ecc15e, -0x9cd84449, 0x6924f884, 0xd8bddae6, 0xfc71f620, -0xb0c24817, 0xa10b79e5, 0x2c56fea8, 0x69758fd1, -0x3c186b7e, 0xc566fc81, 0x48bc078a, 0x4591e6f1, -0xc72faa8b, 0x5c9027ef, 0x223aaa59, 0x2a807097, -0xbd6e5146, 0x633e39c7, 0xa920f5ef, 0x4cf93d3f, -0x2a8f0489, 0x328ee7bd, 0x0a3c2e87, 0xf6b3d878, -0x7ff62d30, 0x59f75c17, 0x50335c28, 0xa83780fc, -0x2f13e02e, 0xdd93d262, 0xc1ff68f0, 0x5f160889, -0x6784d2a2, 0x9974c4d9, 0x27f0989a, 0x06c3c9fb, -0x4d442353, 0x7df6af36, 0x9cebeae0, 0x4593501d, -0x895bece7, 0x163e3662, 0xcd0623f4, 0x73716c92, -0x93647da3, 0x571d2da9, 0xe137e743, 0xb61c0175, -0x655af0f9, 0x46b0ef79, 0x843e460c, 0xed0086c3, -0x3717040a, 0x94d5c66a, 0xd87a171e, 0x71b71821, -0xf352b38b, 0xf3204628, 0x6db9bf37, 0x27c99d15, -0x68fd4a77, 0x54080a7a, 0xc74f52f5, 0x5758a7ec, -0x935f34eb, 0x2f92bf2d, 0xdfc713e0, 0x6be2fa22, -0xf211177b, 0x7e573e70, 0x47772c3b, 0xdc7e840f, -0xd80a3068, 0x5bb261bb, 0xfe6e2ac8, 0x84c644f6, -0xa56f20aa, 0xcc9800dc, 0xfc197391, 0x670d90ab, -0xbb968979, 0x9b8b59e4, 0x16901654, 0x243fe5cd, -0x8e46dd2c, 0x6d5b5e96, 0xc3b2513d, 0x52b14d01, -0x212c5ea7, 0x2c32cb67, 0x22f5b15d, 0x7be025a8, -0x96c87a0d, 0x57032238, 0xd9f871ba, 0xf2264613, -0xd9a21a3d, 0x6a5a3214, 0xe8c86949, 0xb07946ea, -0x2ff9fb1f, 0xe0954cfc, 0x0e9a9f69, 0x602d7ab1, -0xd3cb1e2f, 0x862c7923, 0xe75590cc, 0xc27bd7da, -0x433fd3fa, 0x753bf909, 0xb2144e9e, 0xaf30e910, -0x535e12ce, 0xf2dbbb89, 0x707cbeac, 0x797ca200, -0xc8c01502, 0x95990002, 0x546f641c, 0x21f3d8ed, -0xbe76db45, 0x4cd4f49d, 0xb6d0ea56, 0x520439ae, -0xebe279cb, 0x3f1a7c2a, 0x619235a8, 0x56405f42, -0x501720d7, 0x4a7ef865, 0xfa717641, 0xf31ca260, -0x91316b95, 0x54ae5249, 0x341b05b5, 0xaf7d573e, -0x334bba10, 0xd373b388, 0xcdac2e47, 0x5ae308df, -0x9478800a, 0x86d004b2, 0xa66c7fba, 0x37071be6, -0xd34a6235, 0x4d9f247b, 0x783c21d0, 0x65241a87, -0xd66775d0, 0x1cc8c436, 0x9ef955dc, 0x4dbf6d44, -0xbea46f13, 0x682282ac, 0x5b4c6481, 0xcd17f229, -0x61f16e29, 0x488d8b12, 0xad66f71c, 0xb40314e8, -0xd0a5c610, 0xe260f3e1, 0x5fc8bfc4, 0x61360790, -0xd148e5d1, 0x945bf81b, 0x762f3ed6, 0x77fcc860, -0x7e6f7682, 0x5f72b5d0, 0x646345e7, 0x25aae6ff, -0xbb147982, 0x49545897, 0xf6de875d, 0x518f225d, -0x908cfe23, 0x064556a1, 0x313228b7, 0x869e9b63, -0x1b292069, 0x7c0055c9, 0x7d6b8678, 0xcbab0381, -0x7c215f80, 0x9189d566, 0xf848d9aa, 0x55535f2d, -0x3958620c, 0xe6c0081a, 0x6b2bbacd, 0x0a0ad463, -0xcc3221df, 0x783aa0d5, 0x289468fd, 0x7f813440, -0x02a8ac44, 0x1d893476, 0x1272a61b, 0x518f3582, -0xf85a6840, 0x6095b5bc, 0x552a43c0, 0xdb464e87, -0xd08f74d8, 0x5ac3d2ec, 0x70996668, 0xa13872d2, -0x431ed665, 0xce6a7742, 0x10f8b5ae, 0x4767891b, -0xe411709b, 0x977a5301, 0xc726cca4, 0x21460e48, -0x8165b05e, 0x60a25ecd, 0x7cd8580d, 0x5670cf27, -0xb504c67e, 0x21f9ad8b, 0x2737c2e0, 0x60a7561d, -0x564f20e6, 0x583e4d1e, 0x8afb7fcf, 0xd117a013, -0x2dedeba3, 0x4c42ae87, 0x6fc8074b, 0x90a68e2a, -0xaa4821e6, 0xd1b5f3d2, 0xba3644dc, 0x497d8f52, -0x0625d697, 0x8dc5e978, 0x7d23526e, 0x0a476955, -0xc476d8a6, 0x6f34a681, 0xc9e46006, 0x66970ab9, -0x1bb0bbf2, 0x280d0090, 0xd35cf8c9, 0x439b2a9e, -0x8ac72732, 0x674df5c2, 0x9d241d38, 0xbbc0ee7a, -0x1ef54bc1, 0x49d92718, 0x7736f8bb, 0xf95f6a52, -0x51d7dbf2, 0x9ba738eb, 0x948c1787, 0x65962750, -0x1b15490c, 0xf98112d9, 0xe9a7450c, 0x49954e37, -0x8f545c8a, 0x4c75ecfe, 0x1c81eea7, 0x11c13f67, -0xa49b57a0, 0x56efc5d0, 0x3a93fbc5, 0x4d26f480, -0xb05ac1e7, 0x2fcfdd88, 0x94533ae9, 0xa001c646, -0xf4c3290e, 0x67199cf4, 0xd8b84246, 0xd1f2313a, -0x93cf2a11, 0xb0cedd94, 0x6636e680, 0x7f28ae19, -0xb345e7fb, 0xd1e4c561, 0x007b7886, 0x427e8738, -0xbcd314d7, 0x6b86e787, 0x54d403c2, 0x177baa6b, -0x3fd8cb1e, 0x6c2a7756, 0x5989fe90, 0x477f06ac, -0x5e16aa49, 0x39b1cb69, 0x5795a5e2, 0x9f1b223c, -0x9537e26a, 0x6bce6cb4, 0xb7b6d079, 0xd2b74b15, -0x488e6a89, 0xbd79ca3e, 0x26be9f93, 0x4acb5561, -0x2d88ccad, 0xe5ec5edf, 0x170f68da, 0x42c16b5c, -0xba2cb190, 0x48243011, 0x75ab800c, 0x25728407, -0x7b2cd7b3, 0x519bdfc1, 0xfa1eab24, 0x787a8b76, -0xb0c85b5d, 0x1dd215a4, 0xadafdee4, 0xe1ebba23, -0xdd5a59cf, 0x71712870, 0xeae95666, 0xa65ba058, -0xff3f0885, 0xcbfbb4dc, 0xdfc7ac25, 0x71c07273, -0xdbb6086e, 0x9b39fda3, 0xb27ec2f4, 0x6efa152f, -0x76c1bd96, 0x7e4f0c12, 0x55179b81, 0x011fe1a8, -0xcb7404cb, 0x7654df7c, 0x2a66dc3b, 0x79ea9141, -0xbefe239f, 0x05287ade, 0xa7667a14, 0xf214cfd0, -0x8d217994, 0x7a006397, 0x3cfa146e, 0xad719332, -0x84b65556, 0xe1457370, 0x25fbcdbd, 0x52d3ab75, -0x2932b5f2, 0x9a8fae3c, 0x2372ab7a, 0x5ff75c43, -0x7c10085c, 0x476c0115, 0x5a2e4b6f, 0x0d250055, -0xf0ffd556, 0x50da2ec7, 0x08c38028, 0x643d0953, -0x7e773b1a, 0x0b89dc21, 0xa023d976, 0x9d6b3e83, -0xe0148bcb, 0x6d362334, 0xdcffb904, 0xfbb85c9f, -0x50336118, 0xae98a62e, 0x807b1eb4, 0x58bb652e, -0xaa5ee667, 0xce20b77b, 0x342e21a0, 0x5daf250a, -0xeccce81f, 0x48cb298c, 0x1c3c10a5, 0x3be0c1c7, -0x6a7f3ff1, 0x421ed684, 0xc62ec582, 0x41db8062, -0x13b32c82, 0x01fa6e17, 0xa1b5c0c2, 0x9a103563, -0xa8a5573e, 0x739774f2, 0xd0ce41b3, 0xe45ca941, -0xd57b5f99, 0xb1b5dbbd, 0x56fbf5f7, 0x4c8f6091, -0xf71f2ad6, 0xe189ef6f, 0xff318027, 0x01b3a07c, -0x3b577d20, 0x703e40d0, 0xdc943755, 0x40ceec0f, -0x875f6f75, 0x23c689c0, 0x5edec53a, 0x68e7c50c, -0x4aaf4a1d, 0x4081c16b, 0x4ad8409a, 0x8b813650, -0xdd029252, 0x776b0335, 0xb61af09a, 0xc675cc28, -0x18d32d7b, 0xa5e4d889, 0x4d9c4bf6, 0x737fa6fe, -0x5922b3b1, 0xebd1c6b5, 0xcee18d5a, 0x06511330, -0x8fa95e1d, 0x785789f8, 0xab4d16e4, 0x709155a0, -0xb23ce349, 0x10946eb8, 0xf2e9a02e, 0x7e8795cc, -0xb5777aef, 0x532e88d8, 0x775430aa, 0xf60b3548, -0x40422cfc, 0x60401e57, 0x8f767a2a, 0x90372f3b, -0x9c013672, 0xf469ffcf, 0xabc6d7ab, 0x7e0a1479, -0x79058a26, 0x96f327dc, 0xc356d4f9, 0x183db73a, -0x6b3cb70e, 0x5a63aa80, 0x442c171a, 0x6b87a7d4, -0x1e24ac07, 0x1529e09b, 0xfb59c944, 0x6705a5af, -0x8669338e, 0x4cfb8b4b, 0xb3997f75, 0x3a5c3716, -0xba26316f, 0xbef4d01f, 0x35a2facf, 0xeba8e47f, -0xb5069dd2, 0x258ecc43, 0xa5d27756, 0x272095eb, -0x092d5fe3, 0x849da615, 0x0f2bde22, 0x688e8203, -0xf233aaed, 0x655f7cd5, 0x4d63fc11, 0xdfbbda49, -/* 407-MU16522a.inc */ -0x00000001, 0x0000002a, 0x05121999, 0x00000652, -0xc8b34cc7, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x76f00e60, 0xb9434a7f, 0x5e9ab4c2, 0xcd0a8081, -0xcc2c6b4c, 0x481bff6c, 0xa81c6bb8, 0xef5c8363, -0x6e44f08a, 0x9011d878, 0xed520c57, 0x22571828, -0x939f7c98, 0xa8e6d071, 0x2accc70f, 0xb37b2c5e, -0xff6baf05, 0x016be7a4, 0xea2623ed, 0xecc84aec, -0x19c7c229, 0xf7f0886b, 0xc12cadb9, 0x27f0f5ea, -0x80a157da, 0xe703242e, 0x6d0bb522, 0x9844e0d4, -0xa58dec65, 0x7567ffe7, 0xe80c9da4, 0xa331e7d5, -0x5a4b6453, 0xe638a61b, 0xa6cbd089, 0x1eac6267, -0xa4f3e8ec, 0xbba4fb32, 0x317b7c6b, 0xe17fac53, -0xc8e0673c, 0x28538606, 0xfbd44993, 0x8ec7e8af, -0x6c462f02, 0xe72751cd, 0xb22bc0ef, 0x3ad6128e, -0x99a6222f, 0xbf4c4e6f, 0x122354eb, 0x8fb39904, -0x9058153a, 0x14e61acd, 0xef511b6b, 0xa9b2f095, -0x7eaf14fc, 0xdae7a10a, 0xb1d1b2ba, 0x769b0eab, -0xdb522452, 0xb23d5e86, 0x7de3e9a2, 0xfd2ac952, -0xff866004, 0x45a75e71, 0xa1e060a2, 0xbfc1c2c9, -0x424198ac, 0xf823bdcf, 0xefffc562, 0x68b8edf7, -0xfd4e6d1a, 0xc1f23855, 0x20c0f4e3, 0xa029841b, -0xc5bd6cfd, 0x79f2ad6b, 0xa13b03df, 0xee971307, -0x363b0da8, 0x9c077042, 0xb30115b6, 0x3ddb5013, -0xdfc3243f, 0x85e4159e, 0x0113acb4, 0xebb4bcdf, -0xff244b7d, 0x12a3aaf2, 0xe19e9488, 0xeb7cefc2, -0x566252d7, 0xe186da08, 0x93e670ad, 0x7ce6d3b7, -0xd75bf7cc, 0xbabb15c5, 0x69295dab, 0xc5b3f71d, -0xf08dceb8, 0x7dd96027, 0x93578a64, 0xd314e608, -0x78264a52, 0xa08e7650, 0xcdb08bcc, 0x7107fc39, -0xe51d6c66, 0xd52df3b8, 0x379509e2, 0xc25233d3, -0xdd9f284d, 0x0682ad5b, 0xdf1bbe5c, 0xd2b96b14, -0x5442e8af, 0xca921855, 0x99f35d84, 0x72b7edf9, -0xcabccee5, 0xa477caf9, 0x6fb0014c, 0xcea152be, -0xfb8253d1, 0x70437bb0, 0x8d9c4443, 0xd8a6177d, -0x78023d12, 0xa64f4ff3, 0xcbedd7f8, 0x662d9a07, -0xf45fdfb1, 0xc21ce1cd, 0x30a109e6, 0xcf4abf94, -0xc59fff95, 0x191f3b05, 0xc36a43a4, 0xdc0bd9eb, -0x5b2f6677, 0xc71533dd, 0x92eb59ad, 0x6ee37cc1, -0xcc7fd822, 0xa90f9c92, 0x74860638, 0xce475653, -0xfd8b3b2b, 0x62fcc55e, 0x907466f0, 0xc8ff579b, -0x7a953138, 0xb7e9a3d5, 0xcce7f647, 0x72e27e2b, -0xf37401a0, 0xd12302eb, 0x33518c48, 0xc5c94836, -0xdd2c112d, 0x17f0aa48, 0xcaf068ab, 0xd6d75439, -0x5d96ddf7, 0xdcf939d6, 0x9c50d0ba, 0x6b16166a, -0xdfbdfa9f, 0xa310daa9, 0xde9c8db9, 0x2131f1d7, -0xd445fc23, 0x0a0cc3ae, 0xd58e33b6, 0x7382cbc9, -0x15c5b405, 0x76f11b66, 0x6f939b91, 0x1c4d4a57, -0x65d92f91, 0x75fa89c0, 0x12f3ac58, 0xcdeb4113, -0x6caca31a, 0x53e4ec31, 0xdbdda96d, 0x8bb3b1e1, -0x5f325871, 0xc920019c, 0x8fd12227, 0x037dcd85, -0xd5a992b0, 0xcd68d006, 0x02bbf3d3, 0x5c477b08, -0xc81dfb22, 0x919d0e0a, 0x5e3dfe14, 0x8b94d4c1, -0x8ab037d1, 0x003ffd27, 0x91fc1b17, 0xdcb63a69, -0x0aa59da9, 0xd54442a0, 0xc832489a, 0x7499b7e4, -0xdf8bfe4f, 0xbe5aa6c9, 0x61a559bf, 0x4d60ef8c, -0xa8f652eb, 0x15afb0ad, 0x52a9ecf3, 0x4895b467, -0x143a5c34, 0xbb0a916b, 0x53e69a9c, 0xf53bc838, -0xb4b830c2, 0x53240c80, 0x536aedc6, 0x89ff32ae, -0xe8d2e0c8, 0x718b7504, 0x8e6cfcc5, 0x9615fc2d, -0x7405a9b4, 0xf45b4168, 0x6af78312, 0x1eea41f6, -0x1d1b43a6, 0x1822d9d9, 0x1b987e6d, 0x13bac770, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 618-MU268602.inc */ -0x00000001, 0x00000002, 0x05042000, 0x00000686, -0x332c50fc, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x7cf009ee, 0xde212d8f, 0x40fc8031, 0xcc7df987, -0xd9446c69, 0x534b5354, 0xe8a6009c, 0xb2804e1e, -0xc923d256, 0xdcecf51c, 0xc412b4bc, 0x73396f2b, -0xfd04f60f, 0xd0d7f4d8, 0xa8f9dfe5, 0xb8defb40, -0x4edffe88, 0x646d5420, 0x35e2a45f, 0xd37c054d, -0xc22954f9, 0xc1146393, 0xd245381e, 0xeae167e3, -0x43675583, 0x60ab176c, 0x9736b9c6, 0xbff00b26, -0x16483271, 0x9a701ed5, 0xb458a41c, 0xf5bee887, -0xed55210f, 0x7c0370e1, 0x820c203f, 0x002add3e, -0xea958855, 0x61fcdaea, 0x6ad4a71a, 0xb92bc614, -0xe3a29616, 0x86b62b61, 0xa59b657f, 0xf2c3575b, -0x5d7ac6e7, 0xddeb874d, 0x8359caa3, 0x897b7a7d, -0xe3e5e8b7, 0xf49ecd45, 0xc28a6a45, 0xd6dbe138, -0xb30eaeb2, 0x1eaa65da, 0xb1d64e7c, 0x89cfa875, -0xafe14ac6, 0x33d31a40, 0x3bf217d8, 0xb5ee8cce, -0x943e91cd, 0xead5aeab, 0x6d4545f3, 0x0207a17f, -0x27c0e926, 0x0607325c, 0xfd73ab50, 0xf875a959, -0x715e91c1, 0x27286747, 0xd9e8d5d7, 0x2b5f4eef, -0x48e7507c, 0x631e9526, 0xbe652d3c, 0xf44bdee1, -0x2f0635b5, 0x82f59aa3, 0xc952dd93, 0xdfd7664a, -0xa6c6a511, 0x05f8a567, 0xdfbdd235, 0x93b0f7fa, -0xf230a0e8, 0xb3daf958, 0x9cfb1179, 0x581a9a23, -0xe90d99ec, 0xc6d45f7f, 0x00cc9419, 0xa033e134, -0x3e0c5427, 0xc51880f8, 0xe53d3f75, 0x76e46b82, -0x39216716, 0xc7814c59, 0x3e950f77, 0x796fb5c6, -0xce98e498, 0x93214b85, 0xe3cc1e7c, 0x85a27ccf, -0x3b6985e5, 0xda99f6dd, 0x2525fa5a, 0xb9597992, -0x8771a641, 0xc233d544, 0x365b0022, 0xb6f2adb3, -0xc0a5ae64, 0x11b94f17, 0xd3bc61d7, 0x4b3182fd, -0x1f3cc702, 0x074b85e3, 0x3abfe94b, 0x2f6e8c3a, -0x43a39fa5, 0xea95a0cf, 0xec6ca230, 0xeaed2195, -0x5261d5a7, 0x1e083739, 0x24cfc756, 0x133692f3, -0x68cb9b9b, 0x40a27089, 0x48962268, 0xca1ec286, -0x2a5ef51f, 0x3e9aa09f, 0x9cc0581a, 0xad33b532, -0x1d365147, 0x119e78c5, 0xf99f66bb, 0x14a97e34, -0x26e61f8a, 0x1f80e435, 0xfec0054e, 0x8369b072, -0x1492b201, 0x798cbe1b, 0x05f5aa9b, 0x68c5e6e1, -0xfd3d08a3, 0xf7ce8767, 0xd446e704, 0x9595a872, -0x1361943f, 0xea238ac6, 0x6b40e36d, 0x3239eb09, -0x14c1a58f, 0x10a72214, 0x18716029, 0xffba4d2c, -0xefab5b79, 0x40f2e49a, 0x64518f90, 0xf0983888, -0x1b6f28f8, 0xb4e9bdac, 0x6617d010, 0xcdb49028, -0x4fb8325b, 0xd51ae489, 0xc49e5b0c, 0x4ce77f09, -0x164c5ed6, 0xea407c38, 0xcedd6d50, 0x02ca2e1a, -0x300ecc34, 0x31f1229f, 0x35b3459c, 0x0a9971e3, -0x647fcefa, 0xa54d30bc, 0x14e05e16, 0x459e8d66, -0x42065188, 0x19e93008, 0xda980fa1, 0x71431597, -0x997abb16, 0x3c39889f, 0x549de523, 0x2420d441, -0xc87779ef, 0x475d7dbd, 0x68999988, 0x89ad4a7d, -0xf3da0990, 0x1def1403, 0xedd8d0dd, 0x59eb7a7f, -0x67642d29, 0xc2454f39, 0x88217cde, 0xcdefaf71, -0x12588b55, 0xf48d0ce7, 0x88b7c3d3, 0x5c62b02e, -0x21c05aa4, 0x98cf763b, 0xc02f860e, 0x8a1bf23f, -0x676d2f90, 0xd73b4c08, 0x02dda911, 0x60ba8c76, -0x3ed5df97, 0xf4ca9795, 0x9f7b6271, 0x4be6b998, -0x69a4a139, 0x3a3240cc, 0xaa40b9a8, 0x41e08780, -0x738f645c, 0x79170059, 0x231ff3b2, 0xe34f6b4e, -0xa8021b05, 0x8eb72629, 0x18dbccd1, 0x88f020d7, -0x467dc6b0, 0x72a7070c, 0x0f65f00c, 0x8150ca60, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 534-MU16810d.inc */ -0x00000001, 0x0000000d, 0x09211999, 0x00000681, -0x31708166, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x710e5240, 0xab8bc2df, 0x6e652d5a, 0xcc16718b, -0xaa5c7d1a, 0x43ac1ba0, 0xbdf8684e, 0x82565fa7, -0x1d108edc, 0x96d2d5a2, 0x85f783a0, 0x16e4cba1, -0xbc311213, 0xc36c45a2, 0x443b8d2b, 0xfdc5e9ce, -0xbb6f8637, 0x47011b8b, 0xf3898e4a, 0xb3e90f68, -0x60af6e3a, 0xff9d3de4, 0x9fb2333c, 0x5a1a39ce, -0xffd75d72, 0xa60cc2c0, 0x5729267c, 0xfc6d2da7, -0x8a2c8ae7, 0x71aba5ba, 0xb639ff31, 0x8d1642b8, -0x3aa67efc, 0x9f786473, 0xaedec560, 0x1acb694f, -0x97582a6f, 0x8dc17ea5, 0x19636cfe, 0xb5032243, -0xc46f764f, 0x3a5d3833, 0xf3d1a2b9, 0xc22e59be, -0x15e0b2f3, 0xe58eff24, 0xc679600d, 0x21a3a845, -0xc11cc921, 0xed2f5061, 0x2d4db0d1, 0xcc0cc78f, -0x80197c08, 0x20739d8a, 0xc92ec866, 0xacef343b, -0x47c0913a, 0xee8a69e4, 0xa7b0157e, 0x4c3607a9, -0xcc7ff7ea, 0xb0a36667, 0x41d1bcf0, 0xf54c42d2, -0x946c590e, 0x6da18fe9, 0xf20df0e6, 0x984a2160, -0x479becd3, 0xfb11dd36, 0xbb816653, 0x60c605c2, -0xf52efe8b, 0x90a9f863, 0x69654bfa, 0xf0f03f7c, -0xbf0498d5, 0x68708d82, 0xdab94924, 0x92371217, -0x603feed7, 0xf0ff8329, 0x9c8769df, 0x6d40ab73, -0xd8fd132a, 0x9335543f, 0x40fd3abb, 0xf25665a0, -0x93fe56a6, 0x682a3b24, 0xf3a0f14a, 0x97e92084, -0x4e8736a3, 0xf322db48, 0xb65de2ad, 0x6af68474, -0xfd6dae0d, 0x953afb0e, 0x6ef22a82, 0xfa7a3d7b, -0xb5fe683f, 0x647579c3, 0xd184e7db, 0x99ec7c97, -0x66486a26, 0xf08c8290, 0x94eb3fce, 0x6305e16e, -0xd61dd210, 0x9b8bdbba, 0x41a4b4f5, 0xfca38a75, -0x9c55c7a4, 0x6a4b1f02, 0xf277077a, 0x900e3d03, -0x4f173146, 0xf6fbf7c8, 0xb2636cb2, 0x6329a9d7, -0xf2697eb4, 0x90f80f6f, 0x65de6167, 0xfc6cd065, -0xb4326188, 0x67507c3a, 0xdf3179ff, 0x91207c0b, -0x6408ad58, 0xf7e7d2fe, 0x999af7c0, 0x6a994828, -0xdaecedf4, 0x93cba457, 0x4d924b31, 0xf12b5ae1, -0x9563d541, 0x65bd28f8, 0xfa87a363, 0x983adc3d, -0x45c4f64d, 0xfae3e1ef, 0xb2eb287f, 0x6050f699, -0xfb28cfb6, 0x999b1d45, 0x65027980, 0xf4e507d0, -0xbbd059b7, 0x64cb2688, 0xd29dff15, 0x90927c2c, -0x6d52471a, 0xf64fc745, 0x9e4050ff, 0x68b66e3f, -0xd0a1dd96, 0x9fe8a5a3, 0x454c936b, 0xf926115d, -0x9bfb60ff, 0x604049aa, 0xf3509e5c, 0x9d6cf26f, -0x4d777c5a, 0xfd7cd5ff, 0xb15d4f35, 0x6b1aa6e3, -0xfa279f20, 0x94916fae, 0x9b04dbcc, 0x600defd9, -0xf2977cd8, 0x65fa64be, 0x968feaee, 0xc11681af, -0x66568af6, 0xa539a4ee, 0xcfed5cb1, 0x108445de, -0xa603dfdd, 0xbf5ada02, 0x14b868c5, 0xb2d3b8d2, -0xbabf3637, 0x0c25bfbc, 0xb7a4c247, 0xf2837e05, -0x062ce963, 0xfcb65c46, 0xc6d190e7, 0x4dfce123, -0xcb0bf4c7, 0x8bff9d9d, 0x6794e002, 0x2879661e, -0xa5e93199, 0x77be4be8, 0x22fe3324, 0xb943e4ef, -0x73463d52, 0x31471050, 0xb68fd63f, 0x84cad24f, -0x343d922b, 0x42b9ab31, 0x88ee1549, 0xe913e2ab, -0x4a127048, 0x5057f79f, 0x636eb512, 0x42e02f9c, -0xd3a8b863, 0x9bc40609, 0x4a18edb5, 0x86a4bdaa, -0x91819a4b, 0x12a11e17, 0x8a6d7f21, 0xf42998d9, -0x132b6bbd, 0xe3239feb, 0xf52519d7, 0xada08128, -0xe6febacf, 0x44e15a80, 0xa977610a, 0xf56a8665, -0x4693b6f0, 0xb8386320, 0xfcf7d071, 0xb8a1128d, -0xb2a45d18, 0x075a2095, 0x98ebde53, 0xe8762eaf, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1072-m04f1305.inc */ -0x00000001, 0x00000005, 0x05082003, 0x00000f13, -0x386c53da, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x5001ae2b, 0xf153d2b4, 0xf4fe5845, -0x7353305d, 0x2eb3bfa0, 0xc468112f, 0x82583061, -0x233d5868, 0x9ef78991, 0x1ecdc4a1, 0xd6543acc, -0x6700a864, 0xeec1b6d5, 0x35b67f1b, 0xaee05186, -0x769f6bc1, 0x427908f3, 0x39b58424, 0x05c25438, -0xa84809d5, 0xe971a10c, 0xa160654c, 0x73be48e7, -0xe1012a12, 0xf051e0cb, 0x2bbe146a, 0xa7a78d04, -0x2e9fa622, 0xc5109d9f, 0x15551c3a, 0xe6e2a600, -0x1cf01aa4, 0x49c58079, 0x4c8d88ae, 0xbbf2d0a2, -0xa95df3db, 0xe6c8c5c7, 0x4f2c1041, 0x50c70186, -0x3b777e75, 0x8b1fe76f, 0x28579fc1, 0x3fba0373, -0x510da380, 0xdf1ac785, 0xd1f0f390, 0x167f3702, -0x6673bc0f, 0x3406e180, 0x02538338, 0x1cee4705, -0xd444ebdb, 0x11d3af33, 0x9f753475, 0x2fca1eac, -0x49441be3, 0xac80a36c, 0x9ae8ba7b, 0x5aee4d23, -0x3fdb6203, 0xb90c24a1, 0x94b1260c, 0xc26cfdab, -0x7f7b16cf, 0xd41bfcdd, 0x7bfc2c3f, 0xb6fda687, -0xaad0271f, 0x683e43fe, 0x4b5a8549, 0x9a944db1, -0x259533a8, 0xf752aa57, 0x0aaece02, 0x3e9eb6dc, -0x01529a99, 0xa1120a61, 0x0612f4ae, 0x1c545b24, -0xa161aefd, 0x09ee8195, 0x26d9a47d, 0x95f2fa94, -0x41077351, 0x591759f9, 0x14ebbfb9, 0x71e1a718, -0x504b6d8b, 0xab3b3e1e, 0xbb94fbab, 0xdc078a4f, -0xab9c047e, 0x807e8764, 0xb28d8d69, 0x6d489143, -0x707ea03f, 0xf819352b, 0xf46a392a, 0xc0615234, -0x67e66559, 0xf107b9a1, 0x034b1cff, 0xcddb15e1, -0x2ded2974, 0xbdfa2af0, 0x774955bd, 0xc85f3fce, -0x6f219931, 0xbf4fc6a8, 0xfc6e24cd, 0x03b9c13c, -0xa542941d, 0x91277cff, 0xc0749077, 0x735adc99, -0x152bcc34, 0xd659d8f5, 0x425ff8f6, 0x73550a48, -0x3e822814, 0x44a276ce, 0xeaf24451, 0xbef2fed0, -0x03b149d1, 0x2a19ebcc, 0x942f1414, 0xeb1bafe4, -0x609cb77c, 0x45e67b00, 0x742c98ca, 0x6b054612, -0x1eee23a6, 0x8dc74531, 0x0040b65a, 0xeee298c8, -0xb429988c, 0xde7b9cfa, 0xde6aec9b, 0x2d64954c, -0xb6cd4969, 0xe4480aff, 0x6743154f, 0x3871a946, -0x32967b52, 0xed4a5c7e, 0xe065a558, 0x2d7c288d, -0x9cd34d1c, 0x02cab1bc, 0xef438227, 0x662ef5a7, -0x8b25ea6e, 0xb9475283, 0xa51c79e4, 0xd9ec4746, -0xf3d6b5c1, 0xc330446c, 0xeb3994a6, 0x87cc380e, -0x26bc605c, 0xbb4784b4, 0xc8c6f734, 0x84804cff, -0x29e6d498, 0xbf2f0b7b, 0xe25253a0, 0x364d64e6, -0x6a5f37b9, 0xfb6893b5, 0x27748c57, 0xc214525e, -0x5b4c8f32, 0x3e39d2b6, 0x6bb6092b, 0x33325280, -0x9e97faf4, 0xec0ae39d, 0x9d9d331d, 0xe1fab17c, -0x398b6cec, 0xf6467387, 0xb9c8d5ee, 0xbcca09ef, -0x16be976b, 0x2ffc13f2, 0x15341d17, 0xaf7ba4eb, -0x9cd99ea9, 0xccf923bf, 0xc1f8aefc, 0x9e58f162, -0x449142d6, 0xa45b5c3b, 0x091f2d34, 0x3198ec74, -0x420a2fd6, 0x4bde2efa, 0x87fb82ba, 0xf9d023bf, -0xed5e91e6, 0xd238150b, 0x06afb204, 0x07d90c48, -0x48b47431, 0x8e7f13b8, 0x03d96ffe, 0xcd038364, -0x2cf59804, 0x7fb3ba35, 0xd790285c, 0x2a8e5cbe, -0x528e9b88, 0x6926614e, 0xfa07b720, 0xf7ca68c1, -0xebd7a28e, 0xd97d1dc6, 0xa16092d5, 0x72c1f20d, -0x2a89581e, 0x184e1567, 0x9e3f99a2, 0x00420d9b, -0x6ea5081b, 0x6b19d2dc, 0xcce35407, 0xd7822e92, -0x2a20eb0b, 0xe8b5280f, 0x15b7d076, 0xfa9e8632, -0xe29adc6f, 0x7f251fd9, 0x3e718eae, 0xd28cd498, -0x0987778c, 0x6f5ad282, 0xb82da525, 0xbf78e58a, -0x205a07f7, 0x480d1f4f, 0xdbf07f5b, 0x12ac2504, -0xf6195b0e, 0x27caa6a6, 0x3125fd45, 0xc1bcb8c6, -0xbc3da654, 0x474943d1, 0xf795db64, 0x407da287, -0xd8b1098c, 0xe6015d4e, 0x683e0133, 0xab4b1d47, -0xee2d9eab, 0xe688b255, 0xb68cc171, 0x01bb8385, -0x4b409c68, 0xb138d49a, 0x7010dfcd, 0xdd2a5079, -0xa345ba2c, 0x16b83049, 0xc644b84b, 0x463d5e22, -0xaa016810, 0xb7d47e32, 0x6b3a159c, 0xc2cdcf79, -0x9806acf7, 0x63aa2806, 0x9c587d84, 0x21cd996e, -0xbaa4da3e, 0x5ed95a9a, 0xa92da1da, 0xa3256bbb, -0x82774984, 0xfc6d902a, 0x3cd802c4, 0xea96bdb3, -0x1bd513dc, 0x180a5def, 0xf68b2c7b, 0x1630b952, -0x5fdfccd3, 0x86fcb1f0, 0x1db7c873, 0x426e7203, -0x4e7653c2, 0xf015363e, 0xe1fb4d92, 0x575218c8, -0x55463588, 0x57b9e42a, 0x56271dc7, 0x66caff00, -0x5732c877, 0xf22cbd0d, 0xd3445e1d, 0x392497d3, -0x2d40cfa1, 0xd47efc4a, 0x23154511, 0x79bdd22d, -0xc44b05da, 0xe44d004a, 0x72b2283e, 0xa726ed89, -0xf8efb7fa, 0xd8db9bd4, 0x591c1fd0, 0xb77c25c5, -0x675a794c, 0x979a9c6a, 0x81007ee2, 0x31ad3e84, -0xb1ff590a, 0xcb8b0d6c, 0x2c33533a, 0x2cba2b17, -0x28034408, 0x9a6f595a, 0x10631e7c, 0x7f220b25, -0x361c95e0, 0xa74d0fd0, 0xf6e34216, 0xfdbf26e1, -0xaba66ba0, 0x53dfdf06, 0x51c46bb2, 0x74735bf0, -0x5bbb13b4, 0x7d1fceb8, 0xf022c0f4, 0x172557e3, -0xadc3eaa1, 0x437ff720, 0x74fd1b34, 0xd0a2bdd8, -0x4b469027, 0xd8e2b398, 0x642b05a8, 0x26bcf886, -0x580935a1, 0x19c17435, 0xea07ba9f, 0x82b6a9f3, -0xadc470e2, 0x9f063324, 0xe2ee8f00, 0x85acea76, -0x48ee7054, 0xca1926d9, 0x7d91b8a5, 0xf2234802, -0x18c32e68, 0xac564fa3, 0xd9242a86, 0x314b85e6, -0xb3c0b619, 0x67a28d4b, 0x460fca58, 0xe77f6781, -0x4d44b6fb, 0x23b8792f, 0xa82b06a7, 0x53e761ba, -0xe61fce34, 0xc3d32f78, 0x0a27a861, 0x2f4bbda4, -0xd994086c, 0x9b6295ee, 0x359fe82d, 0x359ef141, -0xc1d15957, 0x0a613caa, 0xe322762c, 0x85399553, -0xb3a621da, 0x0ef4505e, 0xf423bf29, 0xe46011ae, -0x666d7f63, 0x02ed1f2f, 0x8b75b4fa, 0xbc20db71, -0x95dda900, 0x47ee785b, 0x61d702d8, 0xf6323f36, -0xce38e245, 0xf3c2e68e, 0x7b40eeb0, 0x641169f7, -0x2f90e7e9, 0x8a70bec0, 0xa577b168, 0x72ce4f59, -0x2ded6007, 0xf18ef638, 0x8aa8081b, 0x42bd28a2, -0x1ae474cb, 0x126c1d33, 0x699c5be9, 0x3c9cd070, -0xd6fda74b, 0x42ec7826, 0xa1e4b946, 0x81590175, -0x11aedbea, 0xf055f904, 0x6562d6d2, 0x94f802c5, -0x11b1f94e, 0x468c9214, 0xbb481f32, 0x17e6ed48, -0x79adcfa8, 0x128ad16d, 0x9d7a45f3, 0x914a1d48, -0x391121da, 0xa8faa6fd, 0x733ebef5, 0x0a355e2d, -0x196fd93a, 0x8c7a18db, 0xc87018e2, 0xfe5d8f43, -0x6ef1d661, 0xaf4bb5d9, 0xf6848f1a, 0x2cc4b8d1, -0xc5a82a15, 0xa9f58f89, 0xeddf2fc9, 0x3f40bedb, -0xa091724c, 0x6321f26e, 0xeeb85002, 0xddc04d77, -0xe5d21616, 0xb59e2731, 0x8302c19d, 0x66b6b6e3, -0x7ddeacc2, 0xb83f69ba, 0x67546e4c, 0x4f504b47, -0x4dc533f9, 0x5c4ffbc2, 0xff380ef6, 0x3dcadeb1, -0x402da16e, 0xbe2f64a6, 0x9916562e, 0x0d092e1f, -0x7f702ee1, 0xcc49c252, 0x421ca906, 0xff48292a, -0x4fb55b6d, 0x78495c42, 0xe79ebce1, 0x1697e629, -0xd9d6abeb, 0x8ac66ff9, 0xeb90c46c, 0x441d8afe, -0xc830515a, 0x10955461, 0xeffd35dc, 0x5e1bbea5, -0x2fe62b78, 0x20bb1b23, 0xf97f16b4, 0xe750c2d8, -0xecf1821a, 0xdba57d3a, 0xb29da168, 0x568fcf42, -0xd6f89d17, 0xe01ab3f5, 0x20265a7a, 0xf2a0a822, -0xfed039f8, 0x56b6a887, 0xfdc5024d, 0x66d24460, -0x86e7511e, 0x0925d922, 0x9e2e98a1, 0xf9b8024e, -/* 1104-m04f241e.inc */ -0x00000001, 0x0000001e, 0x06052003, 0x00000f24, -0x9ba58d71, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x5715f121, 0x440ce2fa, 0xd5d090eb, -0x70b3e977, 0x92320e8c, 0x4f989906, 0x36907442, -0xcc4b12e2, 0xb456a6ae, 0x0ad5bcf7, 0xe9f0a425, -0x70b932d2, 0xe66202c9, 0x350f884b, 0xd560a828, -0x5c4c5cb4, 0x7b142329, 0xd9e25719, 0x98b1dbb0, -0xb11af93f, 0xe83b07eb, 0x9b6d35a1, 0x0df761c2, -0x1a5e6da5, 0x3c978798, 0x08a7acd8, 0xd20a3b15, -0x0aaeef40, 0xa4ed3a47, 0xb8d15785, 0x2ac39380, -0x153a5ad7, 0xeddc8222, 0xc02510f4, 0xc7cdc21c, -0x09adfdce, 0xf4dc290a, 0xc6e2f5bc, 0x8e60359b, -0xf097f2fd, 0x24ac2ac0, 0x770ecf17, 0x9f80b3f0, -0xf250a757, 0xad071b7e, 0x51d432ef, 0x3c095fc8, -0x3574394a, 0x23e0e092, 0x8c9e2505, 0x927dc9fb, -0x3bfcface, 0xb93be3de, 0x46c03521, 0x00192a46, -0xc6a53c55, 0xfcdbb872, 0xb56349f6, 0xf0bf598e, -0xe86afccc, 0xef930d0a, 0x905ada75, 0x9508c261, -0x8a8cb340, 0x5010a4fa, 0x92437678, 0xa7799056, -0xedd0ea8d, 0x3c25bdc8, 0x914f3f08, 0x27ff4d02, -0xd104ca12, 0x972d1570, 0xadb4a6f9, 0x34f31516, -0xb0aca99e, 0xd05b7382, 0x5fcaeecd, 0x83edf7c4, -0x1b15099f, 0x14146a3c, 0x6150ae4a, 0xd8715907, -0x6d405215, 0x307ebd9a, 0x248fcdf4, 0x1650a34e, -0xa8070739, 0x5fde05cc, 0x1a9433c3, 0x3f5770d9, -0xcedfa47f, 0x1f3c7660, 0xa3bdf9f6, 0x3a2d9d3b, -0x01833189, 0xfebaa041, 0xbc4bf2c8, 0x50c5f238, -0xb132e653, 0xd301e92a, 0x2b094386, 0xfdb557b3, -0xd4ed60d6, 0x75da1146, 0xfedf34fe, 0xa21665bb, -0xd6b6d496, 0x46d9c114, 0x20f26f66, 0x5ee354c2, -0x801aba92, 0x0973251a, 0x63748328, 0x01b293f4, -0x1a13ec73, 0xf17ea3dc, 0xcaf6a499, 0x1cd356e3, -0xa6b450be, 0x6200d2b7, 0xc4b88872, 0xf6aa6f70, -0xdbc917f9, 0x1cf3d760, 0x5d60d15b, 0x48c2407e, -0x9210b35a, 0x171df657, 0xfb14733d, 0x1c837746, -0x6df3dd50, 0xc096efa2, 0xa9202472, 0x56917067, -0x40620e92, 0xd739c7d4, 0x89cce286, 0x8882ee44, -0x2362cb14, 0x3e03d986, 0x6519adee, 0xd7aec296, -0x23a91210, 0x77229af4, 0x97fd4c79, 0x422707b5, -0xbea05034, 0x2ef3b3a4, 0xe3291146, 0x40a0cc32, -0x96b557c6, 0x5aa836bf, 0x9dff3965, 0x31e80540, -0xa0556e13, 0xc08b88ca, 0x3f3e1144, 0x4f093862, -0x96bc622c, 0x497ec377, 0x992d7899, 0xf881becb, -0xc65d3299, 0x827a9be4, 0x78b851b6, 0x8314b5d1, -0xeda31b10, 0x471764db, 0x905d2df0, 0x19e376c0, -0xcf6af8a5, 0x4355d3d3, 0xb2033a88, 0x00f2c0d6, -0x537a95be, 0x6938a3c7, 0x8d85a10e, 0x19f996f8, -0xe5334524, 0xec2cc18b, 0xc540afec, 0x14206bbe, -0x89601729, 0xf21d5916, 0x11c39ad0, 0x93a73d2f, -0xbd8a681e, 0x3d62394c, 0xe43d9c1a, 0xb1b85b09, -0x48e87b21, 0x3dc66cb4, 0xad066e73, 0x745fb4b0, -0x47f5cdd2, 0x28e9dc7c, 0x94515ceb, 0x3a94e085, -0x0fcdb0e4, 0x55cdbb93, 0x38d990f1, 0xa8f13bff, -0x497471f6, 0x4e74b9f0, 0x6212615b, 0xec6ed687, -0xc984443e, 0xd3852197, 0x35ee920a, 0x690a7b44, -0x4c2ad071, 0x8b9e3890, 0x4114aba9, 0xea796a19, -0x0d968acc, 0x97709071, 0x20274074, 0xcecfce72, -0xbfdde5ee, 0x4d694e1e, 0x800d6bfa, 0x969027a0, -0x9417fe60, 0x9cadfc0e, 0x6a103bda, 0x375fc4e8, -0xf309280c, 0x945f197b, 0x5cb77b5d, 0xdf5d5708, -0xced4272d, 0x6b04b696, 0x78e44dc2, 0x8c41f9d4, -0x92650f39, 0xae3d250a, 0x07c91401, 0x1ca1360b, -0x2078a46e, 0x7e0b1a9d, 0x5a667dd3, 0xefdd072c, -0xeee2f749, 0xc1115ebd, 0x743c2890, 0x525d7fa8, -0x4d86d130, 0xc4470f2f, 0xcbd9dc73, 0x88230f84, -0x7476f692, 0xbcdeb696, 0x981f3fd4, 0xba7f6c3a, -0xe073e123, 0x1dfb3790, 0x6ab7fc48, 0xc519cc6e, -0x5383ddda, 0x964da863, 0x1d041e19, 0x5f2288d4, -0x5ff7c34d, 0x73a197c1, 0xd086d7c9, 0xb0314861, -0xbc63a785, 0xe072a384, 0xf37e9d90, 0x63a7a4ac, -0xa33622ab, 0x802471f9, 0x0841f065, 0xff4ea8fd, -0x343caaaa, 0xcb8594f5, 0xf5756925, 0xcc946e7e, -0x9043d824, 0x49812185, 0x1f555515, 0xb62ffebf, -0xa27e379d, 0xa2386704, 0xaf19ccbd, 0x644130f0, -0x29abc386, 0x7d044e0f, 0x5274c8e1, 0xc8298400, -0xc08a2e85, 0x8f13dec2, 0x79f40342, 0x10ed42a2, -0x75541795, 0x9c9608c5, 0x11798ba6, 0x9a7e40ff, -0x4e44f869, 0xb0e0ac45, 0x9865be8d, 0xc361cdf1, -0x88cf2cf2, 0x5cb47192, 0xceaeb1a6, 0xd6c4b77e, -0x567e8aae, 0xd0eaf865, 0x30a9e8f4, 0x049e1005, -0x96c4842e, 0x4d97f912, 0x2837581a, 0x8dd154c0, -0xe88f85e3, 0xd5b8c4bd, 0xf6ae181c, 0x524a4d74, -0x17e15bed, 0xa200218f, 0x241d1c1b, 0x9efc70a7, -0x9e1adbae, 0xf115df9e, 0xda54c448, 0x8fe3ebc3, -0x0b312745, 0x4f0075d9, 0xc2867e55, 0xa19131db, -0xc244a076, 0xbfd954bc, 0x65a49f64, 0x3e99ece9, -0x80940945, 0x626f0b5f, 0x683bb192, 0x9fbb14c6, -0xe4136229, 0xd76f54e7, 0xd8b2b363, 0x049f372e, -0x5f391828, 0xbf27f2b8, 0xc9ba89f6, 0x83047de6, -0x6b9816c7, 0xa37232c5, 0xe86bda74, 0x8c426e07, -0xfca755b4, 0x5d7f53d6, 0x6a123e2e, 0xbef86cef, -0x0ff79e5c, 0xc160e69f, 0x3d9332ee, 0x14b3246c, -0xb1ee9faa, 0x72827d5c, 0x825683a2, 0xbf3143f4, -0x501cad6c, 0xbb872e29, 0x086f7851, 0x392df63f, -0x0013ae33, 0xd643c1ff, 0x5dc4b349, 0xcdf75234, -0x206f8869, 0x9cc8c8b2, 0x872c6d84, 0xc518e0a6, -0x2bdbed94, 0x2cea60cd, 0xd4542cd2, 0xbf5f7c4a, -0x03fd6694, 0x857030b4, 0x932ce1f7, 0x1b24d617, -0x8342fbb9, 0x2484a61e, 0xa76945b6, 0x39c08823, -0xcc4e48b9, 0x31b73d47, 0xe2699dfb, 0x3f43284f, -0xce602dfb, 0x0b50541c, 0x5ecb56d1, 0xefc75a88, -0xdba5beb3, 0xe0e80051, 0x11360a93, 0x27cc6d6a, -0x884a2e79, 0x4c5c9256, 0xe2c4c758, 0xf2422d67, -0x2736306d, 0x60f34846, 0xf41738eb, 0x9286cbe5, -0x27f5c292, 0x410fae37, 0x980f0a33, 0x2522d4db, -0x5c5b5beb, 0xdbd795c2, 0x2fcf3eb9, 0xf13709fc, -0xc76339cc, 0xfef3cf76, 0x152585dc, 0xc321c271, -0x2731085e, 0x676bce0a, 0x93299b87, 0x76e24635, -0x2dad2f9f, 0x4ee82851, 0x45f18669, 0x85a46c9c, -0x430f4c5e, 0xa95cbcc9, 0x42f64717, 0x532ec8ec, -0x2bb74e8e, 0xb23de16c, 0x211fa366, 0x8d3254ae, -0xa950af8b, 0x18a677a5, 0x15efecfd, 0xdf69f07d, -0x8452ab6c, 0x5406396d, 0x88dc53e6, 0x8a0085ac, -0x0d99aeef, 0xcd61d2de, 0xdbef2853, 0x61666ed3, -0x204f160d, 0x954367d9, 0xe98d05bc, 0x8dddc5e8, -0xf67b6d6e, 0x18ce6930, 0x2547eb2b, 0x9f3a4858, -0x8ea6adfb, 0xb1469ac9, 0x67e08b98, 0x50ccc5ad, -0xd1ef2c5e, 0x15d5d2f7, 0x167b96b6, 0x6c7cf41b, -0x9e4a7bba, 0x2b09511b, 0xa05187c3, 0xd6c93b77, -0xe5d5a827, 0x7c0c4a12, 0xe20c53f3, 0x04bebe94, -0xfad3cb34, 0xa410ba0c, 0xa0d19f1a, 0x3f802e05, -0xc42673c4, 0x2b9414ef, 0xd17334b0, 0x21f0bc8e, -0x4bdc73b1, 0x37dad34a, 0xba9ee740, 0x98cb9b36, -0xb0f63a1c, 0x3cef6043, 0x9c5247e2, 0xbc165396, -0xf5686c77, 0xb2dec708, 0x3b3e979b, 0xa1b35fb1, -0xb41af92a, 0xf8f22ace, 0x5ebd44c1, 0x4c133891, -0x997d6952, 0xa2fd9241, 0x1a81ea5e, 0x612d0955, -/* 51-B_c6_616.inc */ -0x00000001, 0x000000c6, 0x12101996, 0x00000616, -0x2d239c7f, 0x00000001, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x0ad2517e, 0x13fb1fdf, 0x34db98de, 0x9ec12e7c, -0xa4950c64, 0x8e2835e3, 0xff533c31, 0x64b35ca4, -0xad6016ab, 0xeaf6c849, 0x1f20af40, 0xb2bc69b7, -0x0581aabd, 0xe682b959, 0x4e5b1e90, 0x98dddd5e, -0xcd7f2db2, 0xff086959, 0x01e35ea0, 0x23034a52, -0x2845a4e7, 0xbbae5ed8, 0xb4ae016c, 0x68d7b250, -0xec2cf14a, 0xb417582a, 0x5492fd47, 0x558f8b0d, -0x53234b31, 0x097d79f5, 0x1f795f2e, 0x61422647, -0x193954c5, 0xac976bdf, 0x02180700, 0x1ce3d6ab, -0x91edd818, 0x77439994, 0x883ba7ed, 0xbb88cca1, -0x100dc3e3, 0x40268bb9, 0x396326c2, 0xc41dac50, -0x784a4d7b, 0x90ddeae3, 0xceaa106c, 0xea4be9d2, -0x4316a8b1, 0xd92b850b, 0xa0ba562c, 0x65509fae, -0xe31fdb20, 0xd8203aca, 0x9874e319, 0x4b418050, -0xdf30cf7e, 0x09f83e18, 0x6c26eee3, 0xcd91e7ee, -0x4529edfd, 0xc22a4c71, 0xef768431, 0x83559ba9, -0xa114a80a, 0x7b0edc7c, 0x77887b8f, 0x79ef5503, -0x6b2b3d70, 0x110b466a, 0x64ea7da3, 0xc565e336, -0x88ebded9, 0x3753ee0f, 0x48e0f094, 0xfea3a6f1, -0x2e26c738, 0xb450975d, 0x8fb76a07, 0x0eee3f74, -0x4a530dd6, 0x090bb52e, 0xa1ede757, 0x7651f0b2, -0xaa242d1a, 0xc80618c7, 0xe267fc22, 0xeb2c37db, -0x26e8dec9, 0xa298171d, 0x65cd8ab4, 0x7a6d249c, -0xfeefeb1d, 0x3244e351, 0x76c3225d, 0xca4d59f5, -0x7e923a36, 0xf8e7a3ea, 0x2f2f70c9, 0x6c8708a5, -0x0ad1134a, 0x05ba3fa8, 0x48cfacd8, 0x0e18b139, -0x3639cab9, 0x96083966, 0x48e774aa, 0xbf0a1b31, -0x0f70e293, 0x5479e1df, 0x993617ab, 0x5153c793, -0x99d54ddc, 0xd9c797b9, 0xf18935ff, 0x4c5a1656, -0x7aa56fac, 0x280516e9, 0x421df9e9, 0x4a748fb9, -0x264bd4a8, 0x59933d32, 0x3e9a9758, 0x31fae11c, -0x4e90132f, 0x6c6f2270, 0x1bf389cc, 0x1a610476, -0x614d0117, 0x9eda7a17, 0xb9a2701d, 0xf382d575, -0x55c71c4e, 0xa5537536, 0x50c6be25, 0x40bf4078, -0x91754301, 0x7fb1b946, 0xfcf2890a, 0x4e834359, -0x2610bcfd, 0xc6d5a889, 0x09f5a032, 0xd433ecaa, -0x4e447c1f, 0xbb60afe8, 0x52c1a16e, 0x0fe5b40a, -0xf4c0f7d0, 0x54a58147, 0x5a96247c, 0x9be3021f, -0x1dd68883, 0x9f3eb6c9, 0x65f9ce10, 0xdb6b6604, -0xf3c2982a, 0x798d5b5d, 0x777b7d18, 0x3ac5b364, -0x8e05142c, 0x55168b66, 0x259d2298, 0xfc005f92, -0x77d14dfd, 0x7e9bbb8d, 0x2b77bc0e, 0x79d7044e, -0x8951aeb0, 0x061d463e, 0x38ea5a4b, 0xd1a71399, -0xcda469a2, 0xa024e9bb, 0x644d9cb1, 0x849fc6f7, -0x940fc84e, 0x961e5b3e, 0x158c8e0b, 0x75ac0566, -0x922644a4, 0xb3d8df0d, 0x0ec2a221, 0x88cc3a1d, -0xd6b703b9, 0x023d596b, 0xedc01c23, 0x00f9e3a8, -0xf6d0b38f, 0xa4843449, 0x1de2029a, 0xf4421771, -0xc6b0fb56, 0x27fa576a, 0x537f2be6, 0x0b10249d, -0x3fa1838e, 0xdb16d838, 0x27503a5c, 0x051630ef, -0x62be469b, 0xe780c603, 0x65035462, 0x37f17677, -0xa99fbf46, 0xdfd14372, 0xd5188f7c, 0x9ca16a08, -0x7d3cb59c, 0x082d8061, 0x6b22bf6d, 0xb7c2896a, -0x88cb78ed, 0xc7e2b169, 0x16db0edf, 0xa5888ece, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -0x278cb2c0, 0xf41d6be8, 0x839b9b57, 0xde7df900, -0xa6d05386, 0xf79d8944, 0x24d4273d, 0x878456fe, -0xbc0006e2, 0x4cbc49c5, 0x16684d87, 0x1f2c79a5, -0x847dc8fb, 0xe873c43a, 0xc92223f2, 0xc9c193d4, -0x8f43d21d, 0xc723f894, 0xa0ed9e53, 0xd0693391, -/* 1374-m2069507.inc */ -0x00000001, 0x00000007, 0x11092004, 0x00000695, -0xf7d0460f, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x75ed45d1, 0xa58cfbe2, 0x95b6ecce, 0x3eec60f2, -0xa3518658, 0x986f23bf, 0x63ade481, 0xe26bbb6a, -0x94f0ad76, 0x0da53309, 0xc920df0e, 0xe6ee5568, -0x4a7fa577, 0x86f184bb, 0x98d09cce, 0x63a857b9, -0xb83f63fd, 0x8a34f546, 0x00f1a9c6, 0xf09c1ba7, -0xb2dab0ca, 0x1dd0f9f2, 0xb97219e9, 0x91489df9, -0x0ae22c43, 0x97602252, 0x9452bf66, 0x7b2490ee, -0x877013a0, 0x80d79558, 0x356747fc, 0xe8a4885f, -0xf7b0cadd, 0x32e006a9, 0xfa724d13, 0xe6625057, -0x41c66cbb, 0x9b638ac9, 0x9111e2ed, 0x686ccdc7, -0xbee8a321, 0xa16a3ae6, 0x5b207450, 0xbaa920d6, -0xd8887148, 0x386de110, 0x90ae1a00, 0x86f2d14d, -0x03a0923c, 0x96edf313, 0xc296dd52, 0x7935f549, -0xf094f7f4, 0xcacc5b02, 0x6b8cf81a, 0xd27d0293, -0xdb27991c, 0x4f4591d8, 0x91740b1a, 0xe5658e97, -0x22e267e6, 0xdfeef285, 0xbd99b6db, 0x0ba5a68e, -0xa8f3ae46, 0xd4e887f0, 0x2ffcb598, 0xb5ab53b7, -0xa34e5ed7, 0x275d2d86, 0xfb6504c5, 0xbf2ced2c, -0x5d3adb47, 0xdd90c777, 0xc247d4de, 0x49756808, -0xa7eccad2, 0xe463e92a, 0x08a1adc2, 0xbb1cdf22, -0xf56620f8, 0x08f73ae2, 0xe33c259b, 0x8c34f791, -0x5ac6f701, 0xd1a568a5, 0xb838c440, 0x1119f612, -0x8067edbf, 0xf891c9d7, 0x792e238a, 0x94aea031, -0xa6219da9, 0x2e657d19, 0xc0986d6b, 0x86845231, -0x1196d0c1, 0xbce3eb01, 0xd06a1421, 0x1ef9f318, -0x8fd9a69c, 0xdd2a5b02, 0x047d44ec, 0xb238dd54, -0xed7cb49c, 0x3a8c80a3, 0xab9a6453, 0xd53347c2, -0x59f19199, 0xd6c42520, 0xc6b433c7, 0x1432aff4, -0xc66caed2, 0xd7b46878, 0x1dee38b5, 0x91a2d549, -0xc847a196, 0x786ef929, 0xb03390ab, 0xeb92b8c3, -0x4a81034f, 0x866b4a13, 0xc1cec9d1, 0x14d1b187, -0xb1588c65, 0xbb04d233, 0x10754b96, 0xfbb7ae86, -0xf40317be, 0x1f5f6fc6, 0xb09daf2d, 0xa63e4a93, -0x224eeae8, 0x8a153313, 0xf62508eb, 0x6b3f448c, -0xab1cc6c7, 0xd90b89a1, 0x766abffe, 0xd96407c3, -0xde2397c5, 0x5c046b75, 0x94a3c7e9, 0x814d735f, -0x0ce5a75c, 0x929ea8f1, 0xe4e1bed5, 0x12a32b5c, -0x91c9e7ba, 0xdfb5f6d9, 0x07089e3f, 0xa39047ec, -0xc48d6f94, 0x60c7b5c9, 0xe791230b, 0xfe80e488, -0x77a83870, 0x8788bc87, 0xe8899973, 0x7a26deae, -0x9328cd9f, 0xcff87fec, 0x704c0630, 0xcf33211f, -0x8dfc1ede, 0x50e158ad, 0xf1bbe640, 0xeb418193, -0x6cfd16a6, 0xdfe57412, 0xf0a85131, 0x916cefdf, -0x68ed7eea, 0x8fd08f4c, 0xe7ad145b, 0x1b406442, -0xe731af91, 0x8a2bc765, 0x5fb4e4f1, 0x16f46d22, -0x8f585450, 0xae91ffb5, 0x2b1b8513, 0x3e0a7161, -0x9e34bb9b, 0x9686df2f, 0x5bd24526, 0x0ef38175, -0xc1c374b2, 0x953ad1e3, 0x0aebce39, 0xdba94281, -0xe065a1d4, 0x2f2304d5, 0xe95460fb, 0x05fe2928, -0x31f7b211, 0x4b01c6ce, 0x579271d7, 0xf10f5f7d, -0x2a32b09e, 0x8cbae3da, 0xb5641d44, 0xcdc2d181, -0xeeed868f, 0xe6a8bd7e, 0xf883e150, 0xe365dcf4, -0xa068d4cb, 0x5c47b100, 0x8c6a0e2b, 0x781d645b, -0x27c9af23, 0x7987c2e3, 0x521cbd5d, 0x5a85cdb2, -0x077941ec, 0x76ba48fb, 0xb0b24203, 0x494f73d0, -0xaf3d76ba, 0xe6a844d5, 0xc9d58989, 0x771cfc9b, -0x48d3cf56, 0x163fd59b, 0xc15a5942, 0x5d217288, -0xe0ffdc3f, 0xb298b4d9, 0x3b961d18, 0xb43b0287, -0xafeb73c6, 0x47f7fdef, 0x0caf84f0, 0xa1fe51ad, -0xd71618ac, 0xc87934bd, 0xe96101d1, 0x55d1976c, -0x471c8505, 0x7a36d839, 0x5d62a9ee, 0xf3c54a8a, -0xa2be15d9, 0x244087c9, 0x042c8037, 0x23224689, -0x281c5d73, 0x2139ecfc, 0xffb8bc8a, 0x834fdd11, -0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, 0x4ae2dbda, -0x86d90089, 0x6675dfce, 0x48876262, 0xcec72538, -0x11dc5c80, 0x86a730f9, 0x313565c9, 0xe3e5be11, -0x106d7cce, 0x752b8be2, 0x3d00a5bc, 0xe6f70e95, -0x44447ac8, 0x600df30c, 0x8335ac3b, 0x8816ddee, -0x700982fe, 0xee495741, 0x48c7e81c, 0xa3d55da2, -0xb0172982, 0x70ab2158, 0xd4460621, 0x3a9e528b, -0x59b18a7b, 0xf4dabc4c, 0xa8454763, 0x70877bb6, -0x66005c97, 0xaf292c06, 0x7b843db1, 0xf343b59b, -0x25cdc7b5, 0xa41da617, 0x9e9d895e, 0xc936f475, -0x7270925a, 0x30024230, 0x8e72f53d, 0x2b6c1b6f, -0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, 0xaf377cc1, -0xbff09a78, 0x4b4e0814, 0x95a0b2c1, 0x270398de, -0x201fca94, 0x2a032a4f, 0x131542b4, 0x0d7306da, -0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, 0xa3b3a991, -0x17ee60c2, 0x852c0b8d, 0x11e5853a, 0x762002a7, -0x92c5311d, 0x0d4bf7e1, 0xfffec870, 0xe3d35e5b, -0xff6ecfb9, 0xdedae6ff, 0x0111a772, 0x9808e780, -0x29c336e8, 0xe9bc05df, 0x5bedde11, 0x945565af, -0xaff808fe, 0x87e3423d, 0x4de6f98f, 0x93b4adef, -0xbf704fa4, 0x09120e91, 0xd54f3692, 0xdf8eab1e, -0xfabbf59c, 0xe74318be, 0xaab87ffc, 0x29fa791c, -0xe3915552, 0xa652cb9b, 0xa1252e74, 0xb35b723b, -0x542aa28b, 0x12fcc5b0, 0x3941f962, 0x82bcc6cc, -0x47b11974, 0xb821611f, 0x78b34250, 0xf1be5659, -0x561b9e61, 0x6f3bd501, 0x584e6f5c, 0xd54ed547, -0xacebcd21, 0x7b5ff816, 0xb64ad233, 0x9f2f330d, -0x69fb1ece, 0xac8710dd, 0x58dc6c60, 0x9bee6139, -0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, 0xa733274f, -0x884d9b55, 0x42b08b63, 0xafa54a74, 0x1c7ccf64, -0x93a20191, 0xaaa3132e, 0xc69831d1, 0x54634889, -0xfbfe3efc, 0xd3cf68d4, 0x302e3117, 0xf5693131, -0xc3ce8c6c, 0x1f03cd89, 0x6243334c, 0xf16bc80f, -0xdca5f130, 0xcb2cd956, 0x4c1bb421, 0xe8de533c, -0x7f86703a, 0x29aa897e, 0xdd54acad, 0x76b2f2ae, -0x7ef82b71, 0x2e30970b, 0xba402597, 0x9a653ab4, -0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, 0x2363d147, -0x5327289a, 0xe89229f3, 0xd63a535c, 0x7efe9273, -0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, 0x1b9c7bfe, -0x5d14b3de, 0x54d575fb, 0x6d65db4c, 0x95648b7f, -0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, 0x8488a45f, -0x8ebc2932, 0xd4767316, 0x3e8c4b8a, 0xbab7402c, -0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, 0xc88528e9, -0x4b2e4e8f, 0xdd938b86, 0x0c964f98, 0xfc88d480, -0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, 0x4d40b3b3, -0xcf203155, 0x0d2fa621, 0x752d2c58, 0xb12bac12, -0x1e7e8c23, 0x94215d54, 0x9854a71c, 0x4de63c64, -0x7a012529, 0x9c171f8d, 0x9e71def7, 0x3bd17d50, -0x11f175d9, 0xec78abf3, 0x7b529eee, 0xd3a69fc3, -0x5b718676, 0x58214d29, 0xa8bd2c34, 0x41ea00ab, -0xa03f64d6, 0x4ee342b0, 0x32b1e444, 0x1c1801a4, -0xc8424702, 0x334a7e35, 0x50cf1543, 0x3b22b495, -0x88683776, 0x8e2e0154, 0x6155c033, 0x4e2fa6ac, -0x42ace700, 0x8d64f97c, 0xaf9ced17, 0xb2a5cb92, -0xa558582d, 0x88705de7, 0x9e528d59, 0x84bd45e4, -0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, 0x10462123, -0x30080f7d, 0xb346cd81, 0x0049c396, 0x4e24165f, -0xa7c66809, 0x2e60bdcf, 0xaad70a08, 0xa73ea713, -0xe28f97a7, 0x283a9eab, 0xd4366489, 0xe776f963, -0x64ffa8ae, 0xde717b50, 0xbd2ca2b5, 0x3bae5f6d, -0x8d2bbef1, 0x7e9181e6, 0xf06aa121, 0xd06b2d20, -0xa83ea826, 0xef935e4f, 0xdfd27456, 0xa3451468, -/* 1336-m02f2610.inc */ -0x00000001, 0x00000010, 0x08052004, 0x00000f26, -0x17ccab58, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x364630c3, 0x90d32ac3, 0xe0b20ae8, 0xd6f51dd2, -0xab715fb0, 0x65eb6c09, 0xdbedd52a, 0x82b77a09, -0x3de6132a, 0xdb7e70d3, 0xf0d480d5, 0xcc178c48, -0xdfcccab8, 0x54dd452a, 0xf3cad623, 0x52223cbd, -0x952b83c7, 0x9f19f457, 0x0ccfdeb4, 0x7db5026d, -0x91b4355b, 0x7578f9da, 0x867c4004, 0x9dfd38ba, -0xd917eb1d, 0x4cd599fc, 0xb02762c7, 0x6a515d1d, -0x9ce55e63, 0xb83a89ce, 0x61770991, 0xf502a3eb, -0xaebb7c0b, 0x48a70ecb, 0x7e70e003, 0xa0445809, -0x61483a7c, 0xd3e42cf4, 0x73e16c21, 0xe3703903, -0x4bb336a4, 0x2a7e6441, 0x5f7c8f18, 0x61fe955e, -0xacad1745, 0x46610311, 0xa438f675, 0x0794bebf, -0x9bcf7916, 0x289ed394, 0xf18602f5, 0xd15fd3ee, -0x21d63004, 0xf8e18369, 0xbd736d58, 0x6cfa6fb2, -0x216e824b, 0x816bb370, 0x87b6b9fc, 0x018352a0, -0x6c7e0fb9, 0x2e73ee68, 0x42932799, 0x030a14a5, -0x7e949147, 0x1c7b903b, 0x202a628b, 0x2b3c29db, -0xb36cbf4b, 0xb8b682c9, 0x52edf51c, 0x21dea18a, -0x3d45795b, 0x17a486b1, 0x0b33ee81, 0xae0e781f, -0x6a51cda0, 0x038a0886, 0xb3803c2a, 0xd37b7663, -0x3fdd3f29, 0x206ff7a2, 0xc4e1d566, 0x4733a703, -0x4109f081, 0x00e13389, 0x8f6a551a, 0x876c6b0d, -0xab5f37cf, 0xa7587856, 0xf2e40d9d, 0x8f96ff94, -0x643ba33d, 0x0a714d2f, 0x9e4cebf5, 0x23be7659, -0x1f1185a3, 0xb7867804, 0x43154b8a, 0x2b410278, -0xfc50256c, 0x0fdbe07f, 0x5323861a, 0xa7743e4d, -0x360f5bbb, 0x0b6dfc4c, 0x6bc99b1f, 0xbfc3cec8, -0x01bae442, 0xbc865050, 0x1c47f2ea, 0xa733d377, -0x114a8e51, 0x4d2fc034, 0x2a1f62e6, 0x295e4b45, -0xa60fe075, 0xcec0b254, 0xd2db93f1, 0x75b76415, -0x9fa15d8f, 0x2f6be332, 0x60969457, 0x4f09bd8d, -0x3cb33e73, 0xe5bfbb05, 0xcaa4318d, 0x469bc154, -0x0c88e1dd, 0x7f0efe55, 0x87caeb36, 0xa30e9e5b, -0x4bfa16e3, 0xd8831e15, 0x859b4752, 0x5c8b8239, -0x7a5f2b0c, 0x3666be1e, 0xf4eed737, 0x5351de66, -0x126fc2c5, 0xfb125bb9, 0x1bf57cce, 0x9305002e, -0xc7fcc490, 0xb5df57e9, 0x3997066b, 0xf7f80664, -0x0f6a3e29, 0x6f8049a5, 0xd7ad0e02, 0xa5a4be93, -0x4e18215e, 0xf431e0c7, 0xb6d9c296, 0x530772c1, -0xa889c064, 0x72a08e3f, 0xf66c4dba, 0xe9de2ecc, -0x3de3883a, 0x800f091d, 0xc60b5c4b, 0x5eb1f9da, -0xedbefcbd, 0xeefd1890, 0x0094667b, 0x9931c091, -0x5b15313f, 0xf3ea84ab, 0x589cddc7, 0xefa38e33, -0xc7ff3dae, 0x122b6d85, 0x6cca8449, 0xddac8bae, -0xee017de3, 0xfb2642f0, 0xb04ea8d1, 0x18a20bc1, -0xbb1f1040, 0x68ce0f26, 0x24f8cc6f, 0xc05a61a4, -0x53142944, 0xbb95814b, 0x0fc3cf29, 0x59dddd7e, -0x53831c7c, 0x8c03946f, 0xa0fd5834, 0xb04b9149, -0x39d5796f, 0xdfc3721b, 0xdb868f07, 0x8ff124ec, -0xa53443ee, 0xc5b7b007, 0x5b9a16f0, 0xa3185b04, -0x1befb1ad, 0x3fdbae2d, 0x924cb3b3, 0xc3954c6d, -0x38d92964, 0x6b7ee259, 0x0fdaf976, 0x706f01f0, -0x6c174791, 0xd6041055, 0xfe603ead, 0x78da5102, -0xa7f1006e, 0xb4aa08ce, 0x981f3922, 0xc247e9a8, -0x27ad39d5, 0x9f510faf, 0xf6e307eb, 0xa1f8a352, -0xfb4943b9, 0x030440d6, 0xc9d8cd88, 0xb7e1375d, -0x4503a334, 0x57f6cc3e, 0x897cb70b, 0x52df60cd, -0x7f6e55b3, 0x8c56d27f, 0x4c1a5070, 0x2cb3b3a5, -0x952934d9, 0xb95db21b, 0xd5772d64, 0x4f0ed27c, -0x2ce5e335, 0xca2ce0ad, 0x8e617972, 0x000eb112, -0xab28976f, 0x7a3e7a12, 0x063ea698, 0xb64f9bab, -0xe5f6e7ee, 0xda973eeb, 0x3e75505b, 0x5b6b8806, -0x7d7b4301, 0x8e6d0b29, 0x7e27b696, 0xf8b2678f, -0x50ebc3f4, 0xdc9d8698, 0xb3be1dd6, 0x9f7c949e, -0xa477da84, 0x713d613e, 0xe1434fc6, 0xe39897c6, -0xcdfa740d, 0xa57b09e1, 0x080626d3, 0x548606b6, -0xbe306932, 0x4e765892, 0xbb7bba2a, 0x8ac2ce69, -0xd8c2ce64, 0xc95b1b7f, 0x1a2a003d, 0x73d5e9bf, -0x2063ff00, 0xb3cf5ddb, 0xbb16f840, 0xefa92e9f, -0xa2bacb3b, 0xe709c06f, 0x498304d6, 0xbb736f46, -0x04745718, 0x56318102, 0x936001b7, 0xe2f76c7d, -0x5ca8b5f6, 0xa609c8ef, 0xb9aa872f, 0x65029242, -0xba28ff9b, 0x4cd3f475, 0x60701e93, 0x9f843fd8, -0x2b89fca8, 0xc55a166d, 0xc2526f94, 0x69271a70, -0xbc7a90f8, 0x926668f6, 0x54e72586, 0xebb05b4a, -0x73cfe779, 0xf94f39cd, 0x70545f32, 0xa849637e, -0x315a5607, 0x70bba510, 0x349ed3b3, 0xd6341c9f, -0x4d6ba61b, 0x98300075, 0x629fd7d9, 0x4c413dd3, -0x7e721ef5, 0x12fc530b, 0xbb4b01cc, 0x9324d6c1, -0x6b2a1feb, 0x90faaf1d, 0x51055400, 0x024dc75b, -0x693d1d5c, 0xb7a952be, 0x1398625b, 0x8ffed6e8, -0xb5e8fa2e, 0x90c83b11, 0x7f7b9e9b, 0x8c06d718, -0x9615a0e3, 0x3d7eda6d, 0xadd850a0, 0xbff9c56c, -0xb9d865a4, 0x95cddce4, 0xe45e6864, 0x04c45d0c, -0x9af72854, 0x2f4df675, 0xd9dc6b39, 0x934e8bb3, -0x49600334, 0xb1df0a72, 0xa0de7818, 0x320e1233, -0x06e0b01c, 0xb8b8dd15, 0x86340fbb, 0x8f338436, -0x99fdb250, 0xe7708e28, 0x2c5de73c, 0xa940eea8, -0xdfc66f15, 0x67d5d880, 0x2db5f20a, 0xd8237025, -0x5224912a, 0x9d2b819a, 0x68d2ba9f, 0x4a43bf62, -0xe01c249f, 0x4ac4e110, 0xb59c4d20, 0xbc0af1b3, -0xec57e2c3, 0xf3dc0277, 0xfa65392a, 0x678eaa4f, -0x757fa21f, 0x9e848a1c, 0x075804cb, 0xd6ab98a1, -0x8e402f59, 0xf5ee99f0, 0x6d45a523, 0x92ce470e, -0xa47332e6, 0x7a62c67b, 0x58f6c4df, 0xcf79a794, -0xd42229ca, 0x8f0bb326, 0xb4e397d4, 0x5db56269, -0xe47dbe8f, 0x0de0a469, 0x71bf3754, 0x51517bbb, -0xae5fbe76, 0x3a0067d0, 0x8c3b07d3, 0xdfebc15a, -0x87955daf, 0x0d73af50, 0x71a73c6f, 0xbc247916, -0x63e1a157, 0x77e92d44, 0xf6193d40, 0xb4c09193, -0xbc415098, 0xfbedcb0e, 0x2f68cbff, 0x5be3f2d5, -0x01b49b44, 0x29bb787d, 0x0e58f10a, 0x43042b8e, -0xd424849c, 0xfad28134, 0xefff8e12, 0x3d9bcadf, -0x67f9aa5c, 0x34129664, 0x710c9e14, 0xdb1c0ba3, -0xfe75b38d, 0x5a421286, 0x8bf94933, 0x7e4446e1, -0x79d4ef3e, 0x85124855, 0x2640de62, 0xec172eac, -0x70d6d02e, 0xe6bd1522, 0xbe71363f, 0xf88dac30, -0x7b6c146e, 0xc979a8e3, 0x177d9714, 0xc4552929, -0xb8de5377, 0x26262eaa, 0xa650654c, 0x363846d3, -0x4773b4a1, 0xcfe7dd20, 0xbd29e2da, 0xfbb3811f, -0x75bb90ce, 0xe8e6fd74, 0x209fe1d7, 0xc06fb9fc, -0xc95cf776, 0xf73f0253, 0x81ee0e10, 0x30dababc, -0x99c09050, 0xd9390ebe, 0x0f32124f, 0x2aaac59f, -0xfbaac523, 0xd9d6dbd8, 0x81509734, 0x9b3a6e21, -0xf2933052, 0x2159de94, 0xd69d47c9, 0x4c6a2a83, -0x2b6b0832, 0x4be2739e, 0x5e19abef, 0xb8f3e429, -0x96cb048f, 0x735638c4, 0x663b3bcc, 0x07a86d81, -0x31de29c5, 0x90c9a217, 0x6fb5bc34, 0x4099b35d, -0x1e000237, 0xc4b3e07e, 0x1f969255, 0xb8b58110, -0x2df57649, 0x7f6911b6, 0x096e9f23, 0x5914dec9, -0x5ec6efd0, 0xb236d75a, 0x03a70758, 0xd2011163, -0x4e9603f0, 0x683d1d35, 0x4558d5d7, 0x2c77e721, -0xe2bc28b9, 0xd2252e46, 0xdd0a1a50, 0x0dbcbadc, -0x29435c48, 0x091e76e2, 0x8b3f2627, 0xf320f8f2, -0xc8bcb1cd, 0x36e35ca8, 0x82a5ea04, 0xe8ebc0cd, -/* 1341-m01f2529.inc */ -0x00000001, 0x00000029, 0x08112004, 0x00000f25, -0x2795ba4b, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x017464fa, 0xd2fb3494, 0xaf1850af, 0x5af88989, -0xd3a0a9dd, 0x8e8bd3ad, 0x8c288786, 0xf15f02b0, -0xf51c1471, 0x6c675200, 0x9c63f3e5, 0xbeb2d710, -0xbfb6d14e, 0x6ba07894, 0x4b08036d, 0x71a24d5a, -0x953125c3, 0x2cee5c1f, 0x744a15b1, 0x43a6f67c, -0x66087dce, 0x58bc5f0c, 0x09c1f187, 0x29065a8c, -0xb46dcc30, 0x597c4675, 0x2ce2fd55, 0x7329e04a, -0xe92adf75, 0x0a4f1f59, 0x6939b7e1, 0x586b6cb9, -0x9e9090f2, 0x612aeaa6, 0x908cfbac, 0x381a3a1d, -0xc0028180, 0xe7759a09, 0x9a41f6d0, 0x49004723, -0x447b0a1e, 0x84cea1bf, 0xdb6cfd61, 0xfa3fe8a1, -0x60569cec, 0x4ed55542, 0xc40d1fbb, 0x9766fe4a, -0xbffcd59e, 0xc0ec45af, 0x34da2fa6, 0x57a8f38b, -0x7cf8ab33, 0x991f0a4b, 0x83c635f3, 0xfaa6b412, -0xd6cfe7cd, 0x7eb7773c, 0xda12abb8, 0xae7f78c6, -0x0c82ad31, 0x28e15d48, 0x80a0cf1e, 0x6b8a9a75, -0x1a9aa64f, 0x4a2969ee, 0x9273d48d, 0x7179df33, -0x06fc27f8, 0x7de9a40b, 0xaaa80cac, 0x83d82561, -0xe0646103, 0xa72284fa, 0xb39b5822, 0xed08ed9d, -0x95760781, 0x2f84666f, 0xd1d45bed, 0x96a86c3a, -0xe4679e8a, 0xfa71d608, 0x86baebc4, 0xf116edb0, -0xd3a7263f, 0x237b4f06, 0x794f33e6, 0x0d783309, -0x2df3bb25, 0x02a800b8, 0x97b8ce5a, 0x2123dc61, -0xee1a5dbe, 0x185cf436, 0x84e325f6, 0x163e3ac3, -0x62288e57, 0xe5901f0f, 0xef985c3e, 0x1b9291fe, -0xb58de2b0, 0xe69eeadb, 0x42eefa7f, 0x0472359e, -0xb1fd90dc, 0x49d374d3, 0x49684482, 0x1156a2ac, -0xd0a6114a, 0x995f94a6, 0xbcf9ed4f, 0x51d161c3, -0xcc68e39f, 0x3d050ca9, 0x8cd08b93, 0x6ed69d22, -0x5fd5cc93, 0xe2783743, 0x5a1816c3, 0xda5a0ea4, -0x9b5c7903, 0xc25d6a23, 0x25cd54ee, 0xe1ab0174, -0x518ffebc, 0x28125044, 0x7ff130d8, 0xfbea3a8d, -0xe093582b, 0xf60baa3d, 0xe4674a15, 0x18a6322c, -0x21cfa3bf, 0x71a1a376, 0xdd4de139, 0xed578831, -0x0ab06a62, 0x9cee036d, 0x11ee0350, 0x62ee22d0, -0x83681acb, 0xef69ded4, 0x65000a40, 0x9ac7ab74, -0xd76792db, 0xf2e662f2, 0xdcae14a5, 0xfa39ba60, -0xf746cf70, 0x0bea4f1b, 0x9b384717, 0xf8dafd90, -0xb2ffc2ab, 0xf3fa97e4, 0x5f22e0c3, 0x04536e9d, -0x22c99598, 0x34631815, 0x9fc99bfa, 0xfe067ae7, -0x03fbd87a, 0xdc73bcd2, 0xc49a0fbc, 0x3138c419, -0x62643c63, 0xfa2597c7, 0x4c84afef, 0xdba2817e, -0xe818ed14, 0x74a5ad6b, 0x9cf3ced5, 0xf633dd12, -0x4ba39a46, 0x8b37b668, 0x65637f55, 0x67c7ce04, -0xe860a2e3, 0xf264ba03, 0x47b91726, 0x887f4d41, -0xb10685e0, 0x95958791, 0xcb835bbc, 0xf1af6594, -0x42fb5a5b, 0x78ff5368, 0xb201a575, 0x8a6b189c, -0xc3f6e3a0, 0xe2bb320e, 0xd75004dc, 0x735b0c3b, -0x70ccd09f, 0x4d157775, 0xc0663e58, 0xf2170355, -0x4d86c74b, 0xace253a3, 0x09fedbf3, 0x5288ffb6, -0xc577a648, 0xf808ffc9, 0x6f1b81ee, 0xa56d4123, -0x60626a1b, 0xc88b4d17, 0x280e44c5, 0xf56c8ddd, -0x9110c257, 0x2d65519d, 0xc96c1ad5, 0xcfdea3e5, -0xa69ea62f, 0xf3ed57ab, 0xbe725f8c, 0x2e3c86df, -0x23635626, 0x7d2607f6, 0x67fe2874, 0xe64ade4d, -0x5fe967da, 0x88cb5547, 0x468c3eb5, 0x73313404, -0x36b6cc3f, 0xf352d0fc, 0xcbd702bd, 0x969a1606, -0xead2f56d, 0xf4c93dd8, 0xd2395873, 0xe5304e3c, -0xdbe3e804, 0x1daf81c0, 0xfd6cbdac, 0xfbb07447, -0x1970d752, 0xff97a936, 0x1cf114a2, 0x03b678d5, -0x6edaacf8, 0xd4a869c9, 0x6db6f5fa, 0xe48335d1, -0x6c59f701, 0x2cd977a6, 0x02079375, 0xc573f27b, -0xd26f8f28, 0xe637b462, 0xb9ef5a9d, 0x2483a550, -0x8e020039, 0x01d2e9d0, 0x8e69c688, 0xfbf941b7, -0x86dcab40, 0xe99730b6, 0x0e57bd5d, 0x11ace616, -0x3a5c73dd, 0xe29052c6, 0x6728d6e3, 0xf5a73743, -0x6ef89691, 0xffa40f45, 0xd1a1b739, 0xf12697be, -0xfc849142, 0x1a6daa37, 0xc52c54a3, 0xe600bbb2, -0x6c90e1e9, 0xf9ba4ed6, 0x118b0436, 0x0d864deb, -0xa574b526, 0x6f2da0ae, 0x7297e467, 0xe33a4e82, -0x6e8a340f, 0x9524f758, 0xb7d9d387, 0x67ed6069, -0x3fcef9be, 0xf3684381, 0xb8012434, 0x86d3a9a9, -0xdb45b646, 0x8de08c40, 0x37a91d86, 0xfd107ef4, -0x0b1db4d3, 0x73988186, 0x74b646a5, 0x92e5a61f, -0x72239610, 0xf9b6564d, 0xce99179a, 0x61ebb35c, -0xfb2495bd, 0x36ab39d8, 0x7cca0da4, 0xec4b5d5c, -0x3210c169, 0xda27c02b, 0xd80c5c8c, 0x38518cea, -0x5daa2473, 0xf15b6134, 0x733e7412, 0xd6a5ae78, -0x3b0d4f4d, 0xc6304bb2, 0x7f6df8e6, 0xf6b0e912, -0x2da01433, 0x2cf7b1ce, 0x32e046e7, 0xcd50021d, -0xe39d167d, 0xef608f10, 0x5d96e85e, 0x38a113a7, -0x3ce761fa, 0x26a0250e, 0xa27c2468, 0xfd563262, -0x9f6f6866, 0xda194d33, 0xa5458a6c, 0x32aa53c8, -0x2517e3bb, 0xe5070380, 0x72d71801, 0xdee77333, -0x63f71503, 0xe4cc9d5a, 0x1f684f79, 0xebab1828, -0xcfdcbec2, 0x1913c83c, 0x72abfe52, 0xfcadec5a, -0x9a32da3e, 0xf730dc13, 0x529ec685, 0x1d558dfa, -0x3fb232f2, 0x041148b4, 0xd10bb0b7, 0xeb6821e2, -0x070d709f, 0xf92b67a4, 0x6d6af041, 0x1724d766, -0xf21a821d, 0xea6e49d8, 0x9d30cef2, 0xe0c055b1, -0x67901316, 0xb37f63f9, 0x5984e1b1, 0xf83466f0, -0x1404ac22, 0x4345d90c, 0xa14ef8b7, 0xa812e742, -0x62593a25, 0xf08c3643, 0x3b376203, 0x5ddf0e1a, -0x429c87d0, 0x31c7a9f9, 0x18f25314, 0xf55e9515, -0xd26dde06, 0xd07605c7, 0x51877d68, 0x31054918, -0x668e3ae2, 0xe273138d, 0xef9b9beb, 0xcf19359e, -0x7ccb675b, 0xca018219, 0x1a614824, 0xa1ac60f6, -0x512484e2, 0x249d2429, 0xa4e02fce, 0x85c52616, -0xfc3e1b33, 0x11885bef, 0xf1729589, 0x78342f7a, -0x3a115d84, 0x74698c2a, 0x59b804d6, 0x96598928, -0xeafb3b9f, 0x788556ba, 0xf956a1c4, 0x5ae7d9b0, -0xe86bc7d9, 0x7483aa3f, 0xa2126202, 0x5852027c, -0xbb2db21b, 0xdf7dcaec, 0x3eaa745c, 0x49390086, -0x60575f57, 0xba173f97, 0x90bd11ab, 0x0db322ea, -0x2a57df73, 0x89157540, 0x57bdf2fb, 0x32b0919b, -0x135b0600, 0xaaeb1076, 0x2a7b30ed, 0x73f755fe, -0x81650eb2, 0x4640b0f0, 0x6f89926c, 0x4bd8b89b, -0xb8233621, 0x24a33dcf, 0x1a6bbb6b, 0xeb01530f, -0xf481b825, 0xcdc1c14e, 0xbb207fb0, 0xd83e142b, -0x95b20b94, 0xe50ac19f, 0x6d3e3ef6, 0x266e4143, -0x27a006aa, 0x2ec25d26, 0x85235a01, 0xd049df42, -0x1ce6650f, 0x3a1657ed, 0xe5f9ecbf, 0x6d18d58f, -0x0da6ed67, 0x3d9f6f19, 0xeb186779, 0x0bd00e5f, -0x21fe220d, 0x742ccb0a, 0x622e21ef, 0x96cedf92, -0x11240fea, 0xf6b746d7, 0xff91e400, 0xecaeab21, -0x072c35cd, 0x9ac8fc0d, 0xa263d5a6, 0x3fd105f9, -0xb81600fd, 0x0a292f3f, 0x89b9c1ce, 0xd16a28e5, -0xfc7f3fdf, 0x2450c2d6, 0x494e87c4, 0x1d9b4dd9, -0x1b40fac1, 0xcee2e920, 0x7cee58ef, 0x361ab9f6, -0x1bac7d85, 0x0bd85367, 0x2df2f60b, 0x07bbc733, -0xd8b22847, 0x2e54d3f4, 0x76b49bfc, 0x336f0ea5, -0xd93b81d1, 0x1eceed7b, 0x563bb551, 0x80a5f398, -0xd9ff04c6, 0x30a4f554, 0x56c69654, 0x725b2af5, -0x9c07b877, 0x9da21f3a, 0x730581ce, 0xf2dfc2ed, -0x45d0c7b2, 0x748ef602, 0x7d186c9b, 0x633aaa77, -/* 410-MU16522d.inc */ -0x00000001, 0x0000002d, 0x05181999, 0x00000652, -0x35182bc2, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x34dc2e66, 0xd27f9e0b, 0x6b5b66e1, 0xe349c526, -0x75b53339, 0xceaf0faf, 0x43377bf8, 0xd3de4b79, -0xabdcd0ae, 0xe6ece6b2, 0x323c792b, 0x4656028b, -0xabf8fde6, 0x46f5d8e4, 0x396ca1cb, 0x7b420d12, -0x13aa276e, 0x9c6c36ce, 0x22b1e7c9, 0x38c0ef9f, -0x5a5b5d7b, 0x3ac00239, 0x6de2d01a, 0x0c3b8968, -0xbf1bb741, 0x21888846, 0xd9d2dfee, 0x51a50463, -0x6529e703, 0x1891c9bc, 0x68d19cb6, 0xc8ca396e, -0x3fd56452, 0x3daf09c0, 0x3e9f5c65, 0xb00b2dd6, -0x34c06009, 0x116b7fc7, 0x10f4a379, 0x56448896, -0xeb1af49a, 0xfa469de5, 0xe6219c14, 0xa616ab2c, -0x554a1561, 0x2962420a, 0x1dffc2fc, 0xb824c7ec, -0x3ba550e2, 0xe784e9e7, 0xf1a0d150, 0xc96568db, -0x1e68af03, 0xc34d1f7e, 0xb3eb5222, 0x0d86e6c6, -0x3edc0e81, 0xbfc6c906, 0xbccbb4e5, 0x66780923, -0x961736f4, 0x02cc763c, 0x3938655e, 0xd6ce2840, -0xb26b29fd, 0x128a069d, 0x4d3c06ff, 0x0ba25f3f, -0x681a85bc, 0x6de8b8e0, 0xb680e272, 0x34aa348e, -0xb4f3607f, 0x12c2f64d, 0x9b95d9fb, 0x3e534391, -0xde916e89, 0x81c5a6e9, 0x7a377fcf, 0xb1d53d3d, -0x8eaacd29, 0xf70d507c, 0x1ca89cb5, 0xab250aeb, -0x4e2cee69, 0xe0d62342, 0x37ffa79d, 0xdec3a3e0, -0xd5e107bd, 0x44a12304, 0x12f56061, 0xe75f935a, -0xe697e2bc, 0x72e0cfef, 0x40f37d47, 0x151df42b, -0xe722c56f, 0x335c122b, 0xd21d1ef4, 0x40210853, -0xbb95dcc3, 0x9398175f, 0x961ee4e8, 0xb0d00aba, -0x95411710, 0xdc208d4a, 0xddd31d07, 0x32823f2b, -0x82ba3b93, 0xabc82d3f, 0xc2161f81, 0xa777fe7e, -0x22f487b3, 0xb2cd9662, 0x222527cf, 0x431adf1c, -0x11b4e831, 0x2888bd62, 0xf993b098, 0xbaa51f92, -0x62ca791f, 0x8fc20296, 0xbef56808, 0x8eba8023, -0x33d74e7b, 0xa65b5e21, 0xd6bee1ff, 0x73283195, -0x06fcd98c, 0x768f8241, 0x0a8d5b5a, 0xfb6d8e00, -0x2eb1e108, 0x10a0a67d, 0x761727ba, 0xfc144648, -0xa609154d, 0x8582bc2c, 0x6ba59d8b, 0xbbf80e58, -0x4859c3d7, 0xabb7d38d, 0x52665ca0, 0x1fe477e5, -0x65fdeeef, 0xc624a036, 0xb79e0897, 0x32233ccf, -0xe2b91643, 0x1aec523a, 0xad9de722, 0xc00e4919, -0xa7da623f, 0xf21094ed, 0x3aee295b, 0xdd1aa696, -0xfdd5f1d0, 0xc07016be, 0xb2f18c64, 0x6b277832, -0x74fcb662, 0x9010ae3f, 0xb1baa7e9, 0x40ba08b9, -0x918c135a, 0x2958ecbb, 0x15ff3626, 0x1cc98354, -0x3abd188a, 0x30ae97e0, 0x2a33013e, 0x8ffb66d3, -0xd81b9918, 0x7bbfe734, 0xadd0be6c, 0x15386784, -0x051f3d28, 0x7bbe4c68, 0x78b2d92b, 0x280efe91, -0x5757b1eb, 0xc26d03c9, 0xbbdd374f, 0x2ae02697, -0x68329100, 0xfd8aae6d, 0x60a3dceb, 0xc7d6af76, -0x894dc15f, 0x11aabd09, 0x18605a69, 0x52a14016, -0x56f5a041, 0xd2c6e6c7, 0xe6886a23, 0x14f91266, -0xcbed2885, 0xd3d45dd7, 0x9878d751, 0x822a5baa, -0xd8533c7b, 0xbd4338de, 0x618a9ffa, 0x4bf77e5e, -0x65c6ab82, 0x2f69c2a7, 0x02bee5fd, 0xc0a8d2f6, -0xc6b02d78, 0xdfc567da, 0x658c28fc, 0xcefee2b9, -0x074f0615, 0xfa442352, 0xaf613696, 0x9c9e7f32, -0x033d5c94, 0x9cf17096, 0x50ecb9ec, 0x2016a0a2, -0xbc553203, 0x886642f5, 0x6aff9fe4, 0xaddb42a9, -0x954af4d8, 0x92041ec5, 0x9eaf96bd, 0x83986d41, -0xadab6db6, 0xedab0945, 0xfe62e5ec, 0xba043d1f, -0xb1789301, 0xeb41a778, 0x319d17a4, 0x1f98a30d, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1100-m04f2737.inc */ -0x00000001, 0x00000037, 0x06042003, 0x00000f27, -0x972cd5fa, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x0000005e, 0x96f952a6, 0xaa368f02, -0x53d271e6, 0xf8286513, 0x484b4e9a, 0x9e0c09c2, -0x03b11314, 0xdfb67c98, 0xa2957d16, 0xf07f25de, -0xb84a2555, 0x72ec8b35, 0x3445c734, 0x7744f543, -0xc3da0cc0, 0xeb36172d, 0x8b2cf574, 0x29c867a2, -0xe79dfaf0, 0x54714bb5, 0x524dfb69, 0x0df65433, -0x0b95ec14, 0x3dc09ca2, 0x584ba068, 0x2aa558ce, -0x8cd679c8, 0x3b2609d0, 0xa06306d1, 0x80bfa93a, -0x482678d8, 0x0cdf1ce6, 0x5ec4e912, 0x8a19f7a6, -0x76f215be, 0x577d92c2, 0x479cd4ba, 0x63d1f415, -0x5af98bc5, 0x8889bb4f, 0x8e70943d, 0xb5528299, -0xfd63e347, 0x836fcfd0, 0x4951a701, 0xf4613cdb, -0xaa7c2f52, 0xa0e290c7, 0xf646a80b, 0xda5b5a03, -0x93517b47, 0x553d99d1, 0xafac198e, 0x486b6c6b, -0x4efa01d8, 0xdc6ce226, 0xdac3a149, 0x9b7cf27f, -0x6c6246a0, 0xb6055a39, 0xb68cc841, 0x87b6adee, -0x1c36edb4, 0x3ee76d20, 0xdbffab67, 0xed12fda6, -0xc1aff2f2, 0xc110932f, 0x0933ccfe, 0x58fa2281, -0x285d5ec1, 0xd05b216a, 0x76315645, 0x570c5c8f, -0x6cc52f1c, 0xaa977e52, 0x066f4e03, 0x812bfd2c, -0xbfbfd7a9, 0x70828199, 0x60182af7, 0x2a04e000, -0x30f413b7, 0x327cef32, 0xac73aa51, 0x7c418d9f, -0xf493ce0e, 0x6c14258d, 0xa5e2755e, 0xd39f994a, -0xee638b08, 0x55d50476, 0x9b7afc5c, 0x5da2ed13, -0xb75bf9f4, 0x2606c01d, 0x8a1d00eb, 0x0f73428f, -0xb29c4fb4, 0xac13e554, 0xa7648fe0, 0xbe56837b, -0xd34fa9ff, 0x59c855a2, 0x7d3cc7d7, 0xb5b0cb50, -0xe6626c0b, 0xf07010b7, 0xd8054587, 0x01a5327a, -0x3ceae28b, 0xa3bf737f, 0x3d1a37e7, 0x6ce48d1d, -0xc9d91222, 0x42f28fae, 0xe8dff3e4, 0xfd6898d0, -0xe772ab47, 0xbe452c12, 0xf188ee09, 0x08edb79c, -0xad4d48fb, 0x5cb75d1d, 0x251f4e02, 0x6b7bb6e3, -0xcada2f09, 0x536d74eb, 0xacfa627a, 0x51e2ffd2, -0xe4655767, 0x311dbbec, 0x1011b68a, 0x6f6e8deb, -0x4298665d, 0xc0522b3c, 0x2c3a19dc, 0x2c48f2ae, -0x49bca621, 0xb6a747fe, 0xa1606c81, 0x9b2a5318, -0x0ac114c3, 0xb5b35aa0, 0x3f4ee00d, 0x8b427e75, -0xb539fcd3, 0xa99fba84, 0x821fc647, 0xe0ac6d6e, -0x912f6f88, 0xf2009cd8, 0xb32330b3, 0xd0b80514, -0x6f25f157, 0xdba2f463, 0x88ef17d1, 0x147c5f21, -0x6e29cd75, 0xec14e5d1, 0xdcfffd24, 0xccc2c510, -0xe5e40798, 0xb24814e1, 0xaf0cdaf2, 0x825cf5e2, -0x12acac6b, 0x439c5f36, 0x0c533619, 0x8e776e71, -0x319b44f5, 0x19c0b404, 0x54111b2a, 0x6a767513, -0xb16944ef, 0x30ef18ce, 0x85df0862, 0x0737ff49, -0x77fe06f2, 0xb2de0d2f, 0x71625e95, 0xc722c5a2, -0x03b401a9, 0xe8b030b4, 0x7f9e62ab, 0xbff8c966, -0x726bfeca, 0x6adf3831, 0xab85067e, 0x5167e87a, -0xb06ad00c, 0xdd974309, 0x5704880d, 0xb7279a43, -0x38aeda19, 0x52f5a31f, 0xd66d79e2, 0x83dad3db, -0xa138d066, 0x0b4674d4, 0x07e7dd7a, 0x7f5c70c7, -0x4aade5f0, 0x4fcd220f, 0x2ae8ab6f, 0x6fb11f68, -0xbf134ecc, 0x71d3125c, 0x3cc3f6ba, 0x92809507, -0xb4a9b236, 0x97a2ef5f, 0xe20e5f23, 0x5610bfa9, -0xad16eba9, 0x5207dfba, 0x0caa3d20, 0xc57cccba, -0x7983d15d, 0x09ced949, 0xec698959, 0x53a4b153, -0x63c74107, 0xacf58270, 0xbc2982cd, 0x42bf9c41, -0x26aff8b4, 0x9832bd6e, 0x34e98158, 0x434f0f43, -0xcb80ccda, 0xd81471b6, 0xbd176071, 0xab13735c, -0x4e80e2c1, 0xcf7815f0, 0xb4e6ae37, 0x1a90c457, -0x79426d6f, 0xa4ac1e2c, 0xf76de77b, 0x1808cd61, -0xd72ea071, 0x1f02af0e, 0x9613b531, 0xe83f2e9a, -0x99a5262a, 0x0e8a756d, 0xbc229ac4, 0x2cb1af6b, -0x8a8720d6, 0xc84d2c77, 0x8547ad96, 0xeb794e72, -0xb51119ea, 0x1c0121ea, 0x9f8ae83b, 0x16459999, -0x5c17deaf, 0x278a3e3b, 0xf2bbb704, 0x54df1a00, -0x521ef94e, 0xd40de734, 0xca5badee, 0xa2fe3027, -0x2ffe3ada, 0x1df00fb9, 0x5feb168c, 0x81674308, -0x99713c0e, 0x56aae017, 0xe62e68f3, 0xaa15163a, -0x31ac7b10, 0xe6a86d9c, 0xa006782e, 0x9baefc91, -0x111277d5, 0x80f63a4b, 0x624044d6, 0xd91a5de5, -0x5d0255d6, 0x92b82310, 0x08faf5e5, 0xe482ff69, -0x0a1f1757, 0xdc010e34, 0x9cd07e48, 0x677fcfa3, -0x0384138d, 0xa104220a, 0x5431c7ec, 0x0e8b7efb, -0xf1ebcd61, 0x97ae7029, 0x191ff006, 0x4308b147, -0xa11e05f7, 0x2c7cb5a4, 0x1d345971, 0x28d23638, -0xc5a7a5bb, 0x3307c971, 0x0d3782ae, 0x2b798842, -0x1fc27334, 0x4ff82ddb, 0x543ba685, 0x47732c7a, -0xad094a6e, 0xb8ff60e4, 0x43f9ee2f, 0xe9a114e8, -0xf036be6e, 0x3fb488a0, 0x280b2d46, 0xb1887c58, -0x54ae583a, 0x454b6ce6, 0xe617a2c1, 0xb9335ac3, -0x72361e12, 0xc856637a, 0x741b6cbe, 0xcf1f6f25, -0x9f405fff, 0xd2525b02, 0x22d8b05a, 0x16860f11, -0xb02983e9, 0x388b9c2c, 0x196cb2f2, 0xfca5f1a2, -0x9e60965d, 0x5bed99ff, 0x59e361fc, 0x9361bde8, -0xa1527365, 0x3f300237, 0xb0f5e2b8, 0x8fb00a40, -0x71cb9744, 0x3327e8d3, 0xe89994d4, 0x3987e389, -0x28c6d8f7, 0xb2ba9fc4, 0xdf109e0e, 0x622634b2, -0x4904a82e, 0x576c3c2f, 0xe95eae46, 0xfb773013, -0xf98b91de, 0x4edc30d5, 0xc6e60080, 0xebefab96, -0xd7684df2, 0x9cd2c3e1, 0xd433902a, 0x7b9aa9eb, -0x3c99cbaa, 0x5a0fa53d, 0x77297830, 0x869db621, -0xaee2d56a, 0x2ce907c1, 0x0aa5097c, 0x662e7862, -0xa5bfbc61, 0x2610f3bf, 0x3a741865, 0x99a5836d, -0x2e533e3b, 0x812aa485, 0x0d7eb66d, 0xb325db47, -0x6ac77937, 0xa1757eb7, 0xb7765633, 0x8845f18f, -0xde7e37f8, 0x08a17789, 0x8af720ca, 0x1f7a530f, -0xadcbb072, 0xd02e2dae, 0x16fbe58f, 0x0e4df085, -0x80663766, 0xdcff020e, 0x4c242d70, 0x3d16d122, -0x154a029b, 0x40c95a2e, 0x5f98eb6f, 0x637ffc42, -0xcdf10a5c, 0xf2211055, 0x998ddc8b, 0xcee90fd8, -0x1ddc7fad, 0x7034d80c, 0xf5bf0592, 0x479205bc, -0x0900e9c9, 0x7bef8c77, 0xc128cebf, 0x9e7dd814, -0xedca7a5e, 0xf15af942, 0x40e55228, 0x065ea7ce, -0x9603da92, 0xa6611211, 0xea9dad76, 0x4fd9d974, -0xea19cb68, 0xeabf508d, 0xd460f6c0, 0x3951733a, -0x249a4453, 0x04356966, 0xac6ec71e, 0x5253e669, -0xfca78245, 0x8ef4d888, 0x6c031fef, 0x8c49e3df, -0xc426b290, 0xfcfd6f10, 0x3a350c13, 0x79790fb9, -0xe9df4ade, 0xd06233f0, 0xe05f0f19, 0x5fb73288, -0x43d01849, 0xd9eb862b, 0xb1510767, 0xcbbe3725, -0x858ac14f, 0x01a0fd53, 0x16a566c9, 0x7d85d87c, -0x6a29b505, 0xc6134b4c, 0x5d528018, 0xfd7f8efe, -0x34268400, 0x98314e02, 0x97b0ed0a, 0xec85ca3f, -0x4dcf5ffc, 0xfb122fc1, 0x04e5a370, 0x8d3040a4, -0x5c2bcad4, 0x6feb287b, 0xe30f7860, 0x631d7a5a, -0x766b9c79, 0x971e2fda, 0x2f7000fd, 0xbd3b9a59, -0xa56dd367, 0xb3deef76, 0x8c2bbcfe, 0x756ec279, -0xbfaca177, 0xb86ab4f6, 0xb3f82039, 0x93231bfe, -0xc8409b8d, 0x16cca28f, 0x367c7562, 0x974a6ace, -0x0101281c, 0xb61716e2, 0x85ef5a4a, 0x78807b55, -0x009828be, 0xd92cee5c, 0xe8e675a9, 0x368ec88a, -0xbdb4d170, 0x9f15e2f6, 0x8b53ad97, 0xeedd0bbd, -0x38f1c5c3, 0x0bf12b39, 0x1f38b2ee, 0x1b6b39a1, -0xa5e3b7c5, 0xd30fde23, 0x6aa07a5d, 0x2426b2bd, -/* 1343-m04f252b.inc */ -0x00000001, 0x0000002b, 0x08112004, 0x00000f25, -0xe4dcce66, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x017464fa, 0xd2fb3494, 0xaf1850af, 0x5af88989, -0xd3a0a9dd, 0x8e8bd3ad, 0x8c288786, 0xf15f02b0, -0xf51c1471, 0x6c675200, 0x9c63f3e5, 0xbeb2d710, -0xbfb6d14e, 0x6ba07894, 0x4b08036d, 0x71a24d5a, -0x953125c3, 0x2cee5c1f, 0x744a15b1, 0x43a6f67c, -0x66087dce, 0x58bc5f0c, 0x09c1f187, 0x29065a8c, -0xb46dcc30, 0x597c4675, 0x2ce2fd55, 0x7329e04a, -0xe92adf75, 0x0a4f1f59, 0x6939b7e1, 0x586b6cb9, -0x9e9090f2, 0x612aeaa6, 0x908cfbac, 0x381a3a1d, -0xc0028180, 0xe7759a09, 0x9a41f6d0, 0x49004723, -0x447b0a1e, 0x84cea1bf, 0xdb6cfd61, 0xfa3fe8a1, -0x60569cec, 0x4ed55542, 0xc40d1fbb, 0x9766fe4a, -0xbffcd59e, 0xc0ec45af, 0x34da2fa6, 0x57a8f38b, -0x7cf8ab33, 0x991f0a4b, 0x83c635f3, 0xfaa6b412, -0xd6cfe7cd, 0x7eb7773c, 0xda12abb8, 0xae7f78c6, -0x0c82ad31, 0x28e15d48, 0x80a0cf1e, 0x6b8a9a75, -0x1a9aa64f, 0x4a2969ee, 0x9273d48d, 0x7179df33, -0x06fc27f8, 0x7de9a40b, 0xaaa80cac, 0x83d82561, -0xe0646103, 0xa72284fa, 0xb39b5822, 0xed08ed9d, -0x95760781, 0x2f84666f, 0xd1d45bed, 0x96a86c3a, -0xe4679e8a, 0xfa71d608, 0x86baebc4, 0xf116edb0, -0xd3a7263f, 0x237b4f06, 0x794f33e6, 0x0d783309, -0x2df3bb25, 0x02a800b8, 0x97b8ce5a, 0x2123dc61, -0xee1a5dbe, 0x185cf436, 0x84e325f6, 0x163e3ac3, -0x62288e57, 0xe5901f0f, 0xef985c3e, 0x1b9291fe, -0xb58de2b0, 0xe69eeadb, 0x42eefa7f, 0x0472359e, -0xb1fd90dc, 0x49d374d3, 0x49684482, 0x1156a2ac, -0xd0a6114a, 0x995f94a6, 0xbcf9ed4f, 0x51d161c3, -0xcc68e39f, 0x3d050ca9, 0x8cd08b93, 0x6ed69d22, -0x5fd5cc93, 0xe2783743, 0x5a1816c3, 0xda5a0ea4, -0x9b5c7903, 0xc25d6a23, 0x25cd54ee, 0xe1ab0174, -0x518ffebc, 0x28125044, 0x7ff130d8, 0xfbea3a8d, -0xe093582b, 0xf60baa3d, 0xe4674a15, 0x18a6322c, -0x21cfa3bf, 0x71a1a376, 0xdd4de139, 0xed578831, -0x0ab06a62, 0x9cee036d, 0x11ee0350, 0x62ee22d0, -0x83681acb, 0xef69ded4, 0x65000a40, 0x9ac7ab74, -0xd76792db, 0xf2e662f2, 0xdcae14a5, 0xfa39ba60, -0xf746cf70, 0x0bea4f1b, 0x9b384717, 0xf8dafd90, -0xb2ffc2ab, 0xf3fa97e4, 0x5f22e0c3, 0x04536e9d, -0x22c99598, 0x34631815, 0x9fc99bfa, 0xfe067ae7, -0x03fbd87a, 0xdc73bcd2, 0xc49a0fbc, 0x3138c419, -0x62643c63, 0xfa2597c7, 0x4c84afef, 0xdba2817e, -0xe818ed14, 0x74a5ad6b, 0x9cf3ced5, 0xf633dd12, -0x4ba39a46, 0x8b37b668, 0x65637f55, 0x67c7ce04, -0xe860a2e3, 0xf264ba03, 0x47b91726, 0x887f4d41, -0xb10685e0, 0x95958791, 0xcb835bbc, 0xf1af6594, -0x42fb5a5b, 0x78ff5368, 0xb201a575, 0x8a6b189c, -0xc3f6e3a0, 0xe2bb320e, 0xd75004dc, 0x735b0c3b, -0x70ccd09f, 0x4d157775, 0xc0663e58, 0xf2170355, -0x4d86c74b, 0xace253a3, 0x09fedbf3, 0x5288ffb6, -0xc577a648, 0xf808ffc9, 0x6f1b81ee, 0xa56d4123, -0x60626a1b, 0xc88b4d17, 0x280e44c5, 0xf56c8ddd, -0x9110c257, 0x2d65519d, 0xc96c1ad5, 0xcfdea3e5, -0xa69ea62f, 0xf3ed57ab, 0xbe725f8c, 0x2e3c86df, -0x23635626, 0x7d2607f6, 0x67fe2874, 0xe64ade4d, -0x5fe967da, 0x88cb5547, 0x468c3eb5, 0x73313404, -0x36b6cc3f, 0xf352d0fc, 0xcbd702bd, 0x969a1606, -0xead2f56d, 0xf4c93dd8, 0xd2395873, 0xe5304e3c, -0xdbe3e804, 0x1daf81c0, 0xfd6cbdac, 0xfbb07447, -0x1970d752, 0xff97a936, 0x1cf114a2, 0x03b678d5, -0x6edaacf8, 0xd4a869c9, 0x6db6f5fa, 0xe48335d1, -0x6c59f701, 0x2cd977a6, 0x02079375, 0xc573f27b, -0xd26f8f28, 0xe637b462, 0xb9ef5a9d, 0x2483a550, -0x8e020039, 0x01d2e9d0, 0x8e69c688, 0xfbf941b7, -0x86dcab40, 0xe99730b6, 0x0e57bd5d, 0x11ace616, -0x3a5c73dd, 0xe29052c6, 0x6728d6e3, 0xf5a73743, -0x6ef89691, 0xffa40f45, 0xd1a1b739, 0xf12697be, -0xfc849142, 0x1a6daa37, 0xc52c54a3, 0xe600bbb2, -0x6c90e1e9, 0xf9ba4ed6, 0x118b0436, 0x0d864deb, -0xa574b526, 0x6f2da0ae, 0x7297e467, 0xe33a4e82, -0x6e8a340f, 0x9524f758, 0xb7d9d387, 0x67ed6069, -0x3fcef9be, 0xf3684381, 0xb8012434, 0x86d3a9a9, -0xdb45b646, 0x8de08c40, 0x37a91d86, 0xfd107ef4, -0x0b1db4d3, 0x73988186, 0x74b646a5, 0x92e5a61f, -0x72239610, 0xf9b6564d, 0xce99179a, 0x61ebb35c, -0xfb2495bd, 0x36ab39d8, 0x7cca0da4, 0xec4b5d5c, -0x3210c169, 0xda27c02b, 0xd80c5c8c, 0x38518cea, -0x5daa2473, 0xf15b6134, 0x733e7412, 0xd6a5ae78, -0x3b0d4f4d, 0xc6304bb2, 0x7f6df8e6, 0xf6b0e912, -0x2da01433, 0x2cf7b1ce, 0x32e046e7, 0xcd50021d, -0xe39d167d, 0xef608f10, 0x5d96e85e, 0x38a113a7, -0x3ce761fa, 0x26a0250e, 0xa27c2468, 0xfd563262, -0x9f6f6866, 0xda194d33, 0xa5458a6c, 0x32aa53c8, -0x2517e3bb, 0xe5070380, 0x72d71801, 0xdee77333, -0x63f71503, 0xe4cc9d5a, 0x1f684f79, 0xebab1828, -0xcfdcbec2, 0x1913c83c, 0x72abfe52, 0xfcadec5a, -0x9a32da3e, 0xf730dc13, 0x529ec685, 0x1d558dfa, -0x3fb232f2, 0x041148b4, 0xd10bb0b7, 0xeb6821e2, -0x070d709f, 0xf92b67a4, 0x6d6af041, 0x1724d766, -0xf21a821d, 0xea6e49d8, 0x9d30cef2, 0xe0c055b1, -0x67901316, 0xb37f63f9, 0x5984e1b1, 0xf83466f0, -0x1404ac22, 0x4345d90c, 0xa14ef8b7, 0xa812e742, -0x62593a25, 0xf08c3643, 0x3b376203, 0x5ddf0e1a, -0x429c87d0, 0x31c7a9f9, 0x18f25314, 0xf55e9515, -0xd26dde06, 0xd07605c7, 0x51877d68, 0x31054918, -0x668e3ae2, 0xe273138d, 0xef9b9beb, 0xcf19359e, -0x7ccb675b, 0xca018219, 0x1a614824, 0xa1ac60f6, -0x512484e2, 0x249d2429, 0xa4e02fce, 0x85c52616, -0xfc3e1b33, 0x11885bef, 0xf1729589, 0x78342f7a, -0x3a115d84, 0x74698c2a, 0x59b804d6, 0x96598928, -0xeafb3b9f, 0x788556ba, 0xf956a1c4, 0x5ae7d9b0, -0xe86bc7d9, 0x7483aa3f, 0xa2126202, 0x5852027c, -0xbb2db21b, 0xdf7dcaec, 0x3eaa745c, 0x49390086, -0x60575f57, 0xba173f97, 0x90bd11ab, 0x0db322ea, -0x2a57df73, 0x89157540, 0x57bdf2fb, 0x32b0919b, -0x135b0600, 0xaaeb1076, 0x2a7b30ed, 0x73f755fe, -0x81650eb2, 0x4640b0f0, 0x6f89926c, 0x4bd8b89b, -0xb8233621, 0x24a33dcf, 0x1a6bbb69, 0xeb01530f, -0x24467581, 0xc5175ba1, 0xbb207fb0, 0xd83e142b, -0x2572acac, 0xf7488d93, 0xddfe99cc, 0x342c0d4f, -0xb209b00f, 0x33ebdadd, 0x35e3fd3b, 0xc26470f4, -0x643a91c0, 0x2386187a, 0xb7048f3d, 0x4bccd894, -0xda15e11f, 0x3b8e9fc3, 0x3f1b93fd, 0x70b9260a, -0x46ef3c91, 0x4d1f9631, 0xe777bd31, 0x8728acdd, -0xcd8012a2, 0x8da6d62f, 0xcaedab69, 0x52c56c21, -0x93472485, 0x87f85990, 0x9587f5f0, 0x0b23b2a1, -0xcd23beab, 0xad81ef05, 0xe7db963d, 0xc6687827, -0xa7847334, 0x12a35621, 0x57c2f21b, 0xdd2bbaf9, -0x59650ce7, 0xd7665e53, 0xedc98b5b, 0x094ae33c, -0x4724f7cc, 0xd8be3c08, 0xd803dbbe, 0x19cbd745, -0x74adc92a, 0x088c82b2, 0x9a6b9ed5, 0x49da3d33, -0x0f75b8e6, 0x021dacc8, 0xdd100353, 0xf5a7226b, -0x6141e3ca, 0x443b676d, 0xb113e9f7, 0x1141f839, -0xa6e4e487, 0xf7a239c2, 0xad0e3019, 0xa33ef735, -0xe9c6134d, 0x12cb0f2b, 0xd2266ee2, 0xa5bf6017, -/* 1854-m86d821.inc */ -0x00000001, 0x00000021, 0x08312006, 0x000006d8, -0xdd4078dd, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x15207f25, 0xaf011e9e, 0xa4f35d2a, 0x5a04d345, -0x0af80416, 0xadf21e32, 0x01008f51, 0x73cfa51b, -0xb09589a5, 0x273ba8a8, 0x5c009724, 0xcc4afd63, -0xe0ec5e49, 0x00a8582d, 0xbd2c9d2e, 0xf722d22f, -0x18d202eb, 0x47ba1bf9, 0xb61d77fa, 0xe5590322, -0x1da550ba, 0xf5009bc7, 0xa74a4b35, 0xeac73686, -0x32d3dd02, 0x1624f898, 0x2ef65a27, 0x1b684b05, -0x74a9a3c1, 0xa999fffb, 0x87704471, 0x8ae62181, -0x0ac0d5c7, 0xffbbeb02, 0xf779f34a, 0x12db3290, -0x4c2eb3bf, 0x015aa152, 0x957aaea1, 0x9864e5e3, -0x33cf93ca, 0xa560730e, 0x25718d0c, 0x94688c1b, -0xf8facf6e, 0x10f705fd, 0x660f4b52, 0xe9927132, -0x7e96650f, 0xb757e269, 0x703d0752, 0x99ce1839, -0x12699204, 0x7a8ffe0c, 0x46ef8ee4, 0xf84924a2, -0x2817013c, 0x3fadf9cf, 0x785abb54, 0x773b4980, -0xb4a5170f, 0x371e7b5d, 0xfa8e4489, 0xff69b2d1, -0xf1c608f9, 0x2a2521aa, 0x1a61ec14, 0x2745d532, -0xff9e36e4, 0x9a432773, 0xbaf61fcf, 0x2c708f79, -0x6455f129, 0x18caf13b, 0xa2a983dc, 0x7d3d09bb, -0xe4767b86, 0xe90830da, 0xa0123777, 0x127d78a9, -0x3eaa2bad, 0x09421617, 0xc1ea9356, 0xdb407f5b, -0x8dadb897, 0xa937c436, 0x36cdbbcf, 0xa4afeb52, -0x9f837837, 0x04a34695, 0x27d42563, 0x8a5a39c2, -0xc0ede8df, 0x2ab05586, 0xef352de0, 0x85332fbf, -0xb38244ee, 0x60325886, 0xf3715b1a, 0xa14ad158, -0x5b57ff65, 0x1e1778b7, 0x94f5c7d6, 0xe95b7b7b, -0xe80b02b2, 0x8b4ff747, 0x5ea6074a, 0x4211651d, -0xc5e0f8c7, 0xb31ee90d, 0x4c41160c, 0xe324dd3c, -0xb95086f4, 0xe8382874, 0x5e00801d, 0xbadb8380, -0x7a7652c8, 0x1b84f2ab, 0xd94eed0a, 0x415f47eb, -0x10263257, 0xf48c707c, 0x097626ec, 0x4e032046, -0x5363e2c8, 0xa4ba7126, 0x1b782652, 0x51aefb22, -0xae5a5936, 0xed79d5cd, 0xa30c0b67, 0x75430551, -0x35a09192, 0x15b67316, 0xb52be608, 0xcb795959, -0x4faca515, 0x1fdb63d3, 0x05fd5c11, 0x297a0e76, -0x7a5f4778, 0x69c433d7, 0xd4d98e94, 0x22e51cfd, -0xdb32e496, 0x10c0d08c, 0x82dc5cc1, 0x0c6d3536, -0x090521bb, 0x6bf482db, 0x41d67592, 0x7f6179d5, -0x8dbbafca, 0xa6de222e, 0x2a5505cf, 0xf8b596f0, -0x7545c4ee, 0x819f5403, 0x7c1f4135, 0x3ac59049, -0x33c7c4ab, 0x15812d35, 0x2a8582ee, 0x96a0e6b2, -0xb92c1d1e, 0x30935633, 0x2db37e90, 0x5fedcdcd, -0x789b9222, 0x18dc64d4, 0x73832a66, 0x84bceeac, -0x3c6653d8, 0x13869ead, 0xee3dffde, 0xb5409354, -0x454320c1, 0x88fce3e6, 0x386a25da, 0xdd090730, -0xa3e3c00e, 0x6d57dbe7, 0xeffe51bc, 0x0e80367b, -0x0df8cf1b, 0x130cf967, 0x3f39302b, 0x29b6687c, -0xa626dfc0, 0xbedd0548, 0x09def856, 0xb314f4e0, -0x0a84facf, 0x9bf757c1, 0x02e24a97, 0x65e14f1c, -0x8f7e6f18, 0x031a816f, 0x4e1b22b1, 0x8e783cc3, -0x07869387, 0x9727c5b0, 0xfcc836fe, 0x487259e5, -0x3aeb7492, 0xbd8feb56, 0x42e69035, 0xe127af9c, -0x9b7ca032, 0xdaadcc97, 0x815fddf1, 0x62a44c71, -0x601b50ef, 0x9e563c36, 0x2fe47b15, 0x8707cb00, -0x6876ed29, 0x061c4c3b, 0x2529167b, 0xd37f9c49, -0xb9b9c817, 0xcb825760, 0xcff75137, 0x575d41b9, -0x8c7f003c, 0x333201b7, 0x0e741508, 0xc32fbf54, -0xd87d5e5e, 0xbab462ff, 0x07a7d41e, 0xa317d6f4, -0xf5deccf7, 0x5e84f011, 0xdd81f04d, 0x7077fdbb, -0xd71618ac, 0xc87934bd, 0xe96101d1, 0x55d1976c, -0x471c8505, 0x7a36d839, 0x5d62a9ee, 0xf3c54a8a, -0xa2be15d9, 0x244087c9, 0x042c8037, 0x23224689, -0x281c5d73, 0x2139ecfc, 0xffb8bc8a, 0x834fdd11, -0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, 0x4ae2dbda, -0x86d90089, 0x6675dfce, 0x48876262, 0xcec72538, -0x11dc5c80, 0x86a730f9, 0x313565c9, 0xe3e5be11, -0x106d7cce, 0x752b8be2, 0x3d00a5bc, 0xe6f70e95, -0x44447ac8, 0x600df30c, 0x8335ac3b, 0x8816ddee, -0x700982fe, 0xee495741, 0x48c7e81c, 0xa3d55da2, -0xb0172982, 0x70ab2158, 0xd4460621, 0x3a9e528b, -0x59b18a7b, 0xf4dabc4c, 0xa8454763, 0x70877bb6, -0x66005c97, 0xaf292c06, 0x7b843db1, 0xf343b59b, -0x25cdc7b5, 0xa41da617, 0x9e9d895e, 0xc936f475, -0x7270925a, 0x30024230, 0x8e72f53d, 0x2b6c1b6f, -0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, 0xaf377cc1, -0xbff09a78, 0x4b4e0814, 0x95a0b2c1, 0x270398de, -0x201fca94, 0x2a032a4f, 0x131542b4, 0x0d7306da, -0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, 0xa3b3a991, -0x17ee60c2, 0x852c0b8d, 0x11e5853a, 0x762002a7, -0x92c5311d, 0x0d4bf7e1, 0xfffec870, 0xe3d35e5b, -0xff6ecfb9, 0xdedae6ff, 0x0111a772, 0x9808e780, -0x29c336e8, 0xe9bc05df, 0x5bedde11, 0x945565af, -0xaff808fe, 0x87e3423d, 0x4de6f98f, 0x93b4adef, -0xbf704fa4, 0x09120e91, 0xd54f3692, 0xdf8eab1e, -0xfabbf59c, 0xe74318be, 0xaab87ffc, 0x29fa791c, -0xe3915552, 0xa652cb9b, 0xa1252e74, 0xb35b723b, -0x542aa28b, 0x12fcc5b0, 0x3941f962, 0x82bcc6cc, -0x47b11974, 0xb821611f, 0x78b34250, 0xf1be5659, -0x561b9e61, 0x6f3bd501, 0x584e6f5c, 0xd54ed547, -0xacebcd21, 0x7b5ff816, 0xb64ad233, 0x9f2f330d, -0x69fb1ece, 0xac8710dd, 0x58dc6c60, 0x9bee6139, -0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, 0xa733274f, -0x884d9b55, 0x42b08b63, 0xafa54a74, 0x1c7ccf64, -0x93a20191, 0xaaa3132e, 0xc69831d1, 0x54634889, -0xfbfe3efc, 0xd3cf68d4, 0x302e3117, 0xf5693131, -0xc3ce8c6c, 0x1f03cd89, 0x6243334c, 0xf16bc80f, -0xdca5f130, 0xcb2cd956, 0x4c1bb421, 0xe8de533c, -0x7f86703a, 0x29aa897e, 0xdd54acad, 0x76b2f2ae, -0x7ef82b71, 0x2e30970b, 0xba402597, 0x9a653ab4, -0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, 0x2363d147, -0x5327289a, 0xe89229f3, 0xd63a535c, 0x7efe9273, -0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, 0x1b9c7bfe, -0x5d14b3de, 0x54d575fb, 0x6d65db4c, 0x95648b7f, -0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, 0x8488a45f, -0x8ebc2932, 0xd4767316, 0x3e8c4b8a, 0xbab7402c, -0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, 0xc88528e9, -0x4b2e4e8f, 0xdd938b86, 0x0c964f98, 0xfc88d480, -0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, 0x4d40b3b3, -0xcf203155, 0x0d2fa621, 0x752d2c58, 0xb12bac12, -0x1e7e8c23, 0x94215d54, 0x9854a71c, 0x4de63c64, -0x7a012529, 0x9c171f8d, 0x9e71def7, 0x3bd17d50, -0x11f175d9, 0xec78abf3, 0x7b529eee, 0xd3a69fc3, -0x5b718676, 0x58214d29, 0xa8bd2c34, 0x41ea00ab, -0xa03f64d6, 0x4ee342b0, 0x32b1e444, 0x1c1801a4, -0xc8424702, 0x334a7e35, 0x50cf1543, 0x3b22b495, -0x88683776, 0x8e2e0154, 0x6155c033, 0x4e2fa6ac, -0x42ace700, 0x8d64f97c, 0xaf9ced17, 0xb2a5cb92, -0xa558582d, 0x88705de7, 0x9e528d59, 0x84bd45e4, -0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, 0x10462123, -0x30080f7d, 0xb346cd81, 0x0049c396, 0x4e24165f, -0xa7c66809, 0x2e60bdcf, 0xaad70a08, 0xa73ea713, -0xe28f97a7, 0x283a9eab, 0xd4366489, 0xe776f963, -0x64ffa8ae, 0xde717b50, 0xbd2ca2b5, 0x3bae5f6d, -0x8d2bbef1, 0x7e9181e6, 0xf06aa121, 0xd06b2d20, -0xa83ea826, 0xef935e4f, 0xdfd27456, 0xa3451468, -/* 588-mu26a101.inc */ -0x00000001, 0x00000001, 0x03062000, 0x000006a1, -0xdac0a4cd, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x1a925620, 0x4b81f389, 0x1f55b086, 0x3a3c0b72, -0x97aa26c2, 0x79093d54, 0x0e67ec11, 0x5c37053d, -0x64e4158f, 0x404d78a9, 0xba6219f9, 0x2e08686b, -0xe5a3d552, 0x09577ec7, 0xaaaa3c45, 0x060fc36e, -0x278c17c5, 0xe0d35e8f, 0x38bb2b7e, 0x44df5aa7, -0xff8034bf, 0xdaf298f0, 0xf404d040, 0x8db62d81, -0xbf0b5755, 0x37273dfd, 0xf067eddc, 0x85556d3c, -0xe028c3fb, 0x361c0e61, 0xe1c91916, 0xf666a76e, -0xad25dcd1, 0x6896a9b5, 0xe62a7960, 0xecdeec60, -0xb4614eec, 0x4ef1446d, 0x8c1b5dea, 0x26dce335, -0xb51a21dc, 0x158dfc3b, 0xac9098dc, 0x6329e4ed, -0xee0fbfc4, 0x42e4ee1f, 0xd42c51be, 0xfbeffdd0, -0x8eb807f7, 0x02940987, 0xb55bf142, 0x51295e5e, -0x0c4bb416, 0x288405da, 0x4044a714, 0x25487c10, -0xc5d42317, 0xa19a5e54, 0x6f591e6a, 0x658d900e, -0xd3e31ed4, 0x9a1e7945, 0x1e822af9, 0xcfa745be, -0xdb4a0bb8, 0x70c034a3, 0x97d53091, 0x0bcb1625, -0xb9757831, 0x607a4345, 0xa8dbefe4, 0xc57d0b71, -0x65068d6b, 0xce8b60c0, 0x13b8d077, 0xc8cdd270, -0x5cfd60f1, 0xba1de286, 0x25fec114, 0x138531a1, -0x98ead827, 0x342e0dc5, 0x184f447d, 0xc39c38c1, -0xdef43d07, 0x3f112321, 0xe56bcd08, 0x21a8954e, -0x9284b430, 0x3f6080b4, 0x26ff7c9f, 0xb87d987d, -0x6c880fc0, 0xfbc48334, 0x896daf3d, 0x2869dce3, -0xb049cd04, 0xacd94d1a, 0x3cd9c76d, 0xd625bf61, -0x3fd33f6c, 0xedc9dfbd, 0x4587d43b, 0x14f024f2, -0x4bb68abf, 0x0be6e522, 0x817cbf56, 0xcd807794, -0x2a3776bc, 0x2d4cc675, 0xa93197cd, 0xd159ea13, -0x4a2f31f8, 0xf9c8483e, 0x5dd3484c, 0xa5e6aa91, -0x56b30ab4, 0x54d8ad98, 0x122cf2a9, 0x0ea32a2c, -0x8c106052, 0xa75018ee, 0xf1ef861c, 0x8eef2c7a, -0x54a3ac2f, 0x236634de, 0xc0b93a7b, 0x624c67ba, -0x7ca4151f, 0x63f5d46a, 0xbf3fc81c, 0x4de97caa, -0x96b26301, 0x53d3d263, 0x9a56b4eb, 0xe9227bd7, -0x6349dca1, 0x1463a57a, 0xe94a8a76, 0x2c1b2f29, -0x408fd765, 0x79c92226, 0x2cdae01e, 0xc0711ae9, -0x6dcad071, 0xc4c848b7, 0x0ad4dc9a, 0xecae9f21, -0xbadc192b, 0x453060e4, 0x05f774cd, 0xc659c877, -0x304c4fa4, 0x7eda6154, 0x7b34f620, 0x14cb0180, -0x95dd0a99, 0x7faf3248, 0x7405b38e, 0x9b83e3dc, -0xc6c13c20, 0x75640563, 0xd138fa21, 0xed2aa41b, -0xdd655165, 0x3604d602, 0x459c69c4, 0x21582dd4, -0xa2609dbf, 0xfe8d29d9, 0x945c3b01, 0x4f77f55d, -0x24ec2ec4, 0x9b88285e, 0x6758ebfe, 0x773bd171, -0xd6c6d39f, 0xdcbbf9e5, 0xa80ba71e, 0x095e3dbb, -0xcd99eb28, 0x4901a58f, 0x34df1c21, 0x8e586420, -0x1cbfdf50, 0x95085823, 0xa2ae7016, 0xaaaef150, -0x14c815f5, 0x8f7c9723, 0x1fd00fa3, 0x0390f0fe, -0xf6e3fcf4, 0x8250779c, 0x421efd91, 0x2f6bf608, -0xea9704ad, 0x448f975c, 0xd68cc3d1, 0xead4e5e7, -0xc52eb1b1, 0x83cb45a7, 0xebc29c1a, 0xcdfc2b79, -0xa6d9ea12, 0x429a8bd2, 0xaf53233b, 0x9b729f98, -0x91e763fa, 0x839af791, 0x31a8072d, 0x78235953, -0x36931de4, 0xdebe9744, 0x3b4d0ee1, 0xd3e19156, -0x860b50a3, 0x5a9e107d, 0x7172d726, 0x6bcb1274, -0xf239330c, 0x474f913e, 0x466f82cc, 0x97f831d3, -0xc0cbc28c, 0x1a95f8b6, 0xc4799e3e, 0x3d90176d, -0x6d8510a9, 0x248ffa74, 0xb08a8d46, 0x892fdea7, -0x0ffadac7, 0x763e7d4d, 0xe350936d, 0x6dc3fd4c, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1462-mbdf4903.inc */ -0x00000001, 0x00000003, 0x04212005, 0x00000f49, -0xf85d53b8, 0x00000001, 0x000000bd, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x1d97a5ab, 0xd8d45b45, 0x89deeee4, 0xdbc956d7, -0xfb0cd01b, 0x3bca266b, 0xd5501500, 0xdc8984df, -0x40b6ac51, 0xf7df8e82, 0x8ec688d7, 0x1ef9fbbd, -0xc78d51ef, 0xae0847c6, 0xdca2d2ca, 0x37e70a9b, -0xe3787616, 0x345fcd33, 0x3cd82279, 0x1def6266, -0x5293bcd1, 0x6fcf26e7, 0xc058fbdf, 0x4047885c, -0xb576571c, 0x4b5cd986, 0x132708b1, 0x80f1c25a, -0x751ba4c7, 0x48c5d0b9, 0x02af5f0a, 0x9ffc999f, -0x30b3c7af, 0x8f53188c, 0x8ab966f6, 0x46afec6f, -0xb781e8e1, 0x93a70da2, 0x221001a6, 0x1d8ac72e, -0x7de05c53, 0x37c414dc, 0x2237c122, 0x2e9f4c87, -0x6d5e59e5, 0x0fe3fc94, 0x37b5ca40, 0x148b94ba, -0x1739ccd1, 0x6c3bc387, 0x43161ebd, 0xa6887dc4, -0xb1578c58, 0x0e1258f2, 0x45135243, 0xcdae3ef5, -0x65ff1746, 0xacf8ebdf, 0xa72112ca, 0x02b84a79, -0x9a216bc4, 0xc292e932, 0x7979f591, 0x69b77fff, -0xef165702, 0x350ea5ad, 0x22257e3b, 0x550ca838, -0x1a1fecbb, 0x18e22ded, 0xa507dde3, 0x468d7844, -0x42f62879, 0x2101eea3, 0xecf6295a, 0xf3ed3037, -0x44a57038, 0x5bb44832, 0xfb0e26ec, 0xbc5fe107, -0xb9452eee, 0xaf33a355, 0x7756a4cc, 0x77fbe8a4, -0x033777eb, 0x9ea1a874, 0x525f582b, 0x7d239934, -0x6793a677, 0x6e19db4b, 0xd1df2782, 0x54411a11, -0xf78d17d0, 0x77c196bb, 0xada667da, 0x70dd255d, -0x4f026ec3, 0x65079cc1, 0xa7c9ea02, 0xce125e00, -0x0c7705b4, 0x1b5f5c57, 0x0bfa7df4, 0x9dec2c5e, -0x5c75ff31, 0xcc3373a9, 0xc697b37d, 0x383e2d04, -0x8a3a8b22, 0x973e6c95, 0x01132ed4, 0x20bf2f8d, -0x5386383e, 0x2326168a, 0x6519809f, 0x410e4030, -0x71535fe9, 0x41b859f9, 0x699b2c62, 0x6dd05418, -0xb5b4621f, 0x36182db3, 0x7ade6401, 0xde4a5be0, -0x5c41bbc0, 0x572a6343, 0x47176e3f, 0xdeef3492, -0x02c4c789, 0xe0742989, 0x80e5e625, 0x2bb8154c, -0x197b8266, 0x95fbc970, 0x47db060c, 0xe6eaf074, -0xa971f29f, 0x2e44a86d, 0xa1537c89, 0xceb9497f, -0x7588bed6, 0xe1de63fd, 0xcc878c9e, 0x3c9f54df, -0xd96f165d, 0x87c39260, 0xa2505ebe, 0x35315b03, -0x69b55f3e, 0x4d061ea1, 0x0a0609e5, 0x1a0e9df5, -0x46f331aa, 0x2f78d5af, 0x15c9b735, 0x2824ec99, -0x8a7bd6c4, 0x315d2911, 0xaaa2a4bd, 0x9bda9226, -0xd37724a8, 0x41bdfaba, 0x4d5422ce, 0xb10d6477, -0x2b761a1e, 0xd8fba6a5, 0xa7845dd4, 0x26f97e4c, -0xb0943661, 0xc0ee2b73, 0x06fdb37f, 0x260d7bec, -0x94a14ef7, 0x7531936d, 0x9ae91b65, 0x2b6b470a, -0x68ee2bae, 0x0c08b024, 0x00ea436f, 0x0accf143, -0x2e5adb51, 0x7a155213, 0xb088dce4, 0x1b81a181, -0x52296f85, 0x4d29e16b, 0x9939f952, 0x1fdcd4ff, -0xa3d75dbb, 0x2b833084, 0x2fa52024, 0x37bdb875, -0x3f694edc, 0x65b0b599, 0xdc72cf85, 0x291ae2ba, -0x35e24c8f, 0x7741c8a9, 0xb01ca44d, 0x6199935d, -0xc0c89383, 0x5f05f874, 0x9292c348, 0x3586bfd8, -0x6345458d, 0x49263bdb, 0x647c36ae, 0xf84b11a1, -0x94827fb8, 0x5798744b, 0x858c7d49, 0xe2cba691, -0x6ccb4f80, 0x8b20c80e, 0xb63311fe, 0x4b22af2b, -0x2f267f69, 0x8f9a34d2, 0xd8969b2d, 0x3abf5472, -0xb27f4eb0, 0x0e9b5f89, 0x2c4c4d99, 0x5c1e1262, -0xdced13a1, 0x530e6b92, 0xafbee3d6, 0x65fe567e, -0xcf9c9149, 0x42e08da6, 0xe92e2843, 0x9b3f275a, -0x914a2744, 0x7ab4c765, 0x6965f671, 0x811f127c, -0x23f7ce13, 0xd4f1ac3f, 0xc2d4ee69, 0x00280023, -0x40785dda, 0xca35a92d, 0x2963b64a, 0xe5b0e712, -0xa9b2d095, 0x4832e02e, 0xed9cea18, 0xa94761fd, -0x57a40f75, 0xb8cd5b69, 0xd506155e, 0x551ab1ce, -0x59c5aad2, 0x97890115, 0x2a5a9df5, 0x29d9ba4b, -0xbdd29034, 0x5bd4952c, 0x1191c80c, 0x1997917b, -0x55eb2b4a, 0x0e72b3e8, 0x367ece32, 0x34b76a3c, -0xe64ad532, 0x3b59055a, 0x0f712d21, 0xf67a9ba3, -0xaf311de6, 0x7cc35910, 0x834453b4, 0xe26aa25f, -0xb22bb98e, 0xe57b180f, 0x8934fbea, 0x4166ccec, -0x4da4712c, 0xc19c8f60, 0xacbfcc98, 0x30dda7a6, -0x1dc3fbd8, 0x7d77916e, 0x180e8ba7, 0x0f992e7d, -0xc5c22947, 0x22aeeffe, 0x0f371fa3, 0x7f7bf57c, -0x78410151, 0x161ee85d, 0x21902fe6, 0xaefebe53, -0xbc6b6150, 0x13d1afc3, 0x9f6ab323, 0xdfde1341, -0xccaab924, 0xb772a93a, 0xfe3b68cd, 0x79383bba, -0x7006023b, 0xf1f2a411, 0x392af6f0, 0x4d3f478a, -0xe8c05af3, 0x00e25e71, 0xa091145c, 0x3aedec59, -0xc03760a8, 0x55e3c016, 0x8da162d3, 0x7390887d, -0x76d23ba6, 0x68e31654, 0x16b5d97f, 0xe3395e91, -0xe6926e89, 0x63ceb3f1, 0x369b7877, 0xa11de4f2, -0xb1fd5839, 0xe345a9fe, 0x515246ab, 0x6180fbd4, -0xb5cff818, 0x986113c8, 0x417d707c, 0x47d843e2, -0x200ac421, 0x1ca10192, 0x88cd37df, 0x2609dca5, -0x8dc2af5f, 0x211c3d1b, 0x2c2b857e, 0x3557f767, -0x9158b820, 0x10c983a9, 0x04cf4090, 0x821ea21c, -0x3e387c5a, 0x00e590da, 0x7813e54b, 0xc17b54ff, -0x307fa6e0, 0x8b76d147, 0xc131a653, 0x146d70de, -0x8323ac2b, 0xf6f5a535, 0xfe86dd65, 0xb96ee8f0, -0xcf485ed1, 0x04f132c5, 0xfcfc6409, 0xd3c2fb83, -0xd3a2f9c0, 0xf96e77c2, 0x56767a87, 0x80fcfb64, -0x7a71268f, 0xa8c76ceb, 0x24229c56, 0x87c44f41, -0x57a44c7a, 0xfbb5cc5b, 0x4cc2eb71, 0x67b29a4b, -0x3c12f5fa, 0x9d652a79, 0x784c4f80, 0x8f71277c, -0xef82dcbe, 0x7568289d, 0xdf2c8be9, 0x17f27058, -0xc1a68e70, 0xa16e8e80, 0x4658d2ea, 0xd9184214, -0x6eb531e0, 0x1bc29124, 0x9c7f17f0, 0xe46d2d7f, -0x12503c08, 0xad1954c5, 0xac3c0dc6, 0xf5daf588, -0x432ca22b, 0xf0b1feee, 0x49a87d08, 0x46cba3b3, -0xd4b21507, 0xe38c4e61, 0x723431ab, 0xb6a77ed9, -0x301c1efa, 0x74ec696b, 0x68a3451e, 0x7f47d0bb, -0x3ae520b5, 0xd12982ce, 0xb6b1a6c5, 0x6a7530ef, -0x4aef2c63, 0x15c35a89, 0x5f4cf69b, 0x7adf5962, -0xf447643d, 0xee650c10, 0xb129db55, 0x4fe6c24e, -0x90d3cdb6, 0xb541e1c3, 0xb2b6ea11, 0x9a4cabc7, -0x43e9b01c, 0xa569ec97, 0x86d846e1, 0x6ac04c33, -0x53149baa, 0x009ce63b, 0x25a3f701, 0x1c3e0b06, -0x7d184768, 0x283dc7d2, 0x6fdd5527, 0xadc78ad5, -0x8e2cdee0, 0x35403b6a, 0x4643688b, 0xd204f471, -0x7d1a21d4, 0x8c031665, 0x282384a9, 0x617c527c, -0x73022432, 0x09698b90, 0x780842d8, 0xe9f441cb, -0xbe83ebe2, 0x1349c504, 0x6ed09b31, 0x65d66a39, -0x7d31d11c, 0xb321873d, 0x6c3f6320, 0xd15ca4dd, -0xa22aaf0c, 0x911e4be2, 0x13a1b26b, 0x94bad56d, -0xf1e386a6, 0xf881ae7a, 0xa2d80428, 0xb173e4cb, -0x18a1dc33, 0xe5d11954, 0x47897c6e, 0xd5c21c81, -0x1b829c73, 0x79148127, 0xb1c7156d, 0xa58fdbb5, -0x8a487db1, 0xa2eac522, 0xfb47bc53, 0x23ea278c, -0xa7450298, 0xeda0181f, 0xe1884691, 0x804b1f72, -0x918aab83, 0x417c0d4a, 0x0c4fd8df, 0x7a200bac, -0xf5a6deea, 0x5cd32457, 0xc8a677fb, 0xae8fa1c0, -0x20b7d314, 0x7b39a1b5, 0x22f6357e, 0x1da85b16, -0xbf0f044b, 0xe0c8869f, 0xe0d7593f, 0xd981b3b9, -0x2deff02a, 0x73edd221, 0xdbf4b6a2, 0x49a66ed8, -0x8ec84132, 0xc93b6577, 0x585c488e, 0x6fdb9a7e, -0xef868706, 0xec5cb3b7, 0x3dd3f005, 0xfff75a03, -/* 1338-m02f292d.inc */ -0x00000001, 0x0000002d, 0x08112004, 0x00000f29, -0x76e56915, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x3329bed4, 0x074ca74b, 0x76a4c9be, 0xb3d0ac3b, -0x59c1ebd3, 0x9d06facf, 0xa272f2b8, 0x185d2aed, -0x1dbb2394, 0x86f96351, 0x12652c86, 0x873bf0a8, -0x4f6956f8, 0xbc5754f1, 0xd43f9485, 0xb0484217, -0x88993f58, 0x071366b3, 0xbb49ef1d, 0xb8ec50b3, -0xd6dd7d67, 0xafae9594, 0xafbcf523, 0x04e3cefb, -0xf6125942, 0x6c58f3aa, 0xa28b05f4, 0xbb31e4f0, -0xde633bba, 0xc2cc4d76, 0x2fc95cef, 0x465474bc, -0x6148f606, 0xa8245d1a, 0x167d68d0, 0xc38533b2, -0xcbfb5881, 0xb912dc66, 0xbb9cc137, 0xbaa2ca73, -0xa9cee564, 0x3edd2b89, 0x2e3ffeed, 0xa68b49eb, -0x0b85b10b, 0xb968370f, 0xd5c4deb8, 0x2d2883d4, -0x288e44af, 0x37b10c8a, 0xa75c2ef5, 0xa5242ad7, -0xff96f783, 0xab3f2161, 0x3921290b, 0x1094e053, -0x9eae586d, 0x9878a4f3, 0xa2d41b7f, 0xb29cc218, -0x93898d3c, 0xdd152eec, 0x638ab207, 0xa7536a0f, -0x5accf54d, 0x798a56a0, 0x8e925de6, 0xe2fec0a0, -0x8b6100f7, 0x910d43f8, 0xb3bcb1ab, 0x3f032f10, -0x667b024d, 0x5303ab2e, 0x50a68459, 0xdbdae9ae, -0x61cab195, 0x8b080d7b, 0xe1c9c484, 0xc0a9cc33, -0xf3c786cb, 0xa226e2f7, 0x4509e980, 0x2ff4bb80, -0x943a2b9b, 0xb0e2d78c, 0xdce9f9df, 0xb9302df9, -0x2f095be2, 0x46f9e8cf, 0x097129ec, 0x5f7ba01f, -0x49e26e4c, 0xde9ff6ce, 0x5d194de6, 0x9114a73f, -0x5114f3e1, 0x9832e8b3, 0xd116f967, 0xfcddf0e7, -0x3011f78c, 0x5d84b6d5, 0xb465a082, 0x8eb129ad, -0x5390d983, 0xdfad741a, 0xef927af0, 0xa062e4fd, -0x94a1b0f5, 0x6c9dcff9, 0x15192e6a, 0x11a1f0b8, -0xbc5f9758, 0x01c1070c, 0x6f5a81c6, 0x7ee5b238, -0xdf75b957, 0x8b5cbac1, 0x5f7cd16a, 0xf7faa6dc, -0x5b74dbb5, 0x0980f147, 0x4aa350ab, 0x7e96c732, -0xdaeacc94, 0x29fd397d, 0xf62b5325, 0x3c519a56, -0x5dbc6524, 0x201364ea, 0x05ee717f, 0x39c8c28c, -0x9ab2580c, 0x95550f9c, 0xfb0eb0ac, 0x242c6155, -0xdd52b4d4, 0xa04672cf, 0xa81f5b28, 0xac10d5f7, -0xd6afd049, 0x323e700a, 0xb710054c, 0x88b48cc0, -0x4c1d370d, 0xb303457b, 0xbc5bf726, 0x2dfc0600, -0xa86d0d2e, 0x9ec95b49, 0xeec42301, 0xa0ddf041, -0xd3697b0d, 0x1cf23cd4, 0xe511afa1, 0x99677ab6, -0xcb82d8fe, 0x03d837ed, 0xcf59b6eb, 0x117c6438, -0x793db420, 0x01210ef0, 0x2f16aa63, 0x092aa912, -0x188fcfe1, 0x0cd78643, 0x4725f2b0, 0x141b4064, -0x060cb591, 0xdb59b5b9, 0x08ca7893, 0x03b02ee2, -0xefdabca5, 0xedc23083, 0x48d71720, 0xc44417e0, -0xb0f5f326, 0x04e0ca58, 0x1cbc21e9, 0xc47f8d91, -0x5465c94d, 0x6f5c300b, 0xce250158, 0x39d3ff3f, -0xb9ba60a4, 0x7e15fc75, 0x6481b42f, 0x4a822d4c, -0x6b251985, 0x01c3f0ff, 0xb961c2c0, 0x56233348, -0x4322f327, 0xfaf3a4b4, 0xa5e2f209, 0x0086e35f, -0x5665e8c8, 0xd284182d, 0x7c66dc76, 0xdead8651, -0x3948f967, 0x29e2cdc5, 0xa85bf1c4, 0xfc81e608, -0x95129e56, 0x39e8ccc0, 0x8a55171d, 0x0ca75f6d, -0x76b3b76a, 0x07063184, 0x40a355b6, 0x0dc9ae64, -0x2f0bcdc9, 0x3c98d57e, 0xbd9f6fc9, 0x0b3b70e8, -0x6598b670, 0x98adb5b0, 0xe38efec2, 0x1b72b2a1, -0xd7760f5b, 0xa5ff1aa2, 0x21d65a27, 0x85170ab7, -0x4f19b28e, 0x147ab845, 0xc61a001a, 0xbf15e323, -0xbea79403, 0x0e9fd315, 0xa5ce5dc1, 0x3dec0102, -0xe344f20f, 0x26772148, 0xe3c335c8, 0x14698661, -0x02045f22, 0x1b9fe294, 0x18fd4760, 0x2b0dcc84, -0x3719068f, 0xe16a4bd5, 0x69b449a0, 0x088176ec, -0x66231f59, 0xe4c8477f, 0x3ccfd123, 0xd67be9aa, -0x8df1652c, 0x11f29283, 0xb13a6168, 0xd79e71f5, -0xdf064c6c, 0x63bbaea0, 0xa32b027f, 0x17fa40de, -0x62dad42b, 0x4a2ba3d1, 0x97566ec5, 0x7ce0870a, -0x7c6ac399, 0x075eae21, 0x02811d28, 0x6effb228, -0xbdffa992, 0xfc9706c7, 0xa2c158ad, 0x3a407afd, -0x94b88ec5, 0xc9019e3e, 0x10cf018e, 0xf08b1e2d, -0xaa09594a, 0x0d896d4a, 0xf83a743f, 0xfc82a2c3, -0xe863355e, 0x619ef2f4, 0x2170df86, 0x34112254, -0x615d93e1, 0x7c25d947, 0xbda74d18, 0x4188f6d8, -0x02a61d07, 0x262bad07, 0x3939c06e, 0x76480101, -0x26697ea6, 0xfce41af7, 0x9bece83f, 0x309c0b9e, -0xdfc2bc12, 0xedcccfee, 0x4f095c0d, 0xd9b08cce, -0x45da7530, 0x2f8e37c0, 0x5f273652, 0xc13511e0, -0xcdb90088, 0x79c7d87a, 0x3df67681, 0x05a0a8d3, -0xf2d2756a, 0x56041d39, 0x185b97c5, 0x62644b35, -0xba24ad0c, 0x0d8ba3a3, 0x90e4793a, 0x4a04a884, -0x05e64fdf, 0xfe710b2b, 0x85703d05, 0x1abc37e1, -0x8db28c4e, 0xdde1b1d5, 0x03682e82, 0xf4d092fa, -0x067f6a0d, 0x3c142430, 0xf2d8bc9a, 0xf546da72, -0x660ec359, 0x4171e4dc, 0xa29d94b2, 0x151add4d, -0x57f35f12, 0x7258f732, 0x9db66fba, 0x77e39897, -0x8a8711c7, 0x1f5db10a, 0x58792090, 0x68600a9a, -0xb2a89ac2, 0xa4a1f018, 0xc27e695f, 0x00aabd02, -0x3f750dbe, 0x9a2e2bd2, 0x70ac647b, 0x9959d044, -0x7669de0e, 0x2f98c181, 0x1c25a4fd, 0xbfa6a204, -0xfb47f2d8, 0x440f46ff, 0x53a2dcfc, 0x1bf83a80, -0x2d0b22d7, 0x4f518fde, 0xc1d17dbc, 0x7e92459e, -0x95608150, 0x04486d5e, 0xd30e6f8a, 0x7e5a4a39, -0xb01dee81, 0x04e7acdf, 0xf7ada4a4, 0x0795880e, -0x26dc8256, 0x0a5aa3c3, 0x8f029565, 0x2f470e3c, -0xa373fc51, 0x1c7e7b45, 0x267796b8, 0x1bcb4991, -0xcec801f8, 0x6c9a6957, 0xc1ce18c5, 0x043c7ab6, -0x3bd723ed, 0x6093b8ab, 0x2f768aa1, 0x4c6de3ce, -0x71b2965a, 0x31ed9427, 0xbdab13e4, 0x7e9eba94, -0x06508808, 0x5867bccf, 0xc0c8c85d, 0x846300c9, -0x03891b7b, 0xe1150b81, 0x56116659, 0xdff07740, -0x6eb9e465, 0x3a8a5801, 0xc54290e2, 0xeef47a33, -0x4c71e22d, 0xd1dcc6be, 0x7075ccca, 0xa14f574c, -0xfa205fcc, 0x71fd97f4, 0x285b90c3, 0x6f4ec636, -0xe5fcc6ac, 0xaaa6e7b4, 0xb02d6ce1, 0x8e6fc58c, -0x0d8c03e5, 0x5f1490ac, 0xa7c85aa5, 0x079a36a1, -0xcf0a5098, 0x596d1e33, 0x23a0615d, 0x90b97898, -0x7bc12833, 0x5c6b310c, 0xb72adacf, 0xff8538e0, -0x750587e9, 0xcda7274f, 0x7e439b7e, 0x57e0932f, -0x3fc98dff, 0x92a8077e, 0xff3c4325, 0xee308b69, -0x72caf71c, 0xb2f163f8, 0xc024caa2, 0xa86d0b31, -0x41e7bc48, 0x1c34e4e6, 0x8d2082c1, 0x79732888, -0xce59daaf, 0x92755a37, 0x76394314, 0xa23c081c, -0xd3b089f6, 0x99827d27, 0x3a4ae173, 0x2a3e8487, -0x20bbdf78, 0x7a48f87e, 0x223e1ce6, 0x4579c5e7, -0x03e1a14b, 0x28f640fc, 0x3bd0f8b0, 0xe005b408, -0x8c289156, 0x83a0f027, 0xee139c51, 0x630fd758, -0x7e7b2a23, 0xe8460ecc, 0x9ffa8bff, 0x53380048, -0x0afa3850, 0xb1bf8f67, 0x96a14fc6, 0x44b25a59, -0xd82b8d56, 0x4c882db3, 0x0f2fa046, 0x90bed183, -0xbe9e1fb1, 0x5f4c0686, 0xed5cc524, 0x2650ed51, -0x59164cc3, 0xb6af6348, 0xcb09a53c, 0x841e16d2, -0x73bcae6c, 0x2f19b19b, 0x7c974049, 0xa8a81c25, -0x2606dbbf, 0xbcb3a630, 0x87274992, 0x66d21787, -0x2cb53251, 0xbb04cccd, 0xf8b53f17, 0x58751075, -0x9264e9e6, 0x431412f5, 0x6fb4b734, 0x2361e760, -0xd42e17d0, 0x7d9077e3, 0x3e73d73e, 0x70c66cf7, -0x477e7d07, 0x330f4048, 0x26ba1aff, 0xb035e29e, -/* 423-MU26522b.inc */ -0x00000001, 0x0000002b, 0x05121999, 0x00000652, -0xd40d4baf, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x82d4f7e4, 0x1ab144dd, 0x6c99135b, 0xf7e85000, -0x485aa4bc, 0xdc2d54c2, 0xe972fccf, 0x3324d019, -0xcbc6a9c4, 0xedce39b7, 0x9f1e2d7b, 0xd3bf100f, -0x494a087f, 0xf7e7cc9d, 0x708a5137, 0xfc9cf9d3, -0xec52ac58, 0xd50c0b24, 0xa8809cd5, 0x0afb0b11, -0x56f58840, 0xb424542b, 0xc3316bd9, 0x78f37d95, -0xb3f56372, 0xf5f84f86, 0x257e3792, 0xa6deb070, -0x2553ff8b, 0xa2f30e61, 0x528f7e35, 0x239ad66d, -0xa2675b0e, 0x43187193, 0xd99d4a9b, 0x551fcc51, -0x43e2cc72, 0x59a00800, 0xb33363f6, 0x33b9858d, -0xc2d4e60e, 0x626d34fe, 0x0b507f65, 0x48593c82, -0xd493b092, 0xbf9ac3cd, 0x5cdeb0fe, 0x9f4fff34, -0xd64ebd7c, 0xf626826f, 0x49794f5f, 0x2fc6a58c, -0x443adef8, 0xda9e1f2b, 0x93af9ec1, 0x02032b82, -0x90ea392e, 0x49ca677c, 0x010fa205, 0x05e86008, -0x7a7a5faa, 0x24c23361, 0x6173974b, 0x40163e01, -0xf6a28873, 0x4d5bb36c, 0x6284d1d2, 0x766d6605, -0xbedaa035, 0x4cea4ed3, 0x9c56ca06, 0x02576d87, -0xc6e33226, 0x5a623905, 0x2256948e, 0x1ba04f19, -0xb8a0d3d2, 0x6e96125f, 0x401fed7a, 0x4240baaf, -0x1065bacd, 0x1021dd17, 0xdcd660ef, 0xc862fed8, -0xfeb165ce, 0xd4581a52, 0xeedd42f1, 0x804c3590, -0x528ba359, 0xab41db70, 0xa7a2bfe3, 0xc6eb9f0e, -0xa1e3f891, 0xb22f81e3, 0xccedb56b, 0x672e34d4, -0xda637bc8, 0x40c785a8, 0xa0b5bfa3, 0x689078cb, -0xb86d32ae, 0x8a08e06b, 0x56b58258, 0x64dd76ae, -0x37f12a71, 0xd0ff69f3, 0x4648eeb1, 0xdecd4cdc, -0xe415e394, 0x0debe186, 0x767e4c09, 0xf349c296, -0x6a39615b, 0x418036b0, 0x919eaceb, 0xffcbfc96, -0xa109780b, 0x39ee64f0, 0x10cc2571, 0x008d0def, -0x73907641, 0x7d2d1b95, 0x28a09912, 0x9c9e0e7c, -0x6cedc58b, 0xb3612e6d, 0xe522629b, 0x7fefc94a, -0x303cd38b, 0xb50f536d, 0x27706e32, 0x43ac6e65, -0x72c05b6f, 0x7fc617b3, 0xf035d5af, 0x875e29d9, -0x201d23ea, 0xfd2928ed, 0x89f5ff66, 0x1acc4258, -0xa4b045d8, 0x10bc6d1b, 0xab858bf3, 0xd4b3c407, -0x9c708b17, 0xe61a59ab, 0x47bdf687, 0xb26d738f, -0x4b950d31, 0x5820de87, 0x6d609b38, 0xec97b0b3, -0x041950cf, 0xdb386054, 0x703e40b1, 0xdbe48d81, -0x3c0d6bb5, 0xa4a5c62e, 0xc88f30b8, 0x5d952f16, -0xc88a086f, 0x47baabc1, 0xe63a91a0, 0x6f2bc793, -0x0c0d57c3, 0xe81a67f0, 0xf5601a47, 0x4f8843ed, -0x199e0104, 0x3671a0cf, 0x24ae5ba7, 0x2ceb6d1f, -0x350ae79c, 0x1aefd992, 0xb8efeccc, 0x53854cb1, -0x58280110, 0x5680f87f, 0x4774752c, 0x00d9f67d, -0xe380b8b4, 0xf330e9a4, 0x722be379, 0xa945dd14, -0xb977c27d, 0x9c8ce733, 0xadaf3828, 0x6c57213f, -0xcb348b3c, 0x863cf367, 0x58efcad1, 0xe59c47c5, -0x97ad46aa, 0x0766206b, 0x51047339, 0xaf492a9f, -0xf40c4e9e, 0xa5c8221f, 0x15414807, 0xf1e7dbab, -0xf7ee703c, 0x25db6887, 0x8f0f71e0, 0x86411ed8, -0x6381c889, 0x2005b533, 0x485e9637, 0x553d2fe0, -0xe89e6e67, 0x6b50c659, 0x0ee55b4d, 0x32d116dc, -0x12a199cc, 0xf0e4d72b, 0xece6292d, 0x084337af, -0x58f73eac, 0x83252ba2, 0xbdd0f99e, 0xa92a7ada, -0x3b670369, 0x78641928, 0x56d530cc, 0x1200f833, -0x5327e8b7, 0x178047e5, 0x0c34522d, 0xeac40852, -0xf62dc30e, 0x9a06d7e5, 0xb2a7f19b, 0x9ab62c5b, -0x8ddbf6a3, 0x8d31e486, 0x38c91832, 0xe53b17d0, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 146-MU16502e.inc */ -0x00000001, 0x0000002e, 0x02111998, 0x00000650, -0x2f41bf64, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xe132daee, 0x34afef27, 0x99d81941, 0x392e42f3, -0x9c561aff, 0xce39093d, 0x98049a92, 0x0b005129, -0x2f7035c4, 0x9c0d1e11, 0x3fd1c199, 0x8745abd2, -0x2d28de23, 0xea2421cb, 0x6bce22bf, 0xd47c54ad, -0x28109db5, 0x805b31ed, 0x05d69044, 0x7d3aebba, -0xf2cbe633, 0x0643b416, 0xaca8e640, 0x12fd321a, -0xb31461af, 0x830e2bd8, 0x18d4f9b6, 0x4b09fc99, -0xf2de9033, 0x45b3eda2, 0x63a0fe91, 0x8a55e5eb, -0x30d6d490, 0x50826a17, 0x2faf2526, 0xa4c8b947, -0x283e83b5, 0x8c68fbfb, 0xef432f69, 0x7e3277a6, -0xe9f7d108, 0xfa62c5ff, 0xe870406e, 0xeb4b43ef, -0xbb6d3f73, 0x602308dc, 0x0e8b4160, 0xcdb5ce40, -0x2527c5df, 0x9088a9d1, 0xfeecd0c1, 0x7e5dac2a, -0xe44cfaa3, 0x996a0fbe, 0xf2d49833, 0xefc79a2a, -0xe3fd08ee, 0x3545571e, 0xef6271eb, 0x42eaf7de, -0x1d5a2ee4, 0x996b7930, 0x67934d3e, 0x13680223, -0x93631599, 0x1ac0bc0b, 0xea6eb669, 0xe50c2448, -0x05540dd9, 0x0fe6fdc7, 0xea2bc7e9, 0x0cc96ccb, -0x0fc0c89b, 0xf7958fd3, 0xec54fd60, 0x0ed777c1, -0x26558cb6, 0x2678f1ba, 0x5c259d10, 0x491d9dd3, -0xa7c8d028, 0x8ca72a7c, 0x6d55eccd, 0x985b8e81, -0x71519c50, 0x29225284, 0xc0fbdb3d, 0x6c22afac, -0xefba78e5, 0x9392274d, 0x3ba1e344, 0xe7f4d8d6, -0x58761578, 0x5013e1ab, 0xe7b26a45, 0x1813f40e, -0xb97c261b, 0xe0a8bb01, 0x6a5575b9, 0x96a3256a, -0x1112d009, 0x3058c734, 0xbcd86a50, 0xaf40d5a7, -0xf67dd1c9, 0xf267eb1d, 0x812a270a, 0x5f8990e2, -0xf1376d47, 0xd482c5be, 0xd0fc1fd6, 0xcdc6f723, -0x454880e6, 0x50715d0a, 0xd32bb4cd, 0xb1670486, -0x77d44af5, 0x22ebd53e, 0x8328b486, 0x88c29b33, -0xae50a13f, 0x22770bea, 0x0530a73f, 0xddde0c78, -0x1c3ae1b1, 0x5e6f6ed5, 0x8badd022, 0x4be97a92, -0xde2c2c15, 0xc521ee92, 0x884ae500, 0xb56c493e, -0x03805667, 0x69192e91, 0x59b04ce5, 0x932fb0cf, -0x8d4e65d1, 0x4ff181c5, 0xd2ba59c6, 0xc1f6f84e, -0x1cc9922c, 0x30007b6e, 0xa8587d99, 0xdebd91be, -0x2e1e29fa, 0x9fe4171c, 0x1315657e, 0x8ec2b106, -0x3d11f9f7, 0xd0b200b6, 0xd65d5ddd, 0xc94f3da3, -0xf36f413a, 0x4cb9dc97, 0xb1f55482, 0x13d60852, -0x53906034, 0x2657258d, 0x0ff8492b, 0xe09601c1, -0x603bc82f, 0xf2425bfd, 0xa3c92025, 0x235bd2d3, -0x5aa25015, 0xc285e72e, 0xc29eb89b, 0xd2be4c2f, -0x1e58a7ff, 0xd9cb5120, 0x86a9b198, 0x52c51541, -0x7048fa24, 0x15e140cd, 0xfed0659e, 0x0b28b864, -0xc75b6d9c, 0x6640765b, 0xf279c46e, 0x1139ca33, -0xe6e86618, 0x6b7d1155, 0x0dc1f2ca, 0x8a70834c, -0x4869056a, 0x69558aab, 0x9b13a871, 0x9e8f8127, -0x5662c5dc, 0xfafd0e87, 0x43a26362, 0x63d42004, -0x2c8a555d, 0x2ca020d3, 0x56b5504c, 0x49f4c325, -0x68d4f5e0, 0xefa0729e, 0x2ae331cd, 0xa380c5cf, -0x5f95fc14, 0x3b54492c, 0xd710f99b, 0x588cd680, -0xe3de26c2, 0x48f955d5, 0x4745bec1, 0xa55f5bde, -0x1c60c19a, 0x6ad28634, 0xaeeeb743, 0x439b8722, -0x91447244, 0x5c767c49, 0x55242701, 0xd834ee44, -0x2f9f4f5f, 0xd2ae99bf, 0xc61aa126, 0x64d0dab3, -0x329c852f, 0x67280e94, 0x84c0d146, 0x4ff4d42d, -0x41d02750, 0x470108cb, 0xf9cbb793, 0x7e30efd4, -0x15c012b0, 0x6a0e41fe, 0x198b2bef, 0xcd724a5b, -0x566891b4, 0x6a5d89b2, 0x3c80520b, 0x11d1d320, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 94-MU265019.inc */ -0x00000001, 0x00000019, 0x12121997, 0x00000650, -0x657d0d11, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x7f26c69c, 0xd965bb4f, 0x94736379, 0xfba9263f, -0x565b87e5, 0x4a7fc60d, 0x0e854e95, 0x4a859fd1, -0x3dac902c, 0xedefdd6c, 0xd959a4da, 0x9b88e637, -0x45b0847e, 0xa7a1108d, 0x1a461adc, 0x0a75cb99, -0x871d3219, 0x8ae64c92, 0xaf5b39bb, 0x59847536, -0x256f5674, 0x191285d5, 0x6edebbd8, 0x461f63ca, -0x4f94669e, 0xadc80ecc, 0x085a64dc, 0x7e1c0fe1, -0xcedd8997, 0x1fb692f9, 0x3b531bbe, 0xb9b262c7, -0x1f05d82e, 0xac688cf2, 0xfbd23704, 0x1bae2071, -0x833361b2, 0x9b437645, 0x3dfc6095, 0x90073d04, -0xbfa2a6d7, 0x9ef6e50f, 0xca35d786, 0xaa6c36de, -0x0c2786de, 0x85235ffd, 0xb461106a, 0x55330169, -0xa19f3ea1, 0x5da8f7e1, 0xc41c430b, 0xd59d2664, -0xc2478a92, 0x2babb133, 0x9245dd44, 0xe48b26b2, -0x7957893d, 0x773399e7, 0xa0477a07, 0x5a6b4dfb, -0xabcb4238, 0x37d4382d, 0xf05606cb, 0x4b879199, -0xdc6f615d, 0xf8c89c29, 0x86cde90b, 0x7b9fd190, -0xf33d098f, 0xfe72438d, 0x17433c27, 0x7a6bf8e5, -0x3ff2e215, 0xca257f64, 0xbec0afe5, 0x8120bb2b, -0x46ab6eef, 0xd9c46159, 0x9d6e38d0, 0xfbcf0853, -0x37037a00, 0x26555abc, 0x25610aab, 0xd7cfc2e6, -0x8e2e6113, 0xf7d6ed4c, 0x8078a9be, 0xddde2955, -0xcaf7efe9, 0x90198b78, 0x2c096951, 0x54a30f72, -0x6ccc7782, 0x8b241075, 0x9d8514ea, 0x60f97f7c, -0xf94aa2cc, 0x53ff3bb5, 0xfe44f65c, 0x0029f22e, -0x64d8fa47, 0x0c452859, 0x8c589fbe, 0x179ae6be, -0x19474570, 0x0f1b16c5, 0x16176dcf, 0xe4a7cc95, -0x3fc74e70, 0x76310041, 0x9fcecc78, 0x9bae5410, -0x9198248b, 0x0f454a0f, 0x6f8f8796, 0xf7305293, -0xe1ea485f, 0x97f712c4, 0x31be336d, 0x06105410, -0x50f441b4, 0x4887ec24, 0xd436101a, 0xa415cafd, -0xa7130475, 0xa7ab7c64, 0x0e00a1c7, 0x0fcb5a01, -0x3c4e5072, 0x99007058, 0xf76ce045, 0x63dec8ec, -0xbfd6fe12, 0x71e605b8, 0x6ab06865, 0xbea0d464, -0x293ac1f4, 0x64f4cc8c, 0x4be6e6b4, 0xfe1dc185, -0xe91bbc6a, 0x6d1ec136, 0x48ac251d, 0x43c7ea70, -0x9c81b91f, 0x0fa15844, 0x31961b0a, 0x1b63d430, -0xfce78113, 0x74dd97c6, 0x3d97591e, 0x9ab5d14d, -0xb0fb091c, 0x83b45dda, 0x9674717d, 0x7edc5dfb, -0x0e919cbb, 0x68484280, 0x5f7f5512, 0x77365ca0, -0xad17fe9f, 0x26ab6b49, 0x0e3e9269, 0x424aa0b3, -0x3cc2ccf3, 0x416a77ad, 0xf56c1f9d, 0xa2f9e471, -0x84d9426c, 0xc7cc1db8, 0xacbc04ab, 0xa42bb1c5, -0xf2c1e51c, 0x5803c2e8, 0x6f628099, 0x5686f059, -0x661dfd4f, 0x711dd3b5, 0xe99ccbb9, 0x49404d0e, -0xa70447c6, 0x7e8cfd74, 0xac21ab9c, 0x8877533d, -0xf2fb6f6d, 0x22dce806, 0xb1c4becc, 0x32a7de8b, -0xae16c79b, 0x892a458f, 0x24f1e262, 0xfa2af121, -0x10fe0865, 0x98e8f24a, 0x0163f658, 0x65665308, -0x5eafa67a, 0xe36d7586, 0x8eaaf4ad, 0x8d7d2dcd, -0x352c5043, 0xab2e3537, 0x6d0a996a, 0xcac06a13, -0x00dda4e1, 0xc4fc8e95, 0x25a511df, 0x0c6c9e98, -0x8a1b9e61, 0xd8260653, 0xbb5a3963, 0xc32bd0a3, -0xee127e88, 0x43837177, 0x1b04b552, 0x181ddadc, -0xe484add2, 0x70ca5012, 0xbf33751f, 0x09c49d74, -0xcf4f9e20, 0x034a2983, 0x63c1e1f5, 0x5d55f43f, -0xb20e1531, 0xb611421e, 0xc456e84f, 0x838e6577, -0x555a4e63, 0xee7c75f5, 0x5e972e65, 0x4ebff639, -0xa5f6aaf6, 0x04862717, 0x3f904365, 0x3de4892d, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 358-MU166d05.inc */ -0x00000001, 0x00000005, 0x03121999, 0x0000066d, -0x270b86cf, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x3eecc08a, 0xa62586a7, 0x408e7837, 0x0dc3d177, -0xedde0b05, 0xa3109474, 0x647d05b0, 0x082dd37a, -0x9508f533, 0x27791251, 0xc76466c7, 0x59d04ed1, -0x0058218c, 0x9bbc0b3c, 0x578a3165, 0x38f67e1b, -0x9016dfd8, 0xddd13c58, 0xfcf10eba, 0xcb62d04c, -0xd2d35472, 0x4f401811, 0x983eee95, 0x67c7e2ca, -0x09661754, 0xf083039e, 0xbc5c8e2b, 0xd033a5f7, -0xdd29decc, 0xb08e45c3, 0x178f020c, 0x6aedb152, -0xb0a543e6, 0x05eb6675, 0x085278cb, 0x8638047b, -0x0ecbe074, 0x1ec99c22, 0x06b43447, 0x58ea9289, -0xc306e6fe, 0x0a457488, 0x3bd17bf1, 0xa7a1c60d, -0xd4d10167, 0xd5f97ee3, 0x7e5b7118, 0xeeb9e726, -0x25fbb795, 0x8f265c96, 0x31dfab47, 0x8e16f37f, -0x30feea5e, 0xf7ad09f4, 0x3f183cca, 0xa093c433, -0x087dec7a, 0x4cba9e59, 0xfcc38136, 0x709092d5, -0x182dffa0, 0x33edcab7, 0x6dfabfa4, 0x9ce2ef89, -0xcac4dec7, 0xcb107150, 0x7735b4f2, 0x3cd277a9, -0x7230d8e3, 0xb2d7ce42, 0x4a40b6fb, 0x0b0a8f86, -0xb9cb10e8, 0x42fa5d95, 0xfc2754ba, 0x92c173b2, -0xd8d2157c, 0xfee978a5, 0x68fa268c, 0x5036fb2a, -0x464a1736, 0xa03ca83e, 0xdc9bab6f, 0x7ddb5f53, -0x59e8f8a9, 0x4ca42caa, 0x7ba80904, 0x7ca57b6f, -0x4ce8bc6e, 0x7b7c4916, 0xe2254a6c, 0x278d62b4, -0x5b421da8, 0xe4376e72, 0xb7dd55da, 0xceb0629b, -0x498b4e10, 0xa40c2942, 0x644dd7ee, 0x81168e6e, -0xdb1b5481, 0xe4235208, 0xf8a65d72, 0x9be1e523, -0xde3c6046, 0x0acbd5c1, 0xb463150d, 0xca5eec67, -0xb8aee1f1, 0x5f90ee6f, 0x5c16d75c, 0x7c7db98d, -0x5325f5b3, 0x4935ebe9, 0xb54b36ff, 0x2903946c, -0x683eed6b, 0xef118016, 0xe0848cd4, 0xc0d1ab12, -0x1fa732d1, 0x832958be, 0xc46f4b10, 0x69e330d7, -0x682c04c7, 0x4d54e3c9, 0x9a3c4e4c, 0x704f2e3a, -0x05fde6d4, 0x2bacfe0b, 0x01feeb9e, 0xa7acd834, -0x53900d41, 0xb7c39057, 0xf2e749b7, 0xb22892b4, -0x02bc3b6a, 0xa9bf07ab, 0x0f21554e, 0x94051643, -0xdfd19589, 0x1d0aa78f, 0x90d6d4c6, 0x1f44d198, -0x41d8fd4c, 0x989126ab, 0x4b4bb83e, 0x6b7efe1e, -0xed1a4871, 0xe14f08ae, 0xe4c9c7a4, 0x60f865a9, -0xb4d07706, 0xc1ac0423, 0xfe52bb9f, 0xa262816b, -0xa8e6d91f, 0x99e12111, 0x17a958f6, 0x2fa56e8b, -0x26a3e40b, 0xb99a86b4, 0x1975e2a7, 0x12c7d158, -0xf04c89ce, 0x1e63c5a8, 0x45fc89ca, 0x08669d2a, -0xefc329cd, 0xcdfa4217, 0x46fdd0d4, 0x832598a5, -0xe66c4533, 0xa082c44a, 0xd3fa6222, 0x16ee47f3, -0x8b90b067, 0xfa7fb243, 0x107a6c75, 0x20a9caeb, -0x32c97825, 0xae4c758c, 0xfac2c32c, 0x7b2c99e2, -0xc67a6b3d, 0x2da13198, 0x40bfb7a1, 0xa86e1b40, -0xdb6fc09e, 0xe9294017, 0xd327adb9, 0x11110cac, -0xbbd27303, 0xae5d51f5, 0x7669ab98, 0xdad9463f, -0xc749fa60, 0x7b9d09e4, 0xb306ff5d, 0x858aa60f, -0x3310d43f, 0x39519ef8, 0xfe9932b5, 0x417fa945, -0x8dad55b5, 0xe3e8de26, 0x35007ade, 0x3492880a, -0xab849e4f, 0xcd774b5c, 0x28544c48, 0x8b498f40, -0xe884eb7b, 0x20241491, 0xc6a03ed4, 0xd328186f, -0xc591ccd9, 0x92750413, 0xc9557d4e, 0x88ef0aaf, -0xa53b30fe, 0x4f1325f8, 0xe6f7379f, 0xd7484b44, -0x88d273b4, 0x916e3b39, 0x4b044249, 0xa7b28fbf, -0xfd49d863, 0x79d3dec6, 0x7dd8135d, 0x948845d1, -0x55db29d1, 0xaf6408a7, 0x600c14a6, 0x89d463a8, -0xb2bd82af, 0x61e04014, 0x326681f3, 0x6053a6c9, -0x250c7a7d, 0x0a642a61, 0x2a6689fd, 0x01c6c9d1, -0x445fc371, 0xc8c5d01e, 0x813c4130, 0xf61f837e, -0x2f243919, 0xce51a67c, 0xb14232a6, 0x1a79eb11, -0x8e5b7f19, 0x94a777cd, 0xd0e61396, 0xc1bb9eec, -0x509fe53f, 0x90bde780, 0xfdabe75a, 0x97af888d, -0xc525cb70, 0x45ea7624, 0x2736a36d, 0xe3ef2095, -0x16b685b9, 0xb8d00570, 0x3a3a5365, 0x2cf032c7, -0x26b4c03e, 0x4271dc33, 0xab85bcfa, 0x3afe2205, -0xc81b634d, 0xc32a2a5a, 0x63028408, 0x7b3fac4b, -0x5a7df74b, 0x35a60cfb, 0x06aace89, 0xc2b02ebe, -0xc50788c0, 0xa1f41242, 0xa5976893, 0x712469a0, -0xd17a0c5a, 0x706e3d86, 0xc2f9685f, 0xf449c450, -0xe72f42e0, 0x1cd28b33, 0xc1155247, 0xaaa41150, -0x261c1d3b, 0x492ff4db, 0xac49bcc4, 0x2692d23e, -0xe1c9a072, 0x30edf533, 0x660e7470, 0xd145fbde, -0x7c5c49b0, 0x7bcf8c05, 0x2ff02005, 0xedcd3a12, -0xa18bf23e, 0x70ebc247, 0x96986456, 0xfc0fb3d6, -0xe1ad3385, 0x89b3ae09, 0xbcc18862, 0x7bc64f50, -0xacac4b0c, 0x64f1f67b, 0x06489941, 0x0f8675c1, -0xad097e7f, 0x19c4d7f0, 0x23180e2b, 0xffbb5788, -0x82e1ffa4, 0xeaa3a7d8, 0x7a37ec77, 0x1db0b023, -0xdee55066, 0x5863d8c3, 0xf4c56ba0, 0x067a0a3b, -0xfd5f26ce, 0x952b7e63, 0x28fa1941, 0xc6118388, -0x8135d105, 0x577c5188, 0xe5217d10, 0xda4410f0, -0xaede1954, 0x0d2c3425, 0x1aa63ce7, 0x95b44276, -0x0770aa23, 0x6e703548, 0x2904c0be, 0xe2df8736, -0x4393f1f9, 0x70ce1525, 0x88d256b0, 0x671bf175, -0xae8b8785, 0x9a26490c, 0xd6bfd6f6, 0x05947a91, -0xe1340d8a, 0xb3b37f6f, 0x3e93c7e7, 0xc24dc70c, -0xdcff96f4, 0xdd05a3dc, 0x462c01ff, 0x05286a87, -0x86f78acd, 0xff056306, 0xf87fd3d2, 0x3cd4abc2, -0x82c0083a, 0x9ef42ebe, 0x709da61f, 0xe1ddc8a4, -0x6d91ca8b, 0x116ac1f5, 0xc4ae1fb8, 0xd9adba26, -0x79418d23, 0x0d5824bd, 0x50edc99f, 0x3980786d, -0x673bef89, 0x9f063042, 0x62b432e5, 0x6967beb9, -0xe37fd96a, 0x7b1592dd, 0x437094c6, 0xa7524f6a, -0x3fa85e93, 0xb17f53f9, 0xa3a7f69a, 0xea03b804, -0x8dea22e6, 0xc095d826, 0x65fbd1dd, 0x241a9527, -0x1c103e6f, 0x07fe651d, 0xca1f3625, 0xe7095692, -0x4e7ca154, 0x9bbc25a4, 0xf7e36d2e, 0x661e8328, -0xdb27f7e2, 0x7725adb7, 0xea2f1ecd, 0xd97d7ce8, -0x64a80e81, 0x0fedfe61, 0xba01f4fe, 0x4125c4f5, -0x7525b5b9, 0x491e09d1, 0x4971bfd7, 0x87e7bf91, -0xd9642634, 0xc613b75c, 0x4eac1995, 0x0676f816, -0x5bbde4bd, 0x9d896773, 0xbef78a8e, 0x664de511, -0xdf272637, 0x6c91f7a5, 0x99b42d3e, 0xe4d12c19, -0xda29b3b0, 0xc99346a3, 0x135ad23b, 0xf63565f2, -0x31e84e51, 0x17503841, 0x2074a43f, 0x4884627f, -0x751d935f, 0xb7de396c, 0x60ac4c22, 0x26a3ecbd, -0x771c6046, 0x9fb24436, 0x69c094e0, 0x3b500ed1, -0x4acfb68f, 0x489263d3, 0x72878f8d, 0xb41fd5f8, -0x9dba1fe0, 0x049eb891, 0x5df03769, 0xc47d9696, -0x72f59209, 0xb151fbe0, 0x260095c7, 0x88adb02f, -0x3e35d2ed, 0xca7b8454, 0xa6d56623, 0x48cfd15d, -0x5ec65c94, 0xdd45c99e, 0xc9ab3a13, 0x1bd8bbe3, -0xfa87c12a, 0x5b32688a, 0x0fcc1d53, 0xea8f88a4, -0x38f68efa, 0xcd13a712, 0x7da1b9bb, 0xd29f6ba2, -0xde23b46a, 0x6622783e, 0xe5a7fb42, 0xe981f7fc, -0x45bc6405, 0xf6e40044, 0x93763406, 0x5f8be3f3, -0xbe01786f, 0x40389874, 0x56bbc03f, 0x02ec4ce9, -0x42ce5877, 0xa658533e, 0xee412a3e, 0x22a47b5d, -0x98965b02, 0x43d40037, 0xd2e1ce86, 0xd19426f0, -0xc763ab1a, 0x5c97b009, 0x6297ffab, 0x896e3a68, -0xf5d7abea, 0x30e0b88a, 0x6b6faa67, 0x2dc017a1, -0xa42fdcb8, 0x304838ab, 0x16907995, 0x6ef05b9a, -/* 678-2f0708.inc */ -0x00000001, 0x00000008, 0x11152000, 0x00000f07, -0xb7b473e7, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x4dddb0e3, 0x5a70c760, 0xe3027e6a, 0x257e0d6e, -0x1cc3bc7f, 0x58220fe4, 0x6b5f6eb7, 0x631a1665, -0x8a7512c0, 0x06161f7e, 0x8069e964, 0x528fd53c, -0x13223d11, 0xd432b7bc, 0x14e91b7c, 0x0a9ef7d5, -0x0e260983, 0xffe44ab3, 0xd1feef0b, 0xc132aee8, -0xe5ea6fc4, 0x18948b86, 0x1008c031, 0xd750f306, -0xf362cdc5, 0xf610851a, 0x27ea5d51, 0x18849a2c, -0x21f0c897, 0xe7bc3877, 0x9865d834, 0xdfbd8ab7, -0xd1b7adf4, 0x1d116923, 0x46d71883, 0xe2b172f4, -0x12065b5e, 0x23984b09, 0x86922920, 0x20ffc1a4, -0x3d53d90c, 0x02603eda, 0x972c6c24, 0x319bb9d4, -0x60df61b9, 0x0e86675f, 0xc4b3e000, 0x77691725, -0x8e2cb3ae, 0xb174fafb, 0x6973c230, 0x5099b0af, -0xeb3b208b, 0xa8629bfd, 0x4eee644e, 0xdf345074, -0x4966d636, 0x4f84bb76, 0x58920fc9, 0xca68b22f, -0xc3e6e2fa, 0x344c1773, 0xb38ceb98, 0x7bd94b4c, -0xa7b02c1d, 0x6c49d324, 0xbee89d2c, 0x05e29d38, -0x832e9907, 0x7a1b71ef, 0x707cdbae, 0x5302f267, -0xdd3ace44, 0xe735b7e6, 0xe9801d71, 0x4fa2cf9b, -0xecef5578, 0xa59d0bb0, 0xc7ee559a, 0x73a22e03, -0x379f0f17, 0xdee4fa9e, 0x994460b9, 0xb789e510, -0x9727b82b, 0x45363eeb, 0x87ffd67b, 0x725908e9, -0x0295aee8, 0x3a70dcb1, 0xb2b6eef2, 0x7ebc23d3, -0x3d692d9b, 0x43aa7591, 0x59713bdc, 0xc98911f7, -0x2ca95380, 0xe577f8b3, 0x7bf4a277, 0x986a17b2, -0xa153447d, 0x78da542f, 0x0c4c2f50, 0xc0dbc22f, -0x2729eecc, 0x51051362, 0x79bc3129, 0x6cfd32f6, -0xaab0a714, 0xc77a2a0d, 0x0b9bb7f6, 0x5f4ea4f0, -0xa04ab8f2, 0x23d7c066, 0x9a3a61e8, 0xc95e854b, -0x6c5365ee, 0xcde17650, 0x0f2f0760, 0x28c82126, -0x00087588, 0x3678486c, 0x8746fc87, 0xd2f54238, -0x0cc355e5, 0xf2f3ba75, 0xf80d5eb5, 0x0c091c89, -0xbc7f9b03, 0xfbd7bea9, 0xe2197cce, 0xf23e9ce9, -0xd2ba317e, 0xf795879d, 0xa7ddd184, 0xf320b681, -0xa1d665b5, 0x10ac8bb4, 0x8ee3146a, 0x5b458e3c, -0xb89da052, 0xda575cc6, 0x0d230bff, 0x9c3cadeb, -0xcd68ee26, 0xd032b247, 0x43658df3, 0xf9f4168e, -0x861b4409, 0x1d279790, 0x866591d7, 0xea409a91, -0x1351048d, 0xf3067a37, 0x6861790e, 0x3b35f621, -0x22a9af0b, 0x28a7042d, 0x890f7f0c, 0xc93dbc2c, -0x20adb3a8, 0xcb7b5697, 0x40c73f52, 0x3f4fde23, -0xd2eb1eed, 0xdc77e6de, 0xd1d59d5d, 0xd975315b, -0x2d37da7e, 0x86dd3507, 0x2012e431, 0xcd197ca7, -0x7cfabd26, 0x56ed3b6a, 0xc6c179b9, 0xb133a293, -0xd1988106, 0xdfdcc553, 0x925f894d, 0x610915a5, -0x9daceed2, 0x1dc3be8d, 0xd92f2d7d, 0xd8ce4067, -0xe0fe80a3, 0xc4c5be9f, 0x4b79f5a6, 0x07f2e89c, -0x104ff0b1, 0xf9d80a95, 0xb469af7f, 0xdeb4e632, -0xe20e68b1, 0xb04c906f, 0xae96d5f0, 0xe8807571, -0x69e653cd, 0x73634a9d, 0x0359cf6c, 0x895bbbdd, -0xddc8e603, 0xd0c6ecf7, 0x55d8d699, 0x6b6c87aa, -0xfb5fa64c, 0x280e725a, 0xf469add1, 0xc71b2676, -0x0d3ffa86, 0xc18b8e6e, 0xe9d5c8fd, 0x388a62fa, -0x96486eb2, 0xe343b757, 0x2d7e5b9a, 0xcdd2fdd7, -0xf37f535f, 0xc22d20f5, 0xb56229ef, 0xf84c2873, -0x3bb8166f, 0x3047942c, 0x0c0c34e6, 0xffb18af5, -0xba123d95, 0xd03ca2c9, 0x492f6877, 0x11123a60, -0x12a4ed70, 0x1359ecf1, 0x54d06dbb, 0xf46dee9f, -0xc12b4b91, 0xed32e734, 0x365d205b, 0x3f4bac05, -0xf9107418, 0xfa1f3314, 0xbf4b26f3, 0xfb727a4a, -0x0491c7f7, 0xae00a8c9, 0x8ae416e6, 0xd6452a4d, -0x37a5613a, 0x63099fa2, 0xe9e1ab5c, 0x8d522050, -0x13df8316, 0xf83472a2, 0x25ebaa4f, 0x760db85f, -0x75ac1227, 0x2c5a02ef, 0xfc6a75ba, 0xc73e3d4f, -0xda41add6, 0xc0cf63a3, 0x9f8b7c51, 0x1edcc855, -0xdafd1090, 0xeaa1f5f6, 0x9f5ab9be, 0xf519b1f9, -0x220ada81, 0xec9b6297, 0x8661ea2c, 0xce9b083c, -0xd9066bd8, 0x3580f9c8, 0x654096f0, 0xcd89c00a, -0xa1cb9789, 0xd81005e0, 0xb38c9d26, 0x16fe94f6, -0xfd7ed18a, 0x7f082e86, 0x46232eb1, 0xdca4c40c, -0x09c2a72f, 0xa457e090, 0x9b006010, 0x6e0ef594, -0x8c2db173, 0xee25f9b6, 0x4b5eac90, 0xa5c29e8b, -0x38287db2, 0x9d44981f, 0x64683efb, 0xd4d7b3c1, -0xcc04d5d9, 0x492e3520, 0x2f4c5009, 0x9166154e, -0x0611df13, 0xe072a1a8, 0x91c621ce, 0x77075850, -0xf167a5e5, 0x21e75939, 0xdea1ea39, 0xd92a1119, -0x1dcf8ad4, 0xd08c8eda, 0xe448b734, 0x3aca7fec, -0x2ac02c01, 0xd190cfc2, 0x5db28d4b, 0xd035d0d1, -0xa3d4ea09, 0x875a7ac8, 0x01905ca5, 0xf5d11ebd, -0x52bb11d7, 0x61d7dde8, 0x1b75b331, 0x8d7519d8, -0x078e4250, 0xd26b936c, 0xb5782301, 0x4b31a8b7, -0x6ec83a0f, 0xf61c0c35, 0xfffa8aa1, 0xd4dfb0c8, -0xc6f66653, 0x118cfdcc, 0x4d21b9b7, 0xfefcad12, -0x0966781a, 0xc924b099, 0x917c8608, 0x13ab58b4, -0x15dd0d17, 0x5e556a71, 0xccede394, 0xfda4dcb2, -0x21302bf2, 0x8753f833, 0x034ff898, 0x7f33ba69, -0x198d898b, 0xf209df4e, 0xfe8c6dbd, 0x82c24300, -0xfa8e133f, 0xe7ead557, 0x38713537, 0xe910e818, -0x85427524, 0x20188bbe, 0x3bffd95e, 0xdf8dff60, -0x54000988, 0xfc26f171, 0xdc175ac5, 0x33ccf2d2, -0xc28930c4, 0x798af4bc, 0xd3038720, 0xf6194887, -0x4d4ff6dc, 0x8ae765df, 0x861a86a3, 0x534d3360, -0x5ef12290, 0xee55d0b0, 0x80a81e9b, 0x9f0db628, -0xe9feb243, 0xaa83d0ba, 0x1d81638e, 0xc8d34c16, -0x94c9c754, 0x5b036e00, 0x1d3fdd62, 0xaa5702d3, -0x78e42d61, 0xf3b33904, 0x7a64e85a, 0x7c81119e, -0x7c8a9214, 0x9c47cab6, 0x169fce10, 0x63714659, -0x6503c9fb, 0xa04376ee, 0xecce86ff, 0x880b1193, -0x52a10bc7, 0xf59865de, 0x26b855b2, 0xd74a8d70, -0x8cfda341, 0xbd75fa8d, 0x417fd8af, 0x8899f8ae, -0xfbccde06, 0x99bdd436, 0x27f2377f, 0x7a861733, -0x44b70631, 0x84112f62, 0x33523bca, 0xc2dbf2c7, -0x65747162, 0x407eb3ba, 0xd552a9a0, 0x81896a57, -0xd2f2bff9, 0x6a8fc9d9, 0x5cde0cbc, 0x58b714be, -0xdfc21b97, 0x00bd281f, 0x38e403e9, 0x6fb80b04, -0x7c9ad9ac, 0x9e3e07c6, 0xa9c6ae35, 0x1c648e56, -0x49b3aa31, 0x78c74846, 0x285f5d6b, 0x5ccb7142, -0xabc6cc11, 0xce36f1f5, 0x093926cf, 0x88b774ab, -0xabea55d0, 0x5d61bca4, 0x594f92a2, 0x6ae8eec6, -0x325ea3d5, 0x8ee663a7, 0x9a00db31, 0x09787a75, -0x13c2726a, 0xa97f00fa, 0x4794b06c, 0x38a57549, -0x9850bc54, 0x15d84a9b, 0xd8ba56e4, 0xec52fbfa, -0xb400471b, 0x31714eae, 0x9e60c723, 0x2d2f238b, -0xcd154356, 0xf2395c4a, 0x07a37c04, 0xac6f6c10, -0x32be7e7e, 0x366b17ea, 0xcaa7d96b, 0xcb3563a1, -0xb15983b5, 0xba2af198, 0xd89900f3, 0xf9437ccf, -0x47e26662, 0x1d5d5c22, 0x17ae16e7, 0x7e0ef361, -0xec639aa4, 0xf46503c1, 0x9b88a712, 0xb7f2ae9b, -0x9bfc2db9, 0x6d75e8f8, 0x896ba8a8, 0xfed54e37, -0x3563eae0, 0xbbd0294c, 0x89b47800, 0xce87a4a4, -0xb15ebb4a, 0xc29f09ef, 0x5830a869, 0x24ebaba5, -0xf1504a05, 0xd58a8084, 0x87157d74, 0x182dced4, -0x2ae81a28, 0x3397700c, 0x72ad1146, 0xbacdc632, -0x7ea7fdd3, 0x23c147b2, 0x7203b0c0, 0x6ee52c7e, -0xff0899af, 0xaaa7dfcd, 0x99012d4b, 0x1580a45f, -/* 1460-m9df4305.inc */ -0x00000001, 0x00000005, 0x04212005, 0x00000f43, -0x77812c17, 0x00000001, 0x0000009d, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x41740bf2, 0x0fb63031, 0x74bc45b3, 0xf307c6fb, -0xaf228a86, 0x79ea9270, 0xc00409b8, 0x7168b2c9, -0xc69ce09c, 0x6feac351, 0x43e9da85, 0x3a90aeb0, -0x585463dc, 0x862a2fdc, 0x940910e5, 0xb505c163, -0xc30e56e9, 0x4e2a719b, 0x42e8bbda, 0x19147d96, -0x7ff726d7, 0x1e0edfda, 0x87d8bc2a, 0x60653903, -0x71774956, 0xa9471d10, 0xf1c88b74, 0xb962703b, -0xf17437d9, 0xc0adbf90, 0x652ab30e, 0xc67fae0c, -0x0e841997, 0x99f91985, 0x3e029b48, 0xa72bde1d, -0x3ea0da5e, 0x96279a8d, 0x1f1ec1cd, 0xa965fa6b, -0x35c8ccbb, 0x6a72ee72, 0x1fc43e03, 0xec7735f6, -0x8823ff1a, 0x3e645212, 0x82a09482, 0x311bf7a3, -0xcadf34af, 0xa6c5cecd, 0x70bf80c8, 0x0845cd4b, -0xf060f6ab, 0x428653f0, 0x4582d8a8, 0x47e4bacf, -0x05b49c22, 0x51443b9c, 0xce21cc4e, 0x1468359a, -0xc3a26269, 0x497f2c70, 0x812df7aa, 0x4d4c04f7, -0xb9a174a5, 0x0ef520b4, 0xde699847, 0x365da54e, -0xb1187e8c, 0xca454e8f, 0x9e8f544a, 0x635a9936, -0x291f0f10, 0xc880aad6, 0x052f194a, 0x8a07d5c9, -0x49dbf128, 0xdf0d5289, 0xd7963495, 0xabbf6337, -0x7b8b78d0, 0xbadf035b, 0x5ce0b492, 0x8f3505e5, -0x4a5993c4, 0x5b5bcf84, 0x27427e04, 0xecb71d2c, -0x19bf1e03, 0x1c0aa23a, 0x0550181a, 0x873111fb, -0x420a4832, 0xfe59acd4, 0xa6639d43, 0xe8586050, -0x7eeaedf9, 0xf262b624, 0xdbaf5bc7, 0xf6a1f48d, -0xcb134184, 0xebb3b6b3, 0x4286edbe, 0x831035db, -0xf21d33cf, 0xf0e5a942, 0x713ba616, 0x67050db1, -0x297d8d43, 0x492ad3e8, 0x7baabecb, 0x182896ce, -0x2dd7ca4b, 0xd9b35d23, 0x7bb66ec7, 0x61d8a014, -0x741f2ffc, 0x9900d5bc, 0x6dca1242, 0xe7fc10f4, -0x189d5169, 0x9dc29201, 0x91dcfc93, 0x3f897e83, -0x5fb4bc8e, 0x90e9d74e, 0x80a59795, 0x52e200b4, -0xb848428e, 0xe1c88c23, 0x4bdb6f55, 0xec37329d, -0xb9319cf5, 0xafc426ad, 0x709291c3, 0xd6337f13, -0x05787ba5, 0x1fd0c9be, 0x04c10f42, 0x8b905c03, -0x9c8ab821, 0x39d16a2c, 0xff92a2fd, 0x03a422f6, -0x399071b6, 0x1a71c1f6, 0x2a06aaa7, 0x5a127792, -0xe0245f90, 0x7ac7a606, 0xca8b0026, 0xc47103e3, -0x711ebc3a, 0x63c83ae1, 0xaf6a9a65, 0x744c86a2, -0xbe10c4ad, 0xc2803284, 0x602b6a17, 0x10d60720, -0x8308d938, 0x6e92a831, 0x64f30617, 0x50a13d14, -0xa5aeb526, 0x1ecb499b, 0x5b60c9e4, 0x8dd251ef, -0x11b16e38, 0xea410ba4, 0x74db14bd, 0x2f4d5e36, -0xf28ea5e5, 0x231f3e77, 0xf436a5a5, 0x56bbfaf8, -0x2ccc07eb, 0x0813c683, 0x86822d1d, 0x95b897c5, -0x3f62fa14, 0x9f3f99f8, 0xd5f7fdbb, 0x0cbe179a, -0x1f3a5628, 0xeca6f2b4, 0x12f7cada, 0xe37a2fdf, -0xb675725f, 0x410037c5, 0xb808ca59, 0xa4bd5413, -0xe32191b9, 0x3235a554, 0x62039695, 0xa0652f4f, -0xc78028d8, 0x499fe81d, 0x316a700c, 0xb1489055, -0x7a513a9b, 0x7f03fad5, 0xff234c2e, 0xc4b2455f, -0xa412eff4, 0xcaa52441, 0x0923a5ae, 0xdcd7187e, -0x758f5fd5, 0x5b1b9e7d, 0x95c7840f, 0xf965e7e5, -0x98b65c42, 0xc61289d9, 0x7249b7a0, 0x5102c56e, -0xfc8aa455, 0xb44da061, 0xb0a37e8b, 0x29d8c01d, -0xbb5e79df, 0xa795eef2, 0x91d432a8, 0x5e5d736e, -0x30f4bfc4, 0x2fe5b1ed, 0xf092e0d1, 0xdd507420, -0x972da66c, 0xd7165069, 0x0a8e6912, 0x30f29776, -0xbe544016, 0xc9af8108, 0x1cc1e045, 0xbf221ed5, -0x1e7cb2ff, 0x8e9442e9, 0xaea734d7, 0xcc58775a, -0x2c115eeb, 0xfb48535e, 0x174d0264, 0xc99a9afe, -0x252c6e79, 0x09e05ab6, 0x0cb416c2, 0x6f0da541, -0xa2947cd5, 0xd134edd6, 0xaa8876a4, 0x35025d69, -0x1d95153d, 0x68392af7, 0xb428842e, 0x72950102, -0x6718027b, 0x8e564123, 0xada1ebcf, 0xa7ee3852, -0x86c0b296, 0xd56a51c0, 0x87bc83f9, 0x94c703fe, -0xd43043ba, 0x7a4f6d96, 0x43cde1ec, 0xb7a7e12a, -0x1160cd1a, 0xe98c5d2c, 0x226ac59c, 0x3561e049, -0x92b8d432, 0x269e9e5d, 0x12a0eca9, 0x52124b1a, -0xdabfc0a9, 0xda11ca8a, 0x59883488, 0x5f0cd8a0, -0x08c4c231, 0xdbabee6e, 0xac686a3c, 0xd4e2b5e3, -0x747a399e, 0xc40b5f06, 0xea298387, 0x21d07cf0, -0x51fce4d8, 0x68044635, 0x10a5ffb3, 0x5298f28c, -0x906a8d2f, 0xa1c8fda2, 0x543e77c7, 0xf8ece9a9, -0x63ed3519, 0xb10c7f4d, 0x04c140ca, 0xd91343fe, -0x9cb4229f, 0x068e8f29, 0x77ec5ea3, 0x0238ac70, -0xd550fdd4, 0xda35bd00, 0x6ab6daf7, 0x6411bd0b, -0x657771ef, 0xe41b9cc9, 0xd3fc46ac, 0xe3562add, -0x6799cce2, 0x25b911e5, 0x50a1d2c8, 0x12ca2a68, -0x136e4bf0, 0x23c049e1, 0x1910cc00, 0xdeb236de, -0x0b9c05dd, 0x6a02b30d, 0xc6fe586b, 0x3d3e45a7, -0x2f22a744, 0x54773926, 0xec0bbc4d, 0x48df3c56, -0x6e3c5d21, 0xfbd2ff57, 0xea2d9bc4, 0x4f52996c, -0xfc81629c, 0xfdc01172, 0x1d953584, 0x63dada41, -0xb6cd3a92, 0x01c070fb, 0x73a6a71e, 0xe5c02fda, -0xfa188df8, 0x633c1650, 0xc8db25c4, 0xaf1f9350, -0x0c74858b, 0xd5bebe13, 0xc6c32a82, 0xbe86fba1, -0x8bf03e83, 0x0f9e7689, 0xab4a988a, 0xd115cc46, -0x4f0268f9, 0x36af63d7, 0x9016f26d, 0xc5abfa8d, -0x46718964, 0x8d6f297a, 0xfb7e84de, 0x72f4563f, -0x93ec2c9d, 0xc1dd760b, 0xd2c167a9, 0x96440c3f, -0xfc6cb1c3, 0x1d72d321, 0x386e6cb9, 0xb173c629, -0x1a876416, 0x388f6f6a, 0x9f45966a, 0x1f015d4c, -0x4c033d79, 0x9fde00f0, 0x44def7c5, 0x7cd0b2a9, -0x85c4ca89, 0x07db2622, 0x731efeba, 0xa9a66091, -0xd4ed0fff, 0x7660ab08, 0x983d6077, 0x1a0ea34a, -0xd4548ba0, 0x66c9b8f2, 0x35173c26, 0xeeaa588d, -0x5c36c76d, 0xd4c88651, 0xe18303d4, 0x824d8807, -0x7b4dd2bd, 0x71719dc5, 0x19c23f5c, 0xc06f19b8, -0xa20fa726, 0xd701ee20, 0x62ca2add, 0x6b8d8f6c, -0x13204a15, 0x5bc46207, 0x9b13c41b, 0x8cbf9545, -0x72faa845, 0xa97a0e66, 0x90acd440, 0x638f02ef, -0xaf944eeb, 0xd11c44c0, 0x7d44f7ae, 0xe2293ba0, -0x45b04be9, 0xb8d14f4f, 0x269e26a9, 0xba24ec3e, -0x9e905c28, 0x5705c02b, 0x8e9b485b, 0x159d2572, -0x2fd0efc9, 0x20d0a053, 0xf9223304, 0xf3791ec6, -0x7620b3e3, 0x871cb096, 0x03c47ccb, 0x45c1e6e4, -0xe9459554, 0x93b06148, 0xe632e819, 0xfc0dae00, -0xa89b13d4, 0x883d2d43, 0x8d67ef3b, 0xc7322610, -0x622b4285, 0x46bfdaed, 0x66042c6a, 0x657249a6, -0x7ad10b29, 0x241c4267, 0x80c7860e, 0xeb3d5887, -0xf939d68c, 0x9ff51d77, 0x84fb0d54, 0x961e1142, -0x8699a335, 0xafea31ac, 0x9ed69870, 0x0d9cedfd, -0x176bfba8, 0x66a83c18, 0xf002bf7e, 0x65f89946, -0x9d25e0f7, 0x84b9c9f2, 0x7537f464, 0xe65c15db, -0x1c5c4435, 0xfab634da, 0x6fc6b100, 0xa2691637, -0x104b7f83, 0x4e07905f, 0x8d024265, 0x85a32eb3, -0xcb57a035, 0x7f4c5350, 0x30602409, 0x0ea22684, -0x52a31ef4, 0x98b176c5, 0x88cf84eb, 0xe2735407, -0xdbb18422, 0xbd24b47b, 0x972b7446, 0x0cffacd4, -0xd8a24e33, 0xc97871ce, 0x2f49bde0, 0x143f6db1, -0x32a5ccd0, 0x55b4bdeb, 0x6c9031de, 0x358c8f66, -0x6c7d431f, 0xa6f7dbbd, 0x87b6a229, 0xd4cebd19, -0x663ebb0c, 0x7a98d7ea, 0xbb5aa19a, 0xafc7a8d6, -0xe514d8f9, 0x0cc34af0, 0xe86257b2, 0xbcc81965, -/* 1376-m8069547.inc */ -0x00000001, 0x00000047, 0x11092004, 0x00000695, -0xa0324f3b, 0x00000001, 0x00000080, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x0c66a43e, 0x6fdc369b, 0x040ec151, 0xaabfb472, -0xf556e326, 0x3739dbc6, 0x4a14fd4e, 0xbe510a9c, -0xe70bf636, 0xdc6858b7, 0xf484a559, 0x24802e67, -0x63d69186, 0x15fdd673, 0x603020db, 0x9f57bd55, -0x8840215e, 0xcb23ca23, 0xa97dbfc7, 0x714c433f, -0xaacc8d9a, 0x46531bfd, 0xbd635f18, 0x429f7a10, -0xa502e1d3, 0x3ba2b6f0, 0xa4f6ca99, 0x0d708861, -0x1b574fe7, 0x485227a4, 0x18d05856, 0x8db5dcaf, -0xff1a7545, 0x6866a2ee, 0xc4aa8c37, 0x0080d8c6, -0xc1cf82f0, 0x2d396ed0, 0x859c1832, 0xa2e48a7e, -0xe71f5f78, 0x87fb8357, 0xa4322cc7, 0x846d5040, -0xdb286962, 0x5b18ed9d, 0xf5f81e6d, 0x959e87d7, -0x8806335e, 0x3c4762a1, 0x21ba50ff, 0x85489e1c, -0x96128b82, 0xa9857202, 0x803eac9e, 0xea6553f6, -0x8bd2d706, 0xeb28a554, 0xa7dfda72, 0xa4059899, -0x88f93cb5, 0x50e1b23b, 0x8dc74029, 0xd9872ffd, -0x4f6202ed, 0xe396c354, 0xa35b81d1, 0xf8701e2c, -0xf33b0f6f, 0xbda6e8f3, 0x9e3d786e, 0xaf4d40fa, -0x35859710, 0x7e460cb0, 0xfdd99345, 0x78f0a992, -0x3794cb3e, 0x4f402d47, 0xaea20bf4, 0xa50aabd1, -0x196885ee, 0xb2c84221, 0x14bc44a0, 0x326479c3, -0x687b0dc6, 0xbc2151d4, 0x686c6647, 0x6ff095b9, -0x4af5886b, 0x5a49ac48, 0xe1f7533d, 0x24924e25, -0x5eb4d9e6, 0x7b8ac82f, 0xac929b2b, 0x7482c790, -0x788a9491, 0x925b2591, 0xb4f3cce2, 0xb91f1662, -0xd5fb65d4, 0x549aae06, 0x93f073b4, 0xcc26dc33, -0x05c41dd6, 0x660c52d8, 0xcd4eeee4, 0x87939004, -0x532c864c, 0x0e94c295, 0x0d2d2251, 0xd6d88925, -0x9e9dc21a, 0xa6bf396b, 0x911daebd, 0x525e105e, -0x1d352b27, 0xdcadd5e1, 0x27d95dec, 0x35726567, -0x03836c6f, 0x4d343b99, 0xa7a18015, 0x23d37d74, -0x632d35c7, 0x00035697, 0x07e8bab5, 0xf7cf3a02, -0x068706f6, 0xdfa171be, 0x3aa2c1c1, 0x5a1d954e, -0xb71b6c1f, 0xbe29fbcf, 0x8de6b15e, 0xf41460cb, -0x18fd0cea, 0x5bedf3f9, 0xd2f177f2, 0x77518f57, -0xe3666a03, 0xe24637e3, 0x0f38deb3, 0x293dc567, -0xfe5e1a23, 0x5177d656, 0x2a9e259b, 0x49fb90bc, -0x6c865d17, 0xde4c3fc1, 0x5c3cdf10, 0x2b4d5c6e, -0xeff3d6a5, 0x8bb9bd18, 0x9ee723b1, 0xbc12ba57, -0x8caa211f, 0xdc83bcdf, 0x208a9ba4, 0xfca21241, -0xc6a6eefe, 0xded5aed8, 0x73d3ae48, 0xa24f5cb7, -0xa8f2da15, 0x63cfd2e7, 0x857c975f, 0x7b0d09a4, -0xe521f32c, 0x05cc1628, 0xb5c210e0, 0x9261386c, -0x447fe66a, 0x4dcf4214, 0xd0be6ce9, 0x7939347f, -0x02deebcd, 0x89a90ff9, 0x8b8c5d30, 0xf674503f, -0xd4c93e7e, 0xfd995ed2, 0xd44dc317, 0xf43a2742, -0xebfdeaa7, 0xa57ab877, 0x8b5feddc, 0x84fa6995, -0xa683f7fe, 0x3f075a90, 0x904711b4, 0xe4f402e9, -0xee714efe, 0xa751db10, 0x4f259590, 0xfebea582, -0x3a6c0d66, 0x25a452a3, 0xd022c348, 0xdc24602a, -0x58716977, 0xf6a70e92, 0xfc82cf6e, 0xae09cca1, -0xa20e842d, 0x15e048d2, 0x96f8fefd, 0xd94fe184, -0x25316b80, 0xb751593d, 0x8aa614c1, 0x4982c5e5, -0x6d211294, 0x7b22c753, 0xc29d3f2c, 0x4bcb73f5, -0x370b4a68, 0x385b671f, 0xc2a023c8, 0x9043117e, -0x76c07ae3, 0x7c5968cd, 0xf2a48406, 0x5ea944d4, -0x0e9e6382, 0x4aaedda5, 0xecb4f191, 0xd14cfab3, -0xf43e8cd5, 0x0946e811, 0x17f743bf, 0xa6665715, -0x586fdb03, 0xfe41799a, 0x9c5e72fa, 0x585128f4, -0xd71618ac, 0xc87934bd, 0xe96101d1, 0x55d1976c, -0x471c8505, 0x7a36d839, 0x5d62a9ee, 0xf3c54a8a, -0xa2be15d9, 0x244087c9, 0x042c8037, 0x23224689, -0x281c5d73, 0x2139ecfc, 0xffb8bc8a, 0x834fdd11, -0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, 0x4ae2dbda, -0x86d90089, 0x6675dfce, 0x48876262, 0xcec72538, -0x11dc5c80, 0x86a730f9, 0x313565c9, 0xe3e5be11, -0x106d7cce, 0x752b8be2, 0x3d00a5bc, 0xe6f70e95, -0x44447ac8, 0x600df30c, 0x8335ac3b, 0x8816ddee, -0x700982fe, 0xee495741, 0x48c7e81c, 0xa3d55da2, -0xb0172982, 0x70ab2158, 0xd4460621, 0x3a9e528b, -0x59b18a7b, 0xf4dabc4c, 0xa8454763, 0x70877bb6, -0x66005c97, 0xaf292c06, 0x7b843db1, 0xf343b59b, -0x25cdc7b5, 0xa41da617, 0x9e9d895e, 0xc936f475, -0x7270925a, 0x30024230, 0x8e72f53d, 0x2b6c1b6f, -0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, 0xaf377cc1, -0xbff09a78, 0x4b4e0814, 0x95a0b2c1, 0x270398de, -0x201fca94, 0x2a032a4f, 0x131542b4, 0x0d7306da, -0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, 0xa3b3a991, -0x17ee60c2, 0x852c0b8d, 0x11e5853a, 0x762002a7, -0x92c5311d, 0x0d4bf7e1, 0xfffec870, 0xe3d35e5b, -0xff6ecfb9, 0xdedae6ff, 0x0111a772, 0x9808e780, -0x29c336e8, 0xe9bc05df, 0x5bedde11, 0x945565af, -0xaff808fe, 0x87e3423d, 0x4de6f98f, 0x93b4adef, -0xbf704fa4, 0x09120e91, 0xd54f3692, 0xdf8eab1e, -0xfabbf59c, 0xe74318be, 0xaab87ffc, 0x29fa791c, -0xe3915552, 0xa652cb9b, 0xa1252e74, 0xb35b723b, -0x542aa28b, 0x12fcc5b0, 0x3941f962, 0x82bcc6cc, -0x47b11974, 0xb821611f, 0x78b34250, 0xf1be5659, -0x561b9e61, 0x6f3bd501, 0x584e6f5c, 0xd54ed547, -0xacebcd21, 0x7b5ff816, 0xb64ad233, 0x9f2f330d, -0x69fb1ece, 0xac8710dd, 0x58dc6c60, 0x9bee6139, -0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, 0xa733274f, -0x884d9b55, 0x42b08b63, 0xafa54a74, 0x1c7ccf64, -0x93a20191, 0xaaa3132e, 0xc69831d1, 0x54634889, -0xfbfe3efc, 0xd3cf68d4, 0x302e3117, 0xf5693131, -0xc3ce8c6c, 0x1f03cd89, 0x6243334c, 0xf16bc80f, -0xdca5f130, 0xcb2cd956, 0x4c1bb421, 0xe8de533c, -0x7f86703a, 0x29aa897e, 0xdd54acad, 0x76b2f2ae, -0x7ef82b71, 0x2e30970b, 0xba402597, 0x9a653ab4, -0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, 0x2363d147, -0x5327289a, 0xe89229f3, 0xd63a535c, 0x7efe9273, -0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, 0x1b9c7bfe, -0x5d14b3de, 0x54d575fb, 0x6d65db4c, 0x95648b7f, -0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, 0x8488a45f, -0x8ebc2932, 0xd4767316, 0x3e8c4b8a, 0xbab7402c, -0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, 0xc88528e9, -0x4b2e4e8f, 0xdd938b86, 0x0c964f98, 0xfc88d480, -0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, 0x4d40b3b3, -0xcf203155, 0x0d2fa621, 0x752d2c58, 0xb12bac12, -0x1e7e8c23, 0x94215d54, 0x9854a71c, 0x4de63c64, -0x7a012529, 0x9c171f8d, 0x9e71def7, 0x3bd17d50, -0x11f175d9, 0xec78abf3, 0x7b529eee, 0xd3a69fc3, -0x5b718676, 0x58214d29, 0xa8bd2c34, 0x41ea00ab, -0xa03f64d6, 0x4ee342b0, 0x32b1e444, 0x1c1801a4, -0xc8424702, 0x334a7e35, 0x50cf1543, 0x3b22b495, -0x88683776, 0x8e2e0154, 0x6155c033, 0x4e2fa6ac, -0x42ace700, 0x8d64f97c, 0xaf9ced17, 0xb2a5cb92, -0xa558582d, 0x88705de7, 0x9e528d59, 0x84bd45e4, -0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, 0x10462123, -0x30080f7d, 0xb346cd81, 0x0049c396, 0x4e24165f, -0xa7c66809, 0x2e60bdcf, 0xaad70a08, 0xa73ea713, -0xe28f97a7, 0x283a9eab, 0xd4366489, 0xe776f963, -0x64ffa8ae, 0xde717b50, 0xbd2ca2b5, 0x3bae5f6d, -0x8d2bbef1, 0x7e9181e6, 0xf06aa121, 0xd06b2d20, -0xa83ea826, 0xef935e4f, 0xdfd27456, 0xa3451468, -/* 386-MU16600a.inc */ -0x00000001, 0x0000000a, 0x05051999, 0x00000660, -0x05b795f4, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x4cce67de, 0xa5bf8c3f, 0x32a4809d, 0x834da372, -0xebefca4e, 0x2434e86d, 0xfd5a5db8, 0x8e6b398d, -0x55992335, 0xa4332cb1, 0xb83d2dc0, 0x5cf2827b, -0xc60d321e, 0xb810d991, 0x10bef54b, 0xa78c0441, -0xe4e17eac, 0x286b11d1, 0xa671919a, 0xd250d9c4, -0x379ee265, 0xc2839bcb, 0xf856f68a, 0x2e7a8104, -0xda21efb6, 0xccdb7c08, 0x2c02f111, 0xfa6d54f5, -0x94ba6c6e, 0x2f1e8d3b, 0xff31de8f, 0xf0eb4e4a, -0x5ef28f35, 0x80e05fd5, 0xd7b633ca, 0x51eb2ac5, -0x97ed41ac, 0xc05679e5, 0x79080c9e, 0xb9d1aa9a, -0x92ae8b93, 0x5d309b94, 0x94462097, 0xab6cc687, -0x14d3570a, 0xf71b9f19, 0xba5782df, 0x767bb600, -0x8ce6d620, 0xbc378afb, 0x0421dd6a, 0xfd2ce01c, -0xea774aae, 0x7f59277e, 0xcc25d565, 0xf43bc0e0, -0x4bad25ad, 0xf5881f9c, 0xb08fcd01, 0x2ad9861d, -0xe6adc0dd, 0xa7a986b7, 0x475fb8ef, 0xaa145653, -0x8c255f6a, 0x7bdc94c9, 0xb4190639, 0x9c2375e7, -0x4339888b, 0xe3c7bae1, 0x885d7df1, 0x5e66da0d, -0xcccb82eb, 0xeecc36ea, 0x260cfc25, 0xfec3a6f3, -0xf090487e, 0x369a58cb, 0xc73ebd0b, 0xe53b8eeb, -0x5cc40a0e, 0x838f0ef8, 0x8465b6c5, 0x72892bfd, -0x84fd5959, 0xa3546de5, 0x754bd7b0, 0xc033d6ca, -0xfe244df9, 0x64d5f3bc, 0xd85fee9a, 0x904169d0, -0x24143452, 0xe41530fe, 0xb5ad3d6a, 0x5f17b744, -0x8a8bd14c, 0x97e3c34d, 0x7f859df5, 0xcf5f5ee3, -0xbea2e386, 0x19eecd45, 0x89bad6bc, 0xbbae906a, -0x78d839f7, 0xa7b9cb2b, 0xb46b1935, 0x75181e1b, -0xea49e613, 0xe9584bc5, 0x33c0e65a, 0xfe24a9c8, -0x98ffa853, 0x41c32d55, 0x8e17f7fc, 0xe65d6dfb, -0x6e39614f, 0xf9ca105c, 0xc9ce257b, 0x0c75a137, -0xabbc7e07, 0x8857f4d5, 0x1473c95d, 0xa8666dcb, -0xf9ef2a6a, 0x77d6e876, 0xec079135, 0xbcf41ae9, -0x05d3a1eb, 0x9e17f380, 0xc4d7fb7a, 0x17d0a44e, -0x84878cf6, 0xfb7de61f, 0x488930a8, 0xd84d601a, -0xb0f12609, 0x1292c5bb, 0x9e9af007, 0xb40da879, -0x6d28dac9, 0x87b9dfde, 0xdf0a960c, 0x520e698e, -0xb3dedc2d, 0xd05b3e4f, 0x1ed592cb, 0x9197efc4, -0xf62b2b8f, 0x09c440f2, 0xea8c3f00, 0xe2755129, -0x19c1a016, 0xbbf776c4, 0xad622a16, 0x0c474162, -0x99b8c2b5, 0x86ca4635, 0x34c1942e, 0x9989309b, -0x9976d3a0, 0x5217db64, 0x802afec6, 0xf606b06d, -0x30d7019f, 0xf5648b65, 0xc710830d, 0x3b24b040, -0xa552be27, 0xf7225873, 0x4502fca7, 0xb15183a5, -0x9ccc29df, 0x96f66773, 0x18534ce5, 0xb15d8a7e, -0xb8a2e9ae, 0x2491fcf9, 0xf58b364b, 0x7e96b5e2, -0x108ef9ba, 0x370c5585, 0x2000847c, 0x4738ffe6, -0x5c88c789, 0x73657dd9, 0x406f3d28, 0x0e33ea60, -0x369376bc, 0x39b123a8, 0x6800959b, 0x2f3dea60, -0x7aed7374, 0x0bfdb4e1, 0x00de8ee7, 0x036c11c1, -0x77e82217, 0xc295c17c, 0x1a255852, 0xdaabd2c7, -0xb54a14ed, 0x34338868, 0x82c38010, 0xe221b872, -0x519bc47a, 0x3dd7df3b, 0x82d0f932, 0xd766c9c9, -0x566ba389, 0xa994de3d, 0xe15e1bdb, 0xc3bdb882, -0xa542a8de, 0xf7e32a2c, 0x93be1c7e, 0xf04633d2, -0x809ded28, 0x35361629, 0x57e56e43, 0xa47e8434, -0x965d1c9b, 0x7c6aed87, 0x7069f4e3, 0x9734a6e2, -0xca52becf, 0x033b7c7c, 0xf33a503d, 0x641ab77b, -0x23bf89fc, 0x21e85f51, 0xfbdf410d, 0x5e52b172, -0xfa6b2b47, 0xbcb4e5a8, 0x00f51032, 0x3dc21da8, -0x55021389, 0xb5c017ea, 0x46b898ec, 0x52cdb1bf, -0x99f5f480, 0xf303a3de, 0x84e3c67f, 0x1b46dd60, -0x141448a3, 0xb8b977ad, 0xe7996448, 0x1fa609a1, -0xa9a00a94, 0x1fc40ca5, 0x5685ee87, 0x061c73dd, -0xee71c124, 0xe4599538, 0xa8700f90, 0xf5a9849a, -0x3effe339, 0x790e00f5, 0x6e3843e0, 0xd9301376, -0x3b54bbd8, 0x79c68090, 0x1dd1fe0f, 0x02602b35, -0xa20dce30, 0x7ec589db, 0x9d504ad2, 0x2cc84db5, -0x8b6bb987, 0x4fa45bc3, 0x2dd5f507, 0xe0cd37f7, -0x043e9d49, 0x7652025b, 0xb6a429a4, 0x36ac261f, -0x08f1fcf9, 0x3219dad1, 0x70119bc3, 0xf977976c, -0xe0872445, 0xca99977c, 0xee8b289e, 0x2a20923f, -0xd79e0af2, 0x42cdc3c9, 0x8d9bfb8c, 0xe265681a, -0x5b61b8ef, 0x6c01c84b, 0x3adc3209, 0x97e9f99c, -0x74a22a40, 0x58e46eae, 0xa107ffa8, 0xbf1d7a89, -0xa2bfb311, 0x3071e5cb, 0xb2eb522b, 0xce4fb5be, -0x16b6e3a8, 0x6106458a, 0x966df562, 0xa0a3d140, -0x4e19ec71, 0x334e9307, 0xef8f374a, 0x3918922e, -0x0e1281f3, 0xbd554469, 0x8b640c00, 0xe57f20cb, -0xbe6440d6, 0x357e4505, 0x6b1db1b7, 0xc1874c75, -0x246891e7, 0xa57d794b, 0x2effd4c9, 0x99b64fae, -0x7e140e0a, 0xfd65c2ce, 0xe16b33b1, 0x2e681417, -0xfcf1624c, 0x869f843f, 0x21d8c306, 0xd6cff670, -0xa123b3d3, 0xb6eba56c, 0xafcf5185, 0x83fa0a9e, -0x746483ea, 0x63641749, 0x55ffac01, 0x23cfdf9d, -0x250613fb, 0x5377d7e5, 0x35224177, 0x6407c393, -0x00f2498f, 0x33f07673, 0x6f1046fe, 0xd53b87bc, -0x50b01249, 0xe9ed1741, 0x31b85bd1, 0x6dd5c47d, -0x125647fb, 0x45e9f7c3, 0x221ead49, 0x6d1d9d53, -0x149a1485, 0x16b67287, 0x27649add, 0x9e2c04e2, -0x71c3d5f9, 0x9c778341, 0x95bfda26, 0xfaf580ec, -0x6ab88278, 0x5bb3cac1, 0xb9801ade, 0xaf4b6e4f, -0xa1f18c51, 0x504012f7, 0xc20a2ae0, 0x7bcfc50d, -0xb68245e8, 0x805052f4, 0x0ce09a23, 0x79005c46, -0x3f15c5cb, 0xef6732ec, 0xd095debe, 0x3a2eae3e, -0x24ee4a9f, 0xf16d102b, 0x27d9f8ef, 0x508a1c57, -0x5ee61f2f, 0xdd958128, 0x7c759709, 0x2e18b30a, -0x0c6ffe63, 0x2174596f, 0x5245b98b, 0x68b46e00, -0xf097f744, 0xb3f02db2, 0x7241d709, 0x5d13fbf7, -0x4cfdd101, 0xe84957c4, 0x7578803c, 0x31c402cf, -0x1ce1eed7, 0xa1197a97, 0xb00f8403, 0x3a25e38d, -0xb011b436, 0xe3538636, 0x7c459351, 0xb97bfe4c, -0xa5f968a9, 0xc93d3bd9, 0xe5736542, 0x05d67655, -0x489c9bd6, 0xd57731cd, 0xb3075b0d, 0x0b247601, -0x47960987, 0xa5fe5782, 0xd387a40a, 0x2e29f2d3, -0xd317fda2, 0x071ff98b, 0x2791e1b9, 0x8f83f16e, -0x16ec3837, 0x66844598, 0xacde4baa, 0xaea64994, -0x15765169, 0xa62c4e7e, 0x093a539d, 0x6cdfea23, -0xe2b19d80, 0x4f729028, 0x758dc967, 0x70519d1f, -0x3f3290e8, 0x2605f3ab, 0x08d67f03, 0xe6fd4ba4, -0x931da42d, 0x1af05337, 0x632c6c86, 0xa9b3c1fa, -0x493db7f1, 0x9f917e1d, 0xb8bd542f, 0xbf23f37c, -0x89e7f900, 0x58a3bccd, 0x3cd1e651, 0x3ed0beae, -0x56104447, 0x3137d4d9, 0xecc5656a, 0x94183130, -0x02420ac9, 0xcdb38cf2, 0xbb11ca10, 0x212e4bc5, -0x11a0b5b3, 0x5edbb0e9, 0x1a4666ff, 0x42224649, -0x70e68a4a, 0xd4c595ac, 0xe8040d0c, 0xafd353c3, -0x11640dfb, 0x71e61d50, 0xb80faf34, 0x4303e651, -0xe405ea4e, 0xbe003b08, 0x7f3d868d, 0x17467335, -0x345050eb, 0xd939f71e, 0x9e7db651, 0x0e08b6cd, -0x6359df9f, 0x2f07f30b, 0x4dd66fd8, 0xb18b789d, -0x02da044b, 0x893e6d58, 0x6764969e, 0x77f1cf45, -0x5019e0fd, 0x8303c5bb, 0x9261e436, 0x662be487, -0x0efcafdf, 0x5bda8102, 0xce198c62, 0x13083943, -0xc4f9a736, 0x2a9acd22, 0x5cf660f4, 0x0a2c6979, -0x54265d72, 0x7072852a, 0x0f7475e7, 0x8f12704c, -/* 728-MU168314.inc */ -0x00000001, 0x00000014, 0x02062001, 0x00000683, -0x0976fd98, 0x00000001, 0x00000010, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xecb2c3c0, 0x2f2f34ff, 0xf7f09bf7, 0xf73c6dec, -0x5d5d0357, 0x35b7471f, 0xb9bb76d7, 0xca8f0786, -0x865fde5d, 0xa0b56c34, 0x147ce4d2, 0x887513d6, -0x341b2ea6, 0x13d1c7f9, 0x31df291b, 0xf8fa9c6a, -0x7667e2e4, 0xb3af02ec, 0xa39a324c, 0xe5af95cc, -0x15012f56, 0x4cead851, 0x81169c7a, 0xbabb599e, -0x31bf0fb7, 0xba2207bf, 0x80ab0c02, 0x4e8794dc, -0xe7e8bf7d, 0xd22029cc, 0x0e687b49, 0x2f6d8e80, -0x57ac268f, 0xe309b495, 0x3aa2a1e1, 0xcc57e97f, -0x8fa37b62, 0x1f735044, 0x2278d1c7, 0xe823c65b, -0xe9dd8511, 0xf89d5743, 0x23e97687, 0x43ce8e2b, -0x61f3e82d, 0xaa139876, 0x097eeb30, 0x6742076d, -0x51761f35, 0x2a9edf6c, 0xbfb9178e, 0x58d479a2, -0x8b73c7b1, 0xf208fb08, 0xef61b94e, 0x76915275, -0xd38ea2f3, 0xa2e97430, 0x3caa8f8b, 0xe2e8d358, -0x8b6073a9, 0x6de2d03d, 0xeb1ac52f, 0x3f6e4a64, -0xdcd1e247, 0xadc6efd6, 0x4a3ca83c, 0xaf990f62, -0xc1926a48, 0x71f368ae, 0x40d90f85, 0xc53f889c, -0xb718c45b, 0x50becb4a, 0xcb3bdfcc, 0xb1f409e0, -0xf82fcf13, 0x52d09c8a, 0xe6c32fd1, 0xecbaeb34, -0x9f91fe0d, 0x67bb864c, 0x9008994a, 0x93bb80b4, -0xc2ccdc09, 0x45bc872d, 0x17a59be7, 0xe1397edd, -0x4b8d55b4, 0x5b0c3be8, 0x3d6b8743, 0xb518b764, -0x4fa6b830, 0x831aac92, 0x7809a29e, 0x1f3d6b50, -0x391a4d09, 0x95546b86, 0xf862139d, 0x99905866, -0xe502c92b, 0x3baedc13, 0x9dfb6c40, 0xf405d944, -0xd1e5db67, 0xb457ee4a, 0xf26946c8, 0x5dcd4b24, -0x9636e6c5, 0x516b6b8b, 0x4a53b969, 0x78a6e461, -0x3eca65cf, 0x8a839e5a, 0x1c52d122, 0x4abef8e9, -0xb4ade44f, 0x372d8c0a, 0xb5d03cce, 0x1f7953b2, -0xec4d8789, 0xa7ebf47d, 0x6f541a16, 0xe32b0e17, -0x80eec93a, 0xc9e1c98f, 0x6ec7f6c0, 0x490b7bc2, -0xd21810b1, 0x28dbdae1, 0x56015f0d, 0x0c501a66, -0xd32d05e6, 0x9e1ccf99, 0x51cd8bc4, 0x054b30a9, -0xcd2719d1, 0x050317cc, 0x50843724, 0x6c4f8527, -0x4c156bff, 0x2969c98b, 0x907ef014, 0x604b7467, -0x0f2cc314, 0x6ce6e896, 0xf30a75ab, 0x064ad5c2, -0x7908978c, 0xf4b13439, 0xe1597cb2, 0x201443f9, -0x93d8b45f, 0xa6351d99, 0xd2b63a84, 0xdd754e89, -0x600cb59c, 0x1de6b866, 0x7a616644, 0x8008893f, -0x31f36621, 0x03622d8e, 0xb2d6aaa7, 0x9096bc8b, -0xeee48428, 0xde1ce3d4, 0x23079f86, 0xe413e3c5, -0xd61a1fc2, 0x2ea4693e, 0x464f8149, 0x6425ef61, -0x86d22b4c, 0xfeec7a8f, 0x9c43a3a3, 0x8b626e93, -0x8af6b054, 0x5e23dcd2, 0x42588e0b, 0xdc877df4, -0x99c547c1, 0x80e6e535, 0x04d360dc, 0x6a28a33e, -0x688eaf7b, 0x8ee2635e, 0x4a81a8c1, 0xf65afada, -0xc6553184, 0x28324872, 0x73f78589, 0x76c000d5, -0xdcb279fe, 0xc6463a1e, 0xeb659f7f, 0xf75311f8, -0xeb4b55d5, 0x4edb5c0d, 0x2b43e7f3, 0x2bc0a3f0, -0xfbe0127e, 0xf76202ab, 0x7bf2a3a7, 0xbae3f575, -0xce6725ff, 0x51feb2ab, 0x350951a0, 0x0a399b8a, -0x33421704, 0x1adce9d4, 0x4215d302, 0x342d8706, -0xd15c92fd, 0x86ac2b2c, 0xfe927dd9, 0x2849d688, -0xfc8066d4, 0xd53b8c1e, 0xad2a7308, 0x291c1ec1, -0xad4f142f, 0x1cca5898, 0xed2c3983, 0x5eb48da7, -0x9e32bcf9, 0xab09c7e9, 0x5c224120, 0x5b3ad2c5, -0xe060df30, 0x9e4f59f6, 0xa5499f2f, 0x2e33f375, -0x08bcfb76, 0x3d1c8e24, 0x1ccdae98, 0x80d27375, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 551-MU168308.inc */ -0x00000001, 0x00000008, 0x10151999, 0x00000683, -0x2942e387, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x3838d964, 0x902da5bd, 0x291242e7, 0x8b611e36, -0xa1f50719, 0x04db741d, 0xf20fd434, 0x81bff663, -0x55f9d881, 0xd165ba1f, 0x8273456e, 0x5ea792cd, -0xb180dfd7, 0x8e132720, 0x5158a07f, 0x974c8cac, -0xe985a9c2, 0x77116988, 0x9763ed80, 0xee285274, -0x54ef293d, 0x82e07a61, 0xe206995a, 0x6a1ea44c, -0xa048dbac, 0xc5079ea0, 0x6e98bb25, 0xa7fe9390, -0xab8eb8b3, 0x676d95c5, 0xa3717b10, 0x88cbb1a0, -0x063c9bb1, 0x8ea06eb7, 0x8a413fe1, 0x06cee3b4, -0xa81517f4, 0x95969e5d, 0x0c461076, 0x9084e3c0, -0xb1b2d589, 0x23f4d34f, 0x9f0f3310, 0xbc405c78, -0x0a7f579b, 0x9387e317, 0x97f3842c, 0x21484298, -0x92fecf31, 0xb5f1b4e6, 0x28d7a97d, 0x90028586, -0x9fe33718, 0x29cd7b3c, 0xbb71c9a8, 0xbe74ac41, -0x28c78336, 0x93a64453, 0xb6aa1d3a, 0x2fff3d35, -0xb8819e2d, 0xbe096062, 0x08b9d869, 0x90246df3, -0xb147c8ca, 0x2e71130f, 0x90c3d7fa, 0xb84820d8, -0x0cfbb1d9, 0x90f2bf7e, 0x9c47e13b, 0x2388d7c2, -0x94ee5ce5, 0xb080b40c, 0x2326bf4d, 0x9375a9a4, -0x9ad8380f, 0x271f5e2c, 0xb5f1de30, 0xbdffd0b8, -0x284ffe0b, 0x9409e2a5, 0xb3a58879, 0x28818b7f, -0xbd91db97, 0xb2abf842, 0x0d2d2b0a, 0x91ecf85d, -0xb91b2eb0, 0x2563e378, 0x9fa7639f, 0xbe81b8c6, -0x0fb5ea70, 0x94f85ab0, 0x97953cc1, 0x2b3a73e2, -0x975d8522, 0xb404623b, 0x207c3245, 0x946c9cf5, -0x967675c6, 0x27aa8f92, 0xb8205a69, 0xb28fe6a9, -0x289b3ce6, 0x93cc869d, 0xb1972934, 0x259f9f02, -0xbea0891d, 0xbcff6fff, 0x07eaa51d, 0x9074834d, -0xb66c1195, 0x22bf078c, 0x995420f5, 0xb7e4e440, -0x03b6db68, 0x9256fe33, 0x908c92da, 0x23c2742b, -0x994aef66, 0xb282f279, 0x2e621d6a, 0x955c0d7a, -0x9a988b30, 0x29d7a2da, 0xb64a9f05, 0xb9fb5b99, -0x28771440, 0x92ee3a9c, 0xbf3fc296, 0x21782c1b, -0xbc2c0593, 0xbfd4f35d, 0x04cbbe43, 0x9fa34c64, -0xbe07f147, 0x29732e30, 0x9f67c5ac, 0xb2e4b75f, -0x04bc34ac, 0x9c9bbff2, 0x9ce62807, 0x2d049c9f, -0x96c1a09a, 0xb19cd8b6, 0x220b181a, 0x982f6389, -0x9070997f, 0x2796d439, 0xb15b5d2f, 0xb8cbd480, -0x2505dfa5, 0x9eab7bc6, 0xb8804227, 0x21c365a0, -0xb6ea7a60, 0xb78cc479, 0x0bd7cdee, 0x93bdaf54, -0xbf06d0c8, 0x2efc2f14, 0x9c50bc3d, 0xbe061fc9, -0x09b1d239, 0x9d108ef5, 0x93a927e3, 0x2de79820, -0x97ff4ab4, 0xba26921f, 0xd2747084, 0xed133b6b, -0x9074dc4c, 0x4e87f999, 0xd8a524e5, 0x03783ce8, -0x4ad8decf, 0x4374b184, 0x0770df64, 0x519e3279, -0x45c979ba, 0x1e7b128a, 0x65395e10, 0xa14f443b, -0x21a1ba1f, 0x8ea82043, 0x8f410b31, 0x4118599f, -0xa79dc4b4, 0x1ca5a94e, 0x496c8ea0, 0x54cd1f90, -0x1950bd4c, 0xb7e041b0, 0x528876e6, 0xe4c1bbad, -0xb1b9bd2f, 0xabd54c9e, 0xe99ab67a, 0x44016c9c, -0xaecbb239, 0x140e16e8, 0xc2538565, 0xa6719fd0, -0x99e70bf0, 0x3abdddbf, 0xabc89721, 0x8e1d1eec, -0x393b9ab4, 0xb031b8d5, 0x8da9d990, 0x79ff13ff, -0xb6d4035f, 0xcbaadfe5, 0x7bf570c0, 0x2e26f67e, -0xc804d983, 0xebb4f852, 0x2e94f0ae, 0xc0764840, -0xe575c6ca, 0x2206ad7c, 0xcdec956c, 0x591a50fc, -0x2945c2ee, 0x758abe31, 0x581d5a78, 0x2edc794a, -0x7d2f7b02, 0x53a4f6b3, 0x2a3d7cfe, 0xa0326a10, -0x5c229fb9, 0xfaefcdd9, 0x468143c7, 0x0e2f860c, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 434-MU165140.inc */ -0x00000001, 0x00000040, 0x05251999, 0x00000651, -0xf400b4ac, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x978e6872, 0x4a954835, 0x53c01813, 0xdcaa7300, -0xd8e79e18, 0x93eacfcb, 0xb49d8293, 0x171068f6, -0x0697234d, 0xbc011718, 0x034c178c, 0x98c3d1c3, -0xee0ec142, 0x4e179169, 0x8a456d4c, 0x15a3f45c, -0x8ed57f11, 0x513f0ca7, 0x500b0ed8, 0x34fc5991, -0x58614871, 0xe03c8839, 0x66cd82e3, 0xd86d4bf4, -0x972e0f2b, 0x151eb98f, 0xcd569727, 0xe1da8c92, -0x65b6f7ca, 0xfbc0307b, 0x204cc2d5, 0xa8cb450d, -0x5aa46728, 0x107c287d, 0x6e52e62d, 0xf9c149b6, -0x3d0985dc, 0xe8fbee2b, 0x7ce7f886, 0x8afb1cb6, -0x9015e6fe, 0xf4aa5390, 0x7516d0b2, 0xeaf9dbfc, -0xdab704d9, 0x695a8a53, 0x7565bb58, 0x496ed34a, -0x25c25f1e, 0xcc9b0cba, 0x660cbd00, 0x6e929aee, -0x57f34393, 0x624ff648, 0x80228d01, 0x72843de0, -0xb1d435a8, 0xed3668d2, 0xfd8464fd, 0x31e001c3, -0x759930ed, 0x9603c659, 0x400cfd6a, 0x5f419e25, -0x4006fa37, 0x2e537230, 0x21353219, 0x84cbcde5, -0x1782e581, 0xb88b9878, 0x34323718, 0x60a9a7bc, -0x2e014802, 0x66bf4487, 0x0801c652, 0x27361269, -0xa5311cb9, 0x658b21a5, 0x8c09eb3f, 0xe209566d, -0x0898b464, 0xc4a7867b, 0x275b6344, 0x0153a992, -0x4dfd837a, 0xf94d1c68, 0x40804d7b, 0x7edd120d, -0xdfd143f8, 0x60487686, 0xed802dfa, 0x1a5f81b2, -0x262fad43, 0x88fcb395, 0xf5c49176, 0x35e70380, -0x242ea915, 0xaed8703e, 0x82606b9b, 0xdf7a6064, -0x3c8f5acb, 0x22cf8e69, 0x6aba405d, 0xaed70597, -0x3e789182, 0xbad3f3fc, 0x61c293e0, 0xdf0fe4e9, -0x99574cb6, 0xc80a031d, 0x886a54a2, 0xeb22d96f, -0x08b18717, 0x32b63fce, 0x258998dc, 0xa93021e9, -0x2044456a, 0x6265412a, 0x6e1afa4f, 0x33756610, -0x4e87c563, 0xcfc5e188, 0xea6b47ad, 0xf4618fd5, -0xb0f3bfa7, 0xa1f6d887, 0x3fdb56e4, 0x19a96630, -0xb4e75181, 0x5054b634, 0xb7b6da3f, 0xd46d4142, -0x66500245, 0xfb8dab60, 0x4b61ac96, 0xe612ef3f, -0x75b98baf, 0x2a555089, 0xbed7cfd0, 0x71e743fb, -0x1dbcb21d, 0xacd80174, 0x30da97db, 0xae582b25, -0x1afb117f, 0x6ace51d5, 0xd9a0e1e5, 0xdeffbb76, -0x7f7f1890, 0xc7eaa76e, 0x7d325c0a, 0x036d7c35, -0xfb182347, 0xe649a621, 0x749b62bc, 0xdd9caced, -0x64313f94, 0x20660b45, 0xa2a5afbc, 0xdebcdf26, -0xfde5cfce, 0xffd981fc, 0x9f933d4c, 0x1ff8e311, -0x4ae23887, 0xe5921b7e, 0x5a93ac85, 0x46bfea57, -0x1b608a97, 0xeb9fe397, 0xd831c985, 0x40bf1cd9, -0x4de5b32a, 0xf06d3e3e, 0x36e0b4a6, 0x1e074f65, -0x2faa9139, 0x0d27ac70, 0xe6c0c61c, 0x361d2373, -0x1a4e0f0c, 0xd14aaf48, 0xcc3dd712, 0xb908cda3, -0x524be3d7, 0xd2623839, 0x2fd3346d, 0xd01f5f83, -0xea0196b5, 0xe38b8397, 0x28692010, 0xb145aa3e, -0x332075f5, 0x73e29850, 0x160f25e0, 0xeba33412, -0xbc7b06cb, 0x1db2194a, 0x0c7af328, 0xe438c0ca, -0xcbf83d1d, 0xad264b9e, 0x6d59bc34, 0x56925253, -0x478c85ce, 0x30e9ab37, 0x8f52dd68, 0xc3749bfc, -0xefe408cd, 0xc0690548, 0xdbeef174, 0x4faa1b0c, -0xf6cc7694, 0xec774556, 0xae02772a, 0x8e076839, -0xe13c8a74, 0xb82a927f, 0x578e05ca, 0x0701f5ec, -0x2b095f0c, 0x413ac09f, 0x274d4a87, 0x22412734, -0x6b525b89, 0x9759891e, 0x137e11ad, 0xf31f8a13, -0x7e763847, 0x74a68800, 0xe5d01275, 0x83c39d58, -0x2a78a748, 0x26a368ed, 0x0ddc2775, 0x20282b9f, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1102-m08f2739.inc */ -0x00000001, 0x00000039, 0x06042003, 0x00000f27, -0x823432ca, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x0000005e, 0x96f952a6, 0xaa368f02, -0x53d271e6, 0xf8286513, 0x484b4e9a, 0x9e0c09c2, -0x03b11314, 0xdfb67c98, 0xa2957d16, 0xf07f25de, -0xb84a2555, 0x72ec8b35, 0x3445c734, 0x7744f543, -0xc3da0cc0, 0xeb36172d, 0x8b2cf574, 0x29c867a2, -0xe79dfaf0, 0x54714bb5, 0x524dfb69, 0x0df65433, -0x0b95ec14, 0x3dc09ca2, 0x584ba068, 0x2aa558ce, -0x8cd679c8, 0x3b2609d0, 0xa06306d1, 0x80bfa93a, -0x482678d8, 0x0cdf1ce6, 0x5ec4e912, 0x8a19f7a6, -0x76f215be, 0x577d92c2, 0x479cd4ba, 0x63d1f415, -0x5af98bc5, 0x8889bb4f, 0x8e70943d, 0xb5528299, -0xfd63e347, 0x836fcfd0, 0x4951a701, 0xf4613cdb, -0xaa7c2f52, 0xa0e290c7, 0xf646a80b, 0xda5b5a03, -0x93517b47, 0x553d99d1, 0xafac198e, 0x486b6c6b, -0x4efa01d8, 0xdc6ce226, 0xdac3a149, 0x9b7cf27f, -0x6c6246a0, 0xb6055a39, 0xb68cc841, 0x87b6adee, -0x1c36edb4, 0x3ee76d20, 0xdbffab67, 0xed12fda6, -0xc1aff2f2, 0xc110932f, 0x0933ccfe, 0x58fa2281, -0x285d5ec1, 0xd05b216a, 0x76315645, 0x570c5c8f, -0x6cc52f1c, 0xaa977e52, 0x066f4e03, 0x812bfd2c, -0xbfbfd7a9, 0x70828199, 0x60182af7, 0x2a04e000, -0x30f413b7, 0x327cef32, 0xac73aa51, 0x7c418d9f, -0xf493ce0e, 0x6c14258d, 0xa5e2755e, 0xd39f994a, -0xee638b08, 0x55d50476, 0x9b7afc5c, 0x5da2ed13, -0xb75bf9f4, 0x2606c01d, 0x8a1d00eb, 0x0f73428f, -0xb29c4fb4, 0xac13e554, 0xa7648fe0, 0xbe56837b, -0xd34fa9ff, 0x59c855a2, 0x7d3cc7d7, 0xb5b0cb50, -0xe6626c0b, 0xf07010b7, 0xd8054587, 0x01a5327a, -0x3ceae28b, 0xa3bf737f, 0x3d1a37e7, 0x6ce48d1d, -0xc9d91222, 0x42f28fae, 0xe8dff3e4, 0xfd6898d0, -0xe772ab47, 0xbe452c12, 0xf188ee09, 0x08edb79c, -0xad4d48fb, 0x5cb75d1d, 0x251f4e02, 0x6b7bb6e3, -0xcada2f09, 0x536d74eb, 0xacfa627a, 0x51e2ffd2, -0xe4655767, 0x311dbbec, 0x1011b68a, 0x6f6e8deb, -0x4298665d, 0xc0522b3c, 0x2c3a19dc, 0x2c48f2ae, -0x49bca621, 0xb6a747fe, 0xa1606c81, 0x9b2a5318, -0x0ac114c3, 0xb5b35aa0, 0x3f4ee00d, 0x8b427e75, -0xb539fcd3, 0xa99fba84, 0x821fc647, 0xe0ac6d6e, -0x912f6f88, 0xf2009cd8, 0xb32330b3, 0xd0b80514, -0x6f25f157, 0xdba2f463, 0x88ef17d1, 0x147c5f21, -0x6e29cd75, 0xec14e5d1, 0xdcfffd24, 0xccc2c510, -0xe5e40798, 0xb24814e1, 0xaf0cdaf2, 0x825cf5e2, -0x12acac6b, 0x439c5f36, 0x0c533619, 0x8e776e71, -0x319b44f5, 0x19c0b404, 0x54111b2a, 0x6a767513, -0xb16944ef, 0x30ef18ce, 0x85df0862, 0x0737ff49, -0x77fe06f2, 0xb2de0d2f, 0x71625e95, 0xc722c5a2, -0x03b401a9, 0xe8b030b4, 0x7f9e62ab, 0xbff8c966, -0x726bfeca, 0x6adf3831, 0xab85067e, 0x5167e87a, -0xb06ad00c, 0xdd974309, 0x5704880d, 0xb7279a43, -0x38aeda19, 0x52f5a31f, 0xd66d79e2, 0x83dad3db, -0xa138d066, 0x0b4674d4, 0x07e7dd7a, 0x7f5c70c7, -0x4aade5f0, 0x4fcd220f, 0x2ae8ab6f, 0x6fb11f68, -0xbf134ecc, 0x71d3125c, 0x3cc3f6ba, 0x92809507, -0xb4a9b236, 0x97a2ef5f, 0xe20e5f23, 0x5610bfa9, -0xad16eba9, 0x5207dfba, 0x0caa3d20, 0xc57cccba, -0x7983d15d, 0x09ced949, 0xec698959, 0x53a4b153, -0x63c74107, 0xacf58270, 0xbc2982cd, 0x42bf9c41, -0x26aff8b4, 0x9832bd6e, 0x34e98158, 0x434f0f43, -0xcb80ccda, 0xd81471b6, 0xbd176071, 0xab13735c, -0x4e80e2c1, 0xcf7815f0, 0xb4e6ae37, 0x1a90c457, -0x79426d6f, 0xa4ac1e2c, 0xf76de77b, 0x1808cd61, -0xd72ea071, 0x1f02af0e, 0x9613b531, 0xe83f2e9a, -0x99a5262a, 0x0e8a756d, 0xbc229ac4, 0x2cb1af6b, -0x8a8720d6, 0xc84d2c77, 0x8547ad96, 0xeb794e72, -0xb51119ea, 0x1c0121ea, 0x9f8ae83b, 0x16459999, -0x5c17deaf, 0x278a3e3b, 0xf2bbb704, 0x54df1a00, -0x521ef94e, 0xd40de734, 0xca5badee, 0xa2fe3027, -0x2ffe3ada, 0x1df00fb9, 0x5feb168c, 0x81674308, -0x99713c0e, 0x56aae017, 0xe62e68f3, 0xaa15163a, -0x31ac7b10, 0xe6a86d9c, 0xa006782e, 0x9baefc91, -0x111277d5, 0x80f63a4b, 0x624044d6, 0xd91a5de5, -0x5d0255d6, 0x92b82310, 0x08faf5e5, 0xe482ff69, -0x0a1f1757, 0xdc010e34, 0x9cd07e48, 0x677fcfa3, -0x0384138d, 0xa104220a, 0x5431c7ec, 0x0e8b7efb, -0xf1ebcd61, 0x97ae7029, 0x191ff006, 0x4308b147, -0xa11e05f7, 0x2c7cb5a4, 0x1d345971, 0x28d23638, -0xc5a7a5bb, 0x3307c971, 0x0d3782ae, 0x2b798842, -0x1fc27334, 0x4ff82ddb, 0x543ba685, 0x47732c7a, -0xad094a6e, 0xb8ff60e4, 0x43f9ee2f, 0xe9a114e8, -0xf036be6e, 0x3fb488a0, 0x280b2d46, 0xb1887c58, -0x54ae583a, 0x454b6ce6, 0xe617a2c1, 0xb9335ac3, -0x72361e12, 0xc856637a, 0x741b6cbe, 0xcf1f6f25, -0x9f405fff, 0xd2525b02, 0x22d8b05a, 0x16860f11, -0xb02983e9, 0x388b9c2c, 0x196cb2f2, 0xfca5f1a2, -0x9e60965d, 0x5bed99ff, 0x59e361fc, 0x9361bde8, -0xa1527365, 0x3f300237, 0xb0f5e2b8, 0x8fb00a40, -0x71cb9744, 0x3327e8d3, 0xe89994d4, 0x3987e389, -0x28c6d8f7, 0xb2ba9fc4, 0xdf109e0e, 0x622634b2, -0x4904a82e, 0x576c3c2f, 0xe95eae46, 0xfb773013, -0xf98b91de, 0x4edc30d5, 0xc6e60080, 0xebefab96, -0xd7684df2, 0x9cd2c3e1, 0xd433902a, 0x7b9aa9eb, -0x3c99cbaa, 0x5a0fa53d, 0x77297830, 0x869db621, -0xaee2d56a, 0x2ce907c1, 0x0aa5097c, 0x662e7862, -0xa5bfbc61, 0x2610f3bf, 0x3a741865, 0x99a5836d, -0x2e533e3b, 0x812aa485, 0x0d7eb66d, 0xb325db47, -0x6ac77937, 0xa1757eb7, 0xb7765633, 0x8845f18f, -0xde7e37f8, 0x08a17789, 0x8af720ca, 0x1f7a530f, -0xadcbb072, 0xd02e2dae, 0x16fbe58f, 0x0e4df085, -0x80663766, 0xdcff020e, 0x4c242d70, 0x3d16d122, -0x154a029b, 0x40c95a2e, 0x5f98eb6f, 0x637ffc42, -0xcdf10a5c, 0xf2211055, 0x998ddc8b, 0xcee90fd8, -0x1ddc7fad, 0x7034d80c, 0xf5bf0592, 0x479205bc, -0x0900e9c9, 0x7bef8c77, 0xc128cebf, 0x9e7dd814, -0xedca7a5e, 0xf15af942, 0x40e55228, 0x065ea7ce, -0x9603da92, 0xa6611211, 0xea9dad76, 0x4fd9d974, -0xea19cb68, 0xeabf508d, 0xd460f6c0, 0x3951733a, -0x249a4453, 0x04356966, 0xac6ec71e, 0x5253e669, -0xfca78245, 0x8ef4d888, 0x6c031fe1, 0x8c49e3df, -0x181ded1f, 0xba9a2a29, 0x3a350c13, 0x5fdb2e20, -0x071f7766, 0x831b60a8, 0xaddc46d4, 0x73fc6685, -0xf814b86a, 0x6b888864, 0xf1253cba, 0x64093883, -0xd1f90479, 0xd99f2676, 0x143461f8, 0xaeb7d324, -0x5971a5d8, 0xa97ecb22, 0x5a9f28fc, 0x0e474ba4, -0x771e7b28, 0x09219fc2, 0xbe3153d9, 0x026236d6, -0x44a0eba2, 0xd3b94e36, 0x405b5759, 0x209cbbb2, -0x73194d9c, 0x82af6596, 0x735d2807, 0xfbc89223, -0x683fbfe5, 0xd7e66cee, 0x3419b4db, 0x089456f2, -0x756b491a, 0xfc12382b, 0xfce57feb, 0x0cf9d1e7, -0x7a9bbe55, 0xb775f2f7, 0x7a7a7612, 0x92e21a2e, -0xf6a87d8e, 0x84356931, 0x21f480c9, 0xef3a9505, -0xf4b0cf63, 0x5098a176, 0x607856e6, 0x5ad0357a, -0x18581ae2, 0x7a0d77cd, 0x2840e6ed, 0x5c26e03d, -0xf05a2704, 0xc3faed2d, 0x8d7d9a09, 0x8a75f27a, -0x10382097, 0x02f6c32c, 0x52d8b14c, 0x0b38157f, -0x1f20300a, 0x47bb86f4, 0x298ce7a0, 0x5d2c8478, -/* 885-MU16b402.inc */ -0x00000001, 0x00000002, 0x01112002, 0x000006b4, -0xf512ec8f, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x8d14e438, 0x725bfb67, 0x2d37e08c, 0xe7b19dfb, -0x4c8d3c95, 0xffc6f57a, 0xfccb06b2, 0xc6e24fdf, -0x1a3c7f2b, 0xa4b0a3ca, 0x09db4042, 0x61f7da54, -0xf3aa8795, 0x7b8f1487, 0xecd5a1b8, 0xdc8c213d, -0xcca7e859, 0xea53a869, 0x6029671d, 0xa2aa975e, -0x5ad10a3c, 0x61dcc9e8, 0x6949a4d4, 0x114d569b, -0xf3373941, 0x1c1838fd, 0xb175a480, 0x4f01d669, -0xe91ced35, 0xe1d0c798, 0xc51cb3ea, 0xb1ca685f, -0xa6d307d8, 0x4abbe7b0, 0xd37e4089, 0x43f218ca, -0x2c775ea9, 0x3e312577, 0x948e06b0, 0x09cc6398, -0x0f717e24, 0xac27b46c, 0xbeb41e37, 0xb6f8bcfb, -0xe357533b, 0xe99f4a97, 0xb20b928d, 0xa3239533, -0xd483e1ee, 0xbe688435, 0x11ce1bc2, 0xef04a8b7, -0x10c9a575, 0xd74f47ec, 0x7e1caa09, 0xbdf4f1b4, -0xbf14445b, 0x21b2f2a2, 0x63f32e79, 0x49df792a, -0xd81e7458, 0x8d1996f9, 0x0ccd33e5, 0x907d96dc, -0xd5b4ae37, 0xd743e460, 0x8d1eeb27, 0xbefe322f, -0x84edfa2e, 0x94a23dcb, 0x5519aa65, 0x60fb77a8, -0xfb3b499d, 0x5accc8df, 0x7e4fa2ae, 0xee70a051, -0xa00e5234, 0x7411fac7, 0x9e3bd4ac, 0x8870b19a, -0x0bf8210d, 0xa13413ee, 0xb18ccc76, 0x72217b46, -0xbac79caa, 0x3c196591, 0x975b9d8e, 0x8750facc, -0x4f4ba92a, 0x54a1c0e8, 0x2c30a8bc, 0xcb228a22, -0x8a1a76a9, 0x20f0b73c, 0xcbf6d97d, 0x2c3d632f, -0x487e9718, 0xdb39229d, 0x9dec941c, 0x857c67ac, -0x3fcb6bed, 0x24b8a438, 0x19802922, 0x6e2ef495, -0x2363800c, 0x8ed26f96, 0xe833a8b4, 0xf0f90321, -0xeee74569, 0x6fe1b339, 0xb571118c, 0x96faaa1f, -0xc0a5b115, 0xe0103aa4, 0x09679bc9, 0xe6c7ecc3, -0xddd7fab7, 0x169d9eab, 0x46de7a6b, 0x8e62dc8d, -0x0352127f, 0x9bbec1b4, 0xb4a22510, 0x06f94e5f, -0xd7cc03d6, 0xb2e2c178, 0x8d8a48ea, 0xa089e856, -0x6f2e29a3, 0xa6de73c0, 0x099bb823, 0xd642a2b6, -0xd222edee, 0x4d618164, 0x8028d02a, 0xe7462bd9, -0x993d5b65, 0x0d76b5b0, 0x20166d1b, 0x5000520b, -0x2d1b6fc8, 0x417d7251, 0x7c13ac74, 0x1aac7da6, -0xe3843e3d, 0xb76299a0, 0x9fb249c1, 0x4864d56e, -0xe12eab25, 0x38ce3d26, 0xc0d5b8a5, 0xd4910b5c, -0xbd428d74, 0x58ff0ae3, 0x78669ee4, 0x10471ff9, -0x534e002a, 0xe1d8feeb, 0xf4feee35, 0x76f222b0, -0x68c0270c, 0x0030d599, 0xd4241546, 0x8cfda1d1, -0x3852f115, 0xd7fb3466, 0x58fe4578, 0x57038162, -0xdb6dc364, 0x88baec17, 0xaf062790, 0xb70f6e83, -0x73fd4542, 0x010debbc, 0xdd02bcda, 0xd7b44398, -0xb2856418, 0x76aa8ecb, 0x72043c88, 0x00ba511e, -0x58df48d2, 0x8a10f33c, 0x684fd7a5, 0x47f15765, -0xe38065bf, 0x584d4eed, 0xa434b261, 0xc9254576, -0xe10ff696, 0x9882bde6, 0xb0967eda, 0x8b12dd5b, -0x1155b6a9, 0x679e8f2d, 0xe522ca3c, 0xff4432e0, -0xf1172213, 0x540032ff, 0xeaa78315, 0x003217dc, -0x96a5e987, 0x02d92ea1, 0x176db865, 0xbff26fc8, -0xa1ed85cc, 0x8d1e3673, 0xaf598c4d, 0xbb472150, -0xa522b7dc, 0x755194c6, 0x2cdafab3, 0x8ebd657c, -0x6197fa59, 0x2ef39c18, 0x8f63f7e8, 0xf1cf5923, -0x55e21350, 0xd44e22d0, 0xe134e739, 0xbd670fe0, -0xe2685063, 0x6dae2e19, 0xfbce6e8d, 0x3d4fdea6, -0xa7f23d9c, 0x1c7fe950, 0x2a23ef65, 0xf3f3a2f6, -0xa3c1fa25, 0xc5b98bc7, 0xc2f482b2, 0xc7745101, -0xfcf64472, 0x3f22aecb, 0x92018d3c, 0x24818346, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 409-MU16522c.inc */ -0x00000001, 0x0000002c, 0x05171999, 0x00000652, -0x05073130, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x73c82980, 0xf239ca39, 0x577aa64c, 0xa0357a54, -0xa85ca5d9, 0x5d73bd4e, 0xc12fbb13, 0x7b099edb, -0x701f7b54, 0x90af2bdb, 0x5fcea607, 0x07db24b4, -0xda564ef1, 0xcee80b1c, 0xdc8dcb71, 0x173f79d8, -0xbdc6d5d9, 0x48e69ab4, 0x6753f2c9, 0x9cf9970c, -0x0a403a42, 0xd2382e59, 0xca8ff898, 0x3d816841, -0x7290853d, 0xc3c48307, 0xdb774d7a, 0x7fbc8d7a, -0x06b1a6af, 0xa35c358c, 0x087fd0a1, 0xab417c72, -0xe7da5c66, 0x240e551a, 0x042223ae, 0xb694e434, -0x759b9b2f, 0x56ea88d4, 0xd934d341, 0xcb2dc2cf, -0x1b08897a, 0x16707fc9, 0x7eecaceb, 0xc4903846, -0x22ab81be, 0x31d0ec20, 0x0a4d7075, 0x7786e56f, -0x9d5a68ba, 0x40763174, 0x8547e000, 0xe9cc6f7d, -0x17de3806, 0x5108956d, 0x641f656f, 0x50bd839f, -0x5c868c4f, 0x32ffd4ca, 0x49abd852, 0x8a940c98, -0xd152285a, 0x2c4b1d15, 0xa8a5038c, 0x9e40fd0a, -0x9f390b45, 0x8048e88c, 0x0a5aace6, 0xdf3ad69e, -0xa8c36431, 0xfe4d3a9b, 0x71246abb, 0x985871e8, -0x21f0fb32, 0xb12143fb, 0x0a93b00c, 0xe552b0bc, -0x3466e546, 0x333e61f2, 0x73664ac8, 0x18e813ef, -0x8512375c, 0x9ececcf6, 0x47ce1e13, 0xcce8549b, -0x1658234f, 0xde3bf1f7, 0x21039e31, 0xe78f0880, -0xd03c5c4b, 0x61232c4b, 0x9fa52e27, 0x5acfd153, -0x65dc9e3f, 0x89b63211, 0xb5d3625d, 0x8c1b7b53, -0x8018a5bc, 0xaf2b81c3, 0xb1b7030b, 0xcedb554e, -0x13c03adc, 0x4abf1ab4, 0x28f1f5fe, 0x27e0ab93, -0xc12af7fd, 0x9c11405a, 0x02000363, 0x38d621cb, -0x77c66630, 0xd559f56c, 0x3b45cc3f, 0xd83b44cd, -0xb1660aa9, 0xb66b1a5f, 0x4518c35b, 0xfb44b10a, -0xc3676b79, 0x85c43391, 0xb5e5bdc9, 0x1d5fa7b9, -0xe1e5ec8a, 0x4e8fe9c7, 0x317c50ff, 0xa3b6bc8d, -0x6ea00f2c, 0x82c56b9f, 0xc0786dea, 0x0f4b370e, -0x7b9c5d13, 0x911629f6, 0x6612e1bf, 0x84f8f05e, -0xbde37cc8, 0xa0e2dcbb, 0xc8f05727, 0x596bd491, -0xb4013d53, 0x443bb9fa, 0x958ece18, 0x10cb627e, -0x19b67554, 0xe0ceafdf, 0x27ef6f6b, 0x6203db81, -0xcbc9113a, 0xeae9241d, 0x672f4296, 0x63eedef3, -0x4aa96ced, 0x44b8fb78, 0x4237594e, 0x685439a1, -0xba6a96e0, 0xea5e0639, 0x7cafe234, 0xc1561b9d, -0xd36c4c33, 0x8669663b, 0xaddab12f, 0xa574cae5, -0x94d9fcbd, 0x30d54321, 0xd89777ea, 0x9e485930, -0x75608c5e, 0xa4b93f86, 0x0fd1de45, 0x8d768bd2, -0xf47e7ea3, 0xae270b70, 0xc578ac27, 0x1779f283, -0xf5069a26, 0x9d28afe8, 0xd339186c, 0x71c601cb, -0xab018df9, 0x4636ca8e, 0xd5a480c4, 0x73866df0, -0x1da8f538, 0x2b12eead, 0x3d36bc45, 0xcfc6a165, -0xbdddc678, 0x777f7f4e, 0x33731adb, 0xafd30037, -0x8b18c0fd, 0x8bd955f0, 0xb9532d87, 0x171d87a4, -0x58b8a3a1, 0xd6c974de, 0xa0c30c65, 0xb830053a, -0xe0ee7291, 0xe0717f2e, 0x8e60d0cd, 0xa5e91c02, -0x7d04e220, 0xeb51f97e, 0x85d428cf, 0x028ee0c3, -0xbe41cf07, 0xc097238f, 0x55d76112, 0x50542345, -0xcdeeb808, 0x6d651c57, 0xb4ea4f00, 0xea30ac97, -0x37b63fa9, 0xe66458ad, 0xabacf15f, 0xa656f5b2, -0x3dcfee29, 0x27e70a8b, 0x2f3206ed, 0x0a1186c2, -0x8cbaabc4, 0xfebf634f, 0xddd411d3, 0xa55cf4ec, -0x5e97a778, 0x5b5540d7, 0x3c85634a, 0x0e9f9e35, -0xee75a230, 0xa390c0e8, 0x9d7d633f, 0xb045a66f, -0xa60e513b, 0xb6663504, 0x15861d13, 0x33dc9917, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1816-m22f6809.inc */ -0x00000001, 0x00000009, 0x07142006, 0x00000f68, -0x0d8bb650, 0x00000001, 0x00000022, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xba995672, 0x28c184bc, 0xc9f4197f, 0xa78abb23, -0x93895bca, 0x87b86a7c, 0xff2beb16, 0x06f7eefd, -0x8aa8c8bb, 0xaa7be533, 0x72e328a3, 0xb9f168d9, -0x5b6104db, 0x2d06c654, 0xa2396a59, 0x68cf7257, -0x299328dd, 0x82109266, 0x2d392ebb, 0xe2a2b7e8, -0x4c5ca66b, 0x4d279736, 0x3dc87da3, 0x8a605dbc, -0x5b32c550, 0xcb040d12, 0x9870438e, 0x8173bd32, -0xa0038404, 0xa66ef1ca, 0x7d123ce7, 0x11153287, -0xfaa50f5b, 0x908b5dd3, 0xd11629eb, 0xa8487d11, -0xee26e9a5, 0x2b13e7ed, 0x238dbfc0, 0x00025dca, -0x16a8c744, 0xb39c52cf, 0x38810ec9, 0xadf842e8, -0xf3f84359, 0x2808d301, 0xcc2e88e8, 0xa70bd0da, -0x6cf33ef6, 0xb62e5138, 0xcc17b7e0, 0xf39100c2, -0x7b114661, 0x835b8b23, 0x02d3fb37, 0x75f167a2, -0x15104aae, 0xe4d74ff2, 0xbe9c0618, 0xaeff5024, -0xdf0fa668, 0x6e1f950c, 0xd424ee3c, 0x530595b7, -0x493bd296, 0x9a47bf52, 0x528e965a, 0xf1a869ea, -0xb51d0889, 0x5c31f5c2, 0xfcf73a56, 0x8870cf28, -0xb0d690e1, 0xe4da0d6c, 0x974de456, 0xe70db8a6, -0xd21a0c0c, 0x82cfb296, 0x777a6dbf, 0x500a4e9f, -0x1a6d344f, 0xd833896e, 0x8df38cf7, 0x8d147af0, -0xc2c080d8, 0x5f3c146d, 0x9afcd9be, 0x0b3e9e29, -0x2e80e8be, 0xb81ad07f, 0x5b9c52eb, 0x9d1c5d45, -0x3032f580, 0x16deb069, 0xee3700b3, 0x886bcd52, -0x4c70bdb7, 0xba2cd82b, 0x42f87777, 0xc1dc3299, -0x82e14d37, 0x88b68a59, 0x09d88007, 0x73d4b070, -0x0d9695cc, 0xdf074428, 0xf1fbcf25, 0x87edb8a9, -0x0343e407, 0x56f5e38c, 0xb576f3ea, 0x59b3a3ef, -0xa0c9445d, 0xb87d6df5, 0x254c590d, 0xd66294cb, -0xef30dab5, 0x7a2b6e23, 0xb98c1e80, 0xa5e9ed82, -0x381e3ec5, 0xefdb0ede, 0x1f11131c, 0x9d9426e3, -0xad11682e, 0x8f12209d, 0xc6eb1ae9, 0x31dc4a3f, -0x4940f824, 0x8448c795, 0x876f536f, 0x9c095325, -0x61a09af7, 0x00f04b50, 0x204038e6, 0xbd415dc4, -0x0ca8e4d1, 0xa6ffad51, 0x79d1769c, 0x1a9a926a, -0x644c26be, 0x8209dca0, 0x8f245c4f, 0x9dbf787d, -0x626cb362, 0x04f227f7, 0x194e1e42, 0x30d8256c, -0x8fe764fb, 0x882e351e, 0x0e8defae, 0xb019031c, -0xdda5f11d, 0x05ce1899, 0xdc2b64c3, 0xafb791f5, -0x55996c92, 0x89bd2bdc, 0xa8746454, 0xb5e786cf, -0xc3f2594b, 0x94faccad, 0x2c903e1e, 0x3685f959, -0x52c8ad19, 0x9f85c5dd, 0x414d7d9e, 0xab671d46, -0xf8740d08, 0x3aa6606c, 0x14265b88, 0x00abd868, -0x17240344, 0xa08717ea, 0x95834a6d, 0xa54bce2b, -0xbff0f3b7, 0x0a880367, 0x06779160, 0xbc4aa0ea, -0x6ee405bc, 0xa3d9a3fd, 0x2163ade5, 0x646576f0, -0xa5558035, 0x84f90b5d, 0x5a1bd90e, 0xf7dc7796, -0x067e92fc, 0x615f7ff5, 0x08bd57d1, 0x8dfbfe95, -0x304e120c, 0xd1839527, 0xb1b2c157, 0xdff80f0b, -0x5f0d3da0, 0xac56eda7, 0x1c68c6c4, 0x6da38397, -0x909f5fde, 0xcd90ec2f, 0x9a705817, 0x8f507d52, -0x3809b4fc, 0x409ebb3a, 0xee70bd63, 0x01c5f4ca, -0x6a940843, 0x89b2e4d4, 0x4efc5a14, 0x822d9a19, -0xe44cc23a, 0x1cc305a1, 0x7b52fbd7, 0xa9d1129c, -0x001a66c0, 0xbf67ed43, 0xf1972f5b, 0x9307f38e, -0x69a18d1e, 0xa28e3863, 0xa034a002, 0x248f9da3, -0xd82b9d7d, 0xb22f2692, 0xcfda0bf0, 0xb3eed633, -0x23ec414c, 0x210bcbec, 0xc32edb0b, 0x7e975e0c, -0x35461e7c, 0x8f6d135b, 0x1e10f68c, 0xeed9332a, -0x6f00b558, 0x5dc663ae, 0x7bd84e1f, 0xa3a22a77, -0xe149e7b1, 0xff5c7459, 0x139e6185, 0xc89f98f7, -0x9a1fe07f, 0xbb6579d0, 0x8901c533, 0x59035aa5, -0x2a0d9bd5, 0xef6107b5, 0xaa4ca7ff, 0xb3a7b0ae, -0x1840527e, 0x4c242dfa, 0x6bc47a21, 0x02d29df1, -0x0b30e397, 0xa34d2948, 0xa0eea27f, 0xa2ce0c76, -0x8d3fe74d, 0x12dab410, 0x1ff015f7, 0xb98709c4, -0x70312242, 0xa7bac1b1, 0x18000444, 0xa2a3a2d4, -0xfb85ffaa, 0xa43c1b1f, 0x7ce2cc34, 0x3ea2fd86, -0x5f2d9c32, 0xa25ccaca, 0x50546c4d, 0x9a9c61a1, -0x54b3f653, 0x2c2ddf22, 0x436878bb, 0x5e6416ce, -0xe5290563, 0xad5b9b97, 0x2db27a4c, 0xcf9d7e5e, -0x4a2093f2, 0x4592666b, 0x6b69a07e, 0xaf23440b, -0x1c714911, 0xcb8292e1, 0xe89dbb45, 0xb0fd0750, -0xfab66e40, 0xa5b8aa2a, 0x57fc427f, 0x120d98b2, -0x08a55b75, 0x923408fa, 0x5d3784c8, 0xaeb34b6f, -0xe92e2918, 0x39f504d9, 0xdec51666, 0x2ecd8903, -0x4514dca9, 0xb2935c5e, 0xb89256aa, 0xa4d77796, -0x19f7961e, 0x2d31cc39, 0x32ad7c50, 0xabf73d8e, -0xa26864e4, 0xa6f99d23, 0x7cf19061, 0x6c7929fa, -0x3942644e, 0x8deec981, 0xb5ff6901, 0xd0f36021, -0x228044fd, 0x7312cedd, 0xb841750a, 0x993cf6da, -0x48f03def, 0xe38c45ee, 0x8c9a2a01, 0xf4d30a1b, -0xf54afa18, 0x81eae3ab, 0xdc7bca06, 0x7fa69138, -0x258baf33, 0xcc9dd1ed, 0xcaf1f8d2, 0x916230bb, -0x951cc5a1, 0x75165ee5, 0x8bfbf6b9, 0x55d1ead3, -0x65c25cf1, 0xb32090db, 0xe069be83, 0xf5f54582, -0x83f2a9e3, 0x76f4c74a, 0xb7379e27, 0x8addb6ea, -0x10a3a6d1, 0xf2db1921, 0xc191c6f7, 0xa750fe85, -0xc00ba5e7, 0xb5577ae2, 0x4534f370, 0x1a785752, -0x263c1700, 0x97b5a0be, 0x40b648ff, 0xaae49c7c, -0x63b1139d, 0x12f00964, 0x6cfbbfec, 0x6fb1b101, -0x75d93d31, 0xb3c17407, 0xeb0ed03a, 0xf9aa97b7, -0x85397fbf, 0x7082ddf1, 0x6e0640df, 0xbedfc8ee, -0x293a8d17, 0xcb43bfec, 0xfa521d52, 0x948873f7, -0xea73c61b, 0xa7949743, 0xb110ac62, 0x07d5e084, -0x6610a3e4, 0x8cce6ba5, 0x928a7640, 0x82eb2aa4, -0x97a034ca, 0x1b236d9d, 0x7edc408a, 0x25afb610, -0xc487982e, 0xa962df87, 0x15825a93, 0xbc3fa026, -0x0164b72f, 0x16ce606a, 0x76c4968e, 0xaf1c8c2a, -0xa9bc5acc, 0xabb11559, 0x00f7baf3, 0x897dcfe8, -0x10996229, 0xa6f15552, 0x9fdd1eda, 0x23a28e76, -0xbe9d5cea, 0xa08a628b, 0x66ecce13, 0xa8cc9081, -0x83982759, 0x29fad5d9, 0x1a00ff8e, 0x284244b8, -0x7038ff57, 0xb15f3f81, 0x180a19e5, 0x9ba3e98e, -0x2fbab9aa, 0x39892bdd, 0xf6500c7f, 0xa17ca618, -0x18fca0ab, 0x9d69014f, 0xf0f1c3a6, 0x984904fc, -0xe9c30749, 0xb3b5bff7, 0x700646f1, 0x3ce7ccff, -0xaecf47e2, 0x98787665, 0xa8c09efc, 0xb1a0d93b, -0xbbf3186e, 0x28343060, 0x38dbe56e, 0x58338390, -0x67b28faf, 0xbcafa8f3, 0x409d36ff, 0xc80d85cc, -0x74f249d8, 0x41c88488, 0x910e6b01, 0x90ed277e, -0x2d59c63f, 0xdcae8c9c, 0x6d82a464, 0xd6d25a51, -0x786859a3, 0xfde4761c, 0x5c57a9b8, 0xe78f7a37, -0xadc69a95, 0x76a8f58f, 0x5ea2f59a, 0x4c0b3723, -0x28277aeb, 0x1bea363d, 0xddcee7c6, 0x5ccc2ce6, -0x697a2c46, 0x08073e08, 0x623c5fc7, 0xbb4942b1, -0x498e8f68, 0x0d7c8b28, 0xd264aae8, 0x39b64ede, -0x9584bbcc, 0x9e4f2ffe, 0xd3383045, 0x49c54b0c, -0x577e9734, 0xedf3bbf8, 0x399f44e4, 0x4a2a9f09, -0xc7411cfe, 0x78233a8f, 0xf93b22bb, 0xd30681ed, -0xe8a829e2, 0x70d06f05, 0xde8fd65c, 0x05336d6f, -0x9272d6f4, 0xf5fcc2df, 0xe1ca2877, 0xbee75be6, -0xddc0ac3b, 0x300b45db, 0xdcfd4c06, 0x3d132a31, -0x6a57f45c, 0x44de22a6, 0xef3d8ffd, 0x63907f2c, -0x93d7c98e, 0x35e8ebaa, 0x17c3e52e, 0x7241ea30, -/* 612-MU168608.inc */ -0x00000001, 0x00000008, 0x05052000, 0x00000686, -0xea2b7b61, 0x00000001, 0x00000010, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x38709a5e, 0x7cbb9fcd, 0x46f2975c, 0xdf0a611a, -0x454f553d, 0x4dd783fc, 0x38b72f92, 0xe6cd7f96, -0xf57804bd, 0xf12c0d73, 0xafa105a2, 0x74073ece, -0xfa02d788, 0xd8a7bdd3, 0x2471c214, 0xcdcf7014, -0x0e6e693c, 0xbafbc7c1, 0xd765a8ca, 0x65b6cc40, -0x2ed8a24a, 0x2c1fcf0d, 0x7d73ba93, 0xcf0a98db, -0x3caea0c2, 0x49e601d9, 0x936c2fef, 0xc87dc94d, -0x1fef698e, 0xda05fa7b, 0x204f5b4e, 0x441cedfd, -0x09f63dcc, 0xf7cc7654, 0x2b69ecf9, 0x495d0ef9, -0x7679dac3, 0x7a4c0547, 0xb7adeed9, 0x29053d15, -0xcf0b21bd, 0x77204452, 0x99ba650b, 0x3d19d146, -0x150b0f41, 0xd7b5238f, 0xd02a8165, 0xd1270d1d, -0xf6d102bc, 0x198ab690, 0xed878dbf, 0x34c2ec98, -0x4c9bee07, 0x66ec11f1, 0xaa5202db, 0x4d2f2fc8, -0x4ba8194b, 0x569fbee6, 0x9016ef51, 0x8fe4062c, -0x90148cec, 0x5be3ddc4, 0xf04ff2c4, 0x5de8d897, -0x09b1d0b4, 0x9f83a4f7, 0x0cf74fdf, 0x3c02a388, -0xa2045a65, 0xbe469468, 0x03e4c532, 0x5f14280e, -0xb384e96b, 0xfdce24fc, 0x2458e3ea, 0x169dbd24, -0x71c8b3f3, 0x67e019af, 0xcda860c1, 0xe279acc0, -0x6bc10e92, 0xe51258ec, 0x4630c6d5, 0xfc260a15, -0xca8197db, 0x30aefd93, 0x789a7c9f, 0x1dbd5410, -0xd4e1c7a1, 0x309e8843, 0xd47f27ab, 0xf0c4a0d6, -0xe30a1e06, 0x3056c766, 0xb45c4d62, 0x3b8a2d43, -0x0b013cdc, 0x8b2163e8, 0x3027cc1b, 0xe4c4db4e, -0x89a26935, 0xaeab01f3, 0x46406071, 0xfe9ca870, -0x73c6b8e0, 0xd55517a0, 0x40672814, 0x28d9e205, -0xfd23b70b, 0x885e72ed, 0x41861524, 0xeb7f77b2, -0xea826a61, 0x06a47055, 0x83d71cfc, 0xb6b5cbb6, -0xeea709e3, 0x25b910bf, 0x64ef9e5a, 0xd048a5a3, -0x0ecae00e, 0x216700b2, 0xf51cc285, 0x107f4916, -0xb390e89e, 0x07efee47, 0x8eb3d423, 0x151e4c0c, -0xab7ebbdc, 0xe471757b, 0x717f586b, 0xaacd6c2a, -0xa0c63ad6, 0xde1feca6, 0x234e73d8, 0xfc302a04, -0x4119848a, 0xbc8c78d5, 0xf3bb6d22, 0x2adc091b, -0x3d6a50a6, 0x80d0806c, 0xe775d1b9, 0xa398ace3, -0x47a09e7d, 0x82e43ac0, 0xb3ae0953, 0x9e953074, -0x4964b471, 0x4a8bb0fd, 0x9e6a6e8e, 0xee971884, -0xc7f2e4cc, 0xdc1b7ff4, 0x0ba3d273, 0x7d37c53c, -0x27554173, 0x7865dc77, 0xb24f15c5, 0x90c00d9b, -0x0ddd4024, 0x65050eb7, 0xf833936d, 0xe93cd40a, -0xe31dd31f, 0xc990cca6, 0xaad5564a, 0xcb6c45b9, -0xb1a6ef0b, 0xbac07112, 0xddbe22b2, 0xa01f1135, -0x0562493a, 0xb3f2f526, 0xd414512f, 0x5d945ebe, -0x0a8c95f1, 0xc214aa4d, 0x5006a179, 0xdd57b9bf, -0x92cc0d68, 0x29556e76, 0xbe68e6a4, 0x5dd7cedc, -0x2606954f, 0xb1168ed2, 0xbc7f4b32, 0x1cd43eee, -0x7f7e1f59, 0xdacd550e, 0x8e7c4adb, 0xd1b6af9e, -0x4abc5f32, 0x81181214, 0xc364896c, 0xc56c4a08, -0xd56aa244, 0x936f0be3, 0x3d0c967b, 0x1578d76a, -0x7cb10003, 0xdf0e8bad, 0x24bc9534, 0x4fbf3524, -0x7052039c, 0x6edb0691, 0x2f10c885, 0xd5adb704, -0x11ff9b52, 0xd6614cf1, 0x1ab2b79f, 0x9c4e93f2, -0x49e3431c, 0x6b80635f, 0x233912ad, 0x05168de1, -0x79e18bd7, 0x4d9d0ce4, 0x1e1d93f7, 0x041c93ca, -0x7109b31c, 0x98af2848, 0x012fd82e, 0xc134e4b1, -0x73cbf75a, 0xbc2ac259, 0xeb5f1138, 0xed0038a1, -0xa75bbad0, 0x9698ef09, 0x37b21e97, 0xe7d971e9, -0x3184de0a, 0x1d64395d, 0x005a6d27, 0xf26dfc59, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 401-MU166a0d.inc */ -0x00000001, 0x0000000d, 0x05051999, 0x0000066a, -0xbb94bae6, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xf98cb58c, 0xf8e34c9b, 0x9a83585c, 0x17590b99, -0xcfc53493, 0x836f4a96, 0x67f4ce01, 0xf4c650a5, -0xbe7e43ed, 0x4fd5a804, 0xf214c3ca, 0xbdc6d158, -0x4e6a28c6, 0xd9efd75b, 0xefcb715b, 0x5596eee6, -0x8138ddf8, 0xd04c7f6f, 0x72f449c1, 0xa11e07b1, -0xf0219ce4, 0x44120d45, 0x9d8bb862, 0xca6839ef, -0x785b4174, 0xb1771be4, 0xf3b2f061, 0x5f013a5d, -0x8975168d, 0xd3ceeee2, 0x5917e02f, 0xb577c84f, -0x96f5525f, 0x64384565, 0xf9a4f42f, 0x99450ef7, -0x255e1f35, 0xb96bade5, 0xbf46da06, 0x6ebe8d43, -0xdfce4d6c, 0xb43849bc, 0x63fc13d0, 0xd12e4a9c, -0xff549463, 0x6261160d, 0x9e6aec4c, 0xd78c76a0, -0x60894bad, 0xb7d60ed4, 0xd851d683, 0x6f36e6a4, -0xf2dfa83a, 0xda86c5a7, 0x20466088, 0xd9584bb9, -0xddb2f004, 0x03ffa24b, 0xdc7d5080, 0xda1b66ca, -0x44bd49b9, 0xd887e55d, 0x98230b4e, 0x643f54b1, -0xd75b6f46, 0xbbb7afe7, 0x659761e5, 0xd841dd93, -0xfa74ad9c, 0x63d43828, 0x9d12781f, 0xd88c6120, -0x64311175, 0xbc633234, 0xd1a2de89, 0x6646226f, -0xf9a69f9c, 0xd122c0b2, 0x21059d21, 0xd84d2aab, -0xd1020ed2, 0x03550e7a, 0xdc8d15fe, 0xd1302d28, -0x48d1cdbe, 0xda8a600e, 0x977918d2, 0x6a8923e6, -0xd29281a5, 0xbe794a67, 0x6e08c98b, 0xdba8ba3d, -0xfe5676d7, 0x6a5edef2, 0x9ecd0698, 0xdd1f5c8a, -0x6804847e, 0xbc7a64d5, 0xd098bb85, 0x6c0184f2, -0xfe734948, 0xd67dc462, 0x27156111, 0xdd05dabd, -0xd860b2a2, 0x0a9269e4, 0xd76fce34, 0xd4dcfefd, -0x4f8377b2, 0xddc2e081, 0x9f6f47d0, 0x6b90d56f, -0xd175a856, 0xb2699bae, 0x63339eed, 0xd44f87f8, -0xf967c3e2, 0x60ca74e0, 0x9f414eb4, 0xd81dd3fc, -0x6a74ea09, 0xb116cbe0, 0xda00af62, 0x69b5f577, -0xf281002f, 0xd3f01bdf, 0x23fdddfd, 0xd8502b48, -0xdb19dfb8, 0x049ea37d, 0xd4feaca5, 0xd4d899db, -0x49089ace, 0xd043ba71, 0x9ea0664f, 0x66e79d5c, -0xdb834bdd, 0xb03f29b3, 0x65678c33, 0xd72c89d3, -0xffa17c2b, 0x6e3563b9, 0x9f5a3fc8, 0xd6451f32, -0x6d4808dd, 0xb4eab099, 0xda846cbb, 0x67e8563d, -0xf081a73c, 0xd102f387, 0x2ae35611, 0xd6911a2e, -0xd65ede54, 0x0ab85a57, 0xdea46bac, 0xdb39c874, -0x4a61ffee, 0xd4405144, 0x9134e1ef, 0x638bb72d, -0xdf219a3e, 0xb54a59e2, 0x6f24712a, 0xdc311585, -0xfc33d659, 0x6bc88815, 0x970ba24f, 0xd46e58a2, -0x685e4b19, 0xb71c790b, 0xbdd49fef, 0x9331b0bd, -0x6aaf8043, 0xd27dda73, 0xb5bcfd6b, 0x6f021da1, -0xd6797be5, 0xb049884c, 0x651d75d9, 0xd3b8e79b, -0xbde67aa8, 0x6898134e, 0xd1ef428d, 0x43f0276e, -0x6b1ccad8, 0x2f5d0470, 0x6ea98b5b, 0x816f7a52, -0x0a8117d2, 0x885b127f, 0x89ef8b1e, 0xeae19c5b, -0x8d3424b1, 0x6a847189, 0xe8cfdd5e, 0x65edb529, -0x6afbd40c, 0xfccb5463, 0x65fe313f, 0x99b34252, -0xf58115ed, 0x6a7188cb, 0x95600f1f, 0xaeb80763, -0x6d16d13f, 0xc44bb6b8, 0xa2aab691, 0xc9d57050, -0xcc63b3f5, 0xfb61657b, 0xc97b26f6, 0x36a6e2b7, -0xf846a502, 0xc29b6e00, 0x7e21dd94, 0xf65cf6d5, -0x8e6e9290, 0x77fb8077, 0x10e3d5af, 0xd6e64ac6, -0x906e156c, 0x4d3b0efa, 0x0839de96, 0xfda92900, -0x92df7861, 0x66182851, 0xfdd34871, 0xe0263245, -0x6f3e8b65, 0x838dcb4f, 0x8715c68a, 0x9927f441, -0xe0db9e74, 0x7bcda352, 0x9399462b, 0xe41bbedf, -0xe17beed2, 0x1910e614, 0x4b547390, 0x8f9d9f91, -0xb525c77e, 0xc3bb9156, 0x322bfbff, 0x20488d87, -0xec17a2bc, 0x5ef1b557, 0xd12b8fc4, 0x6016582c, -0x0bda9d9b, 0xa819a4c1, 0x5bce9374, 0x5a3c4c40, -0xe88f4d3e, 0x08f4376b, 0xa59c45cc, 0x33c46dab, -0xdff3a2f4, 0xca974e43, 0x0d40e3a7, 0x8e963b66, -0x745c501e, 0xa877d75c, 0xc7774bf9, 0x4c6bf397, -0x47aeaa4c, 0xc35d51e5, 0x8a1a23dc, 0xb1db577d, -0x76700f27, 0xf469d22e, 0x97157a8b, 0xe953ef78, -0x52bbc871, 0x801185ad, 0x2771ed5f, 0xe617cf0a, -0x7f44701a, 0x292ab6ee, 0x364e4bcd, 0xa741d8d8, -0x6a53d427, 0xa3da51a2, 0xabddbb74, 0xdacb829a, -0x28cc5ac5, 0x68a1e69f, 0xe8715c0a, 0xe07e193a, -0xb12be636, 0xe75b2fd1, 0xaf716b67, 0x2cfe84b5, -0x768038ec, 0x1a38144b, 0x725be985, 0x0cca8c2d, -0x6377d96b, 0x78be2c3e, 0xfbc7bc7c, 0xc73599e0, -0x3556765b, 0x4acfc4fb, 0x7a625486, 0x216fff33, -0x36f1ca89, 0x5ba664f2, 0xebf1cffe, 0x417ab8a4, -0x5bc200d9, 0x0cd0cfb7, 0xe8579f5a, 0xf133b1d4, -0xbacd9856, 0xc93789f6, 0xcc87a934, 0x41508988, -0x69bbc82b, 0xd81fdd84, 0x4591ee49, 0x8c5bd59d, -0xb7c1639f, 0x901e5d50, 0x3ba0ad68, 0xd9bbe716, -0xc8b73e1b, 0xea23e96e, 0x1cec0793, 0xa0ae0e12, -0x90040f2a, 0x747c330a, 0x88ce23de, 0xeb455dd4, -0x2badd673, 0xa5c3c07a, 0x5ab5d387, 0xd971f0bc, -0x9f4bbfbf, 0x8ff5712d, 0x152cb5e1, 0x83f3ac4d, -0xef1186f6, 0xf36381b0, 0xacc9dc6a, 0x3f6a8524, -0x9acc5c26, 0xb1b40fbc, 0xb34beeb8, 0x3f4a4307, -0x78dc4772, 0xa0ea1e1c, 0xe27bce86, 0x98dfc4d1, -0xf13c0d26, 0xbe5e18c2, 0x0746bbad, 0xa64fc488, -0x987f91ad, 0xc1bdd8c2, 0x4ca3f823, 0xc9981b4a, -0x2ad2bd8a, 0x1016284b, 0xe6adec04, 0x8f8b855b, -0xe6f5e16c, 0x0ec6c6ab, 0x1d96c986, 0x32d7e61b, -0x49449a1a, 0xd683ec58, 0xb89db106, 0x7f020c08, -0x26b2347b, 0x46644ee1, 0xc92754fb, 0x1367f4c5, -0x27ca9199, 0x76cda4f5, 0xd5a81dfe, 0x063a9117, -0xa3ab8a9f, 0x8c81aa67, 0x64afcec9, 0xe78a08d6, -0xdb15d4d2, 0xeb99a428, 0xe7e3a832, 0x243a7f0d, -0x935a659e, 0xca856449, 0x07060d35, 0xc90755d5, -0x1162568f, 0x250ecdfa, 0x4ae8a6ea, 0xa585f274, -0x74b04948, 0x0f54d98f, 0x287e0889, 0xcf260148, -0x72604b94, 0x68d01875, 0x6bc9d36f, 0x842839d4, -0x70263b5c, 0xef51b93e, 0x02ee5b0f, 0x6ea9a2b9, -0xff49aaac, 0xb2060b9c, 0x2920c904, 0x47a055b7, -0xb7b043aa, 0xe4678462, 0xf1abc10c, 0xd9d9c3ae, -0x72d1aca1, 0x1154417f, 0x32fe84fb, 0x64fa78a0, -0xe6c5ebf4, 0xadfc0e00, 0xd18f98ca, 0x607c5fb2, -0xa1324c34, 0x0ce4e61d, 0x6afbe693, 0x9eb7871f, -0x625bc005, 0xb0effb22, 0x60ee628e, 0xcfd76448, -0xd81dc632, 0x005a3783, 0x44302f17, 0x64e097b4, -0xb8e9cda2, 0x57ae42d1, 0x9f9e40a4, 0xd2af30ff, -0x3eca1965, 0x7cda05b9, 0x233081cf, 0x34fc72eb, -0x02642499, 0x721bae11, 0x2ef47751, 0x514e1759, -0x35f0868f, 0xa90c32c6, 0xbe0f6405, 0xfa0d134a, -0x404256ad, 0x959e57ea, 0xb1c5ecde, 0xd175dae0, -0xb7c4107a, 0xa11832b0, 0x7c683cfe, 0x6c9e255b, -0xbd77f7a6, 0x7d1a2d6a, 0x2c6aa994, 0xd66d311d, -0xb7fbfbf2, 0xd69f8b84, 0xd74fd600, 0x72b087a4, -0x6e7e1d4d, 0x68f86d92, 0x64b857ba, 0x40fe4197, -0x83ce4fba, 0x70cc5546, 0xb957da5c, 0x7fcbcab1, -0x5149df69, 0x7f1c2970, 0x4201c39b, 0xaf6825d4, -0x21f0549f, 0xac41ba00, 0xde9b5750, 0xf4f7b104, -0xcd4fd7c4, 0x2aeec406, 0x2d245b77, 0xdd756960, -0xb2981564, 0x3b2875b9, 0x34b03c29, 0x80b7af2b, -0x1388a227, 0x7d527262, 0x706daf9f, 0x046c89c1, -0xcf7bded4, 0xa5245678, 0x3aa7da2f, 0x7f146ba8, -/* 738-MU16b11d.inc */ -0x00000001, 0x0000001d, 0x02202001, 0x000006b1, -0x6d9b5661, 0x00000001, 0x00000020, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x965e94ce, 0xea6ba8df, 0xbfae08d4, 0x3ec50299, -0xbf2b31ed, 0xbd80d71d, 0x19bfb06d, 0x95e56995, -0xa52265a7, 0x247242bb, 0x90900442, 0xa4d69328, -0x15fb69e8, 0x940daeb6, 0x8d930183, 0x2ad6a75d, -0x970bcd0c, 0xbfc335a6, 0x382df453, 0x8dfa472a, -0x95f0eda4, 0x2feaf1e8, 0xb6e292dc, 0xb7c32497, -0x2daa2a09, 0x83b58903, 0xaf122f90, 0x3730c2af, -0xa8f684d3, 0xa7f33a97, 0x11b46600, 0x8f8af52b, -0xab23714a, 0x2a87cf3b, 0x9ae73e3e, 0xa032cf57, -0x0adc600d, 0x96117940, 0x9ac65c28, 0x3a23596e, -0x94800c0f, 0xbf793392, 0x2c503bb1, 0x8dc252ce, -0x9b7de53f, 0x2af3d7b4, 0xb7bd4575, 0xbc71e798, -0x23d62362, 0x8393e39e, 0xafb59604, 0x290633b6, -0xac09d0f8, 0xbaced873, 0x1fbd177c, 0x9b51acfe, -0xa4d82134, 0x2dff3e84, 0x86d59af1, 0xa4789758, -0x0469ae88, 0x9a3f986b, 0x8f18edcb, 0x3a200e44, -0x8138b3f9, 0xb9aaf81c, 0x25af1d92, 0x8313e883, -0x9a7ff75e, 0x20a6b69d, 0xa1bb0bbb, 0xbb78f982, -0x27c1974a, 0x8dafbb13, 0xbc2ac530, 0x2c84f9a8, -0xa1d686a1, 0xbd6b3d97, 0x07419bad, 0x99535e65, -0xa1ee3deb, 0x3aca5a6d, 0x9c60ad82, 0xa9ac0d86, -0x14ba77c2, 0x80b20413, 0x93be9f5f, 0x34c56863, -0x87e25909, 0xbaaf9373, 0x2e9396d7, 0x836c3f99, -0x8c81e59b, 0x24c4123f, 0xbc3b2921, 0xa2744f80, -0x37dec6c6, 0x9e6b0ec7, 0xa6d652e6, 0x349f2dec, -0xafcf34e5, 0xa81bf9cf, 0x046ce7f0, 0x973ce507, -0xbd2386a9, 0x336dbfa6, 0x8de954fe, 0xb823c3bd, -0x13088720, 0x86bec81c, 0x9265d562, 0x24574333, -0x92f871dc, 0xa34ef2fd, 0x366b59f0, 0x84a9a050, -0x81e55751, 0x3f326f2a, 0xbbf66ec3, 0xa784062a, -0x2c9bc339, 0x889b495a, 0xa44822fe, 0x2e9b5fbd, -0xa69f6830, 0xa446b369, 0x1da26dbb, 0x820f296a, -0xbe2c600f, 0x27b90904, 0x88f003c9, 0xa9191c49, -0x024286cb, 0x9fe1354e, 0x91a7670e, 0x38236d32, -0x9c70820d, 0xbad8c44e, 0x2f9b35eb, 0x8fb157de, -0x82ea988a, 0x32f204c5, 0xb6a7fd19, 0xbe64276b, -0x2ad2ea1d, 0x95449132, 0xa7e07868, 0x3ae7a323, -0xbd4b67ba, 0xa1a1914f, 0x1f964ad2, 0x85f986d7, -0xa84bc3cc, 0x2739696c, 0x81196fea, 0xa90cd44b, -0x05728610, 0x8873057c, 0x83035ccc, 0x24e56003, -0x863ee7bf, 0xb4b92f27, 0x328f2941, 0x8ace163b, -0x94f39234, 0x39f2eb7f, 0xa10f03e2, 0xbd9ae083, -0x325e4950, 0x99241d8d, 0xa07f585f, 0xf2ed61ff, -0x3341f541, 0x68372f11, 0xa01b5b7f, 0xcc5d571c, -0x7ac343af, 0xa4a1568a, 0x142d7f47, 0x8f0b9477, -0x720e7fff, 0xf9214071, 0x84fa4a07, 0x5463cfab, -0xffa780fc, 0xb8fbd2fb, 0x84a2fdb4, 0xef1c1b2e, -0x7e4ce78b, 0x8a5e9464, 0x60bbad48, 0x463ffc56, -0x0d9ac7e7, 0x545e8378, 0x595db59f, 0x04edbae3, -0x5e4540e3, 0x489aaeb4, 0x94b5b57c, 0xbe693e7a, -0xcc870854, 0x7f6caa27, 0x0a85aa9d, 0xf678f31c, -0xc0a00529, 0x350ee2b8, 0x163fd3f5, 0x13fc2e76, -0xd92bb224, 0xdf829dcb, 0x07db061e, 0x2c99066b, -0xcb0327e8, 0xe3d4e5e8, 0xd7d7da31, 0x643aed9f, -0x1994a531, 0x73f84914, 0x5f296334, 0x874490b7, -0x517b63f6, 0xc04b51ef, 0x34d7de4d, 0x478cb112, -0x66642af0, 0x2f392ef9, 0x1811ec70, 0x943bc492, -0x70c61209, 0xeec40884, 0x47bb5b01, 0x255afce3, -0x393fcd34, 0x1cca4e00, 0x3d2ac97e, 0x314450fa, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 729-MU268310.inc */ -0x00000001, 0x00000010, 0x02062001, 0x00000683, -0x30bf0a72, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x51a89c70, 0x1411e023, 0x9fad9ce4, 0x67b1bb96, -0xc5793940, 0xdbb14bde, 0x9ebdae45, 0x1d678dd3, -0xdd2c6a0d, 0x231560fd, 0xead2a7a4, 0xca2dfa77, -0xe39fa4f1, 0x29fff4b7, 0x8c743aaf, 0x4c9629a5, -0x9c58f6c0, 0xde8beb3a, 0x38e7687f, 0x8588fd16, -0xc9f9f81b, 0xea2442ac, 0x335faeac, 0x3e37bfd1, -0x295504e5, 0x483d31dc, 0x77a5cb3d, 0x885e8e20, -0xe7850c7b, 0x7804bc39, 0x0e62293b, 0xadb6f55b, -0x9500642e, 0x84cf5c1b, 0xc3cf5d03, 0xf8fca898, -0x43c2b0d3, 0x738b8cf1, 0x452da61c, 0x90b2c9bb, -0x5f6ebd12, 0xdc5287cb, 0xe32d809f, 0xcaa55a03, -0xb6ad3f45, 0x2e858e8b, 0xf81ee98c, 0x858abe24, -0xe2840fc6, 0x4fecaa75, 0x9ed1d6dc, 0x0f8fd8a2, -0x821137cc, 0x34804fb8, 0xb3d0046b, 0x2d94dc78, -0xcc6e5dd8, 0x44bca1b0, 0xee4f69d3, 0x9614cbec, -0xc0eec8d9, 0x9d40be62, 0xcbfcd3ea, 0x3505d921, -0x384b90ef, 0xe55c57cd, 0x1b9db24a, 0xf4fc1864, -0x344f3e05, 0x30a91f38, 0xe4de8bf5, 0xd8a00f67, -0x5d0d08e9, 0xbc62235b, 0x45e91420, 0x168c25be, -0x78a0eaa9, 0xe2b44c13, 0x80b6ee0a, 0x1b92d7a7, -0x2a3f0fd0, 0x1c0076db, 0x2b7247e7, 0x2c3b76f6, -0x1f9304d1, 0x910a7c9c, 0x9deccc0c, 0x600ca6eb, -0xa6c20c05, 0xd1fa730f, 0xa5b85f29, 0x741b4c21, -0x6dc22fa7, 0x9257c832, 0xfc7fc189, 0x46a16122, -0x2d6d8fd4, 0xb262ee0a, 0xd0f4b609, 0x85dbebe2, -0x17b3da24, 0x94d92bcd, 0xaec41c85, 0xdcd01c5b, -0x891397f8, 0x8fbd01ef, 0xc1534f1d, 0x712a5fda, -0x47920862, 0xb03518a2, 0x70dd49d9, 0x7c163dec, -0xc128752c, 0x2cbc6d0b, 0xc5797987, 0x2d43c51f, -0x07c0e8ed, 0xe1b308f8, 0x013b9655, 0xc6f52847, -0x60042e4c, 0xb19e647c, 0x3b61ebbb, 0x6e0036e0, -0xc1c38e2d, 0xb35bb2ce, 0x12cb009e, 0xa5994dca, -0x8c9f6615, 0x11d39ed7, 0x9a3f14dd, 0xfd3f83a2, -0xcd02cd3d, 0xc6911f87, 0xb12638b9, 0xa3b05d6b, -0xea454066, 0xa4e67fb2, 0xd669c44f, 0x0980133f, -0xe324a146, 0xa387ad1f, 0xf1c8aace, 0x8fd30d25, -0x05313805, 0xcadd0388, 0x80b4d986, 0xca62856c, -0x6c3cf3fa, 0xb5cbb43f, 0xf10c6e0b, 0xc5df28ef, -0x912959c2, 0x9411fcba, 0x736906ad, 0x97c2bdaf, -0x1eb1b293, 0xf59b1d4c, 0xcc45755f, 0x0476a5d8, -0xf5970a77, 0xe0bb3bc8, 0xbea59fec, 0x6b71b180, -0x0420e767, 0x30b9c4a4, 0x020c50aa, 0x80ca424c, -0x45263b45, 0x34debf8d, 0x14cbca6a, 0xcf0b27d9, -0xdab6a3bc, 0xc002010f, 0x6e5089b7, 0x0fa16af9, -0xbfb3d03d, 0x86e5e67e, 0x6c764f07, 0x5455c2da, -0x29f70050, 0xdbbdc2d1, 0xaa8a831d, 0xc9b45187, -0x627f1928, 0x8978fd2e, 0xaee4d563, 0x4c96922c, -0x612fe1a4, 0x1abf2c4e, 0xc7d0b1e4, 0xd196ca3f, -0x54d79d88, 0x65cf52c9, 0xe5fcddfa, 0xb4b316aa, -0xccea4d78, 0xa8af6004, 0x990d8765, 0x85f38e66, -0x91bbe471, 0x4dec18df, 0x3954a133, 0xb61627b7, -0xea927cb0, 0xdcbf700e, 0xcab665f1, 0x750d645b, -0x9346130c, 0xd9a8b458, 0x757368ba, 0x92bacf7b, -0x693b022f, 0x4905d26e, 0x237d8707, 0x8b15029a, -0x272a8b8f, 0x6f442555, 0x54b834aa, 0xa9d878bd, -0xf7a55f5d, 0x6041d15c, 0x54883481, 0x320b5fab, -0x07c53edd, 0x3fe2ffe6, 0x2be545ab, 0xcbf7aa86, -0xf97eb865, 0x38dfe927, 0x06c587fe, 0x98565813, -0xab235859, 0x06bd7edd, 0x7229d888, 0xbc4d9cb3, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1373-m1069507.inc */ -0x00000001, 0x00000007, 0x11092004, 0x00000695, -0xf7d0461f, 0x00000001, 0x00000010, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x75ed45d1, 0xa58cfbe2, 0x95b6ecce, 0x3eec60f2, -0xa3518658, 0x986f23bf, 0x63ade481, 0xe26bbb6a, -0x94f0ad76, 0x0da53309, 0xc920df0e, 0xe6ee5568, -0x4a7fa577, 0x86f184bb, 0x98d09cce, 0x63a857b9, -0xb83f63fd, 0x8a34f546, 0x00f1a9c6, 0xf09c1ba7, -0xb2dab0ca, 0x1dd0f9f2, 0xb97219e9, 0x91489df9, -0x0ae22c43, 0x97602252, 0x9452bf66, 0x7b2490ee, -0x877013a0, 0x80d79558, 0x356747fc, 0xe8a4885f, -0xf7b0cadd, 0x32e006a9, 0xfa724d13, 0xe6625057, -0x41c66cbb, 0x9b638ac9, 0x9111e2ed, 0x686ccdc7, -0xbee8a321, 0xa16a3ae6, 0x5b207450, 0xbaa920d6, -0xd8887148, 0x386de110, 0x90ae1a00, 0x86f2d14d, -0x03a0923c, 0x96edf313, 0xc296dd52, 0x7935f549, -0xf094f7f4, 0xcacc5b02, 0x6b8cf81a, 0xd27d0293, -0xdb27991c, 0x4f4591d8, 0x91740b1a, 0xe5658e97, -0x22e267e6, 0xdfeef285, 0xbd99b6db, 0x0ba5a68e, -0xa8f3ae46, 0xd4e887f0, 0x2ffcb598, 0xb5ab53b7, -0xa34e5ed7, 0x275d2d86, 0xfb6504c5, 0xbf2ced2c, -0x5d3adb47, 0xdd90c777, 0xc247d4de, 0x49756808, -0xa7eccad2, 0xe463e92a, 0x08a1adc2, 0xbb1cdf22, -0xf56620f8, 0x08f73ae2, 0xe33c259b, 0x8c34f791, -0x5ac6f701, 0xd1a568a5, 0xb838c440, 0x1119f612, -0x8067edbf, 0xf891c9d7, 0x792e238a, 0x94aea031, -0xa6219da9, 0x2e657d19, 0xc0986d6b, 0x86845231, -0x1196d0c1, 0xbce3eb01, 0xd06a1421, 0x1ef9f318, -0x8fd9a69c, 0xdd2a5b02, 0x047d44ec, 0xb238dd54, -0xed7cb49c, 0x3a8c80a3, 0xab9a6453, 0xd53347c2, -0x59f19199, 0xd6c42520, 0xc6b433c7, 0x1432aff4, -0xc66caed2, 0xd7b46878, 0x1dee38b5, 0x91a2d549, -0xc847a196, 0x786ef929, 0xb03390ab, 0xeb92b8c3, -0x4a81034f, 0x866b4a13, 0xc1cec9d1, 0x14d1b187, -0xb1588c65, 0xbb04d233, 0x10754b96, 0xfbb7ae86, -0xf40317be, 0x1f5f6fc6, 0xb09daf2d, 0xa63e4a93, -0x224eeae8, 0x8a153313, 0xf62508eb, 0x6b3f448c, -0xab1cc6c7, 0xd90b89a1, 0x766abffe, 0xd96407c3, -0xde2397c5, 0x5c046b75, 0x94a3c7e9, 0x814d735f, -0x0ce5a75c, 0x929ea8f1, 0xe4e1bed5, 0x12a32b5c, -0x91c9e7ba, 0xdfb5f6d9, 0x07089e3f, 0xa39047ec, -0xc48d6f94, 0x60c7b5c9, 0xe791230b, 0xfe80e488, -0x77a83870, 0x8788bc87, 0xe8899973, 0x7a26deae, -0x9328cd9f, 0xcff87fec, 0x704c0630, 0xcf33211f, -0x8dfc1ede, 0x50e158ad, 0xf1bbe640, 0xeb418193, -0x6cfd16a6, 0xdfe57412, 0xf0a85131, 0x916cefdf, -0x68ed7eea, 0x8fd08f4c, 0xe7ad145b, 0x1b406442, -0xe731af91, 0x8a2bc765, 0x5fb4e4f1, 0x16f46d22, -0x8f585450, 0xae91ffb5, 0x2b1b8513, 0x3e0a7161, -0x9e34bb9b, 0x9686df2f, 0x5bd24526, 0x0ef38175, -0xc1c374b2, 0x953ad1e3, 0x0aebce39, 0xdba94281, -0xe065a1d4, 0x2f2304d5, 0xe95460fb, 0x05fe2928, -0x31f7b211, 0x4b01c6ce, 0x579271d7, 0xf10f5f7d, -0x2a32b09e, 0x8cbae3da, 0xb5641d44, 0xcdc2d181, -0xeeed868f, 0xe6a8bd7e, 0xf883e150, 0xe365dcf4, -0xa068d4cb, 0x5c47b100, 0x8c6a0e2b, 0x781d645b, -0x27c9af23, 0x7987c2e3, 0x521cbd5d, 0x5a85cdb2, -0x077941ec, 0x76ba48fb, 0xb0b24203, 0x494f73d0, -0xaf3d76ba, 0xe6a844d5, 0xc9d58989, 0x771cfc9b, -0x48d3cf56, 0x163fd59b, 0xc15a5942, 0x5d217288, -0xe0ffdc3f, 0xb298b4d9, 0x3b961d18, 0xb43b0287, -0xafeb73c6, 0x47f7fdef, 0x0caf84f0, 0xa1fe51ad, -0xd71618ac, 0xc87934bd, 0xe96101d1, 0x55d1976c, -0x471c8505, 0x7a36d839, 0x5d62a9ee, 0xf3c54a8a, -0xa2be15d9, 0x244087c9, 0x042c8037, 0x23224689, -0x281c5d73, 0x2139ecfc, 0xffb8bc8a, 0x834fdd11, -0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, 0x4ae2dbda, -0x86d90089, 0x6675dfce, 0x48876262, 0xcec72538, -0x11dc5c80, 0x86a730f9, 0x313565c9, 0xe3e5be11, -0x106d7cce, 0x752b8be2, 0x3d00a5bc, 0xe6f70e95, -0x44447ac8, 0x600df30c, 0x8335ac3b, 0x8816ddee, -0x700982fe, 0xee495741, 0x48c7e81c, 0xa3d55da2, -0xb0172982, 0x70ab2158, 0xd4460621, 0x3a9e528b, -0x59b18a7b, 0xf4dabc4c, 0xa8454763, 0x70877bb6, -0x66005c97, 0xaf292c06, 0x7b843db1, 0xf343b59b, -0x25cdc7b5, 0xa41da617, 0x9e9d895e, 0xc936f475, -0x7270925a, 0x30024230, 0x8e72f53d, 0x2b6c1b6f, -0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, 0xaf377cc1, -0xbff09a78, 0x4b4e0814, 0x95a0b2c1, 0x270398de, -0x201fca94, 0x2a032a4f, 0x131542b4, 0x0d7306da, -0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, 0xa3b3a991, -0x17ee60c2, 0x852c0b8d, 0x11e5853a, 0x762002a7, -0x92c5311d, 0x0d4bf7e1, 0xfffec870, 0xe3d35e5b, -0xff6ecfb9, 0xdedae6ff, 0x0111a772, 0x9808e780, -0x29c336e8, 0xe9bc05df, 0x5bedde11, 0x945565af, -0xaff808fe, 0x87e3423d, 0x4de6f98f, 0x93b4adef, -0xbf704fa4, 0x09120e91, 0xd54f3692, 0xdf8eab1e, -0xfabbf59c, 0xe74318be, 0xaab87ffc, 0x29fa791c, -0xe3915552, 0xa652cb9b, 0xa1252e74, 0xb35b723b, -0x542aa28b, 0x12fcc5b0, 0x3941f962, 0x82bcc6cc, -0x47b11974, 0xb821611f, 0x78b34250, 0xf1be5659, -0x561b9e61, 0x6f3bd501, 0x584e6f5c, 0xd54ed547, -0xacebcd21, 0x7b5ff816, 0xb64ad233, 0x9f2f330d, -0x69fb1ece, 0xac8710dd, 0x58dc6c60, 0x9bee6139, -0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, 0xa733274f, -0x884d9b55, 0x42b08b63, 0xafa54a74, 0x1c7ccf64, -0x93a20191, 0xaaa3132e, 0xc69831d1, 0x54634889, -0xfbfe3efc, 0xd3cf68d4, 0x302e3117, 0xf5693131, -0xc3ce8c6c, 0x1f03cd89, 0x6243334c, 0xf16bc80f, -0xdca5f130, 0xcb2cd956, 0x4c1bb421, 0xe8de533c, -0x7f86703a, 0x29aa897e, 0xdd54acad, 0x76b2f2ae, -0x7ef82b71, 0x2e30970b, 0xba402597, 0x9a653ab4, -0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, 0x2363d147, -0x5327289a, 0xe89229f3, 0xd63a535c, 0x7efe9273, -0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, 0x1b9c7bfe, -0x5d14b3de, 0x54d575fb, 0x6d65db4c, 0x95648b7f, -0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, 0x8488a45f, -0x8ebc2932, 0xd4767316, 0x3e8c4b8a, 0xbab7402c, -0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, 0xc88528e9, -0x4b2e4e8f, 0xdd938b86, 0x0c964f98, 0xfc88d480, -0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, 0x4d40b3b3, -0xcf203155, 0x0d2fa621, 0x752d2c58, 0xb12bac12, -0x1e7e8c23, 0x94215d54, 0x9854a71c, 0x4de63c64, -0x7a012529, 0x9c171f8d, 0x9e71def7, 0x3bd17d50, -0x11f175d9, 0xec78abf3, 0x7b529eee, 0xd3a69fc3, -0x5b718676, 0x58214d29, 0xa8bd2c34, 0x41ea00ab, -0xa03f64d6, 0x4ee342b0, 0x32b1e444, 0x1c1801a4, -0xc8424702, 0x334a7e35, 0x50cf1543, 0x3b22b495, -0x88683776, 0x8e2e0154, 0x6155c033, 0x4e2fa6ac, -0x42ace700, 0x8d64f97c, 0xaf9ced17, 0xb2a5cb92, -0xa558582d, 0x88705de7, 0x9e528d59, 0x84bd45e4, -0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, 0x10462123, -0x30080f7d, 0xb346cd81, 0x0049c396, 0x4e24165f, -0xa7c66809, 0x2e60bdcf, 0xaad70a08, 0xa73ea713, -0xe28f97a7, 0x283a9eab, 0xd4366489, 0xe776f963, -0x64ffa8ae, 0xde717b50, 0xbd2ca2b5, 0x3bae5f6d, -0x8d2bbef1, 0x7e9181e6, 0xf06aa121, 0xd06b2d20, -0xa83ea826, 0xef935e4f, 0xdfd27456, 0xa3451468, -/* 153-d2_619.inc */ -0x00000001, 0x000000d2, 0x02181998, 0x00000619, -0xc5c556c1, 0x00000001, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xdff49ecc, 0xc5d1e527, 0x3a8e7c6e, 0xe9d01207, -0x1e44f786, 0x58e4f3d7, 0xa7499f1f, 0xbc313f6e, -0xe4a24a94, 0x443d60aa, 0x4d3df7cc, 0x2cd064c6, -0xacc5f6da, 0xd958c0fb, 0xdaaa4a12, 0x737184ff, -0x91e00455, 0x467a0dd2, 0xaeab14c1, 0x1e73444d, -0x288bc1fd, 0x6dfaa156, 0xb1024d75, 0x7c0d631f, -0x602d9310, 0x7ed54bf9, 0xcc2819a6, 0x8c2600c3, -0x82eed3ad, 0xf0890270, 0x3d8a5679, 0xea0a9722, -0xff2b13d3, 0xb7011201, 0x2b1a69b1, 0x35e2af2c, -0x653177c6, 0x03168ff8, 0x6d061b4c, 0x16d81f8f, -0xd382f127, 0xce0f26ec, 0xb4d64cf1, 0x89c2aa51, -0xe648b062, 0xec4daa3a, 0x0988f13f, 0x62e0651f, -0x67c95b34, 0x6fb57c53, 0xfe3fb014, 0xc892a9f5, -0x451638d5, 0x4ffb5107, 0x796dbebe, 0x8f0f843e, -0xc1fbcf86, 0x0c8125d8, 0xffea12db, 0x712ad923, -0x2b49a751, 0xa8814975, 0xfd41f3a0, 0xeb18e50e, -0xf6281a79, 0xb4f44390, 0x2b5071c3, 0xc8ddba66, -0xcabf96e0, 0x34574ff2, 0x7c5f897c, 0x4827b909, -0x7026e86b, 0xcf16fa48, 0xe96da218, 0x8c37090b, -0xbadde7fa, 0x58740e35, 0xe0bf1ef0, 0xf3d71e9a, -0x1056b85e, 0x45a15688, 0xb923d493, 0x9e20fa03, -0xa839e632, 0xdedc0090, 0xff92aabe, 0x366986fc, -0x9e5c7f61, 0x4a648912, 0x91265913, 0x2d6d04d1, -0xb7ab8173, 0xbaeb7624, 0xa23f1606, 0xe6f08e1a, -0x479bc72e, 0xda2ee924, 0xf32033d7, 0x53154433, -0x8caf7ca8, 0xe12654a4, 0xc514d572, 0xeac8737d, -0x0a5170ba, 0xf16aded9, 0x565b6bb7, 0xfe452dac, -0xaec903e6, 0xb377e831, 0x3507046f, 0x0fb401d6, -0x25896c75, 0xd6c10589, 0xab3e97bd, 0xe5018b02, -0x9e8ae5c6, 0x8472d65a, 0x7b9a538a, 0xd402c4aa, -0x3e08fee3, 0x1b8441cc, 0x0d39c739, 0x6078d9c1, -0x398f9f6b, 0x85c92e75, 0x32da8bd3, 0xad017f9f, -0x2527e23f, 0xf9bbed0d, 0x352aff03, 0x4ed81a59, -0xebcd6b45, 0xbd57ffd9, 0x67971c0d, 0x6b4965e2, -0xe9d474a8, 0x7cb46bf0, 0x3379efd7, 0x94106bda, -0xf3dcb06b, 0x9a11f63b, 0xdbdbc795, 0x0d5582c3, -0xb1e07809, 0xc53dfc21, 0x3e34d1e9, 0x20ebb843, -0xc25871a6, 0xe2782ed7, 0x9ff3208e, 0x5637b911, -0xfeaae151, 0xc5d6eb76, 0x86f11d36, 0xe8636d97, -0x42cbc64b, 0x7b2ff820, 0x736543a5, 0x6e675dfd, -0xbeb65b45, 0x974e08d9, 0xe020ef1e, 0xca600463, -0xe9c6e29f, 0x6c9ff7be, 0xe50172c8, 0x04d54a42, -0x85d85cd2, 0x4d69dffa, 0x3e682ba4, 0x7707d35c, -0x1741fde4, 0x823ba54d, 0x07d89f59, 0x776e69e1, -0x4ea164f9, 0x3b45af6f, 0xadb026a8, 0x9b11bfe3, -0x2d79d863, 0x6a443d71, 0x75a92bb2, 0xd967d078, -0x531aefda, 0x96273cb8, 0xd3146702, 0x8caf3022, -0xfe5214b7, 0xff2ac722, 0xbab3ec0d, 0x1703c957, -0x29acc59b, 0x2065dfe5, 0x633f8029, 0xd492a296, -0x05615fd2, 0x0b8f02e4, 0xeba4d3fc, 0x6be653fd, -0x3ab070a6, 0xa98357b1, 0x4fc658b3, 0x98b576d7, -0x3f4e7495, 0xd057438f, 0x285b0074, 0xaf5f68eb, -0x098b56d2, 0x5088220c, 0x4c9c8e25, 0x6d6d348f, -0x4f368afe, 0x44f09ba9, 0x0c10ef81, 0x9d044f91, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -0x278cb2c0, 0xf41d6be8, 0x839b9b57, 0xde7df900, -0xa6d05386, 0xf79d8944, 0x24d4273d, 0x878456fe, -0xbc0006e2, 0x4cbc49c5, 0x16684d87, 0x1f2c79a5, -0x847dc8fb, 0xe873c43a, 0xc92223f2, 0xc9c193d4, -0x8f43d21d, 0xc723f894, 0xa0ed9e53, 0xd0693391, -/* 435-MU165141.inc */ -0x00000001, 0x00000041, 0x05251999, 0x00000651, -0xa6218306, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x3d0c5cac, 0x11ff7829, 0x2fa10010, 0xc0ecadaa, -0xcbae2857, 0x6b9584c8, 0xe72d47bf, 0x94415461, -0x2dd34f7a, 0xa2680f76, 0x2f06a3bd, 0x2efb5eac, -0x124ca162, 0xc9c9b1ac, 0xad51979c, 0x860cec07, -0xbcae95e0, 0xb179fc28, 0x380bfe6c, 0x29e36d1d, -0xb6de4a07, 0x43d2f7c0, 0x50d15062, 0xece84109, -0x5ad8ceda, 0x2e6edec4, 0x464d3c8d, 0xa8b047c9, -0xa3c54ec2, 0xf5d1d938, 0xe2c66824, 0x08b51d37, -0x4e914499, 0x0358535f, 0xbcbf6825, 0xd0ab53fc, -0xa4e1cbe2, 0x09414a2f, 0xfcc78650, 0x05b2e8dc, -0x1ecda664, 0x87fece35, 0xadc3aabf, 0x12669a90, -0x62f32415, 0xe4752476, 0x2c4099e9, 0x766ea598, -0xe1f0f9b5, 0x7949f610, 0x40d97a7e, 0x171f2391, -0x334adcbf, 0x8bf26d43, 0x7965630f, 0x28046837, -0x1f71d8b5, 0xa73e586e, 0x2fb7a8fa, 0xe7a2a760, -0x57003172, 0x6a28be58, 0xf2ba6741, 0xf6860c60, -0xf7cc3ef7, 0xf31e69cb, 0xdbc0894b, 0x205e4975, -0x42452229, 0x65ca0ea2, 0x65e34129, 0x4a618e0e, -0xcbbeb9a4, 0x881ebec5, 0x4b0bd791, 0x893c6e16, -0x756523de, 0xe2122ab1, 0x23f26f00, 0xf834a2a8, -0x9e17cf68, 0xe1b0a14d, 0x2f5edd0f, 0x2a8af994, -0xaf09e233, 0x7696ee93, 0x4864b409, 0xff4e530a, -0x4ae54fb9, 0x3801e4a8, 0xe2b391b1, 0x31ecedee, -0x0984604a, 0x783aaf44, 0x88e0efdb, 0x8b3e6649, -0x0bd1fdff, 0x46fa5711, 0x491e7907, 0x2eecc397, -0xdfe3df03, 0x2d821dfe, 0x897468cc, 0x37c4abf3, -0xbfc4e2f7, 0xa2d7394d, 0x13c001cf, 0xf27ef2e9, -0x3fd3c915, 0x0789f599, 0x2723c650, 0xeff3b161, -0x5ebabfd6, 0x6f13571d, 0xb5137ea4, 0x678ed454, -0x3cb93110, 0xae7278f9, 0x96ed6789, 0xefb4b7ed, -0x5d53b1a6, 0x65cd4d1b, 0x37750abb, 0x828b76e8, -0xbbd2da92, 0xe90fc24e, 0x3acf9d50, 0x8700265e, -0x9a44e932, 0x5a65886f, 0x6d883e7a, 0xabfa9ef3, -0x62d5619c, 0xbb915137, 0xf1037b6b, 0xed173ca1, -0x26f275ed, 0x002dd0a9, 0x2c1d7d15, 0x7a848373, -0x9e592b23, 0xa851699c, 0xb0de7ba5, 0x6dce1c73, -0xec7e2b9e, 0xce703232, 0x5057e031, 0x8651bfab, -0xebb69e32, 0x28438085, 0x273f8e74, 0x7f91a931, -0x8e3b6606, 0x2c18a084, 0x85c0acf4, 0xc245296c, -0xc10a0400, 0xf0abff57, 0x09bfbd33, 0x10bfa0c3, -0xa7cac5ad, 0x683e0e91, 0x5e951085, 0xa42cc4f8, -0xbc2dd1e4, 0xbade67f4, 0x31ee0a40, 0xd7ad09c9, -0x6f7d1b54, 0x644e9220, 0xd0aa82f7, 0x323164fd, -0x5202a165, 0xc87d20a7, 0xa1fd6640, 0xa6baa2c5, -0x35449bc2, 0x3b05a7c9, 0xac827721, 0xefa2ff03, -0xa27eba79, 0x6fc394d1, 0x6baefac2, 0xbcdba3fb, -0x02c9238f, 0x299d0700, 0x8ad8cb1a, 0x74dc90cf, -0x5258694c, 0xa9ce8103, 0xa8c79e86, 0xe54d8add, -0x67ec09d8, 0x135e99ac, 0x6084dfde, 0xac44fcc2, -0x53af5b9b, 0x1899f5bd, 0xe5f270ab, 0xe0375b50, -0x5e342404, 0x620baa1c, 0xad99d908, 0x29db18a6, -0xdec25da0, 0xd1b208f8, 0x8f777eea, 0x4e3e94dc, -0x67a40626, 0x8110a1ff, 0x7a53a3ac, 0x91f94f64, -0xc221fe22, 0xde9ee71f, 0xda8d5547, 0x4e9b215c, -0xd5025e9d, 0x4aa0cdd7, 0x1f3163bc, 0xc64716e5, -0x47583201, 0xaaa25f7d, 0x6d9dadd6, 0x56343814, -0xba90ef7a, 0x759ec8fc, 0xac9f5e3a, 0xc9c6d0a5, -0xe18d43da, 0x118bbb21, 0x25df06dd, 0xc53e0218, -0x12c84615, 0xe5e37b46, 0x74ec6542, 0x251cb041, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1340-m08f292f.inc */ -0x00000001, 0x0000002f, 0x08112004, 0x00000f29, -0xfdb52a5d, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x3329bed4, 0x074ca74b, 0x76a4c9be, 0xb3d0ac3b, -0x59c1ebd3, 0x9d06facf, 0xa272f2b8, 0x185d2aed, -0x1dbb2394, 0x86f96351, 0x12652c86, 0x873bf0a8, -0x4f6956f8, 0xbc5754f1, 0xd43f9485, 0xb0484217, -0x88993f58, 0x071366b3, 0xbb49ef1d, 0xb8ec50b3, -0xd6dd7d67, 0xafae9594, 0xafbcf523, 0x04e3cefb, -0xf6125942, 0x6c58f3aa, 0xa28b05f4, 0xbb31e4f0, -0xde633bba, 0xc2cc4d76, 0x2fc95cef, 0x465474bc, -0x6148f606, 0xa8245d1a, 0x167d68d0, 0xc38533b2, -0xcbfb5881, 0xb912dc66, 0xbb9cc137, 0xbaa2ca73, -0xa9cee564, 0x3edd2b89, 0x2e3ffeed, 0xa68b49eb, -0x0b85b10b, 0xb968370f, 0xd5c4deb8, 0x2d2883d4, -0x288e44af, 0x37b10c8a, 0xa75c2ef5, 0xa5242ad7, -0xff96f783, 0xab3f2161, 0x3921290b, 0x1094e053, -0x9eae586d, 0x9878a4f3, 0xa2d41b7f, 0xb29cc218, -0x93898d3c, 0xdd152eec, 0x638ab207, 0xa7536a0f, -0x5accf54d, 0x798a56a0, 0x8e925de6, 0xe2fec0a0, -0x8b6100f7, 0x910d43f8, 0xb3bcb1ab, 0x3f032f10, -0x667b024d, 0x5303ab2e, 0x50a68459, 0xdbdae9ae, -0x61cab195, 0x8b080d7b, 0xe1c9c484, 0xc0a9cc33, -0xf3c786cb, 0xa226e2f7, 0x4509e980, 0x2ff4bb80, -0x943a2b9b, 0xb0e2d78c, 0xdce9f9df, 0xb9302df9, -0x2f095be2, 0x46f9e8cf, 0x097129ec, 0x5f7ba01f, -0x49e26e4c, 0xde9ff6ce, 0x5d194de6, 0x9114a73f, -0x5114f3e1, 0x9832e8b3, 0xd116f967, 0xfcddf0e7, -0x3011f78c, 0x5d84b6d5, 0xb465a082, 0x8eb129ad, -0x5390d983, 0xdfad741a, 0xef927af0, 0xa062e4fd, -0x94a1b0f5, 0x6c9dcff9, 0x15192e6a, 0x11a1f0b8, -0xbc5f9758, 0x01c1070c, 0x6f5a81c6, 0x7ee5b238, -0xdf75b957, 0x8b5cbac1, 0x5f7cd16a, 0xf7faa6dc, -0x5b74dbb5, 0x0980f147, 0x4aa3b0ab, 0x7e96c732, -0xc72ad094, 0x29e6397d, 0xf62bb325, 0x3c519a56, -0x9601dfdd, 0x23f189bc, 0x0109b7a2, 0x13f597b0, -0xc35ff634, 0xa4f9ef96, 0xc430369d, 0x1ed355b9, -0x15f9b440, 0x2aad9fb1, 0x6af73cfb, 0xb602ee0a, -0x06611130, 0x8d08db9e, 0x6351cafb, 0x2be65e02, -0x1d9ed057, 0x34b31503, 0x74692a5b, 0xb56177c6, -0x3ebaded8, 0xa7db0ad3, 0x542be7aa, 0x0ba46019, -0xb820af02, 0x8f55fcfe, 0xcff707bd, 0xa1af5708, -0x41a1232b, 0xb4c897c0, 0xa1dd591b, 0xaf3db2a6, -0xe4687b08, 0x015862ef, 0x15a83ad1, 0xaeca0275, -0x0706cfc4, 0xbe03a5bd, 0x169d5c10, 0x280ab19d, -0x9b99fc66, 0x00345af8, 0x5de2f1a7, 0xb7fc86df, -0x8b00e3cd, 0x8d2711e9, 0x12eed4b0, 0x209bce06, -0x8cf97886, 0x9bf52a0e, 0xed9428f8, 0x9f728b1f, -0xde5fc471, 0xd1f01cdc, 0x69aa4865, 0x878ab1b9, -0xdabbcbe5, 0x550e7f55, 0xeffd94c0, 0xf0cdf203, -0xd7ff2d19, 0x9899bb83, 0x678e80dc, 0x49e5b9c6, -0xcaef9954, 0x7eb67af5, 0x419eeb94, 0xb1602068, -0x97e28a55, 0xe069a36d, 0x6dfcc106, 0x47f9d914, -0x7383e86d, 0xb27b7376, 0x6c2ee630, 0xf85f633b, -0x7c59d82f, 0xafb33c27, 0xca101b90, 0xb3b3bbf9, -0xf02389c6, 0x2ae5f253, 0x95676086, 0x88ff4ac5, -0x2d162899, 0xa222fffc, 0xd159e83b, 0x16b66dd8, -0xdf00350b, 0x3bdd9067, 0xc70ac2b3, 0xa539a829, -0x152a5d8b, 0xb481aa0f, 0xddf95ee7, 0x03e704e2, -0x0aa80b47, 0x8de64970, 0xc24430ce, 0x816af6f5, -0xea7abfc8, 0xd79e1d14, 0x12ad96a3, 0xaed48013, -0x882da4aa, 0x7f7725e2, 0x490b7fd8, 0xdb5124ac, -0x341b99f7, 0xba4d8f7e, 0x3674ad3f, 0x534b0569, -0x2902e14f, 0x58824d7f, 0x77356546, 0x9c95fca1, -0x9c0dc894, 0xedaa0d60, 0x81bfe7a0, 0x425cbcb5, -0xd5e7779b, 0xb9378330, 0x609f2e86, 0xdc7fbbb8, -0xcb72543a, 0xccb64908, 0xe58b6de3, 0xab1b8aa1, -0x3f967b56, 0x5efa057a, 0x07205290, 0xf717088f, -0x150e8090, 0x86edd874, 0x43222360, 0x58b3d233, -0x44ff6d7e, 0x284b195a, 0x5f601ec6, 0xaa541775, -0x5e1b16da, 0xaa198043, 0xd0169c6f, 0x28a71e70, -0xa928321f, 0xa44e4c54, 0xc7be5a61, 0xab93508c, -0x7ab40436, 0xa02182c3, 0x249b39db, 0xad612d6f, -0x899e0a48, 0x0f7d11d3, 0x7eb4ca9f, 0x8aadc9f1, -0xe4e20173, 0xbb07eeb9, 0xe4d773b1, 0x0963bc22, -0x5efe60b7, 0x6b442c1e, 0x6b127791, 0xb5f46698, -0x03bf49f4, 0xe4545f96, 0x4044e40c, 0x489f21ef, -0x1d4eac1c, 0xb0f1a1ca, 0x0345a5fc, 0xc430b5e4, -0x2168a536, 0x9b9d9aed, 0x5a8a9758, 0xbafd2c68, -0x4a83fff8, 0x2bf1095f, 0x20c2bffd, 0xbca3a173, -0x8401dfbc, 0x83105353, 0x972193bc, 0x2993f67a, -0x8c35d677, 0x0c252c66, 0x5f1e71aa, 0xb98fd757, -0x3643fcf4, 0xb3765fe2, 0x8600233a, 0x06fc4590, -0x5ad345ad, 0xb3278dd3, 0xd44b139b, 0xbaf74e42, -0xe5aa65ee, 0xcd805957, 0x09febfe1, 0x8f10ce02, -0x81cb3fa6, 0x5626278b, 0x72fa21ea, 0xd8ff7cb0, -0xa630b63e, 0x9980b352, 0x46ecef9b, 0x6d03626c, -0x1964ae30, 0x3e6bbe08, 0xe608703d, 0x83f86201, -0x610fe575, 0xa25d9faf, 0xce02357c, 0x209ef877, -0x0d04b5cf, 0xa0fd2120, 0x3192020e, 0xa17bd895, -0x1f10032e, 0xf9a15cfc, 0x0c643c71, 0xbe729757, -0xb62b24a4, 0x7dd41f4f, 0x88b583a8, 0xf16d921e, -0x0fe396b9, 0x9d9d9a77, 0x20000241, 0x61c85db4, -0x638521be, 0x1d951e88, 0xa284b337, 0xaabe5c9e, -0x97a40559, 0xb2f20d59, 0x885a02d6, 0x165e152e, -0x2796f0da, 0x9b5b57d4, 0x07b9090c, 0xb9a8bc39, -0xba844c15, 0xbd9bd74b, 0xff355da8, 0xb385ca2d, -0xec5f4117, 0x3d4af9b8, 0xdfac828f, 0x92e2080e, -0x65696e35, 0xb44f5e41, 0xc2734dec, 0x36a677b8, -0x65982d86, 0x04e84c6d, 0x238aaaaf, 0xfae7e9a8, -0xa03bb61b, 0xc16e0305, 0x4a0764be, 0x2e56a853, -0x81216092, 0x63e342f2, 0x4a1cd397, 0x4bc4285f, -0x4110213e, 0x18b58083, 0xd11d5a5f, 0x82a0e6f5, -0x10436c53, 0x6564b86b, 0xcae1a418, 0xc2c38a41, -0x686e097e, 0xc67f4bda, 0x674e6ff8, 0x34e18245, -0xf5d7e68b, 0xc829c2ab, 0xdc22eacc, 0xf862a244, -0xb4057d4a, 0x9fb00332, 0xd50b0eaf, 0xa8a0bfbc, -0xf63d6db2, 0xfa3e4c0b, 0x60b2494b, 0x3c6ebfef, -0x044ef356, 0x082e54d3, 0x7e57f91e, 0x8d4acaa4, -0x31684817, 0xb4731f17, 0xacd44c79, 0x23c1e0d5, -0xe01156d6, 0x539d11b5, 0x7e606458, 0x82a5769f, -0xc54b7362, 0xf9ebadd6, 0x269bcf3b, 0x4bea7201, -0xb1de3e7e, 0x8e095996, 0x1ae2e7af, 0x2e49f015, -0xd8f34325, 0xbbd34107, 0xf42d8640, 0x24765cef, -0x5cf949de, 0xc314ee1a, 0xef5d3635, 0x14030991, -0x4ce7f704, 0x08690d06, 0xcd3360b3, 0x305ab52d, -0x627a7be5, 0xe8556b25, 0x7556d670, 0x7cd14455, -0x1a41f12a, 0x159465d8, 0x5fb182e6, 0xcd67faff, -0x3e898764, 0xaede02c6, 0x54a1098e, 0xa46fcfcf, -0xcf7ce909, 0xe5abe97f, 0x427651a3, 0x9d6cf5d5, -0x25bb56e8, 0xa2a1f9b0, 0xfed4d48a, 0xb4187602, -0xcf6fc3b2, 0xac1aadb4, 0xe5c8152c, 0x59440305, -0x0d83b110, 0x85f16574, 0x97eb47d1, 0xe1b7755e, -0x3fe387b2, 0x730d856f, 0x1b3bc656, 0x21882a28, -0x46e1d427, 0xcfec7d37, 0x7bf0682d, 0xff0030bb, -0xd7777805, 0x2962d76a, 0x8ccef0ae, 0xc80cf897, -0x2d6b7578, 0xe4d439a1, 0x5294cfbc, 0x4070933b, -0x006ee9ef, 0xf2a81dc0, 0x94329cc1, 0x18bc1e34, -/* 620-MU26a401.inc */ -0x00000001, 0x00000001, 0x06162000, 0x000006a4, -0x144a06e8, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x94a2ee8a, 0xbdf9b67b, 0x12e65ed0, 0x09038b3e, -0x792b3c3c, 0x46cb86a2, 0xbc00807e, 0x17aec02d, -0x18a58dae, 0x9f04ff03, 0x76e4b9ab, 0x0248e1fe, -0xcfcc1f1e, 0x33203083, 0x320735f5, 0x10da16f0, -0xf64d147d, 0xd590a640, 0x690873bd, 0xfebe5923, -0xf715c48d, 0x9587ed21, 0x28b5354c, 0xc5dcffc7, -0x36d0d3e1, 0x13c536f1, 0xd1397d6a, 0xa5449667, -0xd3d7c747, 0x20375d46, 0xbaf824a3, 0x408c10e8, -0x8446f0eb, 0x5212cbcf, 0x7e3633fa, 0x5d071088, -0xbb7c4569, 0xc5f08a77, 0xfc085388, 0xf2f9cb6f, -0x2504a442, 0x9fa5c6df, 0x9277f171, 0x4db738f5, -0xbc6d658c, 0x06aca6db, 0x57e5a2e3, 0x5d58f006, -0x068ac2db, 0x37268b87, 0x5c73db56, 0xa7d8be99, -0xff1305db, 0x2cc71495, 0x007ecbc5, 0x1979d587, -0x1a547151, 0xdadd1154, 0x4b437b61, 0xa91d1cf3, -0x87df0a53, 0x9dabe192, 0xa933645a, 0x562d8100, -0xbc11cf6c, 0x74855a93, 0x6ed06c84, 0x8cfaa6e1, -0x8c673650, 0x3c766bf5, 0x4e2f9e35, 0x12c9fc4f, -0xb1890a56, 0x75ee5152, 0x19b4ccd9, 0xef5d0abb, -0x796e9870, 0x9ffa1631, 0xd752c918, 0x99e69e79, -0xf7df0ff5, 0x7d7a963d, 0x6f0e1b7c, 0x74c97cc4, -0x8c025a65, 0x2188487c, 0xd84a0afb, 0xd7e28f22, -0x120b3835, 0x81cee0f0, 0x82ce7884, 0x1a4d0572, -0x41ad1fb7, 0x7d9ac754, 0xca35f0f7, 0x4a07ec7f, -0xb42e4a38, 0x5c9967a1, 0x86be58b3, 0xae823a5b, -0x38fa40b4, 0x6e869ed7, 0xf5e2e363, 0x22337781, -0x00cb640e, 0x509ef4ef, 0x8cd8669c, 0xda4635b6, -0xe42d2ab0, 0x49e70e9e, 0x8d39a0bf, 0x5f2a120e, -0x511969ed, 0x2d8fe6ad, 0xcee3f6fc, 0x4bd6ff61, -0xb17e0477, 0xac603627, 0x4326ed12, 0x4b923741, -0x8fc4bd46, 0xfee4e542, 0x84cdfc91, 0x2be0c360, -0x8e8192ea, 0x1379b18b, 0x02fe7545, 0x18bad614, -0x0eabe9f8, 0x98f9aa1e, 0xe58be654, 0xdfedb4a5, -0xb746598d, 0xfd89af05, 0xe9f0b493, 0x85abfc78, -0x3332898c, 0x168f4bab, 0x0a39229a, 0xb344881f, -0x805e0c63, 0x6b2f1943, 0xeb0d46dd, 0xc7ccb7ad, -0x9b2433b8, 0x03e5cd29, 0x5100773c, 0x4e5a507c, -0x5c43d05a, 0x99be68a6, 0x92557ce0, 0xc7bc15db, -0x785a9b2e, 0xd82b4aca, 0xffc8110d, 0x61a8c353, -0x7bdc211e, 0x84dc14ae, 0x7a08baa7, 0x541b9af9, -0x253b4ee6, 0x8a470dcb, 0x902d9885, 0xdbbf5fcf, -0xfad85625, 0x1217bab9, 0x99fb5020, 0x928c92a4, -0x7a9ad6c9, 0x53afb816, 0x58694a97, 0xb1394297, -0xd005898f, 0xc382c648, 0x3547eb3e, 0xde6213b5, -0x255b6be0, 0x6465df4d, 0xb4dcb4f8, 0x78b2da95, -0x63881ecc, 0x6e9cb6e1, 0x168e0b43, 0x132030f9, -0x07b0b217, 0xd78367b8, 0x6eb45755, 0x561539d6, -0xab95467d, 0x79e25e41, 0x521a8557, 0x0b9988d2, -0xd2aae0e3, 0x9e2de68b, 0x8be791f3, 0x9adbe8c9, -0x76952511, 0x610e5d5b, 0x7eb7fa10, 0xbe8d959b, -0x1e41821c, 0x65f9853c, 0x8ae8a4ad, 0x30446566, -0x9489b295, 0xaa108405, 0x9dbca7c1, 0x8551c3fc, -0xe253a71f, 0x8cacf235, 0xb7dd1794, 0x875638ef, -0x363e9a55, 0x3b059e9d, 0xfb545a0c, 0xa3e1d66d, -0x6cacb56f, 0xf0557939, 0xe64432ce, 0x36134c15, -0xc98489e1, 0x4033844b, 0x8653e914, 0x69781219, -0x4cb5a206, 0xbc1b463d, 0xc4b0a4c0, 0x0db7a044, -0x5031a9d0, 0x480c8be2, 0x64ea2531, 0x891b0ec5, -0x464245a8, 0x63587a97, 0xe6039cdd, 0x8e79b9a5, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 99-B_c6_612.inc */ -0x00000001, 0x000000c6, 0x12101996, 0x00000612, -0x374569e7, 0x00000001, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x600e7f07, 0x34a50449, 0xfe3b9fa3, 0x255f83ab, -0xe6f4e55b, 0x882b9a25, 0x43e8e8b8, 0xf6f90f25, -0xf3683883, 0x544f4e68, 0x92c02e03, 0xf7ee75f8, -0x2325cd70, 0xf1d82ad7, 0xfc5c0799, 0x4545c978, -0x99535b46, 0xc8a2703c, 0x28898193, 0x8d9eb4e7, -0x9239de7c, 0x4c7c4135, 0xd0e5f120, 0xb7423567, -0x79fed144, 0xad1503d1, 0xe7f89b9e, 0x51c26ce8, -0xd35a11f4, 0xbc22f731, 0x571efa4a, 0x8d97c169, -0xb572cb4d, 0x1e694663, 0xb0b180b4, 0x99b03f0d, -0x14275fda, 0xd3c4ea94, 0xbe8d3ec7, 0x6e56592b, -0xd3981563, 0xaefe540a, 0x51d675a2, 0xdd9895a5, -0xc6d8a40f, 0x7b0d4b23, 0xa3f32010, 0xc02780df, -0x42ab6773, 0xea512768, 0x9d0123ce, 0x453529f7, -0x91b3fb17, 0x91b305e9, 0x78a7614c, 0xa3bac298, -0xdea9c1b8, 0x4d0d8a84, 0xa186bd69, 0x8abc794f, -0x4c65b6a2, 0x8345eae2, 0xa2bf2ebf, 0x20503568, -0xa6fb8d32, 0xfb5a9606, 0x354f7358, 0xeb1e94c8, -0x91026281, 0x3e6e4afb, 0xbb03a8bf, 0xce8f070a, -0x0d6fe013, 0xe6a52091, 0x903e3b0c, 0x705cf281, -0x91ca2d06, 0xe5c5f3c4, 0x420171ef, 0xeaf55757, -0xe7a73ebc, 0x486bc315, 0xd25e9d4d, 0xe118afeb, -0x2227b996, 0xa893777a, 0xb23ed386, 0x08924fea, -0x9610c4cb, 0xb3c9bac3, 0x0d9e201c, 0x82bc5fd5, -0xf57cb5c5, 0x0e41e967, 0xe4260c86, 0xe04e6f45, -0x56815cf7, 0x9910831d, 0x955414aa, 0x4193b3c3, -0xb75d195c, 0xa571a238, 0x16c4cde3, 0xa838f3b3, -0xf3cd0b58, 0x736eb039, 0xf2f30a3e, 0x8bf2982e, -0x0001c8b0, 0xdbd68459, 0xabaf0fa6, 0x0f0e0d33, -0xe27f092f, 0xf46e569f, 0x5293f361, 0xecca67de, -0x94600d79, 0x4b30a042, 0xee439c71, 0x8b71724c, -0x1d3f7c10, 0xf24d3e96, 0xcde53f89, 0x6b807ace, -0x86f6e522, 0xb1095929, 0x16ff4902, 0x87905b40, -0xb2797fb2, 0x55431fe9, 0xa80a5524, 0xca21bd87, -0x2d8fce84, 0xba3dc49a, 0xc774bd4d, 0x06d6bdfa, -0xbaf33ea6, 0xd754408a, 0x0329049a, 0xa6400a5d, -0xcde7331c, 0x4e06a769, 0xa61d2cdb, 0xdd5288db, -0x0155560d, 0x9d7bf35b, 0x8ff6ebe9, 0x62aa9d79, -0x8ac240e1, 0xc5599827, 0x10311f4c, 0x20832e69, -0x8823b4e8, 0xac7a47fc, 0xc30a0bb7, 0x1599d765, -0x48a8f706, 0x395813b4, 0x244ebbe6, 0x5ad00326, -0x38d70889, 0x282bf21e, 0x470725e0, 0x77d5573b, -0x5242eb42, 0x5454d767, 0x57086bf8, 0xb37a0e71, -0x1c58e22f, 0xac3dc2d3, 0xd9720857, 0x65748bc2, -0xa98e8103, 0x83d0179c, 0x69dddabf, 0xcba6623f, -0xabfb85de, 0x65150a2d, 0xd3e751cf, 0xb9855add, -0x600f83bf, 0xd0398ae8, 0xee5334b6, 0x5e97b937, -0xac94baeb, 0xb420804f, 0x04ecb7bb, 0xe9ba8428, -0xa4eb1abc, 0x6e721296, 0x806c3a12, 0xb5d9d984, -0x0b5a5b5c, 0xab942e26, 0x69d5eb61, 0xfe1558c6, -0x1d7d357d, 0xccf926d5, 0xc8cb8d85, 0x66e124ac, -0xc757e3af, 0xe680d3de, 0xc9ab585e, 0xd71707c6, -0x18078df2, 0xb8184b56, 0xdbce6fb1, 0xf730feb4, -0xac121b92, 0x2d4a8fa4, 0x243598f7, 0xdb4662a7, -0xf0b64a74, 0x79ebd5f3, 0xb4c4c898, 0x3b0bea3c, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -0x278cb2c0, 0xf41d6be8, 0x839b9b57, 0xde7df900, -0xa6d05386, 0xf79d8944, 0x24d4273d, 0x878456fe, -0xbc0006e2, 0x4cbc49c5, 0x16684d87, 0x1f2c79a5, -0x847dc8fb, 0xe873c43a, 0xc92223f2, 0xc9c193d4, -0x8f43d21d, 0xc723f894, 0xa0ed9e53, 0xd0693391, -/* 1339-m04f292e.inc */ -0x00000001, 0x0000002e, 0x08112004, 0x00000f29, -0x7695d4dc, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x3329bed4, 0x074ca74b, 0x76a4c9be, 0xb3d0ac3b, -0x59c1ebd3, 0x9d06facf, 0xa272f2b8, 0x185d2aed, -0x1dbb2394, 0x86f96351, 0x12652c86, 0x873bf0a8, -0x4f6956f8, 0xbc5754f1, 0xd43f9485, 0xb0484217, -0x88993f58, 0x071366b3, 0xbb49ef1d, 0xb8ec50b3, -0xd6dd7d67, 0xafae9594, 0xafbcf523, 0x04e3cefb, -0xf6125942, 0x6c58f3aa, 0xa28b05f4, 0xbb31e4f0, -0xde633bba, 0xc2cc4d76, 0x2fc95cef, 0x465474bc, -0x6148f606, 0xa8245d1a, 0x167d68d0, 0xc38533b2, -0xcbfb5881, 0xb912dc66, 0xbb9cc137, 0xbaa2ca73, -0xa9cee564, 0x3edd2b89, 0x2e3ffeed, 0xa68b49eb, -0x0b85b10b, 0xb968370f, 0xd5c4deb8, 0x2d2883d4, -0x288e44af, 0x37b10c8a, 0xa75c2ef5, 0xa5242ad7, -0xff96f783, 0xab3f2161, 0x3921290b, 0x1094e053, -0x9eae586d, 0x9878a4f3, 0xa2d41b7f, 0xb29cc218, -0x93898d3c, 0xdd152eec, 0x638ab207, 0xa7536a0f, -0x5accf54d, 0x798a56a0, 0x8e925de6, 0xe2fec0a0, -0x8b6100f7, 0x910d43f8, 0xb3bcb1ab, 0x3f032f10, -0x667b024d, 0x5303ab2e, 0x50a68459, 0xdbdae9ae, -0x61cab195, 0x8b080d7b, 0xe1c9c484, 0xc0a9cc33, -0xf3c786cb, 0xa226e2f7, 0x4509e980, 0x2ff4bb80, -0x943a2b9b, 0xb0e2d78c, 0xdce9f9df, 0xb9302df9, -0x2f095be2, 0x46f9e8cf, 0x097129ec, 0x5f7ba01f, -0x49e26e4c, 0xde9ff6ce, 0x5d194de6, 0x9114a73f, -0x5114f3e1, 0x9832e8b3, 0xd116f967, 0xfcddf0e7, -0x3011f78c, 0x5d84b6d5, 0xb465a082, 0x8eb129ad, -0x5390d983, 0xdfad741a, 0xef927af0, 0xa062e4fd, -0x94a1b0f5, 0x6c9dcff9, 0x15192e6a, 0x11a1f0b8, -0xbc5f9758, 0x01c1070c, 0x6f5a81c6, 0x7ee5b238, -0xdf75b957, 0x8b5cbac1, 0x5f7cd16a, 0xf7faa6dc, -0x5b74dbb5, 0x0980f147, 0x4aa350ab, 0x7e96c732, -0xdaeacc94, 0x29fd397d, 0xf62b5325, 0x3c519a56, -0x5dbc6524, 0x201364ea, 0x05ee717f, 0x39c8c28c, -0x9ab2580c, 0x95550f9c, 0xfb0eb0ac, 0x242c6155, -0xdd52b4d4, 0xa04672cf, 0xa81f5b28, 0xac10d5f7, -0xd6afd049, 0x323e700a, 0xb710054c, 0x88b48cc0, -0x4c1d370d, 0xb303457b, 0xbc5bf726, 0x2dfc0600, -0xa86d0d2e, 0x9ec95b49, 0xeec42301, 0xa0ddf041, -0xd3697b0d, 0x1cf23cd4, 0xe511afa1, 0x99677ab6, -0xcb82d8fe, 0x03d837ed, 0xcf59b6eb, 0x117c6438, -0x793db420, 0x01210ef0, 0x2f16aa63, 0x092aa912, -0x188fcfe1, 0x0cd78643, 0x4725f2b0, 0x141b4064, -0x060cb591, 0xdb59b5b9, 0x08ca7893, 0x03b02ee2, -0xefdabca5, 0xedc23083, 0x48d71720, 0xc44417e0, -0xb0f5f326, 0x04e0ca58, 0x1cbc21e9, 0xc47f8d91, -0x5465c94d, 0x6f5c300b, 0xce250158, 0x39d3ff3f, -0xb9ba60a4, 0x7e15fc75, 0x6481b42f, 0x4a822d4c, -0x6b251985, 0x01c3f0ff, 0xb961c2c0, 0x56233348, -0x4322f327, 0xfaf3a4b4, 0xa5e2f209, 0x0086e35f, -0x5665e8c8, 0xd284182d, 0x7c66dc76, 0xdead8651, -0x3948f967, 0x29e2cdc5, 0xa85bf1c4, 0xfc81e608, -0x95129e56, 0x39e8ccc0, 0x8a55171d, 0x0ca75f6d, -0x76b3b76a, 0x07063184, 0x40a355b6, 0x0dc9ae64, -0x2f0bcdc9, 0x3c98d57e, 0xbd9f6fc9, 0x0b3b70e8, -0x6598b670, 0x98adb5b0, 0xe38efec2, 0x1b72b2a1, -0xd7760f5b, 0xa5ff1aa2, 0x21d65a27, 0x85170ab7, -0x4f19b28e, 0x147ab845, 0xc61a001a, 0xbf15e323, -0xbea79403, 0x0e9fd315, 0xa5ce5dc1, 0x3dec0102, -0xe344f20f, 0x26772148, 0xe3c335c8, 0x14698661, -0x02045f22, 0x1b9fe294, 0x18fd4760, 0x2b0dcc84, -0x3719068f, 0xe16a4bd5, 0x69b449a0, 0x088176ec, -0x66231f59, 0xe4c8477f, 0x3ccfd123, 0xd67be9aa, -0x8df1652c, 0x11f29283, 0xb13a6168, 0xd79e71f5, -0xdf064c6c, 0x63bbaea0, 0xa32b027f, 0x17fa40de, -0x62dad42b, 0x4a2ba3d1, 0x97566ec5, 0x7ce0870a, -0x7c6ac399, 0x075eae21, 0x02811d28, 0x6effb228, -0xbdffa992, 0xfc9706c7, 0xa2c158ad, 0x3a407afd, -0x94b88ec5, 0xc9019e3e, 0x10cf018e, 0xf08b1e2d, -0xaa09594a, 0x0d896d4a, 0xf83a743f, 0xfc82a2c3, -0xe863355e, 0x619ef2f4, 0x2170df86, 0x34112254, -0x615d93e1, 0x7c25d947, 0xbda74d18, 0x4188f6d8, -0x02a61d07, 0x262bad07, 0x3939c06e, 0x76480101, -0x26697ea6, 0xfce41af7, 0x9bece83f, 0x309c0b9e, -0xdfc2bc12, 0xedcccfee, 0x4f095c0d, 0xd9b08cce, -0x45da7530, 0x2f8e37c0, 0x5f273652, 0xc13511e0, -0xcdb90088, 0x79c7d87a, 0x3df67681, 0x05a0a8d3, -0xf2d2756a, 0x56041d39, 0x185b97c5, 0x62644b35, -0xba24ad0c, 0x0d8ba3a3, 0x90e4793a, 0x4a04a884, -0x05e64fdf, 0xfe710b2b, 0x85703d05, 0x1abc37e1, -0x8db28c4e, 0xdde1b1d5, 0x03682e82, 0xf4d092fa, -0x067f6a0d, 0x3c142430, 0xf2d8bc9a, 0xf546da72, -0x660ec359, 0x4171e4dc, 0xa29d94b2, 0x151add4d, -0x57f35f12, 0x7258f732, 0x9db66fba, 0x77e39897, -0x8a8711c7, 0x1f5db10a, 0x58792090, 0x68600a9a, -0xb2a89ac2, 0xa4a1f018, 0xc27e695f, 0x00aabd02, -0x3f750dbe, 0x9a2e2bd2, 0x70ac647b, 0x9959d044, -0x7669de0e, 0x2f98c181, 0x1c25a4fd, 0xbfa6a204, -0xfb47f2d8, 0x440f46ff, 0x53a2dcfc, 0x1bf83a80, -0x2d0b22d7, 0x4f518fde, 0xc1d17dbc, 0x7e92459e, -0x95608150, 0x04486d5e, 0xd30e6f8a, 0x7e5a4a39, -0xb01dee81, 0x04e7acdf, 0xf7ada4a4, 0x0795880e, -0x26dc8256, 0x0a5aa3c3, 0x8f029565, 0x2f470e3c, -0xa373fc51, 0x1c7e7b45, 0x267796b8, 0x1bcb4991, -0xcec801f8, 0x6c9a6957, 0xc1ce18c5, 0x043c7ab6, -0x3bd723ed, 0x6093b8ab, 0x2f768aa1, 0x4c6de3ce, -0x71b2965a, 0x31ed9427, 0xbdab13e4, 0x7e9eba94, -0x06508808, 0x5867bccf, 0xc0c8c85d, 0x846300c9, -0x03891b7b, 0xe1150b81, 0x56116659, 0xdff07740, -0x6eb9e465, 0x3a8a5801, 0xc54290e2, 0xeef47a33, -0x4c71e22d, 0xd1dcc6be, 0x7075ccca, 0xa14f574c, -0xfa205fcc, 0x71fd97f4, 0x285b90c3, 0x6f4ec636, -0xe5fcc6ac, 0xaaa6e7b4, 0xb02d6ce1, 0x8e6fc58c, -0x0d8c03e5, 0x5f1490ac, 0xa7c85aa5, 0x079a36a1, -0xcf0a5098, 0x596d1e33, 0x23a0615d, 0x90b97898, -0x7bc12833, 0x5c6b310c, 0xb72adacf, 0xff8538e0, -0x750587e9, 0xcda7274f, 0x7e439b7e, 0x57e0932f, -0x3fc98dff, 0x92a8077e, 0xff3c4325, 0xee308b69, -0x72caf71c, 0xb2f163f8, 0xc024caa1, 0xa86d0b31, -0x14b28f1d, 0x2961b1f3, 0x8d2082c1, 0xad0918fb, -0x8ec25b94, 0x84f5ec2a, 0x7a354fd4, 0x7a49c860, -0x1402776b, 0x420b3355, 0xdb1de128, 0xe172496b, -0x85a89831, 0x648abaab, 0xcdc11dd7, 0xfb2f1711, -0x8c426c31, 0x00bd97e2, 0x9a91f509, 0xab959673, -0xc0d4e1a3, 0xf4fe6c5f, 0xdf597cb8, 0x59fd4c80, -0xbf0b9c60, 0x650d7e3c, 0x5cd34a1f, 0xc16ae184, -0x8b7dbd72, 0x6640b6a1, 0x8a8ee15a, 0xb0c36bac, -0x6c489ecf, 0x2a15e446, 0xc8546da0, 0xf83856e8, -0xa825a813, 0xb6d8332d, 0xceec0377, 0xf19cbecf, -0x069c28e8, 0xd889195f, 0xd2dbf4d4, 0x28934dc5, -0xcc113de4, 0xdcdd0feb, 0xa04df5f3, 0xc443666f, -0x4f8c2b41, 0x3384a41a, 0x72890c0b, 0x728e69fe, -0xc039391c, 0xf63d92a5, 0x91d700bd, 0x9007116a, -0x5c6eaeb8, 0x4d65fcf1, 0x13551d94, 0x203a4079, -0x1e65fad6, 0x89538401, 0xcff93078, 0x02bc1716, -0x096c8d48, 0x0b4ab7d8, 0x236945c8, 0x894ef357, -/* 1101-m02f2738.inc */ -0x00000001, 0x00000038, 0x06042003, 0x00000f27, -0x6d330d4a, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x0000005e, 0x96f952a6, 0xaa368f02, -0x53d271e6, 0xf8286513, 0x484b4e9a, 0x9e0c09c2, -0x03b11314, 0xdfb67c98, 0xa2957d16, 0xf07f25de, -0xb84a2555, 0x72ec8b35, 0x3445c734, 0x7744f543, -0xc3da0cc0, 0xeb36172d, 0x8b2cf574, 0x29c867a2, -0xe79dfaf0, 0x54714bb5, 0x524dfb69, 0x0df65433, -0x0b95ec14, 0x3dc09ca2, 0x584ba068, 0x2aa558ce, -0x8cd679c8, 0x3b2609d0, 0xa06306d1, 0x80bfa93a, -0x482678d8, 0x0cdf1ce6, 0x5ec4e912, 0x8a19f7a6, -0x76f215be, 0x577d92c2, 0x479cd4ba, 0x63d1f415, -0x5af98bc5, 0x8889bb4f, 0x8e70943d, 0xb5528299, -0xfd63e347, 0x836fcfd0, 0x4951a701, 0xf4613cdb, -0xaa7c2f52, 0xa0e290c7, 0xf646a80b, 0xda5b5a03, -0x93517b47, 0x553d99d1, 0xafac198e, 0x486b6c6b, -0x4efa01d8, 0xdc6ce226, 0xdac3a149, 0x9b7cf27f, -0x6c6246a0, 0xb6055a39, 0xb68cc841, 0x87b6adee, -0x1c36edb4, 0x3ee76d20, 0xdbffab67, 0xed12fda6, -0xc1aff2f2, 0xc110932f, 0x0933ccfe, 0x58fa2281, -0x285d5ec1, 0xd05b216a, 0x76315645, 0x570c5c8f, -0x6cc52f1c, 0xaa977e52, 0x066f4e03, 0x812bfd2c, -0xbfbfd7a9, 0x70828199, 0x60182af7, 0x2a04e000, -0x30f413b7, 0x327cef32, 0xac73aa51, 0x7c418d9f, -0xf493ce0e, 0x6c14258d, 0xa5e2755e, 0xd39f994a, -0xee638b08, 0x55d50476, 0x9b7afc5c, 0x5da2ed13, -0xb75bf9f4, 0x2606c01d, 0x8a1d00eb, 0x0f73428f, -0xb29c4fb4, 0xac13e554, 0xa7648fe0, 0xbe56837b, -0xd34fa9ff, 0x59c855a2, 0x7d3cc7d7, 0xb5b0cb50, -0xe6626c0b, 0xf07010b7, 0xd8054587, 0x01a5327a, -0x3ceae28b, 0xa3bf737f, 0x3d1a37e7, 0x6ce48d1d, -0xc9d91222, 0x42f28fae, 0xe8dff3e4, 0xfd6898d0, -0xe772ab47, 0xbe452c12, 0xf188ee09, 0x08edb79c, -0xad4d48fb, 0x5cb75d1d, 0x251f4e02, 0x6b7bb6e3, -0xcada2f09, 0x536d74eb, 0xacfa627a, 0x51e2ffd2, -0xe4655767, 0x311dbbec, 0x1011b68a, 0x6f6e8deb, -0x4298665d, 0xc0522b3c, 0x2c3a19dc, 0x2c48f2ae, -0x49bca621, 0xb6a747fe, 0xa1606c81, 0x9b2a5318, -0x0ac114c3, 0xb5b35aa0, 0x3f4ee00d, 0x8b427e75, -0xb539fcd3, 0xa99fba84, 0x821fc647, 0xe0ac6d6e, -0x912f6f88, 0xf2009cd8, 0xb32330b3, 0xd0b80514, -0x6f25f157, 0xdba2f463, 0x88ef17d1, 0x147c5f21, -0x6e29cd75, 0xec14e5d1, 0xdcfffd24, 0xccc2c510, -0xe5e40798, 0xb24814e1, 0xaf0cdaf2, 0x825cf5e2, -0x12acac6b, 0x439c5f36, 0x0c533619, 0x8e776e71, -0x319b44f5, 0x19c0b404, 0x54111b2a, 0x6a767513, -0xb16944ef, 0x30ef18ce, 0x85df0862, 0x0737ff49, -0x77fe06f2, 0xb2de0d2f, 0x71625e95, 0xc722c5a2, -0x03b401a9, 0xe8b030b4, 0x7f9e62ab, 0xbff8c966, -0x726bfeca, 0x6adf3831, 0xab85067e, 0x5167e87a, -0xb06ad00c, 0xdd974309, 0x5704880d, 0xb7279a43, -0x38aeda19, 0x52f5a31f, 0xd66d79e2, 0x83dad3db, -0xa138d066, 0x0b4674d4, 0x07e7dd7a, 0x7f5c70c7, -0x4aade5f0, 0x4fcd220f, 0x2ae8ab6f, 0x6fb11f68, -0xbf134ecc, 0x71d3125c, 0x3cc3f6ba, 0x92809507, -0xb4a9b236, 0x97a2ef5f, 0xe20e5f23, 0x5610bfa9, -0xad16eba9, 0x5207dfba, 0x0caa3d20, 0xc57cccba, -0x7983d15d, 0x09ced949, 0xec698959, 0x53a4b153, -0x63c74107, 0xacf58270, 0xbc2982cd, 0x42bf9c41, -0x26aff8b4, 0x9832bd6e, 0x34e98158, 0x434f0f43, -0xcb80ccda, 0xd81471b6, 0xbd176071, 0xab13735c, -0x4e80e2c1, 0xcf7815f0, 0xb4e6ae37, 0x1a90c457, -0x79426d6f, 0xa4ac1e2c, 0xf76de77b, 0x1808cd61, -0xd72ea071, 0x1f02af0e, 0x9613b531, 0xe83f2e9a, -0x99a5262a, 0x0e8a756d, 0xbc229ac4, 0x2cb1af6b, -0x8a8720d6, 0xc84d2c77, 0x8547ad96, 0xeb794e72, -0xb51119ea, 0x1c0121ea, 0x9f8ae83b, 0x16459999, -0x5c17deaf, 0x278a3e3b, 0xf2bbb704, 0x54df1a00, -0x521ef94e, 0xd40de734, 0xca5badee, 0xa2fe3027, -0x2ffe3ada, 0x1df00fb9, 0x5feb168c, 0x81674308, -0x99713c0e, 0x56aae017, 0xe62e68f3, 0xaa15163a, -0x31ac7b10, 0xe6a86d9c, 0xa006782e, 0x9baefc91, -0x111277d5, 0x80f63a4b, 0x624044d6, 0xd91a5de5, -0x5d0255d6, 0x92b82310, 0x08faf5e5, 0xe482ff69, -0x0a1f1757, 0xdc010e34, 0x9cd07e48, 0x677fcfa3, -0x0384138d, 0xa104220a, 0x5431c7ec, 0x0e8b7efb, -0xf1ebcd61, 0x97ae7029, 0x191ff006, 0x4308b147, -0xa11e05f7, 0x2c7cb5a4, 0x1d345971, 0x28d23638, -0xc5a7a5bb, 0x3307c971, 0x0d3782ae, 0x2b798842, -0x1fc27334, 0x4ff82ddb, 0x543ba685, 0x47732c7a, -0xad094a6e, 0xb8ff60e4, 0x43f9ee2f, 0xe9a114e8, -0xf036be6e, 0x3fb488a0, 0x280b2d46, 0xb1887c58, -0x54ae583a, 0x454b6ce6, 0xe617a2c1, 0xb9335ac3, -0x72361e12, 0xc856637a, 0x741b6cbe, 0xcf1f6f25, -0x9f405fff, 0xd2525b02, 0x22d8b05a, 0x16860f11, -0xb02983e9, 0x388b9c2c, 0x196cb2f2, 0xfca5f1a2, -0x9e60965d, 0x5bed99ff, 0x59e361fc, 0x9361bde8, -0xa1527365, 0x3f300237, 0xb0f5e2b8, 0x8fb00a40, -0x71cb9744, 0x3327e8d3, 0xe89994d4, 0x3987e389, -0x28c6d8f7, 0xb2ba9fc4, 0xdf109e0e, 0x622634b2, -0x4904a82e, 0x576c3c2f, 0xe95eae46, 0xfb773013, -0xf98b91de, 0x4edc30d5, 0xc6e60080, 0xebefab96, -0xd7684df2, 0x9cd2c3e1, 0xd433902a, 0x7b9aa9eb, -0x3c99cbaa, 0x5a0fa53d, 0x77297830, 0x869db621, -0xaee2d56a, 0x2ce907c1, 0x0aa5097c, 0x662e7862, -0xa5bfbc61, 0x2610f3bf, 0x3a741865, 0x99a5836d, -0x2e533e3b, 0x812aa485, 0x0d7eb66d, 0xb325db47, -0x6ac77937, 0xa1757eb7, 0xb7765633, 0x8845f18f, -0xde7e37f8, 0x08a17789, 0x8af720ca, 0x1f7a530f, -0xadcbb072, 0xd02e2dae, 0x16fbe58f, 0x0e4df085, -0x80663766, 0xdcff020e, 0x4c242d70, 0x3d16d122, -0x154a029b, 0x40c95a2e, 0x5f98eb6f, 0x637ffc42, -0xcdf10a5c, 0xf2211055, 0x998ddc8b, 0xcee90fd8, -0x1ddc7fad, 0x7034d80c, 0xf5bf0592, 0x479205bc, -0x0900e9c9, 0x7bef8c77, 0xc128cebf, 0x9e7dd814, -0xedca7a5e, 0xf15af942, 0x40e55228, 0x065ea7ce, -0x9603da92, 0xa6611211, 0xea9dad76, 0x4fd9d974, -0xea19cb68, 0xeabf508d, 0xd460f6c0, 0x3951733a, -0x249a4453, 0x04356966, 0xac6ec71e, 0x5253e669, -0xfca78245, 0x8ef4d888, 0x6c031fe0, 0x8c49e3df, -0x67cd07b8, 0xc916f082, 0x3a350c13, 0x17a9b757, -0x5681f1c3, 0x0e656ece, 0x2ae1d3df, 0xb9cd5476, -0xd425f4e0, 0x8b45dee8, 0x8f02eb98, 0x6f00c0fb, -0x1b90977a, 0x521e8094, 0x9b5b08ec, 0x5b504450, -0x449f84f6, 0xb63e6384, 0xf389e505, 0x0b2aab9f, -0x945ecdbf, 0x721a5b10, 0x6a2c6884, 0xd74f9926, -0x9c178148, 0x1f44fd1b, 0xf63a6ffa, 0x4506529a, -0x797d01b4, 0x442147f8, 0xc90a759b, 0x44f0a0fb, -0xdd26e42c, 0x55fcf1d5, 0xaeeee197, 0xbee8c900, -0xf8c70f2f, 0xc32d2eee, 0x5857e821, 0x5ac38d25, -0x873b3c45, 0xa1db703a, 0xf1b7a2a6, 0xc2c7829d, -0xeecb2edb, 0x19f0fe3c, 0xd6f35737, 0x5000b318, -0xcd217d92, 0xc72ec374, 0x321b9e86, 0xfd256b8a, -0x7e9331c9, 0x8a7edd90, 0x8af83898, 0x222c1f2b, -0xb722eb67, 0xdc087998, 0xa512fefc, 0xa5c1bafe, -0x642b8b83, 0x3a617c41, 0x2d081db3, 0xda5ef119, -0xde847082, 0x83d113c3, 0x273dcb52, 0xafbf83b8, -/* 539-mu167210.inc */ -0x00000001, 0x00000010, 0x09221999, 0x00000672, -0x0fc53099, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x5880aae8, 0xfaf512a7, 0x94957b73, 0xde532d8d, -0x63486cc5, 0x03c40bc2, 0xfc37b015, 0xa2bb44db, -0x4cee0355, 0x0caf4096, 0x6a27b5f2, 0xa35d5645, -0xd215451c, 0xc44bbcfd, 0x3af5a7ab, 0xdc73f7a9, -0x6c7fd419, 0x730ed02f, 0x0a17f0ac, 0x0ff2cb01, -0x3568e8f9, 0xb66ffb52, 0x5a491384, 0x951e8f0d, -0xbdef7d13, 0x05bf66c7, 0x2eebe2ed, 0x8b3e282d, -0x6d4d2a7e, 0xa90e5a1a, 0x8da2cf30, 0x27a1e9c1, -0x4c213e6e, 0xe706acdd, 0x107f29d4, 0x8dab4326, -0x0c25a3c6, 0x6614b954, 0xd2da266b, 0x2492aec5, -0x23b67a43, 0x1ad8ec74, 0xc626d333, 0xa84fc0af, -0x1fe014b1, 0x7c571487, 0x0bd8f4fd, 0xb40b50f4, -0x96024e3a, 0xb7fb756d, 0x7b178f2e, 0x63f2f5eb, -0x6c4f0df0, 0x4082d795, 0xddc4c133, 0xdd61b9a0, -0x3b771dd0, 0x2ccb5aa9, 0x0ab1540d, 0x27277645, -0xf669cdca, 0x96dc652c, 0xe9b40689, 0x1c6977d7, -0x3668f5e0, 0x44c48a36, 0x5f86dcc4, 0xdd930f89, -0xf518d808, 0xf3bcc771, 0x3b146ab2, 0x6ab0215a, -0x7f8376df, 0x919dd4e5, 0x72af3e92, 0xcd238191, -0x9de0ba0d, 0xc7d99731, 0x3ffdb94a, 0x70a4c322, -0x3263d10b, 0xc9ab0976, 0x42674ccd, 0x291c4988, -0x178e5728, 0x325854d7, 0x1266fed3, 0x68cfa797, -0xb042263c, 0x83fbf8a2, 0xa1e42d77, 0x06f01879, -0xd4ba01b1, 0x43e18410, 0xad7c57c2, 0x929c65d9, -0xb52b0c58, 0x7bfbdfc0, 0x200e489d, 0xa805d3f3, -0x41c7d2a8, 0x8c7e1072, 0x5ad805c1, 0xf337886f, -0x256a5f75, 0x4292408c, 0x62b1aeea, 0xe0155a3e, -0xe9356b4f, 0x92b8123a, 0x69d788f6, 0x147c9899, -0x94ade173, 0xf1639fb9, 0xd27a0263, 0x55c7b9fd, -0xfbf3d168, 0x8b493de9, 0x5b3e6b02, 0xeb7e1730, -0x9a0e99c7, 0x9bb77bbf, 0x44b82682, 0xbea818e3, -0x0aac061a, 0xdfde0f65, 0x1219fe0c, 0x08db086e, -0x984f8dba, 0x64d669a2, 0xcb4a6056, 0xc335ec63, -0x003db584, 0xa2e85d9a, 0x62b5109c, 0x8979f26d, -0x25f87439, 0xda7b4ff9, 0x9b41ceef, 0xb166f52d, -0x3e12f451, 0xe6bc67aa, 0x105e378a, 0x56aa2225, -0x04ee1756, 0x0bf598ec, 0xfd0d75f4, 0xcc87d91d, -0xf3ab70be, 0x5719b2a6, 0x9c1212a7, 0x5bcfd4a7, -0xba07238f, 0x1e4571f4, 0x9e872e9c, 0x74ab36da, -0xc00d1a89, 0x2190f089, 0x12ee646d, 0x2895d335, -0xc3f4c779, 0x0294df2b, 0x6fe754f8, 0xcee161c7, -0x971aa78a, 0x8d067af4, 0x77626aa5, 0xb97bd5f0, -0x71f09e7f, 0x69cd562c, 0xa0893f41, 0x507b7309, -0x3cd26b46, 0x36ce6092, 0x0ae56616, 0x962c4698, -0x0aad0d3d, 0x1b7bfd33, 0x5e3712bb, 0xc66987e7, -0x42428867, 0x614a8b9d, 0xb1d127cb, 0xe5a965c9, -0x56a5a213, 0x240790c8, 0x745c0950, 0x897da696, -0xf65d24bd, 0x2617eea5, 0xd2349c52, 0x39b4fdd7, -0x5dfdfe3f, 0x0c3e4c1a, 0x10db9fc0, 0xf81bbcba, -0x4b5b0e28, 0x767511bd, 0x2b15bb50, 0x0349ec8a, -0x63481733, 0xbb899174, 0xd1065e6a, 0xbfa14024, -0xfaa727db, 0x0021f11b, 0x0a24c0c1, 0x9b55db09, -0x15ba31c5, 0xa972be16, 0x515e3cda, 0xd3d33e51, -0x5d372c14, 0xdd9160e4, 0x7c877e1b, 0x796cdcba, -0xf6faf1bd, 0x77048424, 0xb4ecd723, 0xb672c546, -0xfc152a26, 0x76423bce, 0x8a7a30fc, 0x005b181a, -0x79fc967a, 0x253e1b6c, 0xa947e4c2, 0x1d21ce72, -0x4e1dab59, 0x938eb0f8, 0xb4b0b387, 0x5fb04592, -0x2ee4a528, 0xe2d10729, 0x2f4c5f42, 0x873563ee, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 436-MU165142.inc */ -0x00000001, 0x00000042, 0x05251999, 0x00000651, -0x48947659, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x80627220, 0xd85bd855, 0x47639013, 0xd3cf398c, -0xe0a1aca1, 0x75782688, 0xbcbd0e4a, 0xd08d2101, -0x6cdce304, 0xa5cb0810, 0xde41a357, 0x430f1d76, -0xd77f20c4, 0xdc427548, 0x03599409, 0xd179d15a, -0xc05179c8, 0x06dcd88e, 0xe3f80686, 0x9d0068ce, -0x7cbe2fd6, 0xd12c8c55, 0xaac4bbeb, 0x23de94f7, -0x9b782d19, 0x9048d664, 0x3a742b9e, 0x806b6df8, -0xcabdd14c, 0x4809ed47, 0xf21ce6ca, 0xa7734c74, -0x5a2d1322, 0xeeb58f7a, 0x970d128b, 0x3dd69a0c, -0xe778f32b, 0xe9e401fc, 0x1894bfb4, 0xc7a36d10, -0x873ec296, 0x35639275, 0xb5689dcb, 0xb6cd13f2, -0x19c16f65, 0x8c82c105, 0xd09b0575, 0x1d027f32, -0xe96523fb, 0xecf75287, 0x16aa137a, 0x9bddca88, -0xd79586e8, 0x6959a6d9, 0xac21f8e4, 0xdb23fcbb, -0x101cb728, 0xb8f20d81, 0xb536da71, 0x773d69f1, -0xc838aaa3, 0xe88f671c, 0x45662670, 0xf5706933, -0xa820ca40, 0x792c651f, 0xca1a0b31, 0xd87f50df, -0x388a16ec, 0xf0d10ce8, 0xaa7cf7e2, 0x71ec5a12, -0xa1af36bb, 0xb1c61da9, 0x0ce8909c, 0xae710f96, -0xdeccbdb1, 0x21fd3a5f, 0xfb049d57, 0xfca6763e, -0x2e17f3aa, 0xf30e173e, 0xf1181dbf, 0x392eb4e9, -0xa85313fa, 0xe1bfaa6a, 0x4b9f3fd3, 0xb73ead33, -0xe8bd6226, 0x4f3f577c, 0x82331156, 0xf795e927, -0x030a2044, 0xa85b1d47, 0x9f8bb50e, 0x10195003, -0xb791ea84, 0xb2344044, 0x30be7898, 0xbc6fcda3, -0xf102dbcb, 0x334d5a52, 0xcdf9ef39, 0xd92e680b, -0x08586800, 0xea2d4023, 0xca4dca39, 0x0bc9e5cd, -0x884f9b74, 0xccd1cb1a, 0x575f266d, 0x91a39fdf, -0xcfe31993, 0x43f8f402, 0x9eff273c, 0xf7293b38, -0x27f1cc5c, 0x9dfaa3ac, 0xa6f75ba9, 0x3685a542, -0xb487f2a6, 0xa8f3a936, 0x1dc0966f, 0xb1419ffb, -0xeb409ca7, 0x28d16bcb, 0xc2eb7670, 0xeddf4746, -0x1a7b5205, 0xc31a4bd3, 0xf2ae9fce, 0x2e68169a, -0x97c91dfc, 0xd11b93b6, 0x44f728b3, 0xb9036dcd, -0xc00dda04, 0x40d309ec, 0xa4dc6048, 0xd6969a3f, -0x1e9f0770, 0x8192f034, 0xb89e5794, 0x2ead7a74, -0xa5eb3ca9, 0x9937ce11, 0x0e901448, 0xba247b0b, -0xdf15ae0c, 0x2644e567, 0xd9c3e518, 0xd73579d8, -0x1282fc61, 0xff4649cd, 0xf0a00348, 0x378ec04b, -0xbae77095, 0xc8a14f7c, 0x4d107cfb, 0x814803f6, -0xe6123a8f, 0x46ffff04, 0x9621a3a4, 0xc6f5bf57, -0x1e2661e5, 0x9910270a, 0xa39c9a88, 0x0aaef1a2, -0x9bbfc380, 0x8690a192, 0x15c72f1b, 0x93f95f79, -0xaf395ee6, 0x8dc8a8c0, 0xe9e73a0b, 0x4c582200, -0x47edf993, 0x01c5aff8, 0x47c2e0f5, 0x597930f7, -0x0650f3b6, 0x7d7a2aa2, 0x71779fad, 0x176ae4b7, -0x43b5c040, 0x71ba7f89, 0x1de736cd, 0x6daf5622, -0x6ae978d2, 0x00c89e34, 0x72a85f6d, 0x7ae4dc59, -0x3c29d6e8, 0x61136bd6, 0x4f53aba8, 0xb5509bf4, -0x7bcd1665, 0xc68f5fb5, 0xa68a76eb, 0x27c80573, -0xfa351d71, 0xe5a65631, 0x3cce28ef, 0xe1229b86, -0xfe48a500, 0x1c567d21, 0xc3087364, 0xd2e8837c, -0x09186b8f, 0x34c9f25d, 0xe652122e, 0xfbdece8b, -0x372ac80a, 0x258b860d, 0xec221231, 0xa9007152, -0x004ebd30, 0x9b5011ba, 0x9e0518f4, 0x199ee23a, -0xa8d84817, 0x9d097dc5, 0x3704212e, 0x6ffa175e, -0xa75f603d, 0xdab10d1e, 0xd0c1cebd, 0x613dfa46, -0x501017d6, 0x390293fd, 0x0d78eb6d, 0xb70f26b3, -0x7d6bf9ca, 0xf4318b61, 0x1fd450bf, 0xb4264709, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1107-m10f2421.inc */ -0x00000001, 0x00000021, 0x06102003, 0x00000f24, -0x83ed02e7, 0x00000001, 0x00000010, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x5715f121, 0x440ce2fa, 0xd5d090eb, -0x70b3e977, 0x92320e8c, 0x4f989906, 0x36907442, -0xcc4b12e2, 0xb456a6ae, 0x0ad5bcf7, 0xe9f0a425, -0x70b932d2, 0xe66202c9, 0x350fd81b, 0xd560a828, -0x15332f71, 0x3c1a2e5b, 0xa661b83d, 0x6528dcc7, -0x76c5c944, 0xa065f688, 0x3cc01463, 0x49f31a7b, -0x79cac706, 0xc9fae8bc, 0xc4b5fbf8, 0x2451d954, -0x232d756e, 0xf1b52f47, 0x89368878, 0x8742b987, -0x8a0108a4, 0x44b8605a, 0xc2dbd287, 0xb44ecbb9, -0x7396c41e, 0x470b8062, 0xd23b7917, 0x6c20092d, -0x0bcba2d7, 0x575d2d99, 0x38295434, 0x69be061c, -0x18942ed5, 0x46e42cba, 0xa2964393, 0x0e74f74b, -0x3637dc23, 0xd1784fba, 0xfc3dfe26, 0x6aabb127, -0x59a37a17, 0xaf5326b0, 0x744189b7, 0xe4c3a8fd, -0x9b9cd170, 0x260d7270, 0xd3da3bf6, 0x94c74a56, -0x7c598514, 0x27e5c754, 0x19f54591, 0x469329bd, -0x0a3e0073, 0x4d93b74e, 0xabd1073e, 0x4cc88fb1, -0x60db113e, 0x710fb8aa, 0x900642dc, 0x79a1de06, -0xa61ec6f9, 0x85d1f05e, 0x4267267c, 0x04299516, -0x1a4a7833, 0xb9e90c17, 0x002d82dd, 0xc16d8583, -0xe32036ca, 0x147f51f1, 0xa5918b9e, 0xaf5c5324, -0x05e6cd0b, 0x45b4ae8d, 0x730c40f3, 0x216e677c, -0x3da1b00b, 0x7b7f4318, 0x8bc68c6a, 0x7a8a63a2, -0x90bb9d83, 0x49adf5fc, 0xf34ae404, 0x1b214f93, -0xd455db1b, 0xffeec367, 0x6bc1edd6, 0x5c288f68, -0xe44b9377, 0xd0e314e7, 0x29d04ba6, 0xb5805ceb, -0xf4c3e44c, 0x085bc99d, 0xf8ffa80a, 0x990defd9, -0x080028d4, 0x388b7cdd, 0x593984a3, 0x4c0a6b9e, -0xadd4d26e, 0x712ed499, 0x4020b0ca, 0x4942fdf9, -0x237c6de5, 0x56be0c27, 0x561043bd, 0x228f73c9, -0x2e7548fe, 0xec510be0, 0xb7740c07, 0x78851cf8, -0xae205a08, 0xa66dd681, 0x7330b0f1, 0x9c4037b7, -0xe3e5acaa, 0x1b2716bf, 0x6c6d1eab, 0xfbe2ed01, -0x81303e33, 0x33422c0e, 0x6027b0eb, 0x7e4fdcf6, -0x004e2184, 0x1653f8df, 0x8505f26c, 0x71041c13, -0xcaf4e533, 0x4d868fa0, 0xec642902, 0x059e5139, -0xe53bf189, 0xa0cf56a7, 0x2cd6dbf4, 0x41007b03, -0xa1835c02, 0xac53e4c5, 0x07d9756a, 0x05ddd6df, -0x8539010d, 0x3b7780b9, 0xff516326, 0x0c60e6c2, -0x3f3d9e04, 0xd5cac62e, 0xc14da162, 0x06627e4f, -0x2ff1bca2, 0x8c302c93, 0x2b7f616e, 0xd080c36d, -0xc5104698, 0x5c45c644, 0xac4c41d1, 0xb0b15b5e, -0xcc10fb90, 0x19d92084, 0x0ad5bb51, 0x1c678ab5, -0x5e2afed1, 0x6634a6bf, 0x54b22cb5, 0x48686646, -0xa57273c2, 0x17cf3f49, 0xe5ce1ebc, 0x19d39091, -0x8791973b, 0xb5f44407, 0x5a8f5060, 0x3634832a, -0x0a750b7c, 0x9b2cdbfd, 0xd7c1184a, 0x118731f0, -0x8190434e, 0x19a1b4ff, 0x047dad90, 0x1bb0d53a, -0x572f018b, 0xbe68c306, 0x73848798, 0x35c531a1, -0x7550e5c9, 0x97b8d4d5, 0xaa50f56e, 0xa3cee83b, -0x1a4023a0, 0x5e0fc940, 0x983194f7, 0xc7604dbe, -0xf25a04cf, 0x02bbf427, 0xcb0fbffb, 0x558e0ebc, -0xfa52e8c5, 0x37eaa143, 0xd33c1060, 0x55c4335c, -0xce995499, 0x1c8b68a9, 0x7c269639, 0x4022b150, -0x4250c7f4, 0xd5e4d3db, 0x2ff4ed03, 0x36b668e0, -0xc26704ff, 0xe62cbc14, 0xa0a4ebfc, 0x8b53c451, -0x8272406f, 0x68ab2da3, 0x9ca241bd, 0x83d9e495, -0x61954000, 0x843a57e3, 0x10f1897b, 0x7f8867e0, -0xe504cbe9, 0x8754366d, 0x8ade70bf, 0xac2dd3a9, -0x41df4d81, 0x5b670297, 0x5c07bdd4, 0xf00e6717, -0x7360fb7f, 0x3743c5d5, 0xb8adda7d, 0x1bc9de27, -0x08649bed, 0x5181dd68, 0xcf05ea0c, 0x7a67cd39, -0xd8110301, 0x65465cbe, 0xd77d1041, 0x64b1771a, -0x784fd182, 0xca9d00b9, 0x39695291, 0x2b3d4de1, -0xd9380b3a, 0xfc5666d9, 0x5f820e27, 0xc6be32ce, -0xf055521f, 0x0354c95d, 0x8fbe1b6e, 0x8bf13c00, -0xa38bfb82, 0x0655ad0e, 0x41030301, 0x3379ae69, -0xb3032933, 0x099f9283, 0xb590385f, 0x67cade03, -0x53a5feba, 0x422e401a, 0x02ff1f2f, 0x03866975, -0x70f1f572, 0xd4c05101, 0x26b66844, 0x1a93f0f6, -0x94593d97, 0x887b722d, 0x57ad233b, 0xd3c7977f, -0xa1b02024, 0x523cf697, 0x2dd20cb5, 0xab49e9f0, -0x0aa2dfaa, 0x60cc0d0f, 0xb8f83218, 0x6d62392f, -0xe9826fd2, 0x44048284, 0x639eb528, 0x060c7cff, -0x7ea2c3dd, 0x3d1c7acf, 0x4137f9fb, 0x0096f96d, -0xb63634b1, 0xc1483db3, 0x17f501da, 0x02088c3f, -0xdf5dc11f, 0xb0f0dfc9, 0x44139c6e, 0xd7a15ba8, -0xf3d5b372, 0x6b5a08b7, 0x7e43b4b2, 0xd38e1449, -0xfff28de0, 0xe392bcc5, 0x48ae5910, 0x0da38cb0, -0xfcbf9742, 0xe06a5487, 0x5e61019c, 0x8dafb3b9, -0x57344d2b, 0x11b79fa5, 0x4c7fb144, 0xe103f809, -0x0fb905c2, 0x660671a7, 0xd846266d, 0x7b283110, -0xd3c62086, 0x37bca79f, 0x75656523, 0x0adb0487, -0x6c3af254, 0x77b82881, 0xcde94898, 0x6a665aff, -0x5608599f, 0x333d31c6, 0xe65847e0, 0x2288ede2, -0xda129233, 0x659210bb, 0x377fb789, 0x5201d054, -0x38b277e6, 0x3acfa257, 0xc058e53f, 0x1da43574, -0x40e1f496, 0xfb94affd, 0x7d438871, 0x3d6b550c, -0xcd63e737, 0x8a422ba2, 0x89b1ba80, 0xdc5b1133, -0x9e79e4a4, 0x4b96300d, 0xc22f9cd6, 0xee4d4bcc, -0x9fe0fcab, 0x576761d6, 0xb6e873ff, 0x21edd45a, -0xaae4b067, 0x3ae52f5e, 0x910e2365, 0x7da9d04d, -0xaf71b07b, 0x45ef40c7, 0xd4ba6224, 0x6bacaa75, -0xefa4db2e, 0xb4c31b79, 0x54f43ea9, 0x04f8e83f, -0x53e2c9f7, 0x8db44cd7, 0x0ea25b66, 0xd87f5c2c, -0xe96c9d87, 0x2ebca750, 0xaea8c953, 0x98c79dd7, -0xb0403778, 0x1e952d41, 0x85982c1e, 0x1af566a4, -0x7b6fe713, 0x46b462d4, 0x2cd47bfa, 0x1c6a68aa, -0x6eaa133f, 0xbfd22f3f, 0x12174dcc, 0x47a2f741, -0x8bcbbbdb, 0xc9ef98cb, 0xe29ab9c0, 0x47b4987d, -0x20d1f9fd, 0x373a5205, 0x436e1733, 0xb11f73e2, -0xae1044db, 0x37c58139, 0x24ab40f8, 0x6d289f8d, -0x5f62ca41, 0x6a9517fc, 0x7fe844a4, 0x33df706f, -0x8ee15ee3, 0x2bd979a8, 0xeb214552, 0x302da2ff, -0x70ab6453, 0x14c9daea, 0x965870c5, 0xd83ed7aa, -0x2afae19f, 0x9b1e0a42, 0xc782ac32, 0xd58e5e96, -0xff59dea5, 0x2deefefb, 0x844e3fc4, 0x2b5da19e, -0x25165c3e, 0xbd0c1726, 0xdcce9175, 0x7bbded39, -0x0e7f9a66, 0xcc31d985, 0xe41a40b5, 0x536267a2, -0xc1c50b09, 0x29119ea9, 0x9bc328ab, 0x3246f0ae, -0xea534459, 0xa24c3cdf, 0x15685876, 0xe0fa8c37, -0xd769ec85, 0x20c2df4c, 0xdc83b5aa, 0x9585dfa9, -0x1e01ce77, 0xb79d5f70, 0x3563d017, 0xaa205ca6, -0x52a0510d, 0xaabaddce, 0xe33bf64b, 0x80e3936e, -0x16057435, 0x87a4a9d1, 0xb4c006b8, 0x4a54633b, -0xed7038ad, 0x040dcf11, 0x85cced44, 0xed4251ac, -0xd7313899, 0x31dbcb9c, 0x4748e453, 0x2cbeb93d, -0xd658e2b5, 0xfdca6e33, 0x0b6bcaf3, 0x112b5d91, -0xcba2e2ce, 0x0be84dca, 0xcd890825, 0x8f488963, -0xbed55a87, 0x723bab52, 0x1863e24f, 0xa2df4790, -0x59838ef7, 0x93270607, 0xb987d2c0, 0x1ea917ad, -0x872b1a14, 0xeb026a8b, 0x4d3c60b0, 0x234ceb88, -0x85054bcb, 0x3999fe14, 0x233c2b38, 0xa46aea96, -0xd6f654a6, 0x412fe4e3, 0x8d371386, 0xb776a912, -0xe54f0cf3, 0xf846023d, 0xc1d21956, 0xcad10e9d, -/* 1467-m0df330c.inc */ -0x00000001, 0x0000000c, 0x04212005, 0x00000f33, -0x58c41efd, 0x00000001, 0x0000000d, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x45fda71c, 0xc5c83cb3, 0x7adca7a3, 0xe906ce8f, -0xc4c9223c, 0x21cfd56b, 0x12cb5b2c, 0xcc5ea32f, -0xfa3ebaf7, 0xf33760bc, 0x9ad2f278, 0x388b2cac, -0x6695b80d, 0xdbba67b7, 0x2f309750, 0x2e02d473, -0xdb6c4476, 0x3128b0de, 0x21122278, 0x1e096794, -0x2a1e624f, 0x29a9baab, 0x992e0e3d, 0x2f99bba9, -0x3cb04252, 0x16c6b72e, 0x53330dc6, 0xc5222b17, -0x394eaa75, 0x37c4d00a, 0xbd40f740, 0xe51c925d, -0x725c9151, 0xd3a53ca3, 0xc839312f, 0x2d55e8dc, -0xc85d99d8, 0xf9928fe6, 0x589b2dfc, 0xd4293d1b, -0xe14a7bb8, 0x3a0880c0, 0xeb13e903, 0xf23eb00a, -0xe293b540, 0xc4b12573, 0x85dbd1f8, 0x0d5cfb5e, -0x3df68fbe, 0xe7f30fe4, 0x469bf086, 0x52a3528d, -0x1425c7a1, 0x08994fdd, 0x6ac3b0c0, 0x6d19c1a1, -0x56e653ef, 0x5867036b, 0x69a115f7, 0x30c35b67, -0x75030427, 0x7c034a2e, 0x0cd2e889, 0xd4bbda8a, -0x516552fa, 0x2b9463c5, 0x62202b82, 0xe9b0403b, -0xc8615504, 0xde514686, 0x94fe6f37, 0x26e95233, -0xd098d60e, 0xfb098be2, 0xcb8ae3d5, 0x6252bc84, -0x79a468b5, 0x2568dec6, 0x2c60ab5f, 0x50d78f40, -0x381796e0, 0x751e28ca, 0x6b1003b5, 0x365f1bd2, -0xadbdc178, 0x54c18945, 0xfd6056ce, 0x8d959eda, -0xe299e5f8, 0x359f24e8, 0x363e35bb, 0xa3deda38, -0x61773547, 0x8bcc3b8d, 0xa16b34a4, 0x39cdc595, -0x7137c122, 0xbe9813c2, 0xac72a9fe, 0x7571c3f4, -0x001b0510, 0x26400b66, 0xc5c872ff, 0x4cc2caa0, -0x38ba9384, 0x7cccf10e, 0xb69e8dba, 0x25765305, -0xd79eee64, 0x40cff2bb, 0x6c25208e, 0xdc1f4211, -0x948b3990, 0x340a1e25, 0xa61c7ad8, 0xe968250c, -0xb77e48ff, 0xc214c91d, 0xdfb4e78f, 0x3a710e38, -0x11d6d920, 0xe2735793, 0x8c7d592f, 0x12b6fff7, -0xe2662cb1, 0x30e7024e, 0xa2ef683f, 0x382a182c, -0x6f6b8682, 0x002617e1, 0xa1d8df0b, 0x371b31d2, -0x4b8b0873, 0x2ad87046, 0xaccce0d5, 0xa64cab61, -0x2b26eee6, 0x2a432eea, 0xc856bdac, 0x83061d84, -0x3489d061, 0xa5fa0d92, 0x3b3361fe, 0x204c5f95, -0x491ee713, 0x8f632e53, 0xe3a93e14, 0x417b7baa, -0x2dceaf08, 0x2dc9f9fa, 0xa875a995, 0x7cf71bd0, -0x882a84c1, 0x47d31cbc, 0x3222b96e, 0x39f889ea, -0x224487e5, 0x77bf22a4, 0x9aae5363, 0xb43b278b, -0x6dd117a8, 0x2b3cc820, 0xbb6ce2fb, 0x885d19d0, -0xe056cd29, 0xb544d68a, 0x888c83dd, 0x20345f2b, -0x24bf175c, 0x9c84eddf, 0x6b092d09, 0x14e60529, -0xe2100950, 0x368a7f49, 0x21cd820d, 0x2ae4e6cf, -0xa354d480, 0x0178af0e, 0x0352ef88, 0x31d0776c, -0x9773994a, 0x31a38a0b, 0xd080e826, 0x800f5ae0, -0x179f0072, 0x21ef6514, 0x9ffcafa9, 0xabedbb31, -0x9d231bc7, 0x8cf5d8b0, 0x923427d1, 0x372fa035, -0xbbd9d44b, 0xb45dbf72, 0x2ed1bde3, 0x1dad7c6a, -0x80819026, 0x20f63235, 0x2fe73bf1, 0x3029768e, -0x49dd331a, 0x0ee94c90, 0x03ff1030, 0x321f8793, -0xae32ae76, 0x30a103d4, 0x70c6f474, 0xc4e3ecc3, -0x66b6962f, 0x22ad66db, 0x5f4596d6, 0xe21f30d4, -0x54a7d44f, 0xd1b45997, 0x4c9a601a, 0x34cd9146, -0xb7c14fa2, 0xfb191a9a, 0x46286984, 0x457130f6, -0xbb0faf3c, 0x3921327b, 0xc07d62bd, 0x6f7f9b8b, -0xa335aff0, 0x44e50b59, 0x90d4fde5, 0x23e1eeb9, -0xfa01f05d, 0x653b053d, 0x82879bb5, 0xa519e9c3, -0x37bc6704, 0x2f31e7be, 0x9f331be3, 0x806b1685, -0xd1b9c361, 0xa9d0aa28, 0x55f282d9, 0x2d8766cd, -0x22c50d1d, 0x89fc9dcc, 0xb68c0a7d, 0x72c3968b, -0x07dc7a7b, 0x3704b5d7, 0xf83f7fbf, 0x74d4e514, -0x3c7d2a14, 0x66930982, 0x1e74a2c3, 0x264e70f5, -0x8eedef74, 0x798245d0, 0x3e7f5cc4, 0xde7bc37f, -0x66fcb4ff, 0x2863b856, 0xcdfaf436, 0xea705543, -0xfc5b5d03, 0xd7a9307e, 0x00701136, 0x3f3e3d8f, -0xca2c8fd7, 0xe07c339c, 0x1463729b, 0x5e649a88, -0x64df56a2, 0x3a5284de, 0xb9176e26, 0x6b596309, -0xf9cce67b, 0x5ee20140, 0xab5ffa99, 0x343001ed, -0xebdb5e56, 0x684a34c3, 0xbbba8603, 0xcb21e7cf, -0xd558b806, 0x23ceb69a, 0xe9647235, 0xfa21c5e5, -0x9a3e151f, 0xcaaad78e, 0x5f4e2f62, 0x2794a25f, -0x22d4e4b9, 0xffd3d734, 0x15e963bb, 0x6498242f, -0x817b67f1, 0x297f1b8a, 0xdeea3945, 0x4ed1afb0, -0xa48f6168, 0xf20aba65, 0x202216ba, 0x347858b2, -0x7b77dae3, 0xdcfed474, 0x2318cd45, 0x2f43d675, -0x8c97a56b, 0x35622d1e, 0x5c9e8507, 0x05b23bc6, -0xe0e064fc, 0x3f6b1e29, 0x22d31146, 0x293c5aec, -0xe4305363, 0x06bd5d59, 0xa26f3833, 0xf2f577d3, -0x1fc2e51a, 0x229f45f3, 0x04c969dc, 0xc2c138de, -0x1073ede1, 0xfff23304, 0x76c6cd54, 0x37972029, -0x6a028240, 0xcb766a6c, 0xe45edcba, 0xe0fc0ab2, -0x75434354, 0x3f1081a6, 0x73d47441, 0xd1c37cf3, -0x84b2cd76, 0xe2ff45e1, 0x84a70fdc, 0x2c2e8df1, -0x897bfd22, 0xcbd9af5b, 0xba0d3a3c, 0x1b09665c, -0x10f7f7d2, 0x204de839, 0x49430f96, 0x2d2ebead, -0xa26a5c8f, 0x15f6ecd1, 0xb5ca1ff5, 0x22d965f3, -0x44751954, 0x266dc552, 0x7d43e5bb, 0xdf4b1f5a, -0x3c0f2a1a, 0x359c9c3f, 0xf096bf30, 0xe15553aa, -0x2bda0831, 0xd42d6010, 0x304e53cb, 0x2191dfc9, -0xbee94875, 0xf7b0ec83, 0x2207174e, 0x4bc7535a, -0x8555bd49, 0x32052583, 0x6cfd21fa, 0x688fab55, -0x33aee02a, 0x45e8cbc5, 0x663f8256, 0x27f194d7, -0x1357258a, 0x65ec6bcb, 0x494ec91b, 0xd9294640, -0xbe66c1c7, 0x20e330c4, 0xbc881b29, 0xe3598be3, -0xda3ea3a1, 0xcf9a928a, 0xdc4a80e4, 0x26cdafd3, -0xbb69f7a0, 0xeb8ea752, 0x7178ba6b, 0x2897330c, -0xd1b55818, 0x3dcb45fa, 0xd247ae1f, 0x0c321066, -0x1cb5d0e6, 0x3a26571a, 0xc2f7f883, 0x35078a50, -0x0e7076ba, 0x0f6f56cd, 0x244427d3, 0xd6f772de, -0x945a89ea, 0x959fe859, 0x32a12387, 0x0f9e28a6, -0x5765abe0, 0x705e0055, 0x77479ad1, 0x465a656c, -0x5ae66df6, 0xc8003c87, 0x8a01f279, 0xee339935, -0x092f7107, 0xb0343860, 0xd8cbfee7, 0x7e395a60, -0xfee92cef, 0x86467a1f, 0x919a0cd2, 0xd1839c64, -0x08f45639, 0xd01ebabc, 0x8423c84f, 0x13a46247, -0x21919c77, 0x5246336b, 0x419c3250, 0xe7ceaf92, -0x053c8e88, 0x7f32dfe4, 0x7546be6f, 0x952afc0e, -0xb3ff1bd4, 0x07209560, 0xbf7e6f17, 0x586ed9c3, -0xb19c766c, 0x362b7a90, 0xd346922a, 0xae4bb663, -0x31253c02, 0xd765c9fa, 0x4b3eba52, 0x654f4989, -0x9bebe752, 0x816c8ed5, 0x61cb366a, 0x9d569d53, -0x69f80992, 0x83feda54, 0x2f597721, 0xd5dcc0b8, -0x33d8a392, 0x767f04c0, 0xf951e755, 0xe6fd02e2, -0x2287d6fd, 0xc1a67938, 0x3bd4bd5b, 0xd1b2275c, -0x900ac73a, 0x1146ff57, 0x6fbc1e0e, 0x35190704, -0x0ac32212, 0xd063f20c, 0x32ba4a23, 0x47ee4127, -0x572104b1, 0x3616b8f8, 0xcc2d0057, 0x0f6874d7, -0x86cfb62a, 0xb4dd6bdb, 0x55088d4d, 0xfca14905, -0x653f8e17, 0x1416212a, 0x0f4c4924, 0x3b7e8a5d, -0xee246bef, 0xf561936f, 0x6a418d5c, 0x82a552e3, -0x351523e0, 0x2d760fa4, 0x7ca18f4a, 0x6c9d411b, -0xea4a38bc, 0x6675850f, 0x6d4384ea, 0x9d6bac13, -0x1d8bc278, 0x790289d8, 0x1c1cbe8f, 0xe89cb07c, -0xb62823fc, 0x75fedf6a, 0x7d4cbaf5, 0x71d501d5, -/* 540-mu267238.inc */ -0x00000001, 0x00000038, 0x09221999, 0x00000672, -0xffd6aa2a, 0x00000001, 0x00000004, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xa2560856, 0x779b0125, 0x1443265a, 0x0a535feb, -0x70e89c38, 0xd71286b0, 0xa0ec5939, 0x525bccb1, -0x6fdfa495, 0xe99aac23, 0x73d359ac, 0x4104d3af, -0xc8a1849d, 0xd8dd20b9, 0x591df59a, 0xb23c9ce8, -0x5720703d, 0x28791338, 0x37b7440c, 0x3f4152d3, -0x946e068c, 0xbd4cbca7, 0x02e2980c, 0x78902676, -0x7c66c91b, 0x55e1a9ca, 0x55cca14b, 0xd0a82082, -0xbe66f162, 0xa499f342, 0xee344972, 0x0b4f8aa4, -0x3c26d31f, 0xa2492061, 0xd845fee0, 0xb253d108, -0x6ccc9b4b, 0x92ce1712, 0x11fcbc36, 0xe384d472, -0x8447afa4, 0x599b1a33, 0x78535766, 0xeb4f2543, -0x91629f05, 0x6af162d5, 0x949517b9, 0xc38e49a6, -0x5805826e, 0xd03155dd, 0xcc8800bb, 0xb98e9a71, -0xb75fd98a, 0x96c79e9a, 0xdf7478d3, 0x29a43071, -0xbf2a5470, 0xd5be473a, 0xf66c074d, 0x7ee133f5, -0xfaa5823b, 0x9fce08e1, 0x43bffec1, 0x12644f98, -0x26fe9f43, 0x096f8940, 0x703a390c, 0x598abb8a, -0x8b79f053, 0x5c294000, 0x6221fba4, 0xeb226211, -0x6b1e7e6e, 0xc5233cc8, 0xae9ab65d, 0x3aa0a89f, -0x0e422a22, 0x0f1886ef, 0x3379e3a6, 0x12f12284, -0x409f4e06, 0x41efac41, 0x07693087, 0x7a9f1916, -0x31269e69, 0x9caf7cbb, 0x3ff0bee6, 0x3ef2a057, -0x1de737d2, 0x8df81860, 0xc41ba7d0, 0x39584115, -0x1321abd7, 0x97dbe297, 0xa376ca1e, 0xaaf6b25b, -0x0c9b1d13, 0x363e1074, 0xc75e2a58, 0x79774604, -0x8ebe27aa, 0x95443c05, 0xb716ee48, 0x77a05fb7, -0x482eaeef, 0xeac5e94f, 0x79e3ef59, 0x2cd191db, -0x2b71c633, 0x95c675c5, 0xbf1e639b, 0xbac226f3, -0xfb2fac20, 0xa9e72a20, 0x5a46b3ee, 0x1743bec9, -0xb89df094, 0x15af2d36, 0x45944344, 0xb41d5a97, -0x2216d4b7, 0x98ba1092, 0xc97d4982, 0x336f6c35, -0xc43df462, 0x9fa0dc3a, 0x7a240c30, 0x7d248a85, -0x0995bbcf, 0xe9929521, 0x5d828729, 0xc8f41f11, -0x2d0f0e4e, 0x8e67c634, 0x68567623, 0xc237ba69, -0x78a6b1d9, 0x6f6c2ba8, 0xa8908a4f, 0x909b771c, -0x0428bb10, 0x7c1b33cf, 0x76af41c8, 0x6037d37c, -0x5ded7bbb, 0x534c6d21, 0xd9a6343b, 0x74482250, -0xb961501d, 0x0988d71b, 0x073dedea, 0x5d0a4702, -0xca22ce05, 0xf14f6f72, 0x8f7f744c, 0x1a78507e, -0x4b0b3b33, 0xe5a62813, 0xb76e4b43, 0xbee09325, -0x21a02fe8, 0x513abf7a, 0xe780fc18, 0x25b7ae25, -0xec70dec0, 0x25d1fc14, 0x47fc868f, 0xd348e013, -0xab83414a, 0x48e8afaa, 0xae9e7eb5, 0x4591f771, -0x8209dd0c, 0x84929f07, 0x7fb35bc9, 0x9ce719af, -0x339470a1, 0x85f7be9e, 0x2ea78a4b, 0x7cf3e760, -0xe0cf2ee2, 0xc8c60ee0, 0x06843417, 0x9ccb4cce, -0x117cde32, 0xe6b68d75, 0xfaedfa5f, 0x6407e9f8, -0x6db65a34, 0x07717a0c, 0x3578a834, 0xcf9f70e0, -0xbb0c1401, 0xc7624cd2, 0xe8102ce4, 0x2c342121, -0x353c2bc0, 0xa08d06e7, 0xee40ca20, 0x069f1b72, -0x1da2d573, 0x766565dd, 0xf684f183, 0x1a9a4c6f, -0x9566f043, 0xe083be7b, 0x1d9c5ed6, 0x85c01b1e, -0x1481bde2, 0x5e3d1b22, 0x0a47aeb2, 0x36c29f21, -0x9b5604ca, 0x8519256a, 0x5bf0e38d, 0xf061f342, -0xf3cc6aff, 0x3e928f99, 0x6c65bca7, 0x950fb3cd, -0x7bc6cc53, 0x5c3bb72a, 0x177eee6e, 0x4f1f0363, -0x7e2d8e88, 0x3ab83f54, 0x062f818a, 0x2b53143c, -0x6127e61f, 0x95cf1f48, 0x04798f41, 0x61ba5878, -0xb0fd99d2, 0x71c835e4, 0x3c4a814a, 0xe07eaa41, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 433-MU165045.inc */ -0x00000001, 0x00000045, 0x05251999, 0x00000650, -0x429c2f70, 0x00000001, 0x00000008, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x77567ca2, 0xdfef9b71, 0x3f95a175, 0xbb90abf9, -0x8207c844, 0x2e319608, 0x84aac65e, 0x97aa48bf, -0x19162ecb, 0x8e8992b4, 0x96080bb2, 0x53c01831, -0xc29ef4af, 0xf967b0ab, 0x1b842ce8, 0xcd848c67, -0x904a21dd, 0x3b072641, 0x801b9ca3, 0xc96a0995, -0x5f083b53, 0x9f008055, 0x80da3025, 0x119500bb, -0xd2c61199, 0x892c8e81, 0x51eed326, 0xd205a6f6, -0xc1967209, 0x1f39e8c7, 0x9d4d2e7d, 0x80f4c001, -0x13660fb4, 0x9dd8c7bc, 0x81f8d10d, 0x44160784, -0x9430ba2d, 0xd242a7ab, 0x49262fc4, 0xa5662a95, -0x9f908eca, 0x763b7ac2, 0xefcf36d6, 0x8f42d959, -0x7f927c4c, 0xfa380ebb, 0xe8d5ccde, 0x51386ee4, -0x9fb76469, 0xc0c896b7, 0x5afa6156, 0xc1c61ab6, -0xcbb860b8, 0x0e7758a1, 0xc3209fde, 0xf676d946, -0x43468b8d, 0xf83b6ba7, 0xb56e1439, 0x1222a434, -0xb956c9a1, 0xe9deb385, 0x178da51a, 0xa62b724c, -0xa3229fdf, 0x082ff04f, 0x8417980a, 0xf1528736, -0x6415599a, 0x97a65c19, 0xb50eb28e, 0x333b4cbf, -0xdcca5404, 0xa09f560d, 0x755c054e, 0xdc1a6982, -0xe4d4bc36, 0x6c55c9ca, 0xbf786948, 0xd109ed91, -0x47825bca, 0x9d75c244, 0xda540f0a, 0x58b6257e, -0xdca5de08, 0xc16a0599, 0x10253e7c, 0xc3ffcd71, -0xce2cacfe, 0x08cc52bf, 0xcc7984bb, 0xc51015f5, -0x4f5c63e4, 0xd90579b1, 0xa3c29d6e, 0x73223879, -0xf28aa49f, 0x8738c565, 0x7ef3a081, 0xfadd4de5, -0xc249b462, 0x781b54c3, 0xdbf9068a, 0xe5db043b, -0x1e3e4b5d, 0xfc0341d7, 0xe9d68d5b, 0x194ddef0, -0xbe3ab885, 0xcee97f92, 0x26e94d85, 0xb089a6b3, -0x99aab45d, 0x0ef69511, 0x97164174, 0x9aaa723f, -0x44079aaa, 0xbf0b8301, 0xd1c6a2ab, 0x49ba4615, -0x970a58ff, 0xf0ddafb7, 0x6039c5a8, 0x9e8acf82, -0xb0b751bf, 0x6b6b70e2, 0xd6f67974, 0x9e7a2da7, -0x679fba31, 0xf6629688, 0x92f55661, 0x6097934b, -0xb6a5725d, 0x907eb122, 0x2db0e80a, 0x995b25c3, -0x93c5af5a, 0x09b5fb9c, 0x993368d4, 0x960d6435, -0x47f945ed, 0x96c93de4, 0xd7554230, 0x6cba9648, -0x9b1dd64a, 0xfd17d8f6, 0x65014cb4, 0x9d012e62, -0xb3825899, 0x69090810, 0xd85586b2, 0x9ea90f07, -0x619e2e88, 0xf7b8dc3f, 0x9aa3e382, 0x640a250c, -0xb8f526aa, 0x9bc79c25, 0x2439ef0d, 0x9b0c2b78, -0x951c0ffa, 0x08dcd2bf, 0x90419137, 0x98a998ae, -0x4092c96c, 0x95092d4e, 0xda47daf1, 0x6a1220ea, -0x9b6c5952, 0xf1f84308, 0x6c505131, 0xac214e2b, -0x95f2eca7, 0xfe7fead7, 0x6a9cf8aa, 0x622c88a9, -0xf4d7256a, 0x90f1ea74, 0x91a952c5, 0xf5b5053a, -0x63156e90, 0x9077a768, 0xfabf56e0, 0x674c82fa, -0x9593925c, 0xf35daf0c, 0x6d0741a2, 0xb0ec7e7a, -0xfac81dd7, 0x45759cce, 0x9d839eaa, 0xdd8ff52a, -0x697da918, 0xbbcda9c1, 0xd4cf0e4c, 0x93c25ecd, -0xb402595d, 0x22a34122, 0xb502962c, 0xbdc66ed7, -0x0d0d84cf, 0xb4b33d9a, 0xbd26b700, 0xf5b50344, -0xb27038f8, 0x46395131, 0xf0821443, 0xba488f6d, -0x4b2873ad, 0xf972fb86, 0xb6e6cb92, 0xbb1e0b12, -0xf12e1951, 0xb516f5fc, 0xb03c3d64, 0x035368a4, -0xb2cbc2ad, 0x4f9e3586, 0x07d591b6, 0xb8d4e609, -0x46adb34a, 0xf861d111, 0x2469e74b, 0x675faad9, -0x66925df7, 0x0be0f3ef, 0x1af7414a, 0x5717dff4, -0x776645dc, 0x2d6bb333, 0x2c75b8d6, 0xce922072, -0x5d1495df, 0x98454968, 0x308b2e62, 0x605b0727, -0x838ba96f, 0x4f0239d3, 0xf295395e, 0xb3c38631, -0x7ea7a143, 0x157a4e43, 0x46f8173f, 0xfbc18d4a, -0xc401e17a, 0xc4620358, 0xd2ab5437, 0xa01db06f, -0x58ce91fc, 0x850de1a3, 0x9b542dba, 0xee77f038, -0xddd3ced6, 0xc225d2ce, 0x63a3f765, 0x3342a06c, -0x6a780c2f, 0xfaa925b2, 0x366ebeec, 0xbcc9abea, -0xc7b3fa4e, 0xf4f1123d, 0x5198702c, 0x3e3458b7, -0x0b1ce9a1, 0x51b1bd7f, 0x711e791e, 0x927d8bed, -0x91dbaea9, 0x7eefbda9, 0x7a19edd9, 0xdf7b8dce, -0x5bb40613, 0x0b0c1e0f, 0x85b82c98, 0x18da4dc1, -0xc5fd78ac, 0x57c1e31d, 0x4c4001b5, 0xe31d2643, -0xa6afbf58, 0xad200e68, 0xf0114ba4, 0xd6a620f2, -0xc753a720, 0xac9022a0, 0x28a41f01, 0x22a4ba95, -0xc00b7531, 0x23d42795, 0xcd836a86, 0x90262708, -0x3292cad0, 0x40022e39, 0xc1581b0a, 0xe5101550, -0x6538096b, 0x208c549d, 0x3ce2bf88, 0xa71df38e, -0x3dec3685, 0xca3949f1, 0x79f3ad1b, 0x3ee8b300, -0x9d305fc6, 0x7a2e5288, 0xbe81a2f2, 0x7ada0c06, -0x191c7f01, 0x58dfcbd1, 0xc78dee72, 0x72364226, -0x1866de12, 0x8d22305c, 0x943a0f0e, 0xc81967ff, -0x4d55fb0f, 0xaf199be1, 0x90bbda61, 0x4e7c234f, -0x90cfec16, 0x9b4bcf26, 0x21622023, 0x0926f0fa, -0x1d504377, 0xa58db427, 0x8d93ce2b, 0x90bfe900, -0x29e67397, 0x2c1261ed, 0x4ace9474, 0xd5c60282, -0xe53fb300, 0x8a61a0ab, 0xa7aa0918, 0x4389d7c5, -0xd09d605c, 0x6c5bedb5, 0xd6d54c51, 0x433dea21, -0x7ad9e677, 0x813bff76, 0x5a162c75, 0x1ee0661f, -0x9b6c2030, 0x8e8dc989, 0xcd4bc9fc, 0x4454675b, -0x8d583c9c, 0xe3400094, 0x116ebb83, 0xe847bc9a, -0x2a4622dd, 0x2a901e6f, 0xd789b1c0, 0x094e2bbb, -0x056e563f, 0x9f17e606, 0x8bc79b8d, 0xd2c535c1, -0x06a45a27, 0x9dc56771, 0xa06649e2, 0x5ff25ac8, -0x6554961e, 0x98e583d9, 0x38ba93da, 0xdee1de18, -0x037cb9d5, 0x6b17f195, 0x3431faaf, 0x13860a0d, -0x28bca10d, 0x0a54c011, 0x9957cdb6, 0x3aa1f429, -0x9d41b7b3, 0x9aea5be2, 0x60c7ce6b, 0x4cd1c10b, -0x24ddddcd, 0xe28412ba, 0xa03a5466, 0xa1896879, -0x59edcb87, 0x1b241765, 0x157bf161, 0xf219f950, -0xe86ff526, 0x262005d9, 0x11769531, 0xbca15d95, -0x28f5ef17, 0x1f27e725, 0xc32631d2, 0x07249e61, -0x1ba851e3, 0x4f49b577, 0xe2a1df5e, 0x826fa7ff, -0xc34e1e2e, 0x7fe26024, 0xbc19800f, 0x0d368dc9, -0xe03da0c6, 0xadaa4f9c, 0x9ad1e43c, 0x96f84e44, -0x0b6cd695, 0x1bb46971, 0x942d6e5b, 0x6316170d, -0x3164509f, 0xc6659450, 0xb2a0370a, 0xabc208e8, -0x6d479811, 0x3684bc0e, 0x80b7b101, 0xa50b7bb5, -0x43d21233, 0xb423559d, 0xf41dcd16, 0xdfd3c276, -0x3e586469, 0xd9b7630a, 0xb88f9e44, 0x0cda6f4d, -0xe5bf5844, 0x8709f788, 0xdae37da6, 0x1fb41777, -0x1d903f69, 0x34383b69, 0xd409ae70, 0xd1c99758, -0xdedfd7a4, 0xa4bdf018, 0xf4058202, 0x8565d66f, -0x5365aed9, 0xfa69742e, 0x2cfbfbcf, 0x88a00b60, -0x506c0713, 0x2866475b, 0x3e1df573, 0xb86f7feb, -0x31d23a7f, 0xc6320e6a, 0x3ebbc2a5, 0x83a1d4ef, -0x15169f5f, 0x42a61753, 0x893e553e, 0x4ddbc66d, -0x7449ec1f, 0x76f65d22, 0x0622e13b, 0x32986f89, -0x21181b4b, 0x99a80c0a, 0xd6fe00b0, 0x282c0e81, -0x9fc1cf88, 0x919b855d, 0x618257d8, 0x82c448b8, -0xe22537a1, 0xa90de388, 0xba73b90c, 0xd765eeb0, -0x62b2727e, 0xa08dfe20, 0x70b3c8c5, 0x3ef04007, -0x9f73732b, 0x2201edd7, 0xb836219c, 0xf913af7c, -0xf50f64ca, 0x93ac107a, 0xf509f84a, 0x6f6026f6, -0xd9bb8eac, 0x4b268cfa, 0xa65a3fa6, 0x9837cb75, -0x784fb835, 0x2060576d, 0xb1604cae, 0xb9da4116, -0xab320cf2, 0x60a1b501, 0x0c73fa79, 0x8d5a6f1e, -0x57688086, 0x218e4005, 0xca054e3d, 0xc1a3c3ec, -/* 1070-m02f122f.inc */ -0x00000001, 0x0000002f, 0x05022003, 0x00000f12, -0x44847acc, 0x00000001, 0x00000002, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0xe6b36263, 0x6f9eaf78, 0x632770bd, -0xb11f8920, 0xbc42e776, 0xbd797134, 0x9768e716, -0x1dce3da1, 0xe0dbe21b, 0x30349ee3, 0xb0aae4c6, -0x1591358e, 0x6646707a, 0x147f6ddc, 0x639c59e3, -0xed11c0d6, 0x2707c252, 0x8053be8a, 0xb432051c, -0x941732da, 0x80e55dca, 0xf389d8f4, 0x738a68e3, -0x85f7042d, 0xe1904f35, 0x1e2e7f3d, 0xf1d4b55d, -0xf9829802, 0x0b8d6394, 0x252d74ca, 0x7b6a0be4, -0x13ec2030, 0x7d8c3429, 0x32380fdb, 0xb595854c, -0x6ab18d3b, 0xfe241438, 0x79ee3c90, 0xf7c80ed2, -0x9735dffb, 0xbba18676, 0x2687be0c, 0x9fb2e5ef, -0x28f85fb1, 0xea0b3223, 0xf1e3f263, 0xffd47414, -0x86a09efc, 0x3b23b61f, 0x03600e24, 0x0f59519b, -0x8868d3b5, 0x1cd3ddcd, 0x174364a6, 0xced7c4ea, -0x637cf55d, 0xab80c838, 0xb2ccd05c, 0x968f8d6f, -0x77f66b77, 0xdf34ebcb, 0xfece6f5e, 0xb819e030, -0x1d73c1d0, 0xf6d86e15, 0xfed82c81, 0x4ac93249, -0x4358711e, 0xe558a942, 0xc19f602c, 0x3d51db79, -0xbc5b9f59, 0x1dcbf598, 0x09326724, 0xae712704, -0x686bb2d8, 0x8cb848bf, 0xd1f00d90, 0x6cebdd80, -0xe9827e3b, 0x7ffc9a62, 0x52851c33, 0xd9f6d8b7, -0x89294625, 0x5cc9e522, 0x416df615, 0x7b4b8c1d, -0xa819df83, 0x458483f8, 0x12c2a1c8, 0x3219f4be, -0x20a99f23, 0x30c8cb2b, 0x0284107f, 0xcaf74794, -0x3b8408e5, 0xe3915f05, 0xfe89b7f1, 0x3b30f859, -0xf6c214a4, 0x53ea7021, 0xf1ae6ce6, 0x300771c2, -0x7c769103, 0x59c4f9ec, 0x954321c1, 0x0010217c, -0x60f87712, 0x9531a33c, 0x6516e8b2, 0x7e6af0e1, -0x159c0a30, 0x5c0df59b, 0x2763d9c5, 0xc5c08122, -0x80be5172, 0x96d9c015, 0x227f4d84, 0x104ad707, -0x7cd7de50, 0xc58e569a, 0xd2129ffd, 0xe9afedf3, -0x61e19908, 0xecd27e20, 0x36ef4ae8, 0xcda53aff, -0xdfbd8a65, 0xaad6eef6, 0x3720e8cb, 0x061f85c6, -0x60643ad4, 0x0e3cd18c, 0x9d19ec4f, 0xec94bb30, -0x9f53ebe5, 0x3f591c58, 0xdb015450, 0xade7e0c7, -0x305be3b2, 0x4cb29bc5, 0x7b57cbb4, 0x3aa89078, -0xfbe6e43d, 0x0b761e6e, 0xed8b5baf, 0x3b4e756d, -0x6a148c9f, 0x1a3a01a8, 0x1d33ac7a, 0x3e3dd3e2, -0xbfb4392c, 0xca1ce690, 0xd1af4a34, 0xa931d9c3, -0xa86836be, 0x34d86f8a, 0x21cb75f0, 0x37c152a4, -0x95b9c9a4, 0xc30f3c29, 0x1b821c8e, 0x637851df, -0x069cc4f8, 0xd88ead11, 0xf5f5728d, 0x1b0ffed7, -0xfd846742, 0xf76f607d, 0x5d8a4740, 0xad48d963, -0x6a9ffcc0, 0x1b320e79, 0xc49b22c3, 0xde2c0048, -0x5fcaddfe, 0x708e63ca, 0x294d5d69, 0xa3dce328, -0xb847b4d2, 0x611c0a2b, 0xcd4513c8, 0xfa1bfa75, -0x45ca8ca2, 0x3681b381, 0xc27f6c94, 0xcd958d01, -0x7b55386f, 0xa4b2c59c, 0xaa58ef1f, 0x752c6c71, -0xdd97125c, 0xdfc2881a, 0xb9d5036e, 0x5148d9ff, -0x24e6b06d, 0x8390116a, 0xea6d4d44, 0x7378ffef, -0xd1833cf6, 0x3415528c, 0xcf3622fe, 0x76729d17, -0xcd1ba4ad, 0x1885ed72, 0xde02375a, 0xa49131ff, -0x3be6df31, 0x6cf2c534, 0x90aacc16, 0xa2eda106, -0xa7aaecef, 0x5831a9fd, 0x5f142437, 0xaf30f7fc, -0xc8f6cdab, 0xda69d12d, 0x5871249f, 0xc011e372, -0x33c8e75d, 0x8087d9fb, 0xc595c587, 0x9cc36c3e, -0x676b2c58, 0x4f242c1b, 0x6b77d07c, 0xa1c8543b, -0x2824e9c7, 0x84be15a4, 0xc0b4a308, 0x0e41511b, -0xfaf3dbbe, 0xc1777e7b, 0x199d042b, 0xb0b35558, -0x9bf8cb58, 0xf68d5c43, 0xf359b550, 0x993d82d1, -0xa8388458, 0x56d3c256, 0x11cbc33f, 0x3c28a56f, -0xe6aa09f9, 0xd41f6c39, 0x11020cd2, 0x985c89db, -0x3705b46f, 0xaf90c2dc, 0xf7ecfc96, 0x355eee96, -0x078e9048, 0x2fd05bf1, 0x48eab9e0, 0xafaab712, -0xcf0c3e12, 0x8095ae6d, 0x8364131e, 0x7221ba38, -0xad0e42d6, 0x20741356, 0x8698ad29, 0x024d1baf, -0xb87c4a77, 0xa4169a47, 0xa487c4c8, 0x966a2b68, -0x9821bace, 0xe64b1014, 0x22eda535, 0x4cc48e4e, -0xb1a80833, 0x0e9ec179, 0xf6bb1c55, 0x95489311, -0xefe8a663, 0xc4cf14f9, 0xe3591c5d, 0x86c3c61b, -0x9fe18d90, 0x3b75ff1b, 0x5ca3d992, 0x8c072f42, -0xecf16b8e, 0x672b72c7, 0x4603e497, 0x45e015d4, -0xd918406b, 0x4f25a635, 0x5feb56b4, 0xf9f94d06, -0x7bd31a73, 0x1ab03fc0, 0xb85fdbd8, 0x4c3e81d9, -0xefc2c666, 0x59a7afcd, 0x8a02428a, 0x73af7adb, -0xd8ea36e0, 0x991a6fd9, 0x7f9c2019, 0x2d3a85d6, -0x8f3295c0, 0x93809471, 0xa5d313f5, 0x8cd5ea3b, -0x7b982971, 0x5e4f0172, 0xcedcb6e6, 0xea24e209, -0x8a46f8b2, 0x74331527, 0xd77ed523, 0xaba69d6a, -0xebd38b4b, 0x04c01b27, 0xcf51542c, 0x25e75d87, -0x69f4e24a, 0xeb1c3f81, 0xdd4508da, 0x0cc85856, -0xd006d573, 0x79a7c5cb, 0x1cc2e951, 0xd1ac0710, -0xa78fbeba, 0x90877b5f, 0x7972ab18, 0xd866ac15, -0xc287620f, 0x54fdeb69, 0x9c2d264f, 0x6c2e6ff9, -0xa12c2962, 0x87f99490, 0x5a9f5f5c, 0x5fd88f09, -0xf6b7e966, 0x02abc4f2, 0xde5eddd1, 0x6ccd06e7, -0x7747ee88, 0x9bc9622a, 0xb807d839, 0x1d14fe6b, -0x1c4676e8, 0xb9add7e1, 0x5a84fc84, 0xa0d232ab, -0xf09b95a0, 0xbd7481db, 0x9f68639a, 0x4870d114, -0x60ebc8a5, 0x42d4d24b, 0xf64d2815, 0xaab0da5f, -0xcba7f41c, 0x44dcd89b, 0x613d50e6, 0x180e700c, -0x18a6bdad, 0x54883f08, 0xa0a9fc4b, 0x9af3ec0b, -0xba3f74f2, 0x9469aa23, 0xc89de01e, 0xe7963adb, -0x8cb13661, 0xdbbd276c, 0x42e113df, 0x4947dfd7, -0x513cc410, 0x57c6db1c, 0x8911377d, 0x01405fa9, -0x7163e406, 0x995a0db3, 0x2e9b208b, 0x4c77dfbc, -0x33f30f4c, 0x5aad99da, 0xcca61b32, 0x027fa2ce, -0x2b5387aa, 0xafca9d2b, 0x7fbe4c67, 0xee92fc72, -0xc3857c05, 0x5e425769, 0x4ae6558f, 0x499427f8, -0x15900b70, 0x3aae1260, 0xa7bfc2a1, 0xdfa73e71, -0x8b79b206, 0x6552c432, 0x56b81866, 0x86d6e834, -0x91685add, 0x7c34051c, 0x4ef8db74, 0xbab855ee, -0x083ab156, 0xc82a579d, 0xec1e3ae3, 0xdfea24a6, -0x9554ee6e, 0xd53b8bd1, 0x9a4bda63, 0x884e86e5, -0x9acf4763, 0x540b9ded, 0x5fde4bca, 0x541d2dd4, -0xc5637486, 0x5fdfc527, 0x6cc50628, 0xc701a605, -0x7fba696e, 0x053a6cd0, 0x3796571c, 0xd11ec6f6, -0x2a653ec1, 0x69a1ade5, 0x16171234, 0x3aa406c1, -0xcc4c0c5c, 0xcaa1b030, 0x5aa895d9, 0xcda3b272, -0xe6d47066, 0x998c147c, 0x1b026939, 0x6371cc60, -0x9ec4d2d9, 0x3b49c98d, 0xbb49a6a5, 0xcb1ed1f9, -0x30b9688a, 0x2db1402d, 0x5665effd, 0x0d9a0e51, -0x25b22259, 0xb0bfbee3, 0x111f4513, 0xa18acb44, -0x382c08fb, 0xd865ca2f, 0x260cb54c, 0xffa0dbb4, -0x9aad6b4a, 0x578ade98, 0xb9f09030, 0xbafe415f, -0xf7235cf8, 0xd19f0413, 0xedc73cef, 0x80d5d335, -0x214f990b, 0x8478604f, 0x944b72e5, 0x131c9537, -0xcb692f67, 0x4a5cbd6b, 0x03133594, 0x80b99f44, -0x371cb369, 0x256baf31, 0x7ceb93d3, 0xf2a3f4b8, -0x422db93a, 0x19729ad5, 0x59847c4a, 0x398f8e81, -0x7be54e1d, 0xe1e41995, 0x1029b034, 0xfc8999a6, -0x7419c8cb, 0xa9b0ccca, 0x2ef57bd5, 0x9fe322f2, -0x18af184d, 0xad51f8dd, 0xe513345b, 0xfaf81d66, -0xca6d45a3, 0x3907407a, 0x3a5b8ac3, 0xa61325ef, -0xdcd94ec0, 0xe88fe5af, 0xa978771d, 0x5570ba47, -/* 964-m01f0712.inc */ -0x00000001, 0x00000012, 0x07162002, 0x00000f07, -0x39e69ff0, 0x00000001, 0x00000001, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xffffffe9, 0x8bb66866, 0x1d79ea57, 0xeae74f1b, -0x361e4a7a, 0x55e2826d, 0x5f734071, 0xb2843de5, -0xae7971bb, 0xe25004de, 0x405dafe0, 0x7d53f66f, -0x4df56461, 0x7b57d0ce, 0xea17af39, 0xedbb1ebc, -0xe9e38d20, 0x8b12c950, 0x4a0b7e87, 0x52c078c1, -0x726e683c, 0xca3f7181, 0xc20dded4, 0x923fe6f8, -0xfc2c31f4, 0xfc1dbb1d, 0xe4d7cd63, 0xe2fbcd17, -0xa8ad72e0, 0x33fea0d3, 0x71d5d527, 0xc456c0fb, -0x4ca199ba, 0xeb863e4b, 0x43210553, 0x05454fcc, -0xdedf6095, 0x5ac66851, 0xc5b84d9d, 0xf1775630, -0xa50e817b, 0x8393f563, 0x4d6a58a4, 0x641c876e, -0x4598072d, 0xfb1875c5, 0x0efb05e9, 0xa5a840dd, -0x54e9190a, 0xe9ebafdb, 0x7bfaa19d, 0xdae03c5e, -0x141069e3, 0x178fbeef, 0xbdf33f79, 0xcdbdd066, -0x07ae0fc7, 0xf45750a0, 0x6f3810e9, 0x6415e0bf, -0x2b46112e, 0x21be86cd, 0x29245980, 0xbb58f310, -0xfb665f23, 0xfeeb9aad, 0xcea2257c, 0x5175328e, -0x0d3d2bd7, 0x81ce7ea2, 0x9a6de78a, 0x9850b5e3, -0xbbee4402, 0xb6319fb0, 0xc010158c, 0xbbb913ff, -0x395f312a, 0x24579055, 0x2ae58ef0, 0x9cc2b14a, -0xc76a13bd, 0x88def903, 0xa9b67b9e, 0x3feb492d, -0x707975d5, 0x5c9559b9, 0xf52a12ac, 0x87d2efe2, -0x2b2e52a8, 0xd0d7df0f, 0x4f1c6f19, 0xebb81a13, -0x80210238, 0x1b3c07f0, 0x7a499318, 0xde7c5eb3, -0x9f875ea6, 0xad68ad52, 0xdf0ad02f, 0x88665580, -0xc1e124bc, 0x2078c537, 0x31428f38, 0x91ab5aa2, -0xc1a64ad2, 0x87cc2159, 0x718ebfd5, 0xc2c3532e, -0x7e7ec93c, 0x1cdda579, 0xcffccb9b, 0x583c8d7e, -0xdd8a3faf, 0x60aa9835, 0x61aba793, 0x3e57affa, -0xa681cda5, 0xb225323f, 0x4b3f7fd0, 0x4d30f709, -0x6d206bbf, 0x51689b07, 0x3040283d, 0x95d95684, -0x53d4f28d, 0x4c5372c8, 0x0e2e293f, 0x7c660707, -0x06a15ae1, 0x1452111f, 0x3c5a0df0, 0x61fef67e, -0x8c9f26e8, 0x879dd434, 0x84937130, 0x28a9c507, -0x9d05cdc4, 0xa58e51f9, 0x78250d1a, 0xb4aa4867, -0x2f277408, 0x1d4281e2, 0x03f7a5c9, 0xb90aa91b, -0x09ddba69, 0x219ff884, 0x63c7aa86, 0x3ac8cae8, -0x3217bb61, 0x166844cd, 0x45518869, 0xb23d4145, -0x444a751c, 0x2c4ea3cf, 0x574cd48f, 0x859e01ae, -0x79901e63, 0x28701f07, 0xf31897aa, 0x0bfbabff, -0x18148ee5, 0x3aa01696, 0x08b8c6e8, 0x073ef026, -0x4bbd2163, 0x278a5b5d, 0xca4f43fe, 0x1581b955, -0xdd310608, 0x4c47f8aa, 0xc4748e35, 0x0938dd48, -0xa7dbd247, 0x4f9c9284, 0x4fd12ae0, 0x4122817e, -0x57af6bb7, 0x1b1cbf56, 0x01713ae5, 0x4693a2a4, -0xd361471c, 0xfb5e5fb9, 0xd57ecb2e, 0x1396b134, -0x6c1ef975, 0xf0ba5604, 0x2bc5fc46, 0xe8e75240, -0xdc5a04ef, 0x0c7fec2b, 0xff44a7d1, 0xf1752a97, -0x4c64f1a6, 0x5f5b6971, 0xf80425d4, 0x26a2d408, -0xdc3661d1, 0x641f52d4, 0xc14d1641, 0x6db4a92b, -0x7ab7b4f4, 0x15c03f01, 0x120456f8, 0x434b9b0b, -0xecd8fd05, 0xe791871f, 0xf115d632, 0x362e7192, -0xb2f6d067, 0xc38caf36, 0x38916496, 0xdb0b52f0, -0x4435b1b4, 0x1e33bc83, 0xdbec3c07, 0xc8a80185, -0x7f5c6ad1, 0x0759aede, 0xfb9afeeb, 0x3da4804e, -0x02b98265, 0x1fdc99d3, 0xe3238746, 0x0b485f0d, -0xc8452172, 0x21f980ed, 0x115b5f9f, 0x2fdb1ab6, -0x51f0b309, 0x07ec0a64, 0x1371f802, 0x1af7b884, -0x2b63d9be, 0x064d5257, 0x9247a258, 0x2e7d9ef4, -0xebc76e82, 0x3744e142, 0x327498ed, 0x1efe2eaa, -0xf4b47f03, 0xd56b8a80, 0xd9df7063, 0x38b6093e, -0xe8952237, 0xd4c3cb00, 0x427aaa2f, 0xde11b0dc, -0xc6389e16, 0x2775052a, 0xb53c88c3, 0xdcc0d91f, -0xa372dba9, 0x56082310, 0xd5eb095a, 0x06bf07de, -0xab0cfa42, 0x450af2c0, 0xb64ae4fb, 0x4b29950c, -0xf66c4395, 0x0878b9c7, 0xbcd15704, 0x634b7b14, -0xdb3de5f4, 0xb08f50bb, 0x831e6abb, 0x010abe5c, -0x4d081d89, 0xb522a1b5, 0xfaf4f82a, 0x8932dcd1, -0x439fdb05, 0x0cacc3de, 0x56e8393b, 0xaaa12d2b, -0xb3c38358, 0x304b273e, 0xd2a231fe, 0x2211e77c, -0x70f73dee, 0x2e5b056e, 0x01df2fde, 0x0d39db76, -0x2c2137b2, 0x11638742, 0x2c160d57, 0x1e29cf1d, -0x62157d15, 0xd71cf60c, 0xcc2012e5, 0x1ef8e889, -0x7438d083, 0xfab2d9e9, 0xcd1e6cfb, 0xe37d919e, -0x738e3e70, 0x2f511109, 0xc88b544a, 0xcb5231cc, -0xb4aabced, 0x20f74006, 0xdf5b722b, 0x0f299cd5, -0x324f3630, 0x139a0348, 0xd45349ea, 0x208af30b, -0x8f2b48fc, 0x38a7e62a, 0xe5eb7bef, 0x18028e8f, -0x365eeece, 0xde32aa2b, 0xb7c86e79, 0x22b3a1a3, -0x3a66b2db, 0xd628c336, 0x2d3a3be9, 0xd82f8a9f, -0x049bc319, 0x3973ea2f, 0x66ef9dec, 0xfd5ed712, -0x8945b138, 0x5a3f99ff, 0xecd0b3b8, 0x29471ee6, -0x6b2a42e5, 0x45c3cc05, 0x2301d9d8, 0x702b2528, -0x1d75be7a, 0x3324b767, 0xe3add8b4, 0x7c0a4bae, -0x791010e8, 0xda59d2bc, 0x612eac2f, 0x235021b0, -0xc18567dc, 0xd15f9148, 0xca5d86fb, 0xc10bc63f, -0x2b8f4c36, 0x2d891b63, 0xa7977c9f, 0xdadb398f, -0x083f6a6a, 0x230e398e, 0x19420c4f, 0x1cc52b2a, -0xae8d117d, 0x2c32000d, 0xad13069e, 0x3a113635, -0xc6522f49, 0x074a7ddc, 0xea16a043, 0x35662b0a, -0xb3bd25b8, 0x18b45214, 0x9f142cbe, 0x1b7c6938, -0xe5f764de, 0x3b252a68, 0xd0c84dde, 0x1d74a684, -0x0b394830, 0x18d2add6, 0x0e14d7e3, 0x2812c01a, -0xb1426e75, 0x97c7426c, 0xca2425ce, 0x3b07c144, -0x92c538a2, 0xb50a1bc5, 0x6b7867a8, 0xb147634f, -0x39d1a5b6, 0x38dd638b, 0x84102bc9, 0xaeaf04e9, -0x75d6755a, 0x359fdcd9, 0x9859936d, 0x801f6834, -0xbba00552, 0xd8c96732, 0x9769642a, 0x92ab9c4d, -0x4b44a4ea, 0x6f3f380d, 0xf112e9a3, 0x8768532a, -0x958c163d, 0xa4a7c80f, 0x6873ae6b, 0x9b0e78b2, -0xd7ab7060, 0x4d9f8791, 0x370f29eb, 0x16e6a4df, -0x2eaa46b8, 0xcc64bf8b, 0x423c788c, 0xeef8371a, -0x497e76e3, 0xe49e1ed6, 0xb6890ea8, 0x7562648f, -0xd30c433a, 0xb967a3d2, 0x17b665fd, 0x0499210d, -0x0df41a8b, 0x60261315, 0x61d25715, 0xf7dfc43e, -0x1567841c, 0xac38e452, 0xb76be7a9, 0xfabea796, -0x017a95c6, 0xd7d2b0da, 0xa24fb7a3, 0x14ec0a12, -0xd3446440, 0xaa70e820, 0x81620b96, 0x466c02e6, -0x9f67c135, 0xee4ff616, 0x509161ad, 0x263587d2, -0x11169e0f, 0x5c46175a, 0xeed237e5, 0xefe242bd, -0x2aed7440, 0xde3f737f, 0xd6ba63eb, 0xe8d8304e, -0x8a1ad7a7, 0xff53828a, 0x0d2c073b, 0x6dc5dbfa, -0xcb76174a, 0xfa1b2c30, 0x384ac449, 0x1f5ea4be, -0xde50549d, 0x5f6e5977, 0x6d5c33e5, 0x2b9b8ab4, -0x8be0c16c, 0x021db150, 0xf3a99a6e, 0x9a4dcfc5, -0x7bc75f76, 0x243be7b0, 0xe53d1b04, 0x38fd5ab9, -0x4d26ca07, 0x90ef6dff, 0x4c8c02db, 0xdf986343, -0xc84edd73, 0x2a46005c, 0x6ebe028e, 0x1d68a9dc, -0x97f23c83, 0x2dda5fde, 0xaf56b1e9, 0xc4f04b0a, -0x97a355a9, 0x3f5b604b, 0x8a4c5c33, 0x4fb3c292, -0x5be0edd7, 0xd05af070, 0x1623da74, 0xb55ff7af, -0x40929043, 0x62e96e20, 0xde5afdec, 0x5bbe38bb, -0x47918b57, 0xba53cfb7, 0xa613b0cb, 0x3c794832, -0x69c9f5b2, 0x62ad3086, 0x2afc0271, 0xdb900632, -0x65d6c7ea, 0x0dd8b907, 0x52f3cabd, 0xf77a8c51, -/* 2337-m806fbB6.inc */ -0x00000001, 0x000000b6, 0x07132007, 0x000006fb, -0x2831cee4, 0x00000001, 0x00000080, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x000000b6, -0x00000035, 0x2a000000, 0x20070712, 0x000002f1, -0x00000001, 0x000006fb, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc67566b4, 0x105501ed, 0x8a79141f, 0xd976d998, -0x39025e8d, 0xc8d4def9, 0x136f7e41, 0xd876436e, -0x58d10d9f, 0xb7f2421d, 0xe4d5fcf1, 0x02889a15, -0xad9bed07, 0xa32ab3e6, 0x3491afcc, 0x9c991c37, -0x2a1c2071, 0xf066191a, 0x3bd898e7, 0x2648d958, -0xc05f7908, 0x05864b9b, 0xbe4c1eee, 0x1e6c7ef4, -0x0e7a539e, 0x100b2ab3, 0x1273dceb, 0xfec8847d, -0x8f37946f, 0x634e3b5c, 0x691dbd61, 0xd89e3cb9, -0x094639d4, 0x7d972e1a, 0xd6dbd94d, 0x2001c3ec, -0x34f791f0, 0xeee0d794, 0x88b7459d, 0xc2c73aa3, -0x607a174d, 0x4f0f8304, 0x65790b35, 0x00532bfe, -0x1fd1e0cc, 0x7b91f873, 0x154ed42b, 0x7a7108e9, -0x81637c95, 0x192cb173, 0x28ccd94e, 0xb9bcc372, -0xac05171b, 0x867f47da, 0xf8e8c47d, 0x1edcdb4a, -0xd2ca6c2d, 0xe9ee9169, 0x5a6efedc, 0xb6825038, -0x09277eaa, 0x2a34e580, 0x0f794366, 0x86c99402, -0x211b98bf, 0xdf8eb0e3, 0xda11d7bd, 0xd440363e, -0xa7d49f1a, 0x16dd7395, 0x5b23c2fc, 0xab93ea3c, -0x00000011, 0x8d12ea76, 0xc5c9c349, 0x92308263, -0xf78e4c9d, 0x72c29f88, 0xd19a18ac, 0x1c90e94d, -0xeb8c5d92, 0xf7bb5a98, 0xa62ae1bb, 0x1d37396a, -0x191737e5, 0xe423c9c2, 0x1c16fae4, 0xb95f9692, -0xaeae4fbf, 0xbed4707f, 0x70f70fa6, 0x3e80ad8a, -0x668f54d9, 0xff968f7e, 0xc4e24190, 0x0872ccf0, -0x4fa39955, 0x55a1a6f5, 0xc36d7848, 0xe82e7047, -0x3ea79a72, 0x27411065, 0x55930d6f, 0x8e94ddfa, -0x6008c698, 0xb315b1d6, 0xedee441f, 0xd3875916, -0xd0a76bae, 0x14ef297d, 0x6393320d, 0x69d787dd, -0x7973bdd6, 0x7e5c4c27, 0xdfe61741, 0xc631b12d, -0xcc99b991, 0xbeed1d1b, 0x9b3c5535, 0x78a48b4a, -0xe278d8a2, 0xf1c80ebe, 0x70f3ed4f, 0x4744194c, -0x53503244, 0xf94ab448, 0x04f48675, 0xa91912e6, -0x0fbe4a37, 0x22dd31d7, 0xc7b0cb0d, 0x752eebc1, -0x83141b0c, 0xb59e8702, 0x5efa7721, 0xc8440cd4, -0x94a00db5, 0xfafd13f4, 0x878cc0a0, 0x735a935a, -0x456ae71e, 0x405aa5f4, 0xcb272526, 0xeb85d034, -0x91f58175, 0xbab6094c, 0x48426d3c, 0x18bb5eea, -0xe9ee4304, 0x0868f031, 0x29413b52, 0x29ab13c3, -0x575646eb, 0xb24f2668, 0x142b91b2, 0xfa969908, -0x12b79a91, 0x38bc2ba2, 0x525e5da2, 0xabc63db2, -0x9bce15d9, 0xa2d2a006, 0xa1744c42, 0xf64f876a, -0x4121f17a, 0x0e24d1b5, 0xb27a09dd, 0x2741ca03, -0xd83fe2bc, 0x59a0aeee, 0xe861ab21, 0xb304ca71, -0xb8bc5b2b, 0x1553f2c5, 0x5d078685, 0x3de43e77, -0x8e1f2eb1, 0xa9eb40bc, 0x3bcb1973, 0x4721b5b6, -0x73e23954, 0xa9464b92, 0x82ad836e, 0x56b8a136, -0x4bb95ff6, 0xa538c8aa, 0xe2bf3da3, 0x1347a40a, -0x34f844c2, 0x596ab878, 0xa9f94b32, 0xdad18fd1, -0x6f2fda04, 0x09c10ec7, 0xed4a2d3f, 0x375add96, -0x0ae45688, 0xa594039e, 0x8fdae080, 0x7f3f4a68, -0xef496e17, 0xab450c5e, 0x9a43c59c, 0xf5394c3a, -0xf09dd852, 0xb9b41813, 0x45ed7124, 0xcfe1955c, -0x7e3eedcc, 0xf4603b14, 0x1907131c, 0x5b45ade1, -0x154c8205, 0xcf98affa, 0xfaf58903, 0xa071e600, -0x0814f47e, 0xacd29fff, 0xa9246964, 0x7a638372, -0x3d1061b1, 0xba47647e, 0xd1fbee16, 0x896dd880, -0x1c100f37, 0x99cb8778, 0x48062c08, 0xd0366a79, -0xa6d7ddb8, 0x86c68a9f, 0x02ac6f34, 0x0e144676, -0x20d43c65, 0xcb6a9b99, 0x0e1c9291, 0x9cfd5b8f, -0xac43cbcf, 0x34a7974d, 0xce017104, 0x975c2efc, -0xd55c5dbb, 0x0e16766d, 0x890dfd62, 0x2934622d, -0x709fa149, 0x21a94f12, 0x43113498, 0xb146aa2f, -0xfbbca7ff, 0x1782cec2, 0x9ff3b595, 0xfe4b2b95, -0x0fd2fbd8, 0x1651f923, 0xa74fe4cc, 0xd07a49c0, -0x0d0adba2, 0x9c70bce9, 0x08e8b8d7, 0x32dbe104, -0x6168b74f, 0x7a24fdbe, 0x5e3b2564, 0x6ffe5439, -0x1e7721c4, 0x94af4976, 0x1391cec8, 0xafa04102, -0x79d64355, 0xd88737af, 0xa2f2298f, 0xc980628f, -0x465e2d9b, 0x8b2bfcf2, 0xc46fb4fd, 0xc352c65c, -0xa3064ff7, 0x3b9264da, 0x7427ca4b, 0x41c01632, -0xa2d1ed33, 0x6cca9f3f, 0xf8b67421, 0x305e1584, -0xc9732051, 0x89a0091d, 0xc374e441, 0x587ab4e7, -0x958dd99b, 0x286d9f81, 0x10c67cdd, 0xb85d1783, -0x67b38f42, 0x30b90891, 0x45894054, 0xd050199d, -0x130063b6, 0x7b5e0863, 0x8a61c4d6, 0x2c44fe2e, -0x148428aa, 0xaa587921, 0xf542fe2b, 0x7b7da7e5, -0xed3bd14f, 0xb2616902, 0xc840e668, 0xb2623ee3, -0xbfc63cca, 0xed8b82dd, 0xf7d3cb2e, 0x41eab7ed, -0x8c3bfe0a, 0xd24a3c82, 0xd6d3d9be, 0x3aedf032, -0x957a863f, 0x04d80868, 0x1a59e52b, 0x52ee31fb, -0x8aa7dfa0, 0x2dfb638d, 0x2967e9cd, 0x0aa67bda, -0xd87b2b96, 0xea23ba62, 0xd6c97957, 0xa6f1cc56, -0xac8c9465, 0x3408348f, 0xc82fc701, 0xdf1d0e14, -0x11f617a5, 0x93f4964c, 0xebfae6fb, 0x07f0a028, -0xb40c5b7c, 0x6c0f33f6, 0x854abf0a, 0x89e518d1, -0xfcb70776, 0x1cf65ddc, 0x1dc0ae2e, 0x418ff41d, -0xafbc49f4, 0x064e2e27, 0x35ce2cc0, 0xece5ac9a, -0x7c245d5d, 0xf22af2a7, 0x5a5df3a5, 0xf991e2f4, -0xcd0b15fd, 0x68bd046a, 0xd29d50c6, 0x1e691c01, -0x7a4d3cd5, 0x2f6275da, 0xf1cee3f3, 0x84261101, -0xd32ecfdc, 0xe75fdec2, 0xc02846a8, 0x13f19aa6, -0x3dafe115, 0x2c2b0488, 0xbb9da407, 0x196198eb, -0x897db3b0, 0x58813217, 0x917af6ba, 0xf7fa30ff, -0x277c26a1, 0xde9ffb6a, 0x85eb946a, 0xb9a6295b, -0x3f7f687a, 0x17fef8a5, 0x3af23085, 0x457a11a3, -0x2a73b9a7, 0xedbfd16a, 0xd2e88242, 0x1e3c02e5, -0x0ea74671, 0x1fc9e250, 0x5a313d7d, 0xd5a49528, -0xe749e126, 0xdf0de086, 0x35b60d77, 0x07fb5491, -0xdedda50a, 0x51325ec5, 0x8cef16c0, 0x5dbc5f47, -0x0c02a13e, 0x76604b7c, 0xbfef93fb, 0x3e7f0bf0, -0xd1add7e3, 0xdd6c3a85, 0x6e1e119e, 0x38278895, -0xa8df00b8, 0x19f99ab9, 0x368b3ea6, 0xcde20a8b, -0xf7acd01f, 0xc59c84f9, 0x0a0b6d38, 0x18cb2d96, -0x37544234, 0xc2c89561, 0x603d7483, 0x8049a647, -0x86cee8e1, 0xfab3b928, 0xbf53d180, 0x548aaaef, -0xd0840b5d, 0x56475635, 0xa29f7fea, 0x1db9078e, -0xc29beac4, 0xe34189e0, 0xae65a95a, 0x5ba92288, -0x50152e52, 0x9ce2d6cc, 0x1a602dca, 0x72671a71, -0xde59b037, 0x7adb5fe0, 0xcadf39c4, 0x7110db44, -0x00200eee, 0xf2a574d0, 0x7cc14a56, 0x9b01c7c7, -0x363a0d5b, 0xff8a60e8, 0x34e900dc, 0x567b5d4e, -0x6b52d659, 0x82e22016, 0xd2e6cb9f, 0x611391c9, -0xe99bad01, 0xc6e46ebb, 0x14e29144, 0xb8e85f81, -0xea508116, 0xae7aa3b1, 0x6d535779, 0x673ec856, -0x285dfb55, 0x4671b198, 0x21491515, 0x1fd77e2b, -0x1dfbfa06, 0x442161e9, 0x0dfa5161, 0x9ba818fe, -0x708a8e17, 0xc9754986, 0xeef3ab77, 0x8caa3151, -0xfe6d3b59, 0xcfba71e2, 0x780b6c3f, 0x0fedcdbe, -0xb3dfbdf4, 0xbb0d7953, 0x1d9450d3, 0x58d71d72, -0x09d71b70, 0x679bd3ed, 0xd68bfb24, 0xe93470ed, -0x36b2a64a, 0x6ddb8077, 0xd6968654, 0x29868706, -0x30af7610, 0x0fc9eb07, 0x10690e76, 0xfe62ee78, -0x9ffb3fc6, 0x0c34f0e5, 0xbc01db4f, 0xd4fbb08f, -0x4420b704, 0xa4af88c9, 0x0a3ae196, 0x6af40c74, -0x08d58801, 0x886ba013, 0xd70a4f3e, 0x924c5830, -0x494ee315, 0x90f62676, 0x727c427b, 0x78e0fb4b, -0xf9b4508b, 0xac37411e, 0x8e1f7b36, 0x54778002, -0x00080c22, 0xd55e89e6, 0xef8b0961, 0x43eab9ab, -0x98e8e142, 0x9ef7eb71, 0xb1b0a6f8, 0xb259fec7, -0xd04d9f7f, 0x873a79fc, 0x6dff58bb, 0x7747a1ef, -0xef25d604, 0x21eb7b76, 0xee7cf400, 0x11056351, -0x57ecdffe, 0xfe939145, 0xf52794bb, 0x55917634, -0x9fb4d599, 0x5bf73f5e, 0x11382735, 0xc6cba6b8, -0x3ce059fe, 0x88f1bfbf, 0x4ed5941f, 0x9009764a, -0xf9c7f463, 0x0f28df41, 0x8cad66cf, 0x3ea7591c, -0x6707c286, 0xd47cb952, 0xf53392e2, 0x94e1a29e, -0xd4fb88f4, 0xa5fcaf93, 0xf5ba3444, 0x91249b70, -0x0bbeb5c9, 0xf943bfe9, 0x92629f51, 0xbc10d3f6, -0x9564f091, 0xad4bb29e, 0x0a50af33, 0xe8f79296, -0x8bf25c64, 0x81bdf02b, 0xec22d493, 0x0d2efea1, -0x52e2a6cf, 0xd412701d, 0xa17df71c, 0xb9f62247, -0x4d7b517a, 0xa9bd93a0, 0x94fb1eaa, 0x2d4bc7fb, -0xcd857966, 0xaf4953b6, 0xf664d4a2, 0xf1e12279, -0x1827aa2d, 0x6db71721, 0x28159f88, 0x9df25ab6, -0xa97443a9, 0x378b6644, 0x6ceebaef, 0x0e01e9fa, -0x048cf8b0, 0x962c3d48, 0x2d375c33, 0x407593a6, -0x693e2d8a, 0x9d5a557c, 0x44863ad9, 0x6ab3e26e, -0x3ec52d9f, 0x0933fed7, 0xa7b06032, 0x266f3a2f, -0x02575fdc, 0x2224ba45, 0x71c02d29, 0x1b08c7d1, -0x8b2200cb, 0xfc1c9a92, 0xbddc0508, 0xf3220cb2, -0xcf373ecb, 0x0dce00e9, 0x59e970e7, 0x0bd36624, -0xbbd1ce75, 0xa8641ec8, 0x06937187, 0xc3f2d380, -0x8a7adc67, 0x79f67552, 0x7fdf88a5, 0xb6941a6e, -0x0aafe9d5, 0x1d86eab7, 0x9240d112, 0xca6c7aac, -0x6ebaa150, 0xbba6c64f, 0xf20ec41c, 0x14a3c3fd, -0x8e3db21b, 0x66ad6654, 0xd339f5e1, 0x749714f2, -0xb22ba620, 0x9f4f0119, 0x3745aaec, 0x5ba03b86, -0x10bb4d86, 0x96309fe1, 0xf93c8620, 0x901c3170, -0x3224e497, 0x453639b7, 0xc8cb8101, 0x860a60c7, -0x10a69fae, 0x5cd0cf62, 0xf0c9fe79, 0x49b7f0b5, -0x89c719bf, 0x8caf497a, 0xca747cd6, 0x4a0cfabc, -0xb2f2cc33, 0x2768703f, 0x89e7e499, 0x44dd965b, -0xf7a772d7, 0xdd508108, 0x8a43b845, 0xba5a74e5, -0x6ca47c79, 0x72b9e0bc, 0x9479ce84, 0x3342f0b1, -0x9a39e2c0, 0x57808b69, 0x288ff4b6, 0xe5fab877, -0xed07f654, 0x0ee79da9, 0x02e7b183, 0x456fdb53, -0x11aeeb6c, 0x8c2fadb9, 0x67f79309, 0x2f97a264, -0x02af0d27, 0xf07f9608, 0xb66fd12c, 0x25e6bbc7, -0x92001908, 0xc52170a0, 0xc9fa7f41, 0xbf361c71, -0x33cd7f76, 0x776f9b61, 0x459cdfe1, 0x065dbdb5, -0x67a6f1d1, 0xcbbee73d, 0x2f7b516c, 0x1fda5e43, -0xeba7d6ab, 0x337c3557, 0x1f2477f5, 0xeec7d493, -0x749fa13a, 0x3c37e01d, 0xa78babcf, 0x9ee438d4, -0xaa57066a, 0x9efe96c5, 0x8d45bd8b, 0xbc36930b, -0xfbf60974, 0xdbb7844b, 0x44001279, 0x14e036b9, -0xb524f4a6, 0xad1cee3d, 0x351aca37, 0x22861da8, -0x0648f10b, 0x394078f1, 0x4287ef8c, 0x5c52b8a2, -0xaa345739, 0x959a7de2, 0xb1cd8059, 0x29b3e4f9, -0x3ee210dd, 0x7a4e3104, 0x7e6ccae0, 0xb6d003d5, -0xfda934b3, 0x0e0a48d0, 0xd4109873, 0x2812c616, -0x635c5c94, 0xe3f9d4ac, 0xf0a6aaca, 0x7541e3f6, -0x3fc3b0c4, 0x49fb84e3, 0x710f44de, 0x7557e168, -0xa524128c, 0x5c7a1cab, 0xd94da26d, 0x635e0b6b, -0x21229736, 0xa4accca9, 0x27ee9ae8, 0x1a5416d1, -0x989833aa, 0x7eebb36a, 0x74ad3b3c, 0x76a2ee47, -0x1424b74a, 0x495bb4ef, 0x95f7352e, 0x0591577f, -0x7c2bc9cb, 0x4fe50735, 0x496ba74f, 0x827dab44, -0x3a4e6eb1, 0xf3089b11, 0xed78dc22, 0x79d5e577, -0x2421bad0, 0x89f97e71, 0x7d069592, 0x53da02fe, -0x6e47d868, 0xb99cfcc6, 0xca203836, 0xacd9ad61, -0x2139c875, 0x9bc56e41, 0xb001c73c, 0xd531ae4b, -0x456e9177, 0x4c8d3f89, 0xd597fb45, 0xb8fa7d69, -0xbf24bde7, 0x9286ac26, 0x43906899, 0xcd57a058, -0x83966715, 0xb6164ea0, 0x4623f16a, 0x9402a156, -0x5fafb09b, 0xd20029a8, 0x4e0c2923, 0xfa02adc7, -0x6f6d2158, 0xc661283a, 0x0cf41257, 0x3ebed2b7, -0xc24fa184, 0x084523bc, 0xb7a62e05, 0xb7b64b28, -0x5c926138, 0x88f3346f, 0xd0bd95ce, 0x0a130c87, -0x4cbee562, 0x4020be46, 0x83460e2a, 0x2e44c926, -0x80b45964, 0x37b94c25, 0x74019708, 0x59c03c00, -0x47bc9dc0, 0x3c3142b2, 0x37a323d3, 0x3a9f60e6, -0x61b527a8, 0x36ead7b3, 0xe0876b20, 0x62e103e4, -0x1d121a6d, 0xc8105f0d, 0xdd252e3d, 0x930b581e, -0xeafa1998, 0xeb7ff364, 0x413bc324, 0x954ce936, -0xa7468f25, 0x885b2cae, 0xc564b9c7, 0x731d380b, -0x868c22f1, 0x598c9eea, 0xeb05f3fa, 0x9459de9a, -0x5f6f64fe, 0xa86f3703, 0x52bf65e3, 0x9a6d1ae3, -0x06403369, 0x9cb53025, 0xcb2e3db2, 0xd0735776, -0x03804548, 0x515e7fd5, 0x1bc911c0, 0xeffde082, -0x6e83c7a2, 0x0968c2c7, 0x05f9223f, 0x61a1ca0b, -0xfa2cdf10, 0xa1fc1a7d, 0x458c9036, 0x8aa6c474, -0xc25743af, 0x9347ba31, 0x595f0df7, 0xfffb4e3d, -0xbc8995d2, 0x25c45251, 0x15d585fa, 0x7aa6dc47, -0x5f4cb245, 0xdde3093c, 0x21d24076, 0xcaac5bc8, -0x4996d45c, 0x68ed647d, 0xa913abad, 0xdaef2834, -0x1af11d90, 0xf8f170c2, 0xd1f2f415, 0xd12e7eca, -0x4a488d17, 0x66cf3181, 0x0cb503f6, 0xe47660b0, -0x6585acdb, 0xd1458ac8, 0x01e03d3a, 0xa3570cdc, -0x089c5cdc, 0xda99762a, 0xffd89a50, 0x1d1af7ea, -0x23c080cc, 0x8f19e36c, 0x0efb27b0, 0x842ffecf, -0x573b335b, 0xb95fc7dd, 0xcc753e1c, 0xcfeeed94, -0x60319281, 0xb951d84f, 0x3d285ef2, 0xad86e154, -0x68ee568b, 0xf773c45b, 0x3da9f5e2, 0x8390a8c0, -0x2a9c24f7, 0x571deb94, 0x72f2ee6c, 0x92da0173, -0xc64d1ab7, 0x2e1c591e, 0xea10f1e4, 0xc4bd43d3, -0x9f40bf13, 0xac535424, 0xdab90153, 0x222dd9d9, -0xe1fa8cfb, 0xac6e48bf, 0x2e315a7d, 0x810ff992, -0x42aa7db5, 0x9264cc20, 0xb37bcf8f, 0x7fc98ded, -0x717896ec, 0x0c8d431f, 0xabf12dc2, 0xa5cb0d3d, -0x4f5aa31b, 0x279b0ae2, 0xabf896e0, 0x6dbbfc53, -0x636a82f3, 0xad99a6c1, 0x4a2a3699, 0xea695ce9, -0x06d8857d, 0x42712072, 0xa20cf6a4, 0x341e3f58, -0x701f9570, 0x6f0e1667, 0x11f6096f, 0x6742b00f, -0x66f8850e, 0x8b6450fb, 0xd8a69fb0, 0xa0e53fd0, -0x134b9267, 0xcdad001b, 0x7d2986e8, 0xea497d52, -0x34e58614, 0x3e566177, 0xeef44c29, 0xea770a4b, -0xb31f234b, 0x7b25a4d0, 0x6e60445e, 0x2666d947, -0x71460fd8, 0xe848e55f, 0xaaeb7796, 0x85fdd232, -0xd7ae0bc7, 0x1bacd300, 0x0bc22f58, 0xd8d89f1d, -0x32b0ee1d, 0x179a3227, 0x89a2a16a, 0x80ba1be5, -0x5b985d2a, 0x01d8f172, 0xde47159b, 0x9f4f6afa, -0xda08f4fe, 0x9979d501, 0x10c87592, 0x432c7695, -0x73227987, 0x3d4f140f, 0x64ce99ee, 0xbf8c5e4c, -0x2d57b3c6, 0xb925c254, 0xd937cce8, 0xf3bc19e8, -0x35c09ef5, 0xfec6cba2, 0x1dd3d617, 0x6395da09, -0x25b186ff, 0x7cd137b0, 0x1c875643, 0x1ef07dee, -0x1ed5f7e2, 0x0e8e78ac, 0x7267452e, 0x1b2519e0, -/* 2334-m016fbB6.inc */ -0x00000001, 0x000000b6, 0x07132007, 0x000006fb, -0xb3176c40, 0x00000001, 0x00000001, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x000000b6, -0x00000035, 0x2a000000, 0x20070712, 0x000002f1, -0x00000001, 0x000006fb, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc67566b4, 0x105501ed, 0x8a79141f, 0xd976d998, -0x39025e8d, 0xc8d4def9, 0x136f7e41, 0xd876436e, -0x58d10d9f, 0xb7f2421d, 0xe4d5fcf1, 0x02889a15, -0xad9bed07, 0xa32ab3e6, 0x3491afcc, 0x9c991c37, -0x2a1c2071, 0xf066191a, 0x3bd898e7, 0x2648d958, -0xc05f7908, 0x05864b9b, 0xbe4c1eee, 0x1e6c7ef4, -0x0e7a539e, 0x100b2ab3, 0x1273dceb, 0xfec8847d, -0x8f37946f, 0x634e3b5c, 0x691dbd61, 0xd89e3cb9, -0x094639d4, 0x7d972e1a, 0xd6dbd94d, 0x2001c3ec, -0x34f791f0, 0xeee0d794, 0x88b7459d, 0xc2c73aa3, -0x607a174d, 0x4f0f8304, 0x65790b35, 0x00532bfe, -0x1fd1e0cc, 0x7b91f873, 0x154ed42b, 0x7a7108e9, -0x81637c95, 0x192cb173, 0x28ccd94e, 0xb9bcc372, -0xac05171b, 0x867f47da, 0xf8e8c47d, 0x1edcdb4a, -0xd2ca6c2d, 0xe9ee9169, 0x5a6efedc, 0xb6825038, -0x09277eaa, 0x2a34e580, 0x0f794366, 0x86c99402, -0x211b98bf, 0xdf8eb0e3, 0xda11d7bd, 0xd440363e, -0xa7d49f1a, 0x16dd7395, 0x5b23c2fc, 0xab93ea3c, -0x00000011, 0x8d12ea76, 0xc5c9c349, 0x92308263, -0xf78e4c9d, 0x72c29f88, 0xd19a18ac, 0x1c90e94d, -0xeb8c5d92, 0xf7bb5a98, 0xa62ae1bb, 0x1d37396a, -0x191737e5, 0xe423c9c2, 0x1c16fae4, 0xb95f9692, -0xaeae4fbf, 0xbed4707f, 0x70f70fa6, 0x3e80ad8a, -0x668f54d9, 0xff968f7e, 0xc4e24190, 0x0872ccf0, -0x4fa39955, 0x55a1a6f5, 0xc36d7848, 0xe82e7047, -0x3ea79a72, 0x27411065, 0x55930d6f, 0x8e94ddfa, -0x6008c698, 0xb315b1d6, 0xedee441f, 0xd3875916, -0xd0a76bae, 0x14ef297d, 0x6393320d, 0x69d787dd, -0x7973bdd6, 0x7e5c4c27, 0xdfe61741, 0xc631b12d, -0xcc99b991, 0xbeed1d1b, 0x9b3c5535, 0x78a48b4a, -0xe278d8a2, 0xf1c80ebe, 0x70f3ed4f, 0x4744194c, -0x53503244, 0xf94ab448, 0x04f48675, 0xa91912e6, -0x0fbe4a37, 0x22dd31d7, 0xc7b0cb0d, 0x752eebc1, -0x83141b0c, 0xb59e8702, 0x5efa7721, 0xc8440cd4, -0x94a00db5, 0xfafd13f4, 0x878cc0a0, 0x735a935a, -0x456ae71e, 0x405aa5f4, 0xcb272526, 0xeb85d034, -0x91f58175, 0xbab6094c, 0x48426d3c, 0x18bb5eea, -0xe9ee4304, 0x0868f031, 0x29413b52, 0x29ab13c3, -0x575646eb, 0xb24f2668, 0x142b91b2, 0xfa969908, -0x12b79a91, 0x38bc2ba2, 0x525e5da2, 0xabc63db2, -0x9bce15d9, 0xa2d2a006, 0xa1744c42, 0xf64f876a, -0x4121f17a, 0x0e24d1b5, 0xb27a09dd, 0x2741ca03, -0xd83fe2bc, 0x59a0aeee, 0xe861ab21, 0xb304ca71, -0xb8bc5b2b, 0x1553f2c5, 0x5d078685, 0x3de43e77, -0x8e1f2eb1, 0xa9eb40bc, 0x3bcb1973, 0x4721b5b6, -0x73e23954, 0xa9464b92, 0x82ad836e, 0x56b8a136, -0x4bb95ff6, 0xa538c8aa, 0xe2bf3da3, 0x1347a40a, -0x34f844c2, 0x596ab878, 0xa9f94b32, 0xdad18fd1, -0x6f2fda04, 0x09c10ec7, 0xed4a2d3f, 0x375add96, -0x0ae45688, 0xa594039e, 0x8fdae080, 0x7f3f4a68, -0xef496e17, 0xab450c5e, 0x9a43c59c, 0xf5394c3a, -0xf09dd852, 0xb9b41813, 0x45ed7124, 0xcfe1955c, -0x7e3eedcc, 0xf4603b14, 0x1907131c, 0x5b45ade1, -0x154c8205, 0xcf98affa, 0xfaf58903, 0xa071e600, -0x0814f47e, 0xacd29fff, 0xa9246964, 0x7a638372, -0x3d1061b1, 0xba47647e, 0xd1fbee16, 0x896dd880, -0x1c100f37, 0x99cb8778, 0x48062c08, 0xd0366a79, -0xa6d7ddb8, 0x86c68a9f, 0x02ac6f34, 0x0e144676, -0x20d43c65, 0xcb6a9b99, 0x0e1c9291, 0x9cfd5b8f, -0xac43cbcf, 0x34a7974d, 0xce017104, 0x975c2efc, -0xd55c5dbb, 0x0e16766d, 0x890dfd62, 0x2934622d, -0x709fa149, 0x21a94f12, 0x43113498, 0xb146aa2f, -0xfbbca7ff, 0x1782cec2, 0x9ff3b595, 0xfe4b2b95, -0x0fd2fbd8, 0x1651f923, 0xa74fe4cc, 0xd07a49c0, -0x0d0adba2, 0x9c70bce9, 0x08e8b8d7, 0x32dbe104, -0x6168b74f, 0x7a24fdbe, 0x5e3b2564, 0x6ffe5439, -0x1e7721c4, 0x94af4976, 0x1391cec8, 0xafa04102, -0x79d64355, 0xd88737af, 0xa2f2298f, 0xc980628f, -0x465e2d9b, 0x8b2bfcf2, 0xc46fb4fd, 0xc352c65c, -0xa3064ff7, 0x3b9264da, 0x7427ca4b, 0x41c01632, -0xa2d1ed33, 0x6cca9f3f, 0xf8b67421, 0x305e1584, -0xc9732051, 0x89a0091d, 0xc374e441, 0x587ab4e7, -0x958dd99b, 0x286d9f81, 0x10c67cdd, 0xb85d1783, -0x67b38f42, 0x30b90891, 0x45894054, 0xd050199d, -0x130063b6, 0x7b5e0863, 0x8a61c4d6, 0x2c44fe2e, -0x148428aa, 0xaa587921, 0xf542fe2b, 0x7b7da7e5, -0xed3bd14f, 0xb2616902, 0xc840e668, 0xb2623ee3, -0xbfc63cca, 0xed8b82dd, 0xf7d3cb2e, 0x41eab7ed, -0x8c3bfe0a, 0xd24a3c82, 0xd6d3d9be, 0x3aedf032, -0x957a863f, 0x04d80868, 0x1a59e52b, 0x52ee31fb, -0x8aa7dfa0, 0x2dfb638d, 0x2967e9cd, 0x0aa67bda, -0xd87b2b96, 0xea23ba62, 0xd6c97957, 0xa6f1cc56, -0xac8c9465, 0x3408348f, 0xc82fc701, 0xdf1d0e14, -0x11f617a5, 0x93f4964c, 0xebfae6fb, 0x07f0a028, -0xb40c5b7c, 0x6c0f33f6, 0x854abf0a, 0x89e518d1, -0xfcb70776, 0x1cf65ddc, 0x1dc0ae2e, 0x418ff41d, -0xafbc49f4, 0x064e2e27, 0x35ce2cc0, 0xece5ac9a, -0x7c245d5d, 0xf22af2a7, 0x5a5df3a5, 0xf991e2f4, -0xcd0b15fd, 0x68bd046a, 0xd29d50c6, 0x1e691c01, -0x7a4d3cd5, 0x2f6275da, 0xf1cee3f3, 0x84261101, -0xd32ecfdc, 0xe75fdec2, 0xc02846a8, 0x13f19aa6, -0x3dafe115, 0x2c2b0488, 0xbb9da407, 0x196198eb, -0x897db3b0, 0x58813217, 0x917af6ba, 0xf7fa30ff, -0x277c26a1, 0xde9ffb6a, 0x85eb946a, 0xb9a6295b, -0x3f7f687a, 0x17fef8a5, 0x3af23085, 0x457a11a3, -0x2a73b9a7, 0xedbfd16a, 0xd2e88242, 0x1e3c02e5, -0x0ea74671, 0x1fc9e250, 0x5a313d7d, 0xd5a49528, -0xe749e126, 0xdf0de086, 0x35b60d77, 0x07fb5491, -0xdedda50a, 0x51325ec5, 0x8cef16c0, 0x5dbc5f47, -0x0c02a13e, 0x76604b7c, 0xbfef93fb, 0x3e7f0bf0, -0xd1add7e3, 0xdd6c3a85, 0x6e1e119e, 0x38278895, -0xa8df00b8, 0x19f99ab9, 0x368b3ea6, 0xcde20a8b, -0xf7acd01f, 0xc59c84f9, 0x0a0b6d38, 0x18cb2d96, -0x37544234, 0xc2c89561, 0x603d7483, 0x8049a647, -0x86cee8e1, 0xfab3b928, 0xbf53d180, 0x548aaaef, -0xd0840b5d, 0x56475635, 0xa29f7fea, 0x1db9078e, -0xc29beac4, 0xe34189e0, 0xae65a95a, 0x5ba92288, -0x50152e52, 0x9ce2d6cc, 0x1a602dca, 0x72671a71, -0xde59b037, 0x7adb5fe0, 0xcadf39c4, 0x7110db44, -0x00200eee, 0xf2a574d0, 0x7cc14a56, 0x9b01c7c7, -0x363a0d5b, 0xff8a60e8, 0x34e900dc, 0x567b5d4e, -0x6b52d659, 0x82e22016, 0xd2e6cb9f, 0x611391c9, -0xe99bad01, 0xc6e46ebb, 0x14e29144, 0xb8e85f81, -0xea508116, 0xae7aa3b1, 0x6d535779, 0x673ec856, -0x285dfb55, 0x4671b198, 0x21491515, 0x1fd77e2b, -0x1dfbfa06, 0x442161e9, 0x0dfa5161, 0x9ba818fe, -0x708a8e17, 0xc9754986, 0xeef3ab77, 0x8caa3151, -0xfe6d3b59, 0xcfba71e2, 0x780b6c3f, 0x0fedcdbe, -0xb3dfbdf4, 0xbb0d7953, 0x1d9450d3, 0x58d71d72, -0x09d71b70, 0x679bd3ed, 0xd68bfb24, 0xe93470ed, -0x36b2a64a, 0x6ddb8077, 0xd6968654, 0x29868706, -0x30af7610, 0x0fc9eb07, 0x10690e76, 0xfe62ee78, -0x9ffb3fc6, 0x0c34f0e5, 0xbc01db4f, 0xd4fbb08f, -0x4420b704, 0xa4af88c9, 0x0a3ae196, 0x6af40c74, -0x08d58801, 0x886ba013, 0xd70a4f3e, 0x924c5830, -0x494ee315, 0x90f62676, 0x727c427b, 0x78e0fb4b, -0xf9b4508b, 0xac37411e, 0x8e1f7b36, 0x54778002, -0x00080c22, 0xd55e89e6, 0xef8b0961, 0x43eab9ab, -0x98e8e142, 0x9ef7eb71, 0xb1b0a6f8, 0xb259fec7, -0xd04d9f7f, 0x873a79fc, 0x6dff58bb, 0x7747a1ef, -0xef25d604, 0x21eb7b76, 0xee7cf400, 0x11056351, -0x57ecdffe, 0xfe939145, 0xf52794bb, 0x55917634, -0x9fb4d599, 0x5bf73f5e, 0x11382735, 0xc6cba6b8, -0x3ce059fe, 0x88f1bfbf, 0x4ed5941f, 0x9009764a, -0xf9c7f463, 0x0f28df41, 0x8cad66cf, 0x3ea7591c, -0x6707c286, 0xd47cb952, 0xf53392e2, 0x94e1a29e, -0xd4fb88f4, 0xa5fcaf93, 0xf5ba3444, 0x91249b70, -0x0bbeb5c9, 0xf943bfe9, 0x92629f51, 0xbc10d3f6, -0x9564f091, 0xad4bb29e, 0x0a50af33, 0xe8f79296, -0x8bf25c64, 0x81bdf02b, 0xec22d493, 0x0d2efea1, -0x52e2a6cf, 0xd412701d, 0xa17df71c, 0xb9f62247, -0x4d7b517a, 0xa9bd93a0, 0x94fb1eaa, 0x2d4bc7fb, -0xcd857966, 0xaf4953b6, 0xf664d4a2, 0xf1e12279, -0x1827aa2d, 0x6db71721, 0x28159f88, 0x9df25ab6, -0xa97443a9, 0x378b6644, 0x6ceebaef, 0x0e01e9fa, -0x048cf8b0, 0x962c3d48, 0x2d375c33, 0x407593a6, -0x693e2d8a, 0x9d5a557c, 0x44863ad9, 0x6ab3e26e, -0x3ec52d9f, 0x0933fed7, 0xa7b06032, 0x266f3a2f, -0x02575fdc, 0x2224ba45, 0x71c02d29, 0x1b08c7d1, -0x8b2200cb, 0xfc1c9a92, 0xbddc0508, 0xf3220cb2, -0xcf373ecb, 0x0dce00e9, 0x59e970e7, 0x0bd36624, -0xbbd1ce75, 0xa8641ec8, 0x06937187, 0xc3f2d380, -0x8a7adc67, 0x79f67552, 0x7fdf88a5, 0xb6941a6e, -0x0aafe9d5, 0x1d86eab7, 0x9240d112, 0xca6c7aac, -0x6ebaa150, 0xbba6c64f, 0xf20ec41c, 0x14a3c3fd, -0x8e3db21b, 0x66ad6654, 0xd339f5e1, 0x749714f2, -0xb22ba620, 0x9f4f0119, 0x3745aaec, 0x5ba03b86, -0x10bb4d86, 0x96309fe1, 0xf93c8620, 0x901c3170, -0x3224e497, 0x453639b7, 0xc8cb8101, 0x860a60c7, -0x10a69fae, 0x5cd0cf62, 0xf0c9fe79, 0x49b7f0b5, -0x89c719bf, 0x8caf497a, 0xca747cd6, 0x4a0cfabc, -0xb2f2cc33, 0x2768703f, 0x89e7e499, 0x44dd965b, -0xf7a772d7, 0xdd508108, 0x8a43b845, 0xba5a74e5, -0x6ca47c79, 0x72b9e0bc, 0x9479ce84, 0x3342f0b1, -0x9a39e2c0, 0x57808b69, 0x288ff4b6, 0xe5fab877, -0xed07f654, 0x0ee79da9, 0x02e7b183, 0x456fdb53, -0x11aeeb6c, 0x8c2fadb9, 0x67f79309, 0x2f97a264, -0x02af0d27, 0xf07f9608, 0xb66fd12c, 0x25e6bbc7, -0x92001908, 0xc52170a0, 0xc9fa7f41, 0xbf361c71, -0x33cd7f76, 0x776f9b61, 0x459cdfe1, 0x065dbdb5, -0x67a6f1d1, 0xcbbee73d, 0x2f7b516c, 0x1fda5e43, -0xeba7d6ab, 0x337c3557, 0x1f2477f5, 0xeec7d493, -0x749fa13a, 0x3c37e01d, 0xa78babcf, 0x9ee438d4, -0xaa57066a, 0x9efe96c5, 0x8d45bd8b, 0xbc36930b, -0xfbf60974, 0xdbb7844b, 0x44001279, 0x14e036b9, -0xb524f4a6, 0xad1cee3d, 0x351aca37, 0x22861da8, -0x0648f10b, 0x394078f1, 0x4287ef8c, 0x5c52b8a2, -0xaa345739, 0x959a7de2, 0xb1cd8059, 0x29b3e4f9, -0x3ee210dd, 0x7a4e3104, 0x7e6ccae0, 0xb6d003d5, -0xfda934b3, 0x0e0a48d0, 0xd4109873, 0x2812c616, -0x635c5c94, 0xe3f9d4ac, 0xf0a6aaca, 0x7541e3f6, -0x3fc3b0c4, 0x49fb84e3, 0x710f44de, 0x7557e168, -0xa524128c, 0xdac666c4, 0x0231bd62, 0x0f8d71da, -0xefc53932, 0xff6f8f71, 0xe28502da, 0x033e463d, -0xcd4e9499, 0x32702fe4, 0x51e3dedc, 0x9923eb00, -0x0d4391d5, 0x55abc4a1, 0xc487b606, 0x67a99b08, -0xf8f3b29a, 0xe21b51bc, 0x3cf54c4c, 0x5ce361fd, -0xa1bbcd20, 0x842530fd, 0xb916ed90, 0x6c0fc501, -0x0306ef82, 0x01f9412c, 0x1f418a83, 0xe1a87a00, -0xe3170dad, 0xee8e482f, 0x9a3c5c02, 0xb3be7f4b, -0x98a8e507, 0x8e567e9d, 0x878294a2, 0x0257b6d8, -0x478dd212, 0xad7f31c2, 0x0ddf5f18, 0x870a41d2, -0xb80eebad, 0x65d01cfd, 0x2420af2d, 0x03d4928d, -0x7ecdd5a2, 0xaed78097, 0x489bbdf8, 0xac3b4047, -0xf86fd0ed, 0xb6e1d459, 0x25cb9f89, 0xa930c756, -0x3fb6730b, 0x6dfd3141, 0x7040efde, 0x5e7b20c1, -0x7e0bf614, 0xff9f51c0, 0x0bc3d4c0, 0xa9646223, -0xf5d6bf0d, 0xa39adc0c, 0xbad2e29f, 0x1fb82009, -0x8a67db42, 0x33371921, 0x8fd37f99, 0x1d8bec6b, -0x3318d993, 0x1d1fc4cc, 0x809090c5, 0xcba8a502, -0x3fe6234f, 0xa0c82c20, 0xcebbdb15, 0xd63aa273, -0xa2697101, 0x0307172d, 0xc9ab9add, 0x10810732, -0xf9572b9e, 0x0446f0f0, 0x201f00ce, 0x58b49de0, -0xad59fb0a, 0xf68fa3d7, 0xf16e483c, 0x2c8712ae, -0x8d813fa1, 0x7cfd639f, 0x177ccd17, 0x20d1b4de, -0xcd0d849a, 0x172391be, 0x46960345, 0xeacd959a, -0x6b5bb948, 0xc918da1d, 0x10e663e9, 0xdeb1947b, -0x97a1daaf, 0xec2aeac7, 0x977a8130, 0xba638e7e, -0xe6013c46, 0x8139db8b, 0x8a99f837, 0xb764477a, -0xc5e25c77, 0xee619c4c, 0xf62b722b, 0x4c668ea5, -0xc844b875, 0xed00e58e, 0x374de0c6, 0x976c7b53, -0xa0f4b261, 0x57fede6a, 0x9c496394, 0x5d6bf467, -0x49c55f0b, 0x7fcaa93d, 0x80af6060, 0x2c06d418, -0x05b6c9f4, 0x530b1c98, 0xf399a24f, 0x5d696799, -0xb4f01406, 0x950b7725, 0x161cc738, 0xbb2cb047, -0xb00e5899, 0xef80ad2e, 0x258efb9f, 0xcea45c0f, -0x2b92718c, 0x43b2b1f2, 0x859df60a, 0xf2d38ec7, -0x8a21f675, 0x8736fc22, 0xe54f56a2, 0x399bf38f, -0x2f0ab0e9, 0x867d5f7c, 0xfb1d5d33, 0xfc37f1bf, -0x54d69e7a, 0xf7857201, 0x38a74088, 0xe9b7f4c7, -0x1499d362, 0x107b8406, 0x9d232cca, 0x258c896f, -0x492dbe35, 0xa501bc07, 0x9163e950, 0xc8bc7f87, -0xad441a50, 0x05951263, 0x90e3eecb, 0x53902d55, -0xed85a316, 0x601f2763, 0x11406d6d, 0x8a6595bb, -0x7742c2e9, 0xc0110a3f, 0x9e302c92, 0x3bad12f5, -0x92621943, 0x15d9ffa7, 0xbf4c7e98, 0xe4329cd4, -0x2dd15e35, 0x14f41072, 0xeb93b35f, 0xa46fda4b, -0xb397dd25, 0xff473a19, 0x4e671ddd, 0xeab28b65, -0x248ee99b, 0xda0fd07e, 0x90622959, 0xaa1b00fc, -0xf66ab278, 0x468a4536, 0x9e8b7fd4, 0x2248ca01, -0x14849148, 0x8b112b0e, 0x9fbe1840, 0xd9329b20, -0x3411070d, 0x18303ffc, 0x6227a516, 0x482105b6, -0xada6610c, 0x4974a4e4, 0x37edb9b2, 0x60cdcd07, -0xb385a684, 0xe40e9d41, 0xd213f44d, 0x1e6f0465, -0x3d9341ba, 0xe6b1ca3f, 0xd90134d2, 0x30a84f64, -0x985f3aa1, 0x8f8960cd, 0x4bbb5ac7, 0x813e6e6c, -0xf9da3cc0, 0x376b463f, 0xbe42b933, 0x601f62a2, -0x3f912588, 0xc3d98614, 0x4a86672b, 0xf83e9f6e, -0x8bc8b9f3, 0x656a02e4, 0x9ed5cf15, 0x71db2aa9, -0xdee9e1ae, 0x31bce974, 0xd90df1ff, 0x2407f850, -0x7dad6b36, 0x04b02538, 0xf3ab51da, 0xadb88427, -0xa8fd87c2, 0x44e3913d, 0x53db94bb, 0x7b9c97d6, -0x1c139a60, 0x446e3d77, 0x7718ed0b, 0xf21d7332, -0xb7acf39c, 0x80a90b35, 0xd6d5b48a, 0x63a41462, -0x00234218, 0x90744431, 0xcd22c178, 0x270c0b5c, -0xafbfd299, 0x69a4382c, 0xa910cd4a, 0xe33fb607, -0xc6466ac3, 0x800bd126, 0xddf65ba6, 0x9363268e, -/* 3104-M08106CA107.inc */ -0x00000001, 0x00000107, 0x08252009, 0x000106ca, -0xbe667ca5, 0x00000001, 0x00000008, 0x000013d0, -0x00001400, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000107, -0x00000010, 0x000500b0, 0x20090820, 0x00000401, -0x00000001, 0x000106ca, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x2beaa92c, 0xfc3395b7, 0x10be81a0, 0xb318e067, -0x723923f0, 0xb297dc63, 0x7d52bc4b, 0xc6ef362f, -0x0882023d, 0x953684cb, 0x0abe06ee, 0xa7ef1798, -0x160d6cb8, 0x930cf745, 0xafc3fd79, 0xa70df3d5, -0xb0620f46, 0x70048a23, 0xbf95ecf0, 0x76c1b997, -0x5128616d, 0xb6b4b969, 0xcc69f71d, 0xdf7416e1, -0xdf9a571b, 0x50c0bcc8, 0x85e2b3cd, 0xc1927532, -0x7a04b6be, 0xe56b7f97, 0x524085c4, 0x668bf327, -0xb3eaa54c, 0xccde06f8, 0x09b4e42b, 0x033b0a46, -0x0f6e2fde, 0xb308ce53, 0x93eff03e, 0x8830014e, -0x5c8a6f22, 0x91d2f757, 0xf70b648d, 0x0789998a, -0xd84d4640, 0xe5f34e80, 0xf3357e64, 0xd1e2beea, -0xc7e95c3a, 0x30e57e4d, 0xec214356, 0x7e10859e, -0x1d5895d5, 0xdeeff6cb, 0xed1030ed, 0x827e603d, -0x6b4b2de3, 0x83ec6fd0, 0xa64092f3, 0x8d9887e4, -0xbefcbedd, 0x2111afef, 0xcb9abf96, 0x5c79ceac, -0x9bf8a57f, 0x5d0e44be, 0xdca3d3b6, 0x9072d1ca, -0x48e73a50, 0x8d0bc804, 0x6aea94d3, 0xc372403e, -0x00000011, 0x3b994153, 0x23faa5e1, 0xc3feae68, -0x76d5e67d, 0xbd696479, 0x138a05ef, 0xf2b5de22, -0x4ccba0ed, 0x333cc95c, 0x8d98a2ae, 0x0bf1fa24, -0x239f1fbf, 0x44701d3b, 0xb176783f, 0x20eff2cc, -0x0cf93bf9, 0x4e6ace41, 0xe346d231, 0x11d560af, -0xae8874a2, 0xe344fa92, 0x0056d268, 0xd8068d91, -0xf336cf97, 0x45c54f6d, 0xc0650992, 0xa3f86cb2, -0xc73d3aac, 0xc7654f1f, 0x385777ad, 0x20928850, -0x47509cab, 0xf40f9ba6, 0x34efbe6c, 0x1fe3b873, -0xfb39bd58, 0xa50b6367, 0x66c20e63, 0x49a4e1ee, -0xe490ed5a, 0x98c340fa, 0x30bfe19d, 0x4c17d142, -0xea54c4e2, 0x8c00e086, 0x219dee1b, 0x739a2fc1, -0x1e07b80f, 0xea6f4799, 0xb4684fc2, 0x42fc725a, -0x1d3c7413, 0x188b6f3c, 0x2c0e440f, 0xc6ad011d, -0x2048625b, 0x3be9d940, 0x0a932622, 0x1fafce30, -0x1cfa4c90, 0xd0e9f989, 0x31c0c399, 0xad0c597d, -0x48a94bb5, 0x109da683, 0xcdc197aa, 0x7bf7ef14, -0xebf3afa0, 0xde4ff7d3, 0x02a79e3f, 0x4d77f0e5, -0xd0c1fd98, 0xdb342a5b, 0x7f753eca, 0xb710c135, -0xacb3b9c0, 0x5e89ece7, 0x2ca4fe84, 0x4f22e461, -0xa6a633fb, 0x508fb453, 0xfe1f342d, 0x79bcff1f, -0x0c776771, 0xd6c5db47, 0xfe4d8cc5, 0x68b9f655, -0x447b7366, 0xddde31ad, 0x8e3496df, 0xe091f8dd, -0x78eb0fe2, 0x9e08c72d, 0x6909c46b, 0x92ca6b4a, -0xfb7a0efb, 0x55f65148, 0x9fcc90e1, 0x254f5f40, -0x0690dcd5, 0xc6a67013, 0xda2e35a9, 0x9171cb50, -0xe477a087, 0xc0f89e14, 0xc1221ebf, 0xf032e99f, -0xc8883a7e, 0xba4b17c9, 0xb0ef0962, 0x6ea751f6, -0xfc8c336c, 0xd1966bf1, 0x26d57e1d, 0x952e847d, -0xccdaf0c9, 0xd0aaee65, 0xb2f22a59, 0xc74bc035, -0x900ef42a, 0xeb1e7bfe, 0xfc465b3a, 0x0cd002ce, -0x560f5d4b, 0xecbc2658, 0x9f38856a, 0xa3f77ba1, -0x3ee18273, 0x7ab97b2c, 0x0f5843cc, 0xdb648b0a, -0x8e450381, 0x80176891, 0x05e3e6d2, 0x36593afe, -0xebe78fce, 0x53d7f64c, 0x2dde1104, 0x293cd7e2, -0x4f430fa6, 0xf3a8cdb0, 0xd28f6535, 0x9159d53b, -0xac66a916, 0x8f77be38, 0xa16b9dad, 0x1a4699d0, -0xe278df12, 0x2c336789, 0xb668fe15, 0x099fa98c, -0x4fe5ef10, 0xf4692cda, 0xb86d4040, 0xb6dce0eb, -0x6c5ef896, 0xdef35c52, 0xc02a04a4, 0xed99c619, -0xd91721b2, 0xa2fac92a, 0x5ab9c724, 0x0ee25329, -0xc2029fce, 0xc847bfbd, 0x3b97ddcb, 0x4aaaa55a, -0xa16e313a, 0x06e4b6cc, 0xc0e56598, 0x60ebfadb, -0x88841f3a, 0x7c6b65ef, 0x15542ce1, 0x70b88b78, -0x382d1155, 0xe73c900c, 0xd8b6409e, 0xf1cc5406, -0x64fc3223, 0x43cb616c, 0x17e3a1ac, 0xa9aba529, -0x8dd83b32, 0xb625cd1d, 0xbcb4b0ed, 0x685cc4b2, -0x803e35f8, 0x4e679481, 0xc7dd7591, 0xf8676b62, -0xac25b6c8, 0xb0211931, 0x5c5df337, 0x3bde6fb6, -0xbc433992, 0xf7315d49, 0x028e112f, 0xe3d59076, -0x7757e95b, 0xe5c5a193, 0x59b243a0, 0x341f33d2, -0x7c0d591d, 0x5f96d138, 0x5116c490, 0x747caf2f, -0x6da223f1, 0xcbe30d11, 0xe10b6b28, 0xa09328e1, -0xdf1b94ee, 0x163b48b9, 0x72e7a36a, 0x78eda572, -0x393f0ad2, 0xf85561ea, 0x6e7ca7c8, 0x352cb3b4, -0xb75bf9f3, 0x97ebcf76, 0x932b8b91, 0x937f1fab, -0x6ef1e868, 0xce84fc3a, 0x9dd09a21, 0xa8f3be36, -0x244834e9, 0xd871f223, 0xdef842f3, 0x787eaf73, -0xf2326bca, 0xd2c3ae20, 0x48dc7621, 0x91419afe, -0x23a44b12, 0xce0443d7, 0x4a6f1d9f, 0x1ea8cf7a, -0xb6b7694d, 0xf29e3e25, 0x51665303, 0x33581b86, -0xc762d72f, 0xaa658158, 0xcddb7354, 0xdacfd75f, -0x9ec31b1c, 0xf8aa3154, 0xfdeeb2e0, 0x9cb52f84, -0x16ce9fa4, 0x25050178, 0x2ef25d50, 0xcf4b4d41, -0xf27d5684, 0x7bae3f36, 0x05b50e59, 0x91d23add, -0xdbdee4ac, 0xe16994b5, 0x0a5481c3, 0x3deb8a17, -0xb8844d77, 0xcbce6140, 0xbd748572, 0x6531627f, -0x2137be68, 0xf46f8aa9, 0x6d2526a0, 0xe72aa307, -0xb361a2c8, 0xed9c2987, 0x75ddeb95, 0x637d3cad, -0x2c4dfd37, 0x01f0e2bd, 0xa521a1a4, 0x1194ab8a, -0x96d7b9c2, 0x94cee6e5, 0x454cc836, 0xa5c0fac3, -0xf6e9fe9b, 0x3107c251, 0x14c8c6a6, 0xd727c1e1, -0x339f2742, 0xb0a033de, 0x56fc9280, 0x36a907cd, -0xb74acdde, 0xe8122571, 0xd0116007, 0x238b3d4f, -0x34532ebe, 0x1c534370, 0xd1eb258d, 0x354b2289, -0x6007a18c, 0x58dcee7f, 0xa033ee94, 0xa5e1145f, -0xe345c315, 0x58510592, 0x33d9db2b, 0x7ea86edf, -0xce60a8ad, 0x2d9a8919, 0xb5e2840e, 0x020e6e15, -0xaff8660e, 0x402c12da, 0xfaea95a5, 0x6ffb0748, -0xc4c730a4, 0x1f57ead7, 0x2cc6d295, 0x0ef4bdb6, -0x01a7368a, 0x52e88f43, 0xf1b14c65, 0x38018686, -0x0c70ee45, 0x271b1fe2, 0x0eea950e, 0x61a6f56a, -0x842497a5, 0xfbcf0f4a, 0x35132cbb, 0x4f2eb1ce, -0x24fb1bc7, 0x343ec960, 0xda94e0a2, 0xf1206e0b, -0x80bf8007, 0x7e09d8d8, 0xba6bc1ff, 0x892c956c, -0x4ceaa5e8, 0x871f3358, 0xe802a1a4, 0x7fa29ced, -0xea8616cb, 0xc1999088, 0xc5baf089, 0xd1490754, -0x091f6f21, 0x9a3e3c4f, 0x1eb11650, 0x13fd05fc, -0x5e9d5b0e, 0xd1485d34, 0x474feaae, 0xc211a60f, -0xa609643e, 0x07052bb2, 0xa7bfb285, 0x30bbc170, -0x9ebe8d27, 0x5207a9ee, 0xfc12bd0e, 0x7fa428af, -0x2d1c8a2d, 0x6f15c0d6, 0xdaf0ee75, 0xd32bb1d1, -0x694463f5, 0xa1ebdae4, 0xeaa3d0b2, 0x954077de, -0x181da0bb, 0x4556808d, 0x46e80a64, 0x0c017172, -0xd8ef8702, 0xa0e6d100, 0x90b0a9f0, 0x4a13a407, -0xf1675dde, 0x5110d8c8, 0x1c028526, 0x7774581f, -0x9d3d8c23, 0xcaf8b632, 0xf401a52f, 0xa5d14a5c, -0xebed6c1b, 0x2ec618ad, 0x5b63935e, 0x89508732, -0x43a48b2e, 0x87535b2b, 0x0ffb28c2, 0x1fd1becd, -0xd2b2a18d, 0x45dccb4c, 0xad41a54b, 0x7ffa2fed, -0xddd18aa1, 0x1db06a98, 0x860d6b58, 0x2997109e, -0x80a2300e, 0x0cc52e7a, 0x15b24c31, 0x8f717016, -0xa425cac3, 0x8153e1bf, 0x5e91fd89, 0x04b17f35, -0x150fd30c, 0xc7309d31, 0x63dce1b0, 0x162eb854, -0x8093904e, 0xf7b4399d, 0xb23fa735, 0x67509c6c, -0x5380dec9, 0xb79172a8, 0xb6c249d1, 0xcd040b42, -0x4efe12f8, 0x63ce3363, 0x406d1666, 0xf8e9bc95, -0x99cbff2c, 0xaf0cac38, 0xe6556ddf, 0x9bb2a399, -0x43387c9e, 0x4951f5ac, 0xfa4ddb69, 0x562ec852, -0xa2e3e441, 0x32a80b75, 0xd88361c5, 0xf04b7ac9, -0xb0ea18bb, 0xf5035c94, 0x520c9c12, 0xb4c7e15c, -0x6f72c4bc, 0x80f2112a, 0x4e4bbb87, 0x7bb5ee1f, -0x54eb313e, 0x18cb6cb9, 0xca5ff580, 0x2538d798, -0x2b813681, 0x58c11a6c, 0x68ae4070, 0x40799341, -0xa740f86a, 0x722ca7ef, 0x815c71c7, 0xe663c6f7, -0x5e249b96, 0xe97e3b71, 0xb7ee5a12, 0xd5f065bd, -0xaa642191, 0x9864e095, 0x0c087780, 0x0fc0d969, -0xf6b82791, 0x04aa55f8, 0x872c7cd1, 0x43bc93b0, -0x12fe4c05, 0x16f15229, 0x06161603, 0x6e76239d, -0x90ea9c62, 0xecf642df, 0xb52a8db6, 0x2e0c5d58, -0x10f09bbc, 0x1bb1b2a3, 0x7132167b, 0x291d5f16, -0xd7814a9e, 0x79e52dbf, 0xef6b61e8, 0x585b920a, -0x18ea4e61, 0x72ce62fc, 0x59ed8e9f, 0x610564d3, -0x40f4f145, 0x0a2f60c1, 0xec64ebc3, 0x8ad5b251, -0xb471e120, 0xb899cffd, 0x2b81118a, 0xa3b591a8, -0xdeced3ab, 0xcb9aacb8, 0xba53fbdd, 0x6e49e298, -0x75fa6c19, 0xd11cfe98, 0xd29ce7fc, 0x7471df09, -0xb59b2474, 0xdff0b07d, 0xae92c4b7, 0x6414ee6b, -0x6acba1a5, 0xed9c0b5b, 0x728f7644, 0xf6d20c7a, -0xf03ad03e, 0x6612b0c3, 0xe156c417, 0x9aec4a8d, -0x02be86ff, 0xe11d1660, 0xefeba14a, 0x7d275f33, -0x16acabb2, 0x7ac99cd7, 0xd18566e4, 0x3bce4ca1, -0xb0312f16, 0x5700f72c, 0x345864bd, 0x917a4db2, -0xaa22b7f0, 0xc66eb69c, 0x62f8a99e, 0x6364a44f, -0x956d2cd2, 0xfa64b7df, 0x47238b18, 0xddebaeff, -0x39c9d16b, 0xaa1487cb, 0xc6f91d13, 0x8191316d, -0xbf5d7ddd, 0xc907cbb1, 0x7a283ba3, 0x0365e6a3, -0x2fbb3185, 0x159d0436, 0xb55b6990, 0xf0935005, -0x441e4fc8, 0xd1dfdc91, 0xdd9ff8bc, 0x95c88203, -0xa8029310, 0x62501ff4, 0xf838a813, 0xfb66d5ce, -0xe6bb8354, 0xe2afb832, 0x55dcf796, 0x315f28cf, -0x400de577, 0x3ad89b1b, 0xeee943aa, 0xbd5d9001, -0x8dd4771b, 0x21ad481c, 0x504d6222, 0xfc0e6728, -0x7abe5d62, 0x332f8309, 0x50d8c688, 0x4b686808, -0xbe6395ec, 0x5153b67c, 0x04144a35, 0xa85077ca, -0xa3775cda, 0x838556dc, 0x973c2222, 0xf5037c9f, -0xd02b0c87, 0xa3e69f8f, 0xdf68cce7, 0x9490d31f, -0x3d9c5cf2, 0x939e7823, 0xc51b9a2d, 0x2e802e27, -0x65079a36, 0x3b6e3d79, 0x5fafbac6, 0x9973bc64, -0xfc4e7124, 0x56e1fad3, 0x10ec049f, 0xefa79c0b, -0xcde48353, 0x3fa7f449, 0x07cb1a31, 0xf6ba0053, -0xe5af7b10, 0x9e2dc089, 0x290f3fa4, 0x116da472, -0x7a006f5b, 0x727205bf, 0x7c59870d, 0x968c6000, -0x3ed4fd57, 0xe423effe, 0xc352ef7a, 0xd23d00e5, -0xbded3a50, 0xedcdc3d0, 0x3a517a74, 0xbdfc58cc, -0x24b2371f, 0xf967f533, 0x26069547, 0x2114e85e, -0xa1953f56, 0xf0c52ebf, 0x235320ae, 0x35600f33, -0x5c1ca2b7, 0xe89db0da, 0x08ce35aa, 0xc66cef79, -0xacd41ce4, 0x865f4c69, 0x15a3376b, 0xdee5d7a1, -0x6fdd6362, 0xa4125977, 0xcb61bae2, 0x5e3da819, -0xc6d2e56a, 0xde1807f2, 0xb30c3473, 0x1c4038c5, -0xbf8afac6, 0x37423d2d, 0x72d9da33, 0x39e95bf5, -0xd6a91cc8, 0xbbf4c2d8, 0x7c9d4b21, 0x13c514d5, -0xcae41aac, 0x07b97f18, 0x0cdfbdee, 0xe7a9020b, -0x1839f082, 0x7c414530, 0x43ba1070, 0x95945971, -0x82e31721, 0x2fb159e5, 0x225c2158, 0xfadf74f6, -0x788387d6, 0xb40c98fe, 0x0c75ba9d, 0x0487eb2f, -0x7e9a1b0e, 0x5c442185, 0xcf1dffde, 0x39f9bc44, -0x46b961d3, 0x9a14b19a, 0xe284d2ac, 0x52151caa, -0x67f34f5e, 0xf4042d4f, 0xa28a223d, 0x3deb23f1, -0x12d14b6f, 0x18901f31, 0xb3c7950a, 0xfb7d3557, -0xb83e457f, 0xb6e13f07, 0xd26f5435, 0x83f05e15, -0xf549a030, 0x6d1122d0, 0x540b3ef9, 0x8ecdac22, -0xdabe1b2d, 0xf4913cc0, 0x579f9d77, 0xd4725d33, -0x76b7abb0, 0x03452691, 0x4d52fff6, 0x12e95a96, -0x42131074, 0xbb3eaa95, 0xb775618e, 0x6325764e, -0xeb847c5a, 0xeb7b9c6d, 0xd01dd328, 0x547269e1, -0x2cebecd3, 0xcbb0ed0f, 0xcc87e62c, 0x8e6b0ce0, -0x8a8f9f06, 0x689e0c4f, 0xb3a1fe5a, 0xed84a0a2, -0x66187741, 0x62a4475b, 0x5c4c31bb, 0xea000d76, -0x8676c757, 0xd59cc6bd, 0x52f107ff, 0x1f4a0c66, -0x7af566ef, 0x4af3586c, 0x11d5cd6f, 0x6b8bc81a, -0x480eed48, 0x2ec7c65e, 0x6c0f3253, 0x100f2794, -0x18d6c62a, 0x338f59f6, 0x8e6e2f9e, 0x75fccfd7, -0xbc80ea7a, 0xa90f1473, 0xfa9d22c4, 0x3ccdaa53, -0xe568fef6, 0x6a761fd4, 0x61c26b23, 0xabc31163, -0x3b840e9e, 0xee864319, 0x84f93208, 0x743a780e, -0x1507a3bf, 0x147dad13, 0x8952177f, 0xbeb40da7, -0x699af39e, 0x6d22bdfb, 0x5fe8112c, 0xdb3f8dbb, -0x026f8ff2, 0x6bf9658d, 0x9faabf0d, 0x6a2f3989, -0x5be4a617, 0x9e55f0c3, 0x70510d75, 0x0fd92413, -0x63d1d3c7, 0x68cf84bd, 0xbbff5901, 0xb0434b77, -0x8564b88f, 0x06eddac5, 0xde2a66b6, 0xc1835355, -0x5566bb1e, 0xbaa890cd, 0x108c6f70, 0x7e80dfcc, -0xb8c03bb3, 0x14bdcbe0, 0x5037daf9, 0xee02697a, -0x3326280f, 0x4f04c814, 0x4f640444, 0xbfa9229e, -0x131c7ba0, 0x5fbcf1ba, 0xebe01998, 0x2a813a9b, -0x3f27c028, 0xf77a6d00, 0xac0ddee5, 0x1b6e52d9, -0xdac4bb99, 0x54a32f86, 0x26bfd80f, 0xf5debd9c, -0x06536e13, 0x9498a87e, 0x3f9e8812, 0x53e0fdee, -0xc08c3c8a, 0x2148b33c, 0x3932e37b, 0xad084cc7, -0xe77a0048, 0x89addf10, 0xb2542186, 0xc4c0be6c, -0xfbc626ce, 0x20a28446, 0x0f29f8f1, 0xbbef5d50, -0x288b8070, 0x31aa2900, 0x4a538fbe, 0xcd344ca3, -0x05170c9d, 0x06c51082, 0xc414194a, 0x6689a2cb, -0x7618c884, 0x412ac324, 0xb0d952d0, 0xfb88757c, -0xaacbb987, 0x92218ac5, 0x032a3895, 0x2e3a7dfd, -0x4bb37e4e, 0x52342695, 0xa699f5b9, 0x45748066, -0x7822f59e, 0x68a55092, 0xf049444b, 0xf274d694, -0x0524ed76, 0x884c3732, 0x22fa43bb, 0x3b97d921, -0x210b8c99, 0xc4ffdf26, 0x17ba16ed, 0xfcdfc437, -0x0b8e2d8a, 0x7b019bb2, 0xd525e662, 0x03346249, -0x7af3c1cd, 0xbf42dbac, 0xb6197a31, 0xebff8e32, -0x84f9980c, 0xa225a4b0, 0xa9f3d94d, 0x8a3da052, -0xc17241e7, 0xf133ce7f, 0x4d4542f0, 0xd884f2f8, -0xa1633ebe, 0xd5c5e6e5, 0x7fce2fca, 0x8ad84a55, -0xfdd96c9f, 0xa60d6f4f, 0xe025d2f2, 0x8be1b787, -0x87a036a7, 0x23819cb9, 0x5967650e, 0x5d549108, -0x57167175, 0x2f94c450, 0xbb536b04, 0xfb381d15, -0x405bd359, 0x3ef9491b, 0xa9834cb1, 0x2cc5151c, -0x148cd3cd, 0x0565ecb0, 0x8e596741, 0xf6d7f089, -0x9e3524fe, 0xf4224e20, 0x583302fa, 0xebe46409, -0x7bfe793a, 0x7d511902, 0x1e4a80dd, 0x53a280cb, -0xa2d81d96, 0xe29b8f4e, 0x877789e5, 0x838ee539, -0x35f9feb5, 0xa5bb1d43, 0xb24d7510, 0x67cd14d7, -0x7cfac97e, 0xf6c72b9b, 0x302f9115, 0x1932060c, -0x0a786f90, 0x85a88dd1, 0x322ef274, 0xb0f8af47, -0xbb5e6bfb, 0x3f1505c5, 0x33b28086, 0x18025326, -0x73293fb1, 0xbd813762, 0xad751414, 0xd533bccc, -0x393b81fe, 0x5b3b79e3, 0x2221dc65, 0x4bf8124d, -0x26df557e, 0xcb9320a3, 0x9e6e762f, 0x2a800bbf, -0xbd30558c, 0xc6b2ebe7, 0x204b2c78, 0x3e55767c, -0xe8dca1c3, 0x1b115140, 0x144da104, 0xad17dbe3, -0x47640bdd, 0xef84b8c5, 0xf2edc388, 0xb051b0f2, -0xb67f4713, 0xdcd7d116, 0xb98d5bcb, 0x8b52a03d, -0x58ae1c24, 0x9404bc9d, 0x01a49407, 0x5cab2a00, -0x5e747e7e, 0x9aea8823, 0x71d4bdfe, 0x1663aaf3, -0x8b80d3d2, 0x6675c138, 0x70d05b5b, 0x6bbadfc8, -0xe05fc1ea, 0xcef15db9, 0xcdee6b25, 0x27f55999, -0xa1496ac5, 0xf494d5e1, 0x271d267a, 0x29ca643d, -0x303facb7, 0xaf6f0968, 0x7ae465be, 0x584c068c, -0x0bd8fb4c, 0x132e1f25, 0xa488d69e, 0xe768cb78, -0x476c4498, 0x648a05a0, 0x779cf9df, 0x2b56ea07, -0xfc8b15b4, 0x1b3f922a, 0xcf818f70, 0x0b89290d, -0x88e3d01f, 0x30da72c3, 0x2eaea5d2, 0xdf0e82b7, -0xe6ff40ba, 0x09c53e7e, 0x78b3f112, 0x1d6812d3, -0x13904820, 0xbb5be6a8, 0xe9635ca0, 0xd83241be, -0x3c2382f4, 0x4f03a252, 0xaa83fa23, 0x6350651d, -0x67770010, 0xe7662496, 0x50f87e8d, 0xea4c361c, -0x62cb111d, 0x5a748529, 0x194b6db1, 0xf3328462, -0x02e7215c, 0xe7beb99f, 0xf304e37a, 0xf8167391, -0x32b23d69, 0x3041d4eb, 0x4938991b, 0x52095853, -0xdc929597, 0x79c1797a, 0xfe235349, 0xa927f0f2, -0x76f3c3af, 0x9552017a, 0x3eef55e4, 0xff153c64, -0xdfa3fbb8, 0x7598d7bf, 0xabc4c81d, 0x31ff99df, -0x3cf58e98, 0x9ef252a8, 0xcfdb2371, 0x87f621c3, -0xcec0442c, 0x208c19a5, 0x0c38d69c, 0x6b5b4ffd, -0xf4c411ac, 0xb309b4a5, 0xe72f34c0, 0x02841ec0, -0x33008fec, 0xee5f5c1d, 0x29ef9810, 0xb5eb9790, -0xa7ef545d, 0x45e476de, 0x54a24e04, 0x0990a7a6, -0x3be1ee6e, 0x9ecd6a6e, 0xb8ec728a, 0x6752ab8a, -0xcbc5c9fc, 0xe297793d, 0xf9d64e3a, 0x9970acff, -0xb52196a6, 0xe40d612f, 0xc7691ae6, 0xbd7cb50d, -0x741712a0, 0x4af143f7, 0x6b8140ac, 0x695edb52, -0x779b36d3, 0xff7319c3, 0x24b22cc8, 0x9549e25d, -0xeb61c0f5, 0xbc0285a6, 0x5b34d260, 0x9ead3844, -0xfa05f755, 0x01205a39, 0x7332b47f, 0x618d193a, -0xf577410e, 0xa43a73f0, 0x5ef40779, 0xf6d05937, -0xe6bdcc69, 0x97c7c59e, 0x1abd06e9, 0x1f6100b4, -0x4193fc0f, 0x58158a8f, 0xeb660c8e, 0xc53c6f4a, -0xdb6cb2d4, 0x9d8c88c7, 0x8ff74335, 0x44cc1e67, -0xd0e4d4d5, 0x926224cc, 0x95cbffe6, 0x621764d4, -0xb7b37387, 0xceecbf7c, 0xa60fda9e, 0xe6bbc331, -0x56911995, 0xcd196d6b, 0xf2a18ead, 0xe6b5484f, -0x1fc18a27, 0x58c18e28, 0xdf947a19, 0x9355834f, -0xd6200656, 0xbfc8210b, 0xa5f74216, 0x550140aa, -0x17e2ca8c, 0x2a56ebde, 0xf387b1ea, 0x9d97f5e6, -0x056ef46f, 0x90909eeb, 0x7a7f5867, 0x86974716, -0xde02612f, 0x389718e6, 0xfba5b72e, 0xd74f780d, -0x370152e3, 0x84bec429, 0x944c0604, 0x80d2e23d, -0x661eca8e, 0x1f45bdb2, 0x00e19b5a, 0xf666af38, -0xd1d383c3, 0x3def0d6f, 0x1444fa5b, 0x0aa11ee2, -0x1eb25d6c, 0xcd51ae3a, 0xdb0c559c, 0x22818716, -0x9ba1ba6f, 0xd0c97b0c, 0xc14f04c5, 0xa1240202, -0xe2110419, 0x293f4dd9, 0x98c2fa3f, 0x67ec66e4, -0x5a9af6c5, 0x4254b385, 0x8c2bb55c, 0x2834b05d, -0x39bac0a4, 0xda998f86, 0xe4797beb, 0x0cec5a2d, -0x938b3950, 0x38d4e088, 0x0305d5b8, 0xf3b28762, -0x589f97e9, 0xa5898e96, 0x1bcd52e7, 0x0652e8f3, -0x69800c5b, 0xed46c25e, 0x09b395a4, 0x06a963a6, -0x71597fad, 0x0570bbd2, 0x0dfd6639, 0x086b5b5d, -0xe3d87df1, 0xaa6e75c9, 0x6bb447c1, 0xa54550ab, -0x4d59eb97, 0xf3a29b0f, 0x969e92cc, 0xf14624b3, -/* 3163-M0120661104.inc */ -0x00000001, 0x00000104, 0x10232009, 0x00020661, -0x38cb12b9, 0x00000001, 0x00000001, 0x000013d0, -0x00001400, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000104, -0x00000017, 0x000500e0, 0x20091019, 0x00000401, -0x00000001, 0x00020661, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x09eccda1, 0x1adbcb9c, 0xc2c1c2d3, 0x052a20d7, -0x37c6c23b, 0xc9a271c8, 0x169f18e1, 0x8ca95050, -0x0882023d, 0x953684cb, 0x0abe06ee, 0xa7ef1798, -0x160d6cb8, 0x930cf745, 0xafc3fd79, 0xa70df3d5, -0xb0620f46, 0x70048a23, 0xbf95ecf0, 0x76c1b997, -0x5128616d, 0xb6b4b969, 0xcc69f71d, 0xdf7416e1, -0xdf9a571b, 0x50c0bcc8, 0x85e2b3cd, 0xc1927532, -0x7a04b6be, 0xe56b7f97, 0x524085c4, 0x668bf327, -0xb3eaa54c, 0xccde06f8, 0x09b4e42b, 0x033b0a46, -0x0f6e2fde, 0xb308ce53, 0x93eff03e, 0x8830014e, -0x5c8a6f22, 0x91d2f757, 0xf70b648d, 0x0789998a, -0xd84d4640, 0xe5f34e80, 0xf3357e64, 0xd1e2beea, -0xc7e95c3a, 0x30e57e4d, 0xec214356, 0x7e10859e, -0x1d5895d5, 0xdeeff6cb, 0xed1030ed, 0x827e603d, -0x6b4b2de3, 0x83ec6fd0, 0xa64092f3, 0x8d9887e4, -0xbefcbedd, 0x2111afef, 0xcb9abf96, 0x5c79ceac, -0x9bf8a57f, 0x5d0e44be, 0xdca3d3b6, 0x9072d1ca, -0x48e73a50, 0x8d0bc804, 0x6aea94d3, 0xc372403e, -0x00000011, 0x7d61ca09, 0x31f73022, 0x072dcedd, -0x935818f7, 0x9edef5c3, 0xa37a44c7, 0x6753a39f, -0x07a3f8a3, 0x29e66ce6, 0x32b334e4, 0xfee3e6dc, -0x97902bbc, 0xb99aba25, 0x9d54e519, 0x69254f0a, -0xb9b7621a, 0x71f115bc, 0x7ebc2520, 0x71c9ffe8, -0x078bcbcb, 0x37042cf2, 0x3d7c3d89, 0x386b656d, -0xb3e39f6a, 0xbd27c008, 0x1d24a30d, 0xbab73f64, -0xa8757048, 0xda99d30b, 0x970d7a4d, 0xd0825dc8, -0xf95bcfe8, 0x1211aa07, 0xd038be1c, 0xc38ba912, -0x2f654a0f, 0x7bdfd541, 0x7af6c93a, 0xb1e3bc1b, -0x6a43b3cd, 0x37797707, 0x29188706, 0xcb2edfcc, -0xc90e2d35, 0x5b05961f, 0x47bbce1f, 0x369a81d6, -0xf5dded77, 0xde27bfbd, 0x2c22af3f, 0x3a1a5290, -0x3989782d, 0xff4f723e, 0x431542e5, 0x90686229, -0x8bb3357f, 0xd317ab6d, 0x3f552399, 0x0166b0ca, -0x98d987b3, 0x071de61b, 0x97b06d99, 0x68aaec88, -0x22047fe5, 0x82077c14, 0xda7e9c45, 0xfcc09973, -0x3dd45fe1, 0xc6723244, 0x02a3c93a, 0x7336c7d5, -0x252aa0d9, 0x6ea83874, 0xf74357d0, 0x21232a94, -0x1ea7ba93, 0x19fa2088, 0x7988f064, 0xa7088cd9, -0x06f9fbb2, 0xe22e9503, 0x441aa57c, 0xb10ff11f, -0x37a36a23, 0x2e4274c8, 0x2018eb1f, 0x4f405084, -0xb178f9f8, 0xf0380878, 0x3334a5e5, 0xa282e950, -0x3a98e7ef, 0xbdb4a8d7, 0xe7ba9dd3, 0xf7672495, -0xa5c21278, 0xc09769c7, 0xc151c549, 0x78059e80, -0xe1ec9e1d, 0xeb729cbb, 0x32cddfbd, 0x04e949a7, -0x5c944ca9, 0x385230c7, 0x7113a400, 0x99ea1700, -0x5c1329aa, 0xe4dea11e, 0x302cf77d, 0x173e69f1, -0x3668f586, 0x0e1324eb, 0x59bb59ff, 0xe23374f3, -0xd4d8414c, 0xd8e8b1af, 0x52005b2a, 0xe3d569ca, -0x93b32b87, 0xdd5aa02b, 0xf8aa2a3e, 0x726446dc, -0x981d0b99, 0x61fa5fd8, 0x4914b799, 0x1e548f8c, -0x61ead44a, 0xfca5a62b, 0x04213c77, 0xef7dc06d, -0xb4ec8c96, 0x4db099f1, 0x8faf5452, 0xa01937e5, -0xa250560e, 0xd36e04db, 0x873e9fe5, 0x7c3a83e6, -0x68cc3ed3, 0x008ebf08, 0xcbaadca4, 0x4bd65401, -0xa9e3c4aa, 0xb3d364b2, 0xd3059746, 0x024984fa, -0xcdea0600, 0x9e0a05dd, 0x5c9010a2, 0x419de94d, -0xd552d4b4, 0xd639999c, 0xe21a5411, 0x67225aeb, -0x3969f21f, 0x71b18631, 0xa9238cca, 0x43eb89be, -0x1df93119, 0x63f976f7, 0x095d59de, 0xb8717d14, -0x815fc874, 0x7e076b5f, 0xb5f00ae5, 0x6458d539, -0x6dc88ada, 0x8c1cd801, 0xd0150eb3, 0x34a00d18, -0xf542d1eb, 0x49bf0834, 0x12263a0c, 0x5150edb3, -0x407b4219, 0xd3a0e4b2, 0x8f2c53fb, 0x8f0bbd94, -0x2e6e1f3d, 0x9e04971a, 0x4f1c1e24, 0xad597a91, -0x4f97bc6c, 0x10e7abd8, 0xb1fda778, 0xb43e636c, -0xd4a097c6, 0x6e89fbc4, 0xe7b14774, 0x439d06fb, -0x00aa6517, 0xaae49fce, 0x911315dc, 0x07276afc, -0x280c56bf, 0x1359f177, 0x6ad2db10, 0xe8b68788, -0x734d6b53, 0x9579a46d, 0x8f84df58, 0x6eb3e6a1, -0x4fc3a5be, 0xf3b02c20, 0x1131dfc9, 0x04e4cc97, -0x2d1fead8, 0x06a332db, 0xf2dbb652, 0x80fee0fc, -0xd85f7a23, 0x428ccb0f, 0x15cbabe8, 0x19518941, -0x74dd3421, 0x953306c9, 0xb484130e, 0xbd586100, -0xb054fe86, 0x1924de13, 0x13eb8bdf, 0x82515d58, -0x96aa7c85, 0x29f69abb, 0x51d9af18, 0xa888d214, -0x3060657a, 0x5f71b582, 0x4f708181, 0xc5644402, -0xb58e041c, 0xb0f94784, 0xfe2b7cbb, 0x45af15ed, -0x2ecf84c0, 0x987ee925, 0xc7228d62, 0x90333ca6, -0x021642cd, 0x1e2dfad3, 0xb5639c98, 0x5b908ef7, -0xec64b383, 0xf7ce0d9e, 0xdd606d70, 0xe7912bf9, -0x53b0f840, 0xd0a86e86, 0x007d7e38, 0x80d4f5ea, -0xf29bc3dc, 0x575e3860, 0x8ba76d1d, 0x76cc7650, -0x049da6a8, 0xfd416631, 0xf9da20db, 0x098fb993, -0x426cf8e8, 0xb3ccbf56, 0xba9fdb7a, 0xe354957c, -0x48e4789c, 0xaef62572, 0x2f5cf1fb, 0xe7a6d946, -0x7b849a95, 0x732b6c1f, 0xe3abd991, 0x9eb235a2, -0x8ebe442c, 0x5e129d04, 0x5bb55f96, 0x3766a553, -0x0edf853e, 0xb9226767, 0x60ff14b2, 0x0ee0d1b6, -0x5e9a9aee, 0xc8ef744a, 0xde27e5a0, 0x352377fd, -0x493f12b4, 0x0d5a34c0, 0xaa64972a, 0xb4bc4c3c, -0x964012cf, 0x3d5baaaa, 0x1df4ab07, 0xc03c8ce2, -0xaf618dee, 0xc84f58a1, 0xdc57eb15, 0x045ad08c, -0x5570f4e0, 0x08ddd264, 0xbb5820fc, 0x7106fa23, -0xf1510c32, 0x5d064af0, 0xb1b2809f, 0x8ebcbe08, -0x69ac1fcf, 0x5e9a9d56, 0x0f42ceea, 0x58ffe164, -0xb0d6d0c8, 0xc64255f2, 0xb281380f, 0xa3d49ec0, -0x9f19ebfe, 0xf826410a, 0x14729256, 0xcdbe6238, -0xba8ef29c, 0xdae66aad, 0xaf025ac7, 0x906f6486, -0x9211983e, 0x9c4c218d, 0xce336e9e, 0x7a8e0236, -0x30449839, 0x0099b8df, 0x2d66cea0, 0x7eb12083, -0x8b1bf8e9, 0xf2a1804f, 0xee28de85, 0x03f739e3, -0x1d0cdde6, 0xa9fdda74, 0x93166d7f, 0xe26c02d5, -0x7dfaa665, 0x0120ed11, 0xc1264694, 0x16963113, -0xef497ce5, 0xf6e22268, 0xdbf63b1d, 0xd61d95aa, -0x03d1a2c1, 0x9158daac, 0x4a47782a, 0x3ff5df3b, -0xe3c31825, 0x74992ec4, 0x11423b65, 0xaf976543, -0x59d3e1fe, 0x26c961f3, 0xe803c69f, 0xcf35f089, -0x01e0e058, 0xf04939a7, 0xb1540a05, 0xaa2e4101, -0xf779b9bd, 0xf59bde35, 0x63df12bf, 0x556e084a, -0xb164bea4, 0x208359c4, 0xd76ad441, 0x46ff3c1d, -0x833c2aa7, 0x5d72e561, 0x5b9facfe, 0xaa8d71f7, -0x82d7aa3c, 0x375724bd, 0x1b3aa15f, 0xe9fbcbfd, -0xb1f759a9, 0x6293146a, 0x230eeb2a, 0xe9a09014, -0x2640ac37, 0x5674f6a5, 0x61d12dcb, 0x072520af, -0x7850d98f, 0x77a562bc, 0x0e920abf, 0xab574cd3, -0x652249cc, 0x4c26a183, 0xe18441a0, 0x6199e869, -0x9e20991c, 0xf1238bcc, 0x094f7979, 0xc64e1ac7, -0x90b8dc7e, 0xdd290230, 0x86a86ad5, 0xb97b9c89, -0xa9d616ea, 0xe807765f, 0x7e7b8baa, 0xa2dcbeb6, -0x66bc1f73, 0xe4b3d5e6, 0x7764247c, 0xb5719986, -0x78ee22a4, 0xe3445d6b, 0xab333b58, 0x00b19be3, -0x1220d5b6, 0x3b222fdf, 0x98f6166c, 0xf7771bcd, -0x0a017231, 0xb140c1b2, 0x6dcc7889, 0x8e84be0e, -0x74710aaf, 0x1dfde198, 0x5c1763ea, 0x378574c8, -0x40506214, 0x7890d495, 0x1caeea7c, 0x124242e8, -0x0d2d1659, 0x3f632058, 0x3c948895, 0xf05a7b07, -0xa0ae5a68, 0x9c3882cb, 0xda70168b, 0x644edf01, -0x1ed86205, 0xbe4571f4, 0x60a05e6d, 0xd880f52a, -0x7e9fccb7, 0xa170228c, 0x5bb4c3c0, 0xb502c3c8, -0x3836fd89, 0xbfb7ea87, 0x0b2e37d1, 0x73f27ac3, -0x1559bee7, 0x30512c5b, 0xe70ceec0, 0x2a7e651a, -0x0a0413b8, 0x5df2c436, 0x9f8542fe, 0xc9e602b7, -0xd4622d8d, 0x4200d89d, 0x348f4871, 0x1be6a6b4, -0xabb0549f, 0xddb20150, 0xf0ba0e1f, 0x1d8855c4, -0x2dd38376, 0xee8f2d82, 0xadbc10a6, 0xe91e5519, -0x0f13f842, 0x53db0df7, 0xf751701f, 0x0f31a7a8, -0xeaa01aa3, 0xa1ef5209, 0xece5ef7d, 0xac0f769b, -0xd1e4a05f, 0xb0fe376c, 0xd3343845, 0xdd10d122, -0xf9f9f315, 0x996edf75, 0xcdb63031, 0x3412a583, -0x500502f3, 0x9e837736, 0xa4e3551d, 0x8e3a1115, -0x55374f41, 0x038fa5e7, 0xc1e03295, 0xd20ee68e, -0xf9add7eb, 0x52f05765, 0xef6fde6d, 0x6b0f3c63, -0xa85dcfa0, 0xc73e3916, 0x6ee12d69, 0x6d60ce09, -0xfaa6a21f, 0xd5f75658, 0xfd9376ea, 0x6efe1c49, -0xb4e8cf4b, 0x2c76b2fc, 0x12a2201c, 0x617eb6db, -0xa79f3bea, 0xbf14f2dd, 0x1d2a7341, 0x1234eff9, -0x5520f778, 0x91a73b06, 0xa60125cf, 0x54c26f5e, -0x6fb9adc3, 0x99728dde, 0x84367e1e, 0x540532a3, -0x20a6be33, 0x8a0999ab, 0x652d3997, 0xd6648136, -0x45b2b27e, 0xf9e024a0, 0x9577257e, 0x3112b0c4, -0xedab0e70, 0x0402efb3, 0x3420df5d, 0x2f2f0c8e, -0x5d33b666, 0x2963d87f, 0xc12bfde8, 0x5a672b5d, -0xe153b99a, 0xba8bc958, 0x38198ccd, 0x60dcfca3, -0x53e2a2d8, 0x547046f2, 0x1b62e6af, 0xd957edc8, -0x50485902, 0xee89bde5, 0xb9337b9b, 0x2a4c67a5, -0x489780f8, 0x55b7fa51, 0xb752488c, 0x5180343e, -0xaca850d2, 0x6562c04d, 0xdadb0df3, 0x4c41ab1d, -0x9042f0e6, 0xc9a6e24e, 0xeaeb5b13, 0x94497bfb, -0x8c66669e, 0x3c36991a, 0xbb77d8cd, 0x13a18643, -0x4f37a9a6, 0x64130ca5, 0xe0d0523e, 0x3088857c, -0x75d7b6b3, 0x954d1200, 0x8cc8b751, 0x1c735711, -0xa7139327, 0x1414e332, 0x43c5cfc2, 0xa0bac637, -0x092d9bde, 0x7b48f481, 0xbc85744b, 0x4329b471, -0x2736395b, 0x645b68e3, 0x00051777, 0x299678a7, -0x7e2410a5, 0xf70ad7e5, 0x072db60d, 0x338ff2ec, -0x803d495b, 0x0766fbbd, 0x7f8c28e7, 0x2628ea6d, -0x82ae362e, 0x2bcc94b1, 0xd6f1389e, 0x171051eb, -0x4b35d341, 0x21aacdc8, 0x8f312e67, 0xae9f9802, -0xf024b14b, 0xc3ef3800, 0x847f8652, 0x2105eb06, -0xc186f047, 0xbb8983fe, 0x0ba80ab8, 0xb124aad9, -0x776bcf6b, 0xc8b5f288, 0x5efb4775, 0xb0d89882, -0xa6002c35, 0xb1347ce8, 0x42e28393, 0xb9d2b908, -0x087dcf68, 0xdf2f69fe, 0xbd468dab, 0x66c7bdaa, -0x92d64079, 0x8bb3dc42, 0x75547044, 0x2b49d657, -0xf69698d8, 0x1c0cdaac, 0xaa4ff692, 0x855a848a, -0x39637035, 0x7226b2b4, 0x0622d9ab, 0xd5ffba4d, -0x69c1885e, 0x5ab21654, 0x6a322924, 0x0013f5f9, -0xf449ca24, 0x3e529a61, 0xcd720cc1, 0x3d136d69, -0x80f94ece, 0xb97e5734, 0x3bd3f9cf, 0xc90d918d, -0x3bd375de, 0x4b4005ae, 0x4377ba61, 0x3e203bd3, -0x2859dd53, 0x1ec891b8, 0x304d644c, 0x72e76e2f, -0x1aa490f4, 0x544f1e44, 0x2dfaf13c, 0x0a1a57f5, -0x4614ae5b, 0x86d994a7, 0xcd5e21dc, 0x25431c18, -0x1bd8a027, 0x192f7a3a, 0xc9452665, 0x424bbbc9, -0x3c1fdf3d, 0x1eb011ce, 0x56dd422d, 0x10a583df, -0xdc833ac5, 0x1740d1f4, 0xec22ccef, 0x342de440, -0x32cd5698, 0x898348a3, 0x04729722, 0xb5c04ca5, -0x5d10afab, 0x7520e420, 0x944f23c0, 0x0eaebf30, -0xb049858f, 0xee8b2a31, 0x28f3f6c6, 0x183139d6, -0x69c77811, 0xf000979b, 0x380af897, 0x8db863bc, -0x401a59e9, 0x8bf677c2, 0xe1e407c1, 0x981f5307, -0x96170b41, 0xad4e659f, 0x95aaf0da, 0xde07972e, -0x54adc504, 0x7ab335a6, 0x694e02f0, 0xfdbf697e, -0x2869bfe6, 0x898820bb, 0x871b4dd7, 0x844d0aea, -0x7c82715a, 0xffd382c3, 0x6ef81f04, 0x4b99ca24, -0xc1a03d0c, 0x255630a1, 0x31d72f33, 0xdc881d50, -0xc4bb2bf5, 0x19c77fb0, 0x82916267, 0xe4f829a5, -0xa5fb06ab, 0x1c00eceb, 0xb5681578, 0xb0102538, -0x53e27946, 0x1a713c01, 0xd045e629, 0xfc6f72e0, -0x8c75631a, 0xedee54a5, 0x5ae6db96, 0x60e114cd, -0x8d386f10, 0xd0ac0559, 0x8c9e9ad2, 0x82efd55c, -0x248e141c, 0xf03153b9, 0x172dcc7f, 0xd9e911e3, -0x3e2aab72, 0x19bf1260, 0x1a018b44, 0x69785695, -0x9dbd5d01, 0x01e4c0c6, 0xf65b35ef, 0x05c9af36, -0xb8845f18, 0xc91a2ffe, 0xa353508b, 0x297b5e57, -0x9ede5250, 0xa79f06bd, 0x8691f1ff, 0x833265f0, -0xcad9c2e2, 0xa0bfdf97, 0x6df7994f, 0xc6ffec58, -0xfd3b9080, 0xad1eeab4, 0x95ce3e78, 0xcaa92283, -0xd9c1f34b, 0xb92b46e7, 0x0ced810a, 0x5cb5524a, -0xe2101184, 0x5d964d71, 0xe1ffa4a9, 0x9ef79635, -0x461b7b3c, 0xd16f144c, 0xb29b29f4, 0xfa5575f3, -0x30ed99cc, 0x2c732f21, 0xe74d99f9, 0xe4d96ae7, -0xa363a343, 0x50dd809c, 0x87d08e2d, 0x84be8539, -0xfe7a8d42, 0x088c8aba, 0x38f0b2a8, 0x53f5ba6c, -0x0bb96259, 0xbb54db8b, 0xdb6519b4, 0xc4b96c3e, -0x3b9c6f4e, 0x457ec3f9, 0x2d0aa736, 0x5a9aa11a, -0xfba5ad21, 0xf3e73e9b, 0x28fac9c7, 0x3043fa2e, -0x4bdeb494, 0x9fceb866, 0x259313fd, 0xad10db5f, -0x41c90297, 0x3adec81e, 0x45a72730, 0x82bbdf24, -0x6257ecd9, 0x0f0c000e, 0x92c485eb, 0xef7b1b57, -0x7f6c87c5, 0x6c686ade, 0xaa0d35ff, 0x5fb026f1, -0xcbae0fd2, 0x0d955aba, 0xb5e40d4d, 0x7b17e99d, -0x188894de, 0xe1256a11, 0xddc7ad71, 0x31d5ad6d, -0x2d3fdebe, 0xcc384b5a, 0x88251dcd, 0xb47edd23, -0x7171e827, 0x8c94eb92, 0xc9cece99, 0xf724ed1d, -0xefc40f22, 0x64640818, 0xe984b477, 0xb36d2246, -0xbd8a8fa3, 0x0d127830, 0xcb947316, 0xccc46186, -0xdc00a748, 0x4885c7c5, 0x83f84ca7, 0xe47289d0, -0x7bb66db7, 0xfb186ff1, 0x36eac763, 0xff60f259, -0x104a8bb2, 0x619cc6ef, 0xf28345a7, 0xde8febdf, -0xb0cc0782, 0x22d3398f, 0x0c755146, 0x34f2f67d, -0xcd955d13, 0x6f5182bf, 0x67aecfda, 0x1397387f, -0x28648298, 0xd2aef962, 0x1b19874c, 0xe1af5081, -0x6222d2f3, 0xebfeacf4, 0x3fa5e0ca, 0xb3ecc863, -0x85f8aa99, 0x40d245c6, 0x9e9e9d48, 0xc5d6a612, -0x243034b5, 0x2449b452, 0xfeb39478, 0xce95c40f, -0x1a7778c1, 0xb7f5779d, 0x63caba0c, 0x888e9a4a, -0xa8c03d83, 0xf776f730, 0x63fe4983, 0x7f7fa72f, -0xbeb8eb4f, 0x5b879f48, 0x390f90d6, 0xea4c5e86, -0x9f3f26ea, 0x90138766, 0x11a445ba, 0x53b82cb1, -0xc06c1eb0, 0x010b176e, 0x42fac1c3, 0x9d2b3b6c, -0xc993513a, 0x85c05db1, 0xf7f46de9, 0xfc028b83, -0x6a8d5e4d, 0xc79e97ee, 0x1588b0a4, 0xc48d1947, -0xc9fee867, 0xed9080e8, 0x3bbaa41a, 0x4ee77d1b, -0x57cd0414, 0x3be088ea, 0xd966d067, 0xa86218b6, -0x67360391, 0xdafaca11, 0x70778929, 0x0d357ab2, -0x9ecfe3e9, 0x4123c823, 0x89dde9b2, 0x23f94f3e, -0x11d921c3, 0x511927a0, 0x5631c8d2, 0x3f6093a6, -0xe01a4ff6, 0xa2a308e2, 0x501a6cc0, 0x15f11b02, -0x0121e2ef, 0xc5c51722, 0xf5a61a53, 0xf1fcab3a, -0x65fcb566, 0x9b13ff9a, 0xabf94b6f, 0xd20f0ae0, -0x0244925d, 0x8b496c04, 0xee554ad3, 0xa73c9bb6, -0xbfa187f8, 0xf57c6180, 0xa58b4389, 0x22a509be, -0x6e979df9, 0x0cf0b5a6, 0xa5658006, 0x921a50fa, -0x1bb771a6, 0x0b3ca3a6, 0x75cc7f88, 0xef52392f, -0x8caab3c9, 0x08718abb, 0xf3a26670, 0x6bad815c, -0xb7e8de89, 0xed74fdaa, 0xa763b3c4, 0x24fdfc21, -0x5987597b, 0x968604db, 0x991165d6, 0x3efb1e1f, -0x1b50a1d1, 0x41282b70, 0x1037c78b, 0xb627a637, -0xa1980b2e, 0xcdf286e6, 0xfe0d0e43, 0x42510ea9, -0xd1608d03, 0x33f65fb5, 0xc709bfc1, 0x87fa5d03, -0xcfd8cf00, 0xc0b57852, 0xc061862f, 0xa959ade2, -0x8e364680, 0x64f5272c, 0xfd4ca784, 0x00ad807f, -0x3080b57f, 0x5bc48efd, 0xf712c48c, 0x6f114cef, -0x40d4baec, 0xee9b37fd, 0x3228d2ad, 0x3438571c, -0x6c1b630b, 0xf6612367, 0x41e672c9, 0xb47ef772, -0x785ec58e, 0xfebb29bf, 0x73b2d64c, 0xec62b92b, -0x4018be37, 0x9e010b63, 0xf98d52c3, 0x914db535, -0xc13dab9f, 0xa99a11d2, 0xa3619315, 0x092477bd, -0xb9d0df00, 0x6bc8772a, 0x159504ad, 0x73338536, -0xdf420687, 0xe50c003e, 0xf2a8adba, 0xf64c3af4, -0x78fa5b14, 0x709d4ceb, 0x9cfb08d6, 0x692f4e3b, -0x09b2b909, 0xd8b958ec, 0x0cd7d12d, 0x339993c5, -0xbe960ae6, 0x04c67ecc, 0xb688d974, 0xf79a00bf, -0x8e4c8b64, 0xf0650562, 0xa31916e1, 0x2c03fd22, -0x4d5063d0, 0x8824d74c, 0xadccf855, 0x520a2667, -0x80490a5d, 0x5d507ae3, 0x4fb9f0f7, 0xd977889e, -0x604f8316, 0xe003b824, 0x81d9cc7d, 0x180c1aca, -0x583e4541, 0xf3af9101, 0x0597f24c, 0xf1d3f27d, -0x3d8105d7, 0x3f754795, 0xd2ae2bb7, 0xf1b029c4, -0xaa0906cd, 0x913724aa, 0x80c9d08b, 0x9a40d932, -0x2850c9f8, 0x0740881e, 0x425a6c1f, 0xa8eecf2b, -0x559c2516, 0x79b7838b, 0x6d76fc2a, 0xddd9d44d, -0xb9d8b3f9, 0xca72d6ac, 0x9eccd98b, 0x9cd453f5, -0xd7ce8448, 0x56cc9c05, 0x39e92a48, 0x64b026e0, -0xe38795ba, 0xc4794b34, 0x69666aec, 0xab9204d3, -0xa0176871, 0xc7a7ed75, 0xc8cc2c8f, 0x2816c94c, -0x21335231, 0x4dcc77c0, 0x912793ac, 0xf0593e32, -0x903bb227, 0xade63501, 0x78a47304, 0x2152867d, -0x9fa75a0a, 0x1c3501e9, 0x74af0cdf, 0xf20889be, -0x0af8a22a, 0xa482d2c1, 0x357993b0, 0x2f8ce8a0, -0x5ca39d4b, 0x5ba792c5, 0x80d47282, 0x1fb6093d, -0x3698bfef, 0x4dd1e36e, 0x89b73456, 0xb225b141, -0x854f0dca, 0xecad993f, 0x01039099, 0xb8016aef, -0x58867f1e, 0x659c0a6d, 0xe33ab20a, 0x945898d7, -0x9820cead, 0x55675aea, 0xf64a3c37, 0x7847a357, -0x6ec74002, 0xc447e854, 0x819de2bd, 0xc72f11c9, -0x0f392cca, 0x321acf32, 0x0a189496, 0xb09fa869, -0x6c7646e5, 0xc01439e7, 0xc2ac4caf, 0x66cecad9, -0x98307c00, 0x3260c110, 0xf1af87ed, 0x99b06a3f, -0xbe28465c, 0x996d9b6e, 0xc2192fe1, 0x0815ad08, -0x1e5ef57f, 0xefdcb325, 0xd753786a, 0x095a4526, -0xfb4f1889, 0xdf50ec92, 0x8157bd6e, 0xeb8f10e1, -0x2c8eb2f5, 0x2b930245, 0x9e1fdcf4, 0xe3302927, -0xe9854348, 0xf8c8509d, 0x0cbbd8cd, 0x12bbe742, -0x6b28e2bd, 0x3ec1c26f, 0x1599b9f6, 0xe1cfb308, -0x36d8e348, 0x4077c732, 0x52bbbf12, 0x74a7917a, -0x3fd750f2, 0xcc63d23b, 0x71f5ce09, 0x95ff72a9, -0x8ffc9a1b, 0x5f3d5968, 0xa272f01a, 0xcedb2501, -0xd393616f, 0x0037a0bc, 0x9e104e9d, 0xb8a79ae0, -0xf7801b39, 0xd2e7d768, 0x0655b59d, 0xcfa2d671, -/* 2174-m041066136.inc */ -0x00000001, 0x00000036, 0x05012007, 0x00010661, -0x007ab882, 0x00000001, 0x00000004, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0xc6abcb1f, 0xb00adb19, 0x06cf0bfc, 0x8a7087be, -0x82f00bf8, 0x338c857a, 0xf8b9bc24, 0xfa192601, -0x84d5bb77, 0x8fdc9321, 0xb2becf58, 0x3e374ae8, -0xf75cd1a9, 0x16a7a2cf, 0xa3f26ee4, 0x214512e9, -0x29d231c0, 0x11e8cd27, 0xbf9e07b1, 0x7f803296, -0xb9f9fb12, 0x55a14a7a, 0x570a6594, 0xc7e949cd, -0xb5dd0739, 0xa46a74a8, 0x03d69674, 0xbd75ce58, -0xe4a1e74a, 0x38a5d0d9, 0x68c56828, 0x2a88b833, -0xd99e16e4, 0x085b2409, 0xd952511d, 0x8381d712, -0x1b99c686, 0x965a7243, 0x36305bf6, 0xbd41cea9, -0x59d03e08, 0xfb2cca65, 0x9695cabb, 0x6be9102d, -0x788edef1, 0xd746f3e3, 0xa14f477f, 0x6eb56408, -0xae141130, 0xa7635dc2, 0xecf6f721, 0xeb30f9b5, -0x85212db0, 0x98121e34, 0x295b8d3e, 0x9a862d71, -0x379171b2, 0x986a0771, 0x04b45d77, 0xe99390eb, -0x612a2ed1, 0xf7319d57, 0xb730f677, 0x2ed63dfa, -0x67e9df58, 0xb20dc282, 0x4c2b0edb, 0x8b1a7a6a, -0xa87779bb, 0xe220d133, 0x3bfbf9d0, 0xe76b1cb6, -0x8f543b5f, 0x689210db, 0x0fbe41c3, 0x9fd2a821, -0xbfde6e19, 0x9a40209e, 0x008b339b, 0x690b779f, -0xf46f54d0, 0x63389138, 0x919546db, 0x843b651d, -0x8942a49e, 0x4a68ac5c, 0xd4a7add2, 0xf6e60e94, -0x6dfeebad, 0x4c760a59, 0xeb2e04f9, 0xf5c2781c, -0x6b9a919c, 0x8e2eaa8c, 0x58770ca1, 0x76bbd4e4, -0x46ce1fe5, 0x16bf1e38, 0xe6e1b525, 0x66b177c3, -0xebdad6bd, 0xc5bfcab0, 0x3bd3cbd6, 0x7d879201, -0x9f03cdbb, 0xebaeeb34, 0x93296cce, 0x55ad46f2, -0x1573d61a, 0xdcd2e2fc, 0x1320b9cb, 0x18ea7fa9, -0xa53b8710, 0xe4bf6eef, 0x91610b85, 0x017d8742, -0x2fe45976, 0xf0ac6cb7, 0xdbe8d962, 0x5d4b57a4, -0x4aa89970, 0xc814a41a, 0x087928ed, 0x4a96e34c, -0xf79ab8b9, 0x45abd2e2, 0x918f98fa, 0x19aa3631, -0x6bb3ad98, 0xd60a4234, 0x326429ac, 0xc88641ce, -0x00ba6f1d, 0xf477194e, 0x7d780085, 0xb74dd9ec, -0x0ca754e4, 0x6c179f61, 0xa97d7971, 0x6c361c9a, -0x451896f5, 0x258ceb76, 0xdb143afb, 0x1ec79b33, -0xfdacf563, 0x29d0bb61, 0x9b25bdeb, 0x122bdf21, -0x6bd65e78, 0xdd89483b, 0x22540b64, 0xf24db092, -0xe2355d36, 0x4738fbda, 0x5182b9f0, 0x9370e7e4, -0x25b53d1c, 0xd190ff54, 0xdff9a4f3, 0xddf54748, -0xfdd6b8af, 0x590ca4d0, 0x5c365831, 0x78bcafdc, -0x28d8bdb3, 0x09b6bc4a, 0xa963889f, 0x7a1733bf, -0xf9e6f050, 0x89ed8b13, 0xec82ad5a, 0x7929831d, -0x15f290cf, 0x5acb5256, 0xfb253d78, 0xda18987b, -0xbc4bea51, 0xa7876e2a, 0x9797ed9a, 0x8446a558, -0xf92499af, 0x78593d67, 0x5595886c, 0xf2d283dc, -0xaf63d5b4, 0x952f18c3, 0xa7ceb0b0, 0x6c32f956, -0x1c5aa1ee, 0x9d004776, 0xae10be37, 0x429ad061, -0x08f50134, 0xdef7fc54, 0x43f2f1d3, 0x50b9110f, -0x01631928, 0x020d9ea0, 0xcc7eef44, 0xced62583, -0x1bd9b506, 0xe9830223, 0xf81ca148, 0x09f0f34c, -0xf2569a85, 0x1eacbba6, 0xdd4b7eba, 0x5fc11003, -0x048c027d, 0xf30a32ad, 0x606eb024, 0x463297d7, -0x5c173e31, 0xf82c929f, 0x89c21a4b, 0xd537bbf4, -0x9d01b46b, 0x745e97d5, 0xb7a676a9, 0xc1a84b37, -0xb09acd84, 0xab6306e8, 0xd4c7eaa5, 0xbecc5400, -0x571089fe, 0xc8341773, 0x114e0220, 0x868891ed, -0xccc42472, 0x411d6345, 0x12523237, 0xdb9658f7, -0x96f92f7e, 0xffdf781a, 0xdc78f459, 0xc87f53fd, -0xd1a0c0bb, 0xec5dcd39, 0x496884d6, 0x01336220, -0xfb49b634, 0xbbc7440e, 0x1c8815c8, 0xb8f89052, -0x958b5858, 0x9d10772e, 0x4a693846, 0x0f0a9686, -0x1290982e, 0x0e13e625, 0x8b093a5b, 0xf54613a0, -0x3b46a140, 0xdb99edba, 0x79381c8b, 0x49402ece, -0x7083aeca, 0x885db471, 0xf28d986e, 0x7a46c1ce, -0x10d2c8a3, 0x571e1a63, 0x13a7c0eb, 0x02704358, -0xe66f813c, 0xf541c81f, 0x906095b0, 0xe7edc0a6, -0x4976578d, 0xe6d47f48, 0x817565f0, 0xe0321fbd, -0x14abe8cf, 0xc310e4dc, 0xafd6e3c2, 0x5f8c242e, -0xd2cd4918, 0xf17000c6, 0xc52ae235, 0xdd73e4bf, -0x7e2a72f1, 0x515e1ee7, 0xff27b9c2, 0xc280aab7, -0x4837fabe, 0x913a1c96, 0x17e0c110, 0x68ab31e1, -0x0a1b75d8, 0xd6009c30, 0xc0af295d, 0x92eb932d, -0xba288766, 0xe7e1a637, 0x3cc91199, 0x714bca64, -0x3871e0b9, 0x42d5e440, 0x4719172c, 0xe7652c40, -0xa5ec682a, 0xd060486c, 0x10fae5a5, 0x0f49a4cc, -0xedc92f80, 0xc0cf7616, 0x88c3b1d9, 0x6bf5421e, -0x6e3aabc6, 0xb88271fa, 0xdeb61fbc, 0x755cbba4, -0x53ea8b19, 0x8f64027f, 0x5cd064ac, 0x151548ca, -0x450e8c1e, 0x14246e1c, 0x35a66d40, 0x39875b36, -0x4cdac82c, 0x4feb4480, 0xb693dbe7, 0x471176ff, -0xd7040ae4, 0x4e6b302c, 0xe5b7a33c, 0x8bbea098, -0xb3ed3f64, 0xdcddb271, 0x267ca8f1, 0x28cac2c7, -0x09626eea, 0xbf02498e, 0x7f6b5fc4, 0x502e091a, -0xcddcb743, 0x352047c9, 0x90c5dbd0, 0xf453c523, -0x5587854d, 0xe8674056, 0x30e4d0ef, 0x13b395a9, -0x86f79009, 0x43638968, 0x6207f7e5, 0xce2c9b65, -0x9c12ea07, 0xb4595117, 0x76341c1f, 0xcef0faaa, -0x3642d3eb, 0xa7309093, 0xc6d539c3, 0x938121f8, -0xfc6ba288, 0xcaee582a, 0xbef0cc72, 0xc8ba3fa9, -0xc08a7c00, 0x7fffa363, 0x3f788297, 0x1cc199d2, -0x9a2ad3a4, 0x058a7cb6, 0x23507932, 0x44d5f8c5, -0x9c9b53eb, 0x7ed2d9ef, 0xab2d770e, 0x1ba567c1, -0x2d9e3b1e, 0xeaa289f8, 0xcf6ea0d7, 0x49ce1ac3, -0x26fb7f6a, 0x3065f08e, 0x413b50c5, 0xf58a6b43, -0xc5df6d9b, 0x5d0c243e, 0x203d24d5, 0x1a4965b5, -0xada68b69, 0x1c8951db, 0xf7ec6194, 0x251dd237, -0x1333c6ab, 0x9a9b26ff, 0x5b411385, 0xc2a86b67, -0x975c51fb, 0x36231971, 0x9890ce01, 0x45b7034c, -0xb72a448a, 0x782a1785, 0xb4dccdc3, 0x59ef3395, -0x7479669d, 0x2ddb557e, 0xddd4c482, 0x3c4196d1, -0x21d7f2c1, 0x8bab7533, 0xe371cdd1, 0x4cbc4d82, -0x4f837ff4, 0x281e963f, 0x7c0cf6b5, 0x2ede52f5, -0x7bf6ff37, 0x866aba12, 0x42a88b40, 0x21b9b5e8, -0x02e3c941, 0x39292d47, 0x128d245f, 0xf3c7f48b, -0xa07661c0, 0x7f95f989, 0x398d799a, 0x60f6af7a, -0xc5241071, 0x0d4011db, 0x557143f3, 0x465338cc, -0xf38528c9, 0xd42e73e6, 0xb8511584, 0x07aab66f, -0x83c0d8db, 0xe045a176, 0xe5a87665, 0x189bb5a4, -0x8d40f5ae, 0x283a45a4, 0xc816f56c, 0xc05b2562, -0xdb4f5264, 0x7065894c, 0x73334852, 0xa5f33316, -0x83fe2bf8, 0xc8b7c4f5, 0xbc650d6a, 0x0f2f948e, -0x45ae5409, 0x1f36e8b1, 0x39aa1aa7, 0xa9c093ae, -0x061972b1, 0xc52e4f5a, 0x4720bdea, 0x45ffed75, -0x51117574, 0xde18f60d, 0xaef27830, 0xa5011c04, -0x49b69861, 0x6d035a2c, 0x5853e858, 0xfa7c457a, -0x031631ff, 0xbb7820a3, 0x497110a7, 0xcd7fceb8, -0x0d05c95f, 0x1d51bfa0, 0x4ee87fbb, 0x22d0d182, -0x1af9deb2, 0x49f95c63, 0x3492f7ba, 0x09d07509, -0x2aea37b6, 0x3890dbec, 0x2b75adf5, 0x0f0dd2dc, -0x885bfee0, 0x8e262e15, 0x54117704, 0x8054211c, -0xb1a8f6cb, 0xbf2afbfc, 0x559cdee5, 0x3152b9b0, -0x187e8ad5, 0xfcaf41d7, 0x24f02eaf, 0x798d6537, -0x0313670c, 0x76c9f206, 0x6815fcf5, 0x26a2577c, -0xb3c41d3d, 0x361c8809, 0x05b11eaa, 0x486e1509, -0x0c6e2c73, 0x2bb9fbdd, 0x667eef0e, 0x31999f89, -0x823ec3b6, 0xa0abfb52, 0x86d62ad2, 0xcbe3fb6b, -0xdbc3b8db, 0x8882ed5b, 0x3d18011d, 0xb786ce7e, -0xb163e9ba, 0xd51c74e7, 0xcb1d93f5, 0xf06c8d5c, -0x0f4575f7, 0xb85c9c61, 0xeebd89f8, 0xae0b1ddd, -0xc5d86461, 0x08b9778a, 0x099bc349, 0xc3a97bcb, -0x270610a1, 0xbf41bafc, 0x2d4178dc, 0x6ae7c0c5, -0x58df15d9, 0x7ad2f187, 0x4ede37de, 0xa8724d66, -0xee5b7777, 0x8f282c44, 0x782367e9, 0x2a1c812d, -0xcac724e4, 0xc7db0da8, 0xfacb2832, 0x0d5febba, -0x179f4a3b, 0xbbc2b693, 0x1798f694, 0x93b9d966, -0x0e034a01, 0xeef9f502, 0x6fdc6397, 0x206affba, -0xc028af2b, 0x68f95f2d, 0x7482ad04, 0x2d904ac0, -0xe53ec3a8, 0x146de389, 0x084e05b4, 0xa72ad313, -0xa07b8a4f, 0xbe6c0e42, 0x8005755b, 0x85d99ef3, -0x213713b1, 0xeec1bc60, 0xb0e739b1, 0x400cfc9a, -0x44fd1bcf, 0xd500c58c, 0xdfa59e14, 0xb6356e38, -0xcfc9c716, 0x86e8809a, 0x1a44b054, 0xa69ea7ba, -0x616655bf, 0x3ea8093d, 0x3de4f119, 0x45039af6, -0x1255da1c, 0xf337862a, 0x26f71c0a, 0x718d60db, -0xa3cc6ddc, 0xff0773d2, 0xaa52c7bb, 0x74cb97ac, -0xef37dfa1, 0xf873b4fa, 0xcf243c8d, 0xafaf2a83, -0x0ba04a12, 0xd88c8680, 0x2016032c, 0x71a7b92f, -0x43b4916e, 0x3c5be59f, 0xb98737e2, 0x9448d923, -0x7c020e4c, 0x995ca16b, 0x7f81170f, 0x6cacd779, -0x05fe0f02, 0xf61b46ac, 0xa53ad4f6, 0x49847599, -0x5b5bfdb3, 0x349d37be, 0xdefd2302, 0x6e0affb2, -0x860cacb5, 0xff0a9fc4, 0x2d1fb7f8, 0xf3222464, -0x99e5c92e, 0xaa58b392, 0x5262d8ea, 0x4bd7a622, -0x0751f66e, 0x6ffea9ba, 0x94428ee7, 0x5e0e36f9, -0x4e62ee71, 0xc3a88917, 0x25cfd106, 0x4b7bcfcb, -0x49e049ea, 0x11a9ca42, 0x3d8984f6, 0x0f2d55a4, -0x0659d306, 0xfec80d3c, 0x07778fc5, 0xc14d274b, -0x702e8f6b, 0x56890490, 0xf8e9ef29, 0x45c0c7c7, -0x800437b2, 0xed53e7b5, 0xa82b48d8, 0xe2046cfc, -0xd4474b71, 0x4577b76d, 0xb1a71474, 0x8b6600c0, -0x59e2af91, 0x16bd23f4, 0x8d76cfe6, 0x621320c8, -0xb67c6d2f, 0x9e99b02b, 0x394ba142, 0x53b3ff23, -0x69522fa6, 0x41b90cb2, 0x565bc299, 0x1106e9db, -0x32f64255, 0x5a1e17d2, 0x77bc7581, 0x6345764e, -0x31fb54cc, 0x95f4728d, 0x2f579221, 0xc8cc9359, -0x3dc41abd, 0xf1b5deae, 0x4ff43adc, 0xde1f7cf6, -0x0a365307, 0x5431af2b, 0x088dddad, 0x88de3b1e, -0xa66ad5ba, 0x4df61b5f, 0xc3d31e46, 0xaa21d66e, -0x053c0faa, 0x8992a6ee, 0xdcb1836b, 0xc85d4974, -0xcc6457c3, 0xd2f2293e, 0xfdd901b2, 0x184f750e, -0x0f2e54a3, 0xd0d9becc, 0x4fcde77d, 0x2935c5c2, -0xc714b17e, 0x76567883, 0x80127e1b, 0xb72a44cf, -0xef89daa9, 0x79a70e45, 0x2ba15e3b, 0x8a023a9f, -0x346578c1, 0x628ee70d, 0xd12a0dee, 0x40630577, -0x362fc11f, 0xbcd17e2d, 0x4de44598, 0xecd24c04, -0x2e240014, 0x9961c95d, 0x8a93bbc8, 0xf1367096, -0xe88a72b3, 0x39cf42b5, 0xd8ff0f1a, 0xeb0f8f17, -0xe8b731e0, 0xf0c4e53d, 0x8076d545, 0x1a51f4d8, -0x10a577da, 0x24decfc0, 0xde230104, 0x5763c2e5, -0x681d8364, 0xdfc0b231, 0x3dece0d3, 0x306d2934, -0x69226af3, 0x5a7036d2, 0x78059c83, 0xf7bde2dd, -0xf95c7d46, 0x67d3a7e5, 0x7a4373d6, 0x4b3a73cb, -0xf2fecaab, 0xd0f8271f, 0x6b2b8fd3, 0xe7d12276, -0x268e1c3c, 0xd153177c, 0x86f0bd57, 0x6e070d11, -0xc4848668, 0xdc5f5330, 0xe100de6e, 0x283da5f1, -0xb21dff23, 0x05f349a1, 0xea258eca, 0xb7f45c97, -0x666928b1, 0x5198a3ef, 0x2b69a6e7, 0x2884cab4, -0xbf445fc0, 0x63570280, 0x6bc309e2, 0x3caab884, -0x07e59d04, 0x95d880d4, 0x90847bb2, 0x0272af68, -0x4f371911, 0x6ee590bd, 0x18bcce77, 0xf2446c3f, -0xfb20be2d, 0x6d8f16c9, 0x307d076d, 0x2403f194, -0xe473560f, 0x73813ba1, 0x4c29079f, 0xff17ef1c, -0x5fd1272c, 0xc4986190, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2497-m041067660C.inc */ -0x00000001, 0x0000060c, 0x01192008, 0x00010676, -0xfbac0f69, 0x00000001, 0x00000004, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x0000060c, -0x00000035, 0x2e000000, 0x20080119, 0x00000301, -0x00000001, 0x00010676, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc8f5cd92, 0x30bd1beb, 0x77c4fb8b, 0xe899c960, -0xc729b4cd, 0x1d9b8923, 0xfcdfc554, 0x580d39f9, -0x170ce7c7, 0xd727c705, 0x019b1ba5, 0xe0414a29, -0x57d45458, 0x26a8a411, 0x9faad966, 0x095ec8b0, -0x083a7c2a, 0x17cfc70f, 0x3c8e78a8, 0xce18c419, -0x5f2ddeb7, 0xc9c95d71, 0x437a5116, 0xe0253ad0, -0xec78db42, 0x681e436f, 0x7fd028bb, 0x1149a501, -0x0bdf0d05, 0xc2321514, 0xd6866cd8, 0x64942685, -0x21e0276b, 0x0817a288, 0x09138669, 0x792985dc, -0xbd60d6aa, 0xfbf902ec, 0x43fee69d, 0x5c5823c0, -0x9dca1fe6, 0xb528b0c5, 0x22fd29ab, 0xac4fe251, -0x77207813, 0x0637a1f9, 0x16bfcf73, 0x80497f6b, -0xe5bca939, 0x1539fa1a, 0x66607fea, 0x2276c06f, -0xd003229e, 0x3622fda7, 0x18d0b8af, 0x9f399760, -0x3ac6387b, 0x6c7148fa, 0xfaf4df9f, 0x965db840, -0x7c142542, 0x7b805f4c, 0x3f2002a3, 0x061399ce, -0x2f1a03c4, 0x7f1c7616, 0xb2f9ab42, 0x4e6a92a2, -0xb44b96d6, 0xe1167017, 0xec4b2fb3, 0xa15376be, -0x00000011, 0x4872f26c, 0x88971c10, 0x66db1385, -0x1e532ab2, 0x7ccd2d72, 0x38dd766c, 0x131f4505, -0x7d5e1e0a, 0x1932938b, 0x79c1db9a, 0x9fe5b8bd, -0x07037c1a, 0x698cd351, 0xbadb5300, 0x063f17d9, -0x8558ada3, 0x224c2288, 0x26fa35b3, 0xe64efb19, -0x0e1b52db, 0x696d5461, 0x3a0f765c, 0x4b853dfe, -0x05147b28, 0xbe146518, 0xb61e1de2, 0xc342998e, -0x083d5f41, 0x737fdbb5, 0xdd812ce1, 0xa7b9549c, -0x164b5fbf, 0xaffd6139, 0x44154437, 0x23d44899, -0xbe41eae1, 0xeecc8d45, 0x31fc971a, 0x44475238, -0x5d4ab69c, 0x67f342a0, 0x118cb268, 0x513fb847, -0x0a86fce3, 0x23f22535, 0x5fa15360, 0x929aa833, -0x3cbd4138, 0xc1dead1e, 0x3efa210b, 0x9781a61d, -0x00b53f73, 0x07df4d30, 0xffe97322, 0xf7b12998, -0xba4d7316, 0x4b746898, 0x45ece500, 0x78cf31d5, -0x0208c1c6, 0xc3999e15, 0xce2f90f4, 0x7e130a0b, -0x3c74ce12, 0x37612fd2, 0x7ce3ae15, 0x99a26321, -0x52ac391f, 0xcb32f7e1, 0x0e50140d, 0x3a6bfc41, -0x497f7f9f, 0x334b7e17, 0xbcf4e41d, 0x3311b0db, -0x0dc65367, 0x44847807, 0x991c439a, 0xd2965df2, -0xfd72e4fd, 0x44b01f14, 0x5a0cf5c5, 0x70029e37, -0x92af3f34, 0x47949bdf, 0x771a3c07, 0x0874f372, -0x7a54670b, 0x7430b00b, 0x356234f3, 0x74edf1e6, -0xaaf60a4c, 0x2bb5eee4, 0xc2c1d43f, 0xc4ee788b, -0x4198fd90, 0x0aba19a3, 0xc251f028, 0xe42404df, -0xccbd25f2, 0xdb13eb69, 0x888f89a5, 0x5a6c8cd3, -0x1e3b469b, 0xe07e48c6, 0x87f25228, 0x64324c03, -0xe0426f9f, 0x148f828b, 0x4a3c82ab, 0x7d46539d, -0x0b5079ea, 0x2c675b3e, 0x83134717, 0xbe775c77, -0x74841ec3, 0x4470addb, 0xfabfa06d, 0x548757fb, -0x184ea712, 0x502765b5, 0xd7067ce2, 0x15afee11, -0x8a95590d, 0x3a1734cd, 0x212c7f7d, 0xe5aa3e5b, -0x9c7e75c3, 0x07486966, 0x5827bbea, 0x391e46fe, -0xc6acbc9e, 0x9761b6a9, 0x37bef8c4, 0x733eb81f, -0x7ac9a87a, 0xceacd157, 0xd931072a, 0x9383c10d, -0x5eae74ef, 0x5f82f6a0, 0xcf89077d, 0xbc641bd8, -0x1b7d1213, 0x980a4ed3, 0x410fa7e8, 0xaaa1a011, -0xa5e94ef2, 0x74937d5f, 0x3c109f67, 0x8e58bdcc, -0x2b43ad95, 0xaa516349, 0x6fa9cca2, 0x48a18062, -0x663c7fd7, 0xf3822d87, 0xbaaf1f97, 0x8da372b2, -0xa416831b, 0x6a645364, 0x9c7ac6fb, 0x3f5a9cab, -0x8cf6f4b4, 0x514fd1dc, 0x7e9d0918, 0x2075f774, -0xfda8677b, 0x3b5c16ac, 0xe887694b, 0x7d622e9f, -0x5427472d, 0x540e5c99, 0x2196e138, 0x5d5e9c58, -0x84a5fc17, 0xb17d6d41, 0x63273bdf, 0xfbb912b5, -0xaf16b7c1, 0xeb1914d7, 0x5d654b8f, 0xf4a594f6, -0x554a6311, 0xb391f519, 0xa5ad4acf, 0x9c052bb7, -0xea68faa7, 0x37399a25, 0x8f6f6d36, 0x47c20f2b, -0xf241ab98, 0x66da024d, 0xee90a06a, 0x33718b17, -0xaa89087e, 0x6dcca7f5, 0x43a59f0e, 0xcb2e3ab8, -0xb19126bb, 0xc56bccb3, 0x04f6fd9a, 0x0f63850e, -0xa2b6c85e, 0x309f9817, 0x7252b154, 0xcba20ff3, -0x143156b8, 0xcfcdc8ae, 0x13c2a75b, 0xea4bf1b8, -0x6e474959, 0xa9c376f5, 0x40d252b8, 0xb6209e70, -0x993efa22, 0x3d7e8007, 0x1857ba0d, 0x72f25310, -0x233a8f68, 0xeb4ca923, 0xb17917d1, 0x9ca3f4f6, -0xdecf1498, 0x99f5ddae, 0x8b6ba2b7, 0x54f41fb0, -0x1ec9ffa2, 0x74ad3bd6, 0x84fee3e6, 0x5294820d, -0x147e8b14, 0xd2dc15f4, 0x152fc744, 0x306bc043, -0xfdbb74d8, 0xf4ea207c, 0x53edfac5, 0x1b609795, -0xe990ee73, 0x749dbed4, 0xd1cefc95, 0x5c7b37f6, -0xc6b39045, 0x7281e3f7, 0xed0e6aa4, 0x590a246a, -0xe6e6a81d, 0x604491ac, 0x6cd14e8a, 0x7a19f5da, -0xf7c7326a, 0x0ef8029e, 0x0e741b48, 0xc962a062, -0x6f4ad86e, 0xa2729726, 0x93bcaf1f, 0x1bb56970, -0x12495cdc, 0x180512e7, 0xa1d68081, 0xb924c24b, -0x5a1461ca, 0x21438ca9, 0x5449ae48, 0x0f564503, -0xcec8df3c, 0x789f9b80, 0x5a708df1, 0x28735bfc, -0xcf11d2fc, 0xa5d01625, 0x80b0b533, 0xa09f026d, -0x1d22fdf2, 0x01928228, 0x8b6779ed, 0x04f7cc95, -0x581fe0b2, 0xcc9a66a4, 0x55b3f130, 0x0f22abed, -0x05b7e95d, 0xd8cc9c30, 0x0850ca8a, 0x34d729dd, -0x973300a7, 0x80ffedb1, 0xbf5b28e7, 0x135c8cc6, -0x4337b017, 0x31d8dd09, 0x35ed75a1, 0xb8f990b9, -0x4384dc18, 0x29d72b56, 0x021aa2b2, 0xa3248b3f, -0x5f4e7301, 0x29991927, 0x1cc50c18, 0x79fcc545, -0x56e2e683, 0xe5127777, 0x4b727957, 0x94d1bc22, -0xacd0da9e, 0xd24771fd, 0x5997ff0a, 0xb9947cb8, -0x8cb9bb5c, 0x16a4c5e0, 0x00d6995f, 0x1e05edff, -0x3a7f1af3, 0x445fd70d, 0x24a602c7, 0x6b50001a, -0x6c99f5e5, 0xad2c00c5, 0xbd16a90d, 0x3b7b6032, -0xa8dd4f8b, 0x437145f1, 0x5a593d5f, 0x749ee409, -0x9c6d8223, 0x40c1dad0, 0x578e7e1f, 0x89072e7b, -0x0ccf47c1, 0x427606d8, 0x4a7bb48c, 0xf85cc4e9, -0xca5ca3b6, 0x9b989f23, 0x6496403f, 0xdf8ef891, -0xf4458e90, 0x28eed125, 0xef91afe9, 0x97a8d65b, -0xe022b3dd, 0xc93c2adf, 0x520cbe7c, 0x58995018, -0x719a724a, 0x9258733f, 0x8df05767, 0x879b9ba1, -0x84684054, 0x71a62082, 0x5be959cd, 0x12c937ec, -0xc21fb3b8, 0x6738aa89, 0xb01d872b, 0x0ff6ec3c, -0x50fc63ea, 0x715b7c5d, 0x4e5d50c3, 0x086c862e, -0x34ec9201, 0xd41176ef, 0xd0238088, 0x53518100, -0x8e1500dd, 0xc6ea9594, 0x0359517e, 0x58d81a35, -0x48c40983, 0x2d562dc6, 0xecf5be9e, 0x4cd82ead, -0x45faeb2b, 0x1a66ec1c, 0x6b692a76, 0x6cb326b0, -0x3a6c362c, 0xf0174da3, 0x5e4549d9, 0xc12c5972, -0x73716059, 0xdd54591d, 0x32ee704b, 0x5a55c22d, -0x56bd1e7e, 0x2bd34024, 0xa42c85d2, 0xb1ce248a, -0x604a7570, 0xbbf4b3fb, 0xe0eeb866, 0x130b7dd4, -0xdb39dc1d, 0xd873b0c4, 0x3aedb6ef, 0x5efb2481, -0xbfaff9bc, 0xb94930d6, 0xa3fe71cc, 0x75867e01, -0x7c8ee191, 0xf38f4963, 0x8d077957, 0x658e7c2b, -0xc1bd58ed, 0xb86a20b2, 0xc624489c, 0x4624732d, -0xc11f1ee3, 0xf1874ed7, 0x173684cf, 0x0e5851d4, -0xc2662118, 0x13dbb926, 0x1668df5e, 0x00749d03, -0xab9530d2, 0x5758e602, 0x6db90ff1, 0x87270f9d, -0x774a52f5, 0xcd1b4b5a, 0xd706025e, 0xe3a51fc4, -0x31c5d55b, 0xbd0278a1, 0x16dce1bf, 0x75a3446f, -0xe030c121, 0xa6f6b3c8, 0x504e3b3b, 0x4c1428b1, -0x74229a60, 0x25d5b7b7, 0xea284c21, 0xf5f1c7cd, -0x0025e9fc, 0xa7db9e56, 0x4e3aeb90, 0x8bad0f3b, -0xc19e88eb, 0x8ea86b83, 0x25cf5d26, 0xca78504e, -0x94109c06, 0x60ad3975, 0x138b8038, 0x4c9d8fdd, -0x28a91526, 0x5d3d6c3a, 0xf81ab861, 0x8db34426, -0x35a3b398, 0xf3b40170, 0xb7e6994b, 0xea72c1f5, -0x63201cd4, 0x1c5749dc, 0x420ada27, 0x419f4847, -0x49244543, 0xb915645f, 0x3a00b3e2, 0x0122000b, -0x296b6bad, 0x7b45d76b, 0x5be8f025, 0x2a04919f, -0x8291fea4, 0xaae644f9, 0x7af3fb96, 0x77d9878c, -0xa8996848, 0xa9a0c1c3, 0xb47ae6d2, 0xc5b6cf90, -0xb04b4863, 0x43fa113b, 0x66ef4993, 0x03a5b4e9, -0x94b661dd, 0x145a5909, 0xd42f70cc, 0x6b816775, -0xfbc0cb04, 0x5e890eb1, 0xb6900305, 0xcd19304b, -0x85c67d21, 0x19e91907, 0x27b3898c, 0xe0ce6ba2, -0x4110d80d, 0x85953740, 0xba7a4225, 0x51db6dd9, -0x04c21ffe, 0xd34ef7cd, 0xeb13f075, 0xc1f8eb04, -0x19a1227a, 0x3e99efae, 0x318346e2, 0x3d4c73bb, -0x402dacc7, 0x5a9e892d, 0x01304401, 0xb3950c6f, -0x9254bea1, 0x5cc8f025, 0x53cb9416, 0x52d716c5, -0x3ff575a5, 0xede2046b, 0x2cbd6b85, 0x7e8feb25, -0xc2d35482, 0xa49b8495, 0x214fed4b, 0xc93ae54f, -0xde3d8a18, 0xe4456b47, 0x505555c1, 0x6418926d, -0x4b6ac1e7, 0x7ac213ea, 0xc081eea5, 0x467ff1c3, -0x1ed5d79d, 0x746dbb24, 0x38b1dbde, 0x4d495fc0, -0x7ddabfe1, 0xfbac0ba1, 0xd17cfc3b, 0x32c819f3, -0x1f4c39cd, 0x6fa5c3ed, 0x0d2e7f50, 0x1f5cb318, -0x1e1770d1, 0xef12c293, 0xb149ace5, 0x93df9bdf, -0x14a98319, 0x3374906f, 0x746d603f, 0x5a368e6d, -0x8dbaef76, 0xb7923f42, 0x607655cc, 0xd144703c, -0xa01fa0f6, 0xa83f4e65, 0x224bba03, 0x6e082d15, -0x11ef27eb, 0xad91427e, 0xd8f0e3bd, 0xba7bc3df, -0xdb031557, 0xf33052d0, 0x2bc3df37, 0xf55d25c2, -0x99af998a, 0x5819eb07, 0xe4b9ebc5, 0xbc3da46e, -0xde1abe71, 0xb8c66434, 0xe811e29d, 0xa48ee5e6, -0x7f961c60, 0x5500769f, 0x9c8e0d00, 0x94680cea, -0x2f7a0c5f, 0x9a058310, 0xd3ddca08, 0x74276c4c, -0x855ebef2, 0x61979f79, 0x09684303, 0x3ea777dd, -0xf700db1f, 0xdf7bcae0, 0x0fa7db2b, 0xd0115231, -0xc0015882, 0xe4af6f72, 0xb4388c7d, 0xfb5656bc, -0xbe1d38b3, 0xf59ae9d3, 0xddc692bf, 0x3aaef998, -0x561f993f, 0x4d191a40, 0x4492df05, 0x7eb17670, -0x0770001b, 0x9b320a87, 0xbc8a559a, 0x19781e02, -0x13c995b1, 0xcb8c1e47, 0x462019e3, 0x7ee6bcc1, -0x9da2afce, 0xee1dbf76, 0x3a72ad3f, 0x711f786a, -0x0c72d639, 0xa3455dc9, 0xef155308, 0x82f3e1c9, -0xc9540414, 0xcec2cde1, 0x748005bb, 0x24197d5d, -0x4b8b7f7b, 0x3dde3129, 0x9ac952c9, 0x6f7932a7, -0xa99005e4, 0x4261280d, 0xfad329af, 0x90bcacb3, -0xe1c4a202, 0x9200d928, 0xffe55142, 0xf69b2a40, -0x227783a3, 0xe4b0c9c4, 0xeca97ce9, 0x9245597d, -0xa922db08, 0x94bff912, 0xdbebd937, 0x5c658f30, -0xb3f4a726, 0x24e2ca27, 0x9ca037d7, 0x745d3d5e, -0x3e8c437e, 0xb807af86, 0xee5fa977, 0xfe335297, -0x5c0a6707, 0x8ab801af, 0x05d02766, 0xcd0906b4, -0x791b47d3, 0xff5a0291, 0x09465b16, 0xa7fff3a1, -0xe2e6d825, 0x7f4f2b9a, 0xc1f2e668, 0xa5cfe1d6, -0x95fd7bde, 0x38681314, 0xc3c7dce1, 0x7b82e044, -0x2c883c77, 0xe8aa72be, 0xd53867d7, 0x7022fdc3, -0x3b697ccd, 0xd71618ac, 0xc87934bd, 0xe96101d1, -0x55d1976c, 0x471c8505, 0x7a36d839, 0x5d62a9ee, -0xf3c54a8a, 0xa2be15d9, 0x244087c9, 0x042c8037, -0x23224689, 0x281c5d73, 0x2139ecfc, 0xffb8bc8a, -0x834fdd11, 0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, -0x4ae2dbda, 0x86d90089, 0x6675dfce, 0x48876262, -0xcec72538, 0x11dc5c80, 0x86a730f9, 0x313565c9, -0xe3e5be11, 0x106d7cce, 0x752b8be2, 0x3d00a5bc, -0xe6f70e95, 0x44447ac8, 0x600df30c, 0x8335ac3b, -0x8816ddee, 0x700982fe, 0xee495741, 0x48c7e81c, -0xa3d55da2, 0xb0172982, 0x70ab2158, 0xd4460621, -0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, 0xa8454763, -0x70877bb6, 0x66005c97, 0xaf292c06, 0x7b843db1, -0xf343b59b, 0x25cdc7b5, 0xa41da617, 0x9e9d895e, -0xc936f475, 0x7270925a, 0x30024230, 0x8e72f53d, -0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, -0xaf377cc1, 0xbff09a78, 0x4b4e0814, 0x95a0b2c1, -0x270398de, 0x201fca94, 0x2a032a4f, 0x131542b4, -0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, -0xa3b3a991, 0x17ee60c2, 0x852c0b8d, 0x11e5853a, -0x762002a7, 0x92c5311d, 0x0d4bf7e1, 0xfffec870, -0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, 0x0111a772, -0x9808e780, 0x29c336e8, 0xe9bc05df, 0x5bedde11, -0x945565af, 0xaff808fe, 0x87e3423d, 0x4de6f98f, -0x93b4adef, 0xbf704fa4, 0x09120e91, 0xd54f3692, -0xdf8eab1e, 0xfabbf59c, 0xe74318be, 0xaab87ffc, -0x29fa791c, 0xe3915552, 0xa652cb9b, 0xa1252e74, -0xb35b723b, 0x542aa28b, 0x12fcc5b0, 0x3941f962, -0x82bcc6cc, 0x47b11974, 0xb821611f, 0x78b34250, -0xf1be5659, 0x561b9e61, 0x6f3bd501, 0x584e6f5c, -0xd54ed547, 0xacebcd21, 0x7b5ff816, 0xb64ad233, -0x9f2f330d, 0x69fb1ece, 0xac8710dd, 0x58dc6c60, -0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, -0xa733274f, 0x884d9b55, 0x42b08b63, 0xafa54a74, -0x1c7ccf64, 0x93a20191, 0xaaa3132e, 0xc69831d1, -0x54634889, 0xfbfe3efc, 0xd3cf68d4, 0x302e3117, -0xf5693131, 0xc3ce8c6c, 0x1f03cd89, 0x6243334c, -0xf16bc80f, 0xdca5f130, 0xcb2cd956, 0x4c1bb421, -0xe8de533c, 0x7f86703a, 0x29aa897e, 0xdd54acad, -0x76b2f2ae, 0x7ef82b71, 0x2e30970b, 0xba402597, -0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, -0x2363d147, 0x5327289a, 0xe89229f3, 0xd63a535c, -0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, -0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, 0x6d65db4c, -0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, -0x8488a45f, 0x8ebc2932, 0xd4767316, 0x3e8c4b8a, -0xbab7402c, 0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, -0xc88528e9, 0x4b2e4e8f, 0xdd938b86, 0x0c964f98, -0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, -0x4d40b3b3, 0xcf203155, 0x0d2fa621, 0x752d2c58, -0xb12bac12, 0x1e7e8c23, 0x94215d54, 0x9854a71c, -0x4de63c64, 0x7a012529, 0x9c171f8d, 0x9e71def7, -0x3bd17d50, 0x11f175d9, 0xec78abf3, 0x7b529eee, -0xd3a69fc3, 0x5b718676, 0x58214d29, 0xa8bd2c34, -0x41ea00ab, 0xa03f64d6, 0x4ee342b0, 0x32b1e444, -0x1c1801a4, 0xc8424702, 0x334a7e35, 0x50cf1543, -0x3b22b495, 0x88683776, 0x8e2e0154, 0x6155c033, -0x4e2fa6ac, 0x42ace700, 0x8d64f97c, 0xaf9ced17, -0xb2a5cb92, 0xa558582d, 0x88705de7, 0x9e528d59, -0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, -0x10462123, 0x30080f7d, 0xb346cd81, 0x0049c396, -/* 2991-m406fbB9.inc */ -0x00000001, 0x000000b9, 0x05112009, 0x000006fb, -0x70fed5b1, 0x00000001, 0x00000040, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x000000b9, -0x0000003f, 0x2a000000, 0x20090510, 0x00000341, -0x00000001, 0x000006fb, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x15341951, 0xd9f92c58, 0xd61aff76, 0xe96873ee, -0xdec6dd45, 0x3dfa2e4e, 0x61661b88, 0xcf5c5841, -0x58d10d9f, 0xb7f2421d, 0xe4d5fcf1, 0x02889a15, -0xad9bed07, 0xa32ab3e6, 0x3491afcc, 0x9c991c37, -0x2a1c2071, 0xf066191a, 0x3bd898e7, 0x2648d958, -0xc05f7908, 0x05864b9b, 0xbe4c1eee, 0x1e6c7ef4, -0x0e7a539e, 0x100b2ab3, 0x1273dceb, 0xfec8847d, -0x8f37946f, 0x634e3b5c, 0x691dbd61, 0xd89e3cb9, -0x094639d4, 0x7d972e1a, 0xd6dbd94d, 0x2001c3ec, -0x34f791f0, 0xeee0d794, 0x88b7459d, 0xc2c73aa3, -0x607a174d, 0x4f0f8304, 0x65790b35, 0x00532bfe, -0x1fd1e0cc, 0x7b91f873, 0x154ed42b, 0x7a7108e9, -0x81637c95, 0x192cb173, 0x28ccd94e, 0xb9bcc372, -0xac05171b, 0x867f47da, 0xf8e8c47d, 0x1edcdb4a, -0xd2ca6c2d, 0xe9ee9169, 0x5a6efedc, 0xb6825038, -0x09277eaa, 0x2a34e580, 0x0f794366, 0x86c99402, -0x211b98bf, 0xdf8eb0e3, 0xda11d7bd, 0xd440363e, -0xa7d49f1a, 0x16dd7395, 0x5b23c2fc, 0xab93ea3c, -0x00000011, 0x0741cbc1, 0xcb879f12, 0xb53a6cbd, -0x8d26a6ca, 0x2aca7c7a, 0x1e952ea5, 0x07da17e7, -0x52d164d9, 0x62c68a73, 0x2d489e03, 0x45a07f1b, -0x0f0cc8cf, 0x4fa8fa70, 0x2315d683, 0x33e36418, -0xdda877f3, 0x8e1bfc6c, 0x7f636e46, 0xbb114fab, -0x69c0e244, 0xf261040f, 0xeeeea4a8, 0xc88fbfac, -0x507ac028, 0x4932bf5f, 0xb40db20e, 0x8d18c03e, -0x44b1f658, 0x2f0527f9, 0xe6d65979, 0xfd881db7, -0x770be7a8, 0x459b7a4b, 0xfc00c5d2, 0x1bdee510, -0x94bf752f, 0x68a06b2c, 0x4fdf4668, 0xdd08536a, -0x19438a29, 0xdfa14148, 0x266ccbb8, 0xd7ab60f2, -0xceaf893a, 0xb00858da, 0xd204d03b, 0xea8d3784, -0x4f3a4d8b, 0x323f53e4, 0x3180af2e, 0xd06428fc, -0x932bfc3d, 0x8d701652, 0xacd6f494, 0xebd48f9e, -0x2b1248b0, 0x63f4d854, 0xbedc0412, 0x505e1f49, -0xad20cee5, 0xc95a2a56, 0x49b90a51, 0xb3de9036, -0x1f4c88df, 0xb7460c4f, 0xad3a53b4, 0x3d3e83cd, -0xde1ea2d5, 0x5d3b0237, 0xda3c8637, 0x0aeeeead, -0xae2b5959, 0x35624290, 0xbabab8d5, 0xa4899633, -0x7d6e607d, 0x410383ae, 0x10916b70, 0xb2adf0c0, -0x52d8faac, 0xe6937b79, 0xb959bc66, 0x14d8d06b, -0x0ec3c602, 0xb6c71f26, 0xbbd8c4dd, 0x63d23706, -0x6bee321d, 0xc8a1ec7d, 0x8de3941e, 0xd549d1c4, -0xe33588e8, 0x681cff2d, 0x66dddada, 0x807040e6, -0x006c83b0, 0xba10f7c8, 0x38eafe62, 0x0777e74d, -0xfa39a198, 0x05720466, 0xec377dbb, 0x23d46da7, -0x3a387dc8, 0xe005ab95, 0x5d92190b, 0xb811b9d9, -0x9b09dddc, 0x62a64be5, 0x0c9014bb, 0xcc871ef9, -0x4846edba, 0xc60305e2, 0x91b831aa, 0x8f7d5aa7, -0x6712012e, 0xbae578bd, 0xc5bb2872, 0xb635139f, -0x41444279, 0xc51f819a, 0x92fe6768, 0x96c480e6, -0x6a958394, 0xb4b7a6e5, 0x007c0429, 0x43af55b5, -0x33697de5, 0xcb6b363e, 0xf527556a, 0xd4a79f83, -0x9c628ccb, 0xef72182a, 0x8406cbce, 0x6035ff55, -0xd6325e79, 0x111ea438, 0x962b7e5c, 0xecc816e1, -0x39a8f348, 0x8f5bb065, 0xa2419dd2, 0xc036db13, -0x5360daa6, 0x82d2ffb8, 0x15681502, 0x6d5497d6, -0xe9028ce5, 0x2e05c16a, 0xee8711ae, 0xac5b11e4, -0xabba0581, 0x1ef11c35, 0x54ecf615, 0xcf45b599, -0xd8ee7594, 0xecda2c12, 0xa6b2b120, 0x32edc139, -0x7734c724, 0xbb88978b, 0x12092d6b, 0x133fb4f4, -0xa6fa233d, 0xa059395e, 0xb86920df, 0x60b25bff, -0x1fe831ef, 0x2b5cb3aa, 0x27ef4afe, 0x02f3ad21, -0xea597773, 0x2caaf33c, 0x03b30480, 0x7d8e32e5, -0xad9a917e, 0x1bd0695c, 0x68d8ca07, 0xeef84400, -0x928ff8b4, 0xecea6a3c, 0x9bbedbd8, 0x5c2654bf, -0x2d1644d5, 0x961ddc1e, 0xcb216e0c, 0x55fcff3b, -0x6054f145, 0xad2d4159, 0xdcbe8ed7, 0x3b2e7495, -0x7a33fdb5, 0xa92fdfde, 0x65ad1aa7, 0xf6866ab0, -0x53388681, 0x0a369d17, 0xf087441f, 0x44007109, -0xd1d8b88d, 0xdc94549b, 0xa11f14d2, 0x72864a34, -0xd7f71dd9, 0x6f948c77, 0xd3e89fc0, 0x11b097a8, -0xfd2cd3fc, 0x774f951d, 0xe1170076, 0x2bde8936, -0xa3ea656e, 0xabbe230e, 0x2fe6e1d2, 0x53b331e2, -0x7b392823, 0x48c2aa80, 0xb7824981, 0x275bac51, -0xd3b3eb48, 0xa3541a00, 0x4375b1fe, 0x086302fb, -0xd744a440, 0x0323a890, 0xcebc28fc, 0x9921427c, -0x7a4b5465, 0xf4db5f26, 0x6461f88c, 0x2dbe6ea3, -0xeb6dd03c, 0x8257fcce, 0xf44dadd6, 0x7d367355, -0xda56024d, 0x750430f5, 0x5e4151d9, 0xd90a0db6, -0xdc29eff5, 0x6acb146c, 0x97ef9139, 0x4992e11e, -0x87833d75, 0x897f9beb, 0x33aa151c, 0x28a717fa, -0x5c5bb59f, 0x45617198, 0xfc791809, 0xef17a7b2, -0x10931956, 0xdd697c3a, 0xd8a2f728, 0xd4171ff8, -0xd507ad63, 0x40c2a2b8, 0x519fe54e, 0x6ddbf5e2, -0x215f916e, 0x99694eca, 0xeb87cf67, 0x69691e42, -0x76d17fa0, 0x0edb5d25, 0x82303164, 0xa6ff4797, -0x8a19ce37, 0x71005b4d, 0x41930843, 0x0251a3cc, -0x594886d3, 0xe2e463e0, 0x812ab47f, 0x477b2ba6, -0x17c544a2, 0x802b8757, 0x1692cc60, 0xb86bf34f, -0x1f8a5fc2, 0x0693dda6, 0x5da932c7, 0xfd216376, -0x25002074, 0xad6987f9, 0x93bde120, 0x2ae45842, -0x092941c2, 0x0bc4878d, 0x30507588, 0xe9351bb4, -0x81dda9a2, 0x6b89e825, 0x948482ef, 0xaeb22085, -0xace5a27e, 0xa20c3f4a, 0xd768a0da, 0x919d2d26, -0xded8effd, 0x01812972, 0x9ba923be, 0xb69023a5, -0xe7defcfe, 0x865e123e, 0x02107238, 0x92c688cf, -0x30b0a462, 0xb56e62e5, 0x009e60fb, 0x02db37ca, -0x19a5c9d0, 0x9b879be1, 0x16ec478f, 0xa983dd56, -0x2776b4bd, 0xb858a7c4, 0xdf340c19, 0x137d7e01, -0x4467564d, 0x855bcac8, 0x9cf1cd0e, 0x54a19437, -0x2e4ed636, 0x7b693cfa, 0xddba25a3, 0xef65d915, -0xaccd377f, 0xcdc2f092, 0x74704385, 0xda63baf4, -0x1ac4bc8a, 0xb4ea4309, 0xa73ad61f, 0x6293ce83, -0xdde1e829, 0xf88514aa, 0xcc488bcc, 0x6e4c9d36, -0x78b7e22e, 0x5a7d29e2, 0x42f40246, 0xdf4a9afb, -0x82ca32e0, 0xc7118b4e, 0x25165db0, 0x7770aecf, -0xdf7582f0, 0x35b55887, 0x33a47c37, 0x08c158f6, -0x7a21b06c, 0xcb6a9bbb, 0xdabcfc6f, 0x486b55b8, -0x6187d764, 0xe5c70327, 0x492a7da7, 0x24264c3e, -0x8e5c09d7, 0x3836c445, 0x9fa2d9cb, 0x6bc2b196, -0x1ef155ed, 0xb949f5e8, 0x00846e44, 0x2b79a60a, -0x9e40d440, 0xe8b97836, 0x90a14cef, 0x786cae97, -0xe39447a6, 0xccf6d399, 0x0accbac1, 0x54250900, -0xc0351c81, 0x00b88195, 0x5beb4553, 0x682e6920, -0x9379d47f, 0x69cd76f7, 0x097b55db, 0xa9ead305, -0xbcbf9b4e, 0x8d627c2a, 0x380a2367, 0x14790660, -0x9c95ebed, 0x76e551eb, 0x645370f3, 0x497634cf, -0xeffa7029, 0xf66aa141, 0xfe718fc6, 0x094c6914, -0xbd00207c, 0x77e3154e, 0xabc1749e, 0xb8c40c07, -0xaac4f806, 0x89d5f6eb, 0x2d89377c, 0x65caeecc, -0x1c21568c, 0x901ddb9d, 0x915df7d7, 0x4f9cb664, -0xf62c432c, 0xeeecadaf, 0x0ccb4f75, 0x14186099, -0x68245f8f, 0xd981ff3b, 0x722de32c, 0x2b55e9ef, -0xb918ac26, 0x94fdb9bc, 0x02b7ad08, 0x7592dd6d, -0x470f9624, 0x9d403aeb, 0x5e7b4f3d, 0xb5e11056, -0xa97be649, 0xe9826083, 0xeec24fba, 0xe731ac9b, -0x5b339d05, 0x97af9713, 0x86390c44, 0xed541028, -0xeaf9969b, 0x3c72446f, 0x0b654ab2, 0x281b99a0, -0xa31e8b79, 0x86175d4a, 0x96fa99f3, 0xabd90de1, -0x642bc82c, 0xdcc81442, 0x16719e3c, 0x0cc60e15, -0xc276faaf, 0x9d0e7759, 0xe8594cd3, 0xbfa376e0, -0x4daabe5f, 0xcbe3009e, 0xd1812e8c, 0x744b1fc0, -0xcf3728a2, 0x34442fb9, 0x1c28619a, 0x35844d65, -0x115306a6, 0xa3c936d2, 0xf781af3e, 0xef7bb760, -0x0264321d, 0xf52bb605, 0x3a83684d, 0xdd21a5ff, -0x777115f2, 0x69b8e872, 0x64517548, 0x70267f4f, -0xbe3b1dcd, 0x5a2bc602, 0x222c7241, 0x424864ae, -0xa735c475, 0xcc44d6f0, 0x27d8d5db, 0x67bc23f8, -0x3391d751, 0x197aa11b, 0xf16a2a9c, 0xe4d58566, -0x9dae5211, 0x1601c94b, 0x491bd296, 0x48dac3f6, -0x8c6ddb0c, 0x734bc4ed, 0x83d4015c, 0x29ff784b, -0x3707b6dc, 0x6c14e801, 0xc76aa725, 0x70740fc1, -0x6aba6f3e, 0xf122dfd2, 0xffddda9d, 0x516c60ff, -0x396bf3b6, 0x2d3406b4, 0x4355cfb9, 0x126d6dbf, -0xd0d55fcb, 0x6f23a648, 0xe2f286dc, 0x8af42ef8, -0x497f9446, 0x7285afdf, 0x3ff58008, 0x583df7d2, -0x3aa49b76, 0x9281e837, 0x6196b8d5, 0x5ee4428a, -0xf4f92c37, 0x6c6376d2, 0x6afb2760, 0x3f355e4a, -0x1ea450bb, 0x5e9da7c6, 0x2b4b1e72, 0x74d5e29e, -0x07de0aea, 0x77544e2c, 0x66c19ac3, 0xbe86aaa4, -0xe5233e14, 0x7d4e763e, 0x31ca0aef, 0x0527e563, -0x149b4d2a, 0x5f5ad61f, 0x65f1161b, 0x86c7633b, -0x2877e065, 0xf5592a41, 0x60e67df5, 0x555aafdd, -0xe3caffab, 0x501e6b00, 0x11ac37c4, 0xf84c8688, -0xbad031ee, 0x6c10e5f9, 0xc7087e4b, 0x86d0bcf2, -0xdcec3d4a, 0x999fb6a6, 0x7de512a3, 0x25a4304b, -0x775003fe, 0xc3da9a99, 0xdb02be9c, 0x8c8bae98, -0xd95e979d, 0x6094a6f2, 0xf69c4d09, 0x51fa8ab0, -0x9e31adf5, 0xed2c1ddf, 0x0bdc379d, 0xe0c24b81, -0x021511d9, 0x6aab3cd8, 0xbdb35278, 0x5e253639, -0xdc51e798, 0xb7969a75, 0xb448b42a, 0x4db2c7bd, -0x92ab4fd1, 0x99a0c92c, 0x5b59394e, 0x5e06cd33, -0x76d0636b, 0x01c826fb, 0x66d62ad4, 0x2177e49d, -0xbfdf80c4, 0x0687e341, 0x2cb66974, 0x0765697e, -0x33a9d5c8, 0x790deacd, 0xb528b72a, 0xad4f0332, -0x9efb2065, 0xa1621eda, 0x6da51c10, 0x891eb234, -0x66015c9d, 0x8551be17, 0x34ddbe4a, 0xafc5de23, -0x9ee441d8, 0x92153585, 0xd4ee376d, 0x7f267079, -0xdffe357f, 0x0e0cd672, 0x8d914a79, 0x55c6242b, -0xba984937, 0x6d4e5c6e, 0xdbbf9de8, 0x7b07ffb1, -0x4c60f396, 0x81780d39, 0x1158e09f, 0xa7b04aa5, -0x29e4e907, 0x321756e8, 0x938df05f, 0x3d2e2a2f, -0xa0218157, 0x3b43bb2b, 0x90aed14c, 0x99e51a0f, -0x94ed8b33, 0x230c8dc4, 0x49a1aaca, 0x38552316, -0xd2b4d683, 0x402572f2, 0x6b35d2ab, 0x8f54d64e, -0xbf6713fd, 0xb1baab41, 0xea513b9d, 0xee1fabdb, -0x96965270, 0xb9c73510, 0x307504f6, 0x66e6efb6, -0xe5edf87e, 0x0dfc0dda, 0xce9b9f4b, 0xc495c0dc, -0x8eb4ae2e, 0x15d4ffaa, 0x3f72c117, 0x9066433b, -0x1e326a9a, 0x87e472b4, 0xe8e9924e, 0x2d34ddd6, -0x9f045dc5, 0x4e517bf9, 0xd4215701, 0x997945f2, -0xda577384, 0xc26b9a43, 0x72cc0d2c, 0x1a6f0feb, -0xb0deaa5f, 0x085e3c1c, 0xe84cd89d, 0x0c0b72ea, -0xb6ba866b, 0x5495bf3c, 0x322cead1, 0xc15fa497, -0x90813acd, 0xabdc90af, 0x25f8bca2, 0xef81a57d, -0xa3f95491, 0x257d3c3d, 0x2ac7aa7b, 0xd713ee46, -0x11a2cb99, 0x516713f4, 0x3c2e6d1f, 0x8dfc69e6, -0xb2aa11c3, 0x4735befc, 0xccc1c2e9, 0xedd47dc8, -0xfea0a020, 0x7477af3e, 0x59c5a8c3, 0x22546f44, -0xfed2ffc9, 0x3b1dc4f3, 0x6d4fd900, 0x0df8a070, -0x1bdbd385, 0x1b028b64, 0xd2c7b639, 0xaf26374b, -0x48a6a1bf, 0x4f7896de, 0x0356256a, 0xb0bf4df2, -0x3d0f3382, 0x28f1a73f, 0xadf4ed6b, 0xced36065, -0x1c807f0b, 0xcd33028c, 0x62da94be, 0x79a2b539, -0x3b81dc8b, 0xda9094c2, 0xdf52d610, 0x47d10d38, -0xed9cd5c0, 0x482e26a0, 0x1459e4f0, 0x6cf0b6cb, -0x4e29d1ef, 0xe67e1cb9, 0xd2ddca3f, 0x6e67ef3d, -0x299c296c, 0x1e39f62d, 0xe77ee72f, 0xfc3c6f35, -0x1317aa16, 0x5b9b266f, 0x292eca31, 0x39a8d234, -0xd667205f, 0x4a2d3bf6, 0x70ed41af, 0x4e5d9985, -0xa7ed1e30, 0x4a5ef783, 0xa9b51db1, 0x6fa70d0f, -0xe7414e10, 0xc310129c, 0x2a486151, 0x2a0c9bee, -0xa45f38f7, 0x0be89a12, 0xcb4ba82c, 0xb80cc7ee, -0xb59b6377, 0x89a46c16, 0x8c6a2053, 0x55d4ac40, -0x8b0103b8, 0xee2b7231, 0x2a8bd3b6, 0x567f5aa9, -0x118de9bd, 0x23dd7c43, 0x76b854f4, 0xdc870cc7, -0x475066e2, 0x98643269, 0x003da392, 0x7fcb79c0, -0x6a19745f, 0x4cb11f54, 0x7550a953, 0x9e00fd82, -0x7ba3d396, 0x70fbddb6, 0xb0086afc, 0x8c630c63, -0x8c7a72dc, 0xab309532, 0x12d57a02, 0xfc45f3e5, -0x26123a10, 0x25ddff38, 0x1135398d, 0x239017fc, -0xaf185ed4, 0x71d242a1, 0x12c502e9, 0x24bab537, -0x9c01afdb, 0x34987dd1, 0x5d30cb55, 0x0da06f96, -0x713b12e0, 0xecdd0606, 0x4089a6c9, 0xde346dca, -0x7dce2041, 0x8ce9be80, 0xa9bbe5fe, 0x0a5207c0, -0x20ba0dd1, 0x7d3d4cfe, 0x8bf88a8a, 0xc1e6e73d, -0x37ae952a, 0x74045543, 0xb77aef47, 0x7e889eb6, -0x3a74c9a7, 0xacc58f0e, 0x548a9eaf, 0xe198514e, -0x8f0d69df, 0x615c18c2, 0x1efbe64f, 0x919d94b6, -0xe7d16ae8, 0x733404df, 0xb0d2e3f1, 0x9bc52fda, -0x2b9b5131, 0x7d5fd99f, 0x916d49fb, 0x0bcd42a6, -0x674f1d18, 0x46df8419, 0x438cce94, 0x8e327aba, -0x96f9e53b, 0x0b648858, 0x5b3cb404, 0xf5a9bfb1, -0xabdcfec8, 0xb6d91462, 0x9df9b0b1, 0x45325bd8, -0x6267c960, 0xacac4260, 0xbe79add3, 0xbfb52703, -0x710a56c1, 0xe1a186b6, 0x2f0c8089, 0x87325dce, -0x5f6294f2, 0x7bfb3154, 0x2f980339, 0xfdad67e5, -0xda83b599, 0x3825e4bf, 0x0725c08b, 0x42136832, -0x3fe97615, 0x5d619d4c, 0xa7372fa0, 0x242aeed9, -0x23ab6f72, 0xccd9abba, 0x75a07704, 0x18be55c4, -0xe6a1efb2, 0x8fa154f3, 0x065e7822, 0xf1aef4f2, -0x41d63927, 0x595f940b, 0xa72c1a4f, 0xb28883a1, -0x8a31a6d6, 0xe576b453, 0x2cffe544, 0x49ac5cdc, -0x0f6f18c1, 0xa36344b3, 0x6a931225, 0x5a129bc3, -0x50da2193, 0x676ef4c9, 0x7703ad95, 0x3819c775, -0x82f2c375, 0x01d5e074, 0x2cec57c5, 0x11346e2f, -0xc4478508, 0xe887d515, 0x004dc5b6, 0x41f2bf05, -0x48bb3a8c, 0x94cc6e3f, 0xa1779e34, 0x04834e8f, -0xd892fabe, 0x49885984, 0xc50f2d1a, 0x08718f16, -0x131a7c82, 0x7220ce58, 0xbea4d3a6, 0xf723d2e4, -0x7a005f10, 0x7433c300, 0x11e0d9f1, 0x8a0a033f, -0x9b7c85c2, 0x0de86135, 0x0db57b88, 0x2f45e3c6, -0x7e5bf322, 0x35e01ea0, 0xfa6e5e49, 0x8b6d10d1, -0x48991d44, 0x4d8faf15, 0x80e31bb6, 0x8a2a499f, -0x246129fa, 0x75309f90, 0xb4848ea9, 0x90db1871, -0x1e121457, 0x8cf5386a, 0xb12e296f, 0x1210062b, -0x3508597f, 0x72f53cd3, 0x8641d284, 0x3d019297, -0xfbf12ccf, 0xd616e0ba, 0xcf44c3ac, 0x77b8c351, -/* 1468-m1df3417.inc */ -0x00000001, 0x00000017, 0x04212005, 0x00000f34, -0x2cbd6146, 0x00000001, 0x0000001d, 0x00001bd0, -0x00001c00, 0x00000000, 0x00000000, 0x00000000, -0x9fbf327a, 0x2b41b451, 0x9faf9c59, 0x6b62b8e4, -0x28a4bf1b, 0x68a90200, 0x76d16a17, 0xb90dfc19, -0x3ca53521, 0xa04666fc, 0x045ad035, 0x26fb2e1b, -0xa4fb1229, 0x07e4f3e8, 0xc94461ea, 0x7c1a3eab, -0x7a43994c, 0xc7bb8bc4, 0x7e35699a, 0xf76ff2a0, -0x3113ad2a, 0xdf89abbb, 0xa846dac9, 0x8878dd67, -0x4f2fbf68, 0x8a2629f3, 0x19cdde5c, 0x33f5d3ac, -0x89cc0510, 0x6939b57c, 0x1d0ce21f, 0xcbd8c975, -0x8399bc7a, 0x3340bc9c, 0x2ae5b33c, 0x483f6d55, -0xa5c23575, 0x0cd85b6e, 0xc46e5a9c, 0xb31204bc, -0xcb5a96a5, 0x6a24d1fa, 0xc1b09daf, 0x65976bd8, -0x627382c5, 0x31d99884, 0xcd760418, 0xab85819f, -0xcd4e400a, 0xe754b7db, 0xbfdca0b2, 0x6fb4bace, -0x7cbaafdc, 0xdedbe28c, 0x0ff4856b, 0xd2007e27, -0x34fdfd0c, 0x7d4b8aed, 0xc725c407, 0x559f7b96, -0xcd9944ec, 0x04d189a0, 0x05f53e1e, 0x4d17446c, -0x0086f6ce, 0xa59a413e, 0x0699a7a9, 0xcb8771ea, -0x8dc80f22, 0x7d755b17, 0x124d5c52, 0xf30007ef, -0xbdbcf840, 0xc33d1110, 0xa921cc9d, 0x3bc9349a, -0x482c8e1f, 0x447545a2, 0xa83e956f, 0x7ec240ae, -0xb0232daf, 0x1eb4493f, 0x74fae03a, 0x2255247a, -0x14988d81, 0xcf53b699, 0xbcdb4ffc, 0xc96b0d2e, -0x77ab6ea5, 0xc4248a9c, 0x171b4742, 0x321b4876, -0x6e075f51, 0xd09770b6, 0x44f74bce, 0x1b3237c0, -0x81abc949, 0x8e7ba040, 0x3f452974, 0xc7a1e70e, -0x2c8a7ea3, 0x75de2024, 0x21530e34, 0x95cd09eb, -0x6e7e331d, 0x8490c8a8, 0x3a3e2583, 0xeae1701f, -0x3a3ae0c1, 0xb9c43ac9, 0x0847b7b3, 0x2240cbca, -0x66e7dde3, 0xbd4b056e, 0xe17baf88, 0xc48cb80d, -0xcaadad18, 0x9f632517, 0xa6851399, 0x482f1e16, -0xbdb7390e, 0xb866ab63, 0x3a6eeda9, 0x9b39fddd, -0x9308b31b, 0x6a77de17, 0x1511896e, 0xbb4432ca, -0x64c81fad, 0x5031f2f6, 0x48e5dc67, 0x925b469d, -0xf73f3940, 0xa06e860c, 0xd074345b, 0xe45d7a19, -0xf67b6e78, 0xa169f2e0, 0xb5696203, 0x8e9c54be, -0xbabad9f8, 0xdfa25abb, 0xe7b16383, 0x1377744e, -0x0c3ae192, 0xcc7e10d9, 0x4dc5dbba, 0x88660539, -0x0da822f2, 0x11ae62f4, 0xf19acd3f, 0xab62f4c1, -0x6ed9a55f, 0xec3e0236, 0x049fd614, 0xbc5c4ee9, -0x3ef5b063, 0x346ca46f, 0x51785dfc, 0x711692d0, -0xe5a0878e, 0x48163770, 0x6846a808, 0x6548dc1b, -0xe176a619, 0x6ab36fde, 0xbc8af42c, 0xc43e6ffe, -0x5bf49353, 0x1986adbc, 0x3989e6db, 0x6e0f3f71, -0x63991ff9, 0x421dbc52, 0x0a172c1d, 0xf9201b49, -0xc864df42, 0xa717211e, 0xbd7b027c, 0xc37b488a, -0x1b40159f, 0x82b56e29, 0x7045a923, 0xa9635f95, -0x6e442902, 0xd05d3946, 0x18ef6c8a, 0x53301361, -0x98093b21, 0x6987e008, 0xbd759198, 0x8335a7a3, -0xe4a07e31, 0x829b3256, 0x86d14f5d, 0x373236b0, -0xee1603a2, 0x8cab0af8, 0x5bbc822f, 0xa5f50977, -0xadf829a4, 0xc6a7a5c8, 0x4f9a770a, 0x68f5f5b9, -0x1811fc08, 0x49aaa013, 0xc40a9793, 0x45b7e720, -0x11f95952, 0xa58fc5dd, 0x4bd441a4, 0x31dff79d, -0x6d4bc050, 0xe50e6b2f, 0xb5986885, 0xe7ba87b7, -0x003f5f10, 0xb8f38176, 0xfa8298c3, 0xf1438f7b, -0xabe50c0a, 0xaebcb389, 0xba1cf4cc, 0x5f69924b, -0xcad57af2, 0x033f0a88, 0x76612fd4, 0x8b6d7e6c, -0xe505f26c, 0x63b3fcc1, 0x0ac99a9e, 0x032af319, -0x0b085c33, 0x38d40f09, 0xd79d97c6, 0xc928bfbb, -0x7a8aa8a4, 0x09a15c0b, 0xfd64b3f9, 0x79a2749b, -0x94b17267, 0x5a940a3f, 0xa808ec13, 0xd5c2fdc8, -0xd76c2cca, 0x18bb8f2f, 0xec3cbe35, 0x0149c406, -0xeec40085, 0xa4174252, 0x24d308e1, 0x7a07c657, -0x993c6a29, 0xc4877c78, 0x20f7588b, 0x8ab0ce57, -0x44958e90, 0x0ccfa678, 0x177749a3, 0x9925fca5, -0x98a51a3e, 0x51f7e7df, 0x2efcb727, 0x34fdc710, -0x1df07336, 0xa5403783, 0x68a088f8, 0x7ccbde02, -0x0fad4485, 0xe644d152, 0x81ac8f42, 0x16b72c24, -0xb02b9675, 0x23a8c950, 0x951e2abe, 0xb1eb3c0e, -0x0ebdcedd, 0x72cee426, 0xb3697ccb, 0x408e1ca6, -0x10e66a49, 0x425d427f, 0xae915e79, 0xc36737b2, -0xe4ca6c88, 0x25513a8f, 0x1e11aabd, 0xcb787d7d, -0x3fbe9a7e, 0xca7d6195, 0xf10e27a5, 0xd263b030, -0xdf8e8f6e, 0xa2ed8fa9, 0x2d0586e8, 0xe0e9ebe8, -0xe4487a72, 0xb541b1ab, 0x9b6f7dbd, 0xe78208b6, -0xb34470f0, 0x43462a39, 0xa3612161, 0x39b82e49, -0xbfff3022, 0x05a7b499, 0xb4039476, 0x5ed1c3db, -0x29bc6edd, 0x07815f50, 0x94debedd, 0x5f4d27a2, -0x0b192aff, 0x34d6381f, 0xefa1db27, 0x1f5e12f8, -0x3486ff01, 0xe8855253, 0x928a0aca, 0x672ac1b4, -0xb89e4a1b, 0x27f4c297, 0x5af71582, 0x5011f9d1, -0x6272394d, 0xcc0a8a11, 0xc05f332a, 0x78b6c2af, -0xefb583df, 0x6b682e78, 0x4be2b005, 0x78d67f2c, -0xf8fa6493, 0x5980ef20, 0x242a33a2, 0xd9670ba1, -0xc95cc1b6, 0x42a88ba2, 0x2a59f02d, 0x16bef734, -0x883967d3, 0xa23c3ac3, 0xd24d0aec, 0xc97dc00f, -0x4a348e69, 0x3727a38d, 0xe6bcc557, 0xc0100195, -0xab209095, 0x95906360, 0x8ba59b4d, 0x03658604, -0x761e0b60, 0x40de9b58, 0x75a7ac7e, 0x5d64f18a, -0x8d15ace2, 0x3451a20e, 0xc84fa43b, 0xd80206db, -0xd6a9abbe, 0x2f213d06, 0x43b503e4, 0xd43272e8, -0x2551c40d, 0x5eca9263, 0xb5164cc0, 0x0a8b6849, -0x2be92588, 0xb324cf51, 0x9ac0bf91, 0xae2d3af1, -0xdeccb499, 0x867a6379, 0x5a9dd70a, 0x86e2ff85, -0xa394c8b9, 0xf1733ddc, 0xd627dcd2, 0xcce1c8cc, -0xe4ed2ac3, 0x0c9e942b, 0xce847fb7, 0x86410f94, -0xe4dea9ee, 0xbb6c0455, 0x3bf1323e, 0x9ef37011, -0x66482b56, 0x7e426c99, 0xfa834c08, 0x396d97dc, -0x39fa76e1, 0xc5dc6086, 0x643eec7c, 0x505d6257, -0xb88cb057, 0xed8e1582, 0xebc58cc6, 0x12bc0eec, -0x5d4c6dce, 0xe15e513e, 0x1b615938, 0x03f37a1e, -0xb2d47c1a, 0xe4898548, 0xd9db0f73, 0x3116ed30, -0xf37a985c, 0x984f292f, 0xb95c3bb8, 0x5983471b, -0xd32606a9, 0xd262306c, 0x27022229, 0x835a2cf1, -0x32412a68, 0xe34f9512, 0x87b3fe20, 0x8921143c, -0xffc72ac2, 0xe68110a3, 0x8f03c326, 0x94204988, -0x4dec33c6, 0xdc32ba80, 0x9b6c0fdd, 0x1dd023bc, -0x41f6a622, 0xe5148ca4, 0xcad8f563, 0xb60a0491, -0x3bb8ac3a, 0x5319fd1f, 0x150fd957, 0x2b0e5084, -0x459f73db, 0xb8565124, 0x3c12d214, 0x37163859, -0xdfa7bf0b, 0x21e500ec, 0x89e7a004, 0x9f97ce69, -0xe6c3d033, 0xbf7f818d, 0x2285f31c, 0x474d96c6, -0x2f377d76, 0x73ad1ee6, 0x1f7247ce, 0x95adc53a, -0x4c62d951, 0xfe732dc0, 0xef0fbbe3, 0x51bf9d4f, -0x3254179d, 0x394f146c, 0x62cc6315, 0xf00bc3be, -0xcecad864, 0xbfb9b53e, 0x7a65501e, 0xe427e75b, -0xeabe0e6a, 0x25d1e01f, 0x1788e58b, 0x39c913bf, -0xf37b1195, 0x7c4f1ce6, 0x1e5768b0, 0xbb8a8561, -0x78c498a2, 0xff89a1d2, 0x3afa4408, 0xabfb7f98, -0xa03a3dc9, 0xabcfaeab, 0x7bbc277c, 0x11cbbd49, -0x369e55f1, 0x472dac75, 0x3b52f318, 0xef5d8a5b, -0x5048b3bf, 0xca6f5686, 0xacdbb5f4, 0x27f8d0ef, -0x0bd0bac1, 0xbdacf44f, 0x692e1c21, 0x003ed188, -0x906cb52e, 0xbb08bb91, 0xca89a92d, 0x51794247, -0x68b875d0, 0x064699bc, 0x8fe578fe, 0x9eccb2c1, -0x94f4c3e9, 0x33cbfe22, 0x56a6b1c2, 0x9edc591a, -0x1b6adf0d, 0x8ef4e2ab, 0x627ab711, 0x1f85c4e3, -0x4353abb4, 0xbcf76e01, 0x0a6c7528, 0x9483a0d6, -0xf3da4fc9, 0x42187754, 0x68de6664, 0xbc0ff8d5, -0xd026c5dc, 0x6eada9c2, 0xe7e3e431, 0x6e22fc23, -0x61719184, 0x416554a7, 0x8e918580, 0xa7b1829a, -0xab055dad, 0x8fd67f87, 0x8551783b, 0xa9e8a4e6, -0x420e4767, 0x8a282bdb, 0x627c7474, 0x94391f49, -0x0587364f, 0x0e05dee5, 0x3c200cfa, 0x37ad7941, -0x9e064ec9, 0xa08a79f1, 0xded3e03d, 0x52ddca95, -0xe7f248f1, 0xadc21d4e, 0xe8f609bb, 0xa7d00e2f, -0xcee52be6, 0xce59a13c, 0x77a22385, 0xe907de8f, -0xdd1becd1, 0x4f62b855, 0xf809431b, 0x9051abe1, -0x1b97f1c1, 0x3956b8a1, 0x9b67349b, 0xe7172623, -0x0c587452, 0xce3e5760, 0x02528d3b, 0x4a3e386a, -0xa23b7545, 0xa5c8d0c1, 0x7dbc3772, 0x865ef72b, -0xa1636170, 0x59086e5d, 0x5118d371, 0xc5a2e317, -0x5495a3b7, 0x328ab06f, 0xbd5173bb, 0x49bf468a, -0xbe3a6251, 0xa1f2400a, 0xf07cddbe, 0x3db625f5, -0xa506cc25, 0x195dae27, 0x701937de, 0x21844e06, -0x8d58481c, 0xf73c095a, 0x3b9be321, 0x05e12f42, -0x55739f6f, 0x21df4a8f, 0x5d5000e6, 0xd8fefc8d, -0x88ca172b, 0x620a50d8, 0x1e215ff2, 0x0fd1f2a9, -0x84312202, 0xf721e46f, 0x9e5614ef, 0x4cc9bdd6, -0x345a9f13, 0xcb1b458f, 0x8ffc6a39, 0x36d7cc81, -0x821c0b49, 0xdfb4a6d4, 0xcf060d96, 0xe12f48b2, -0xdda3960f, 0x6923305d, 0xa44e3d32, 0x3b050c55, -0x53fc8cf7, 0x074c49f1, 0x8fc60933, 0x68a81bea, -0x938a8e74, 0x1db192f3, 0xb8c90a66, 0x9010ba15, -0x07b0a534, 0x08f1ac18, 0x2e1ad868, 0xa030c62a, -0x4a87b72e, 0x2bbb71b1, 0xd9511feb, 0xe69e471e, -0x643dcc65, 0xaae14581, 0xbb525c1f, 0xfb2c9a36, -0x6b981977, 0xa90c1274, 0xbad2a083, 0xe0623243, -0xb64e5036, 0xf02da84c, 0xa6036fa9, 0x4a7937f1, -0x0628b829, 0x14c65dfe, 0x66f0f18a, 0x3d8450c9, -0xdc46f5a9, 0x2b760960, 0x9bd27d34, 0xf1a4e1a0, -0x2fce1f0e, 0xa6ff5ae7, 0x36ca01bf, 0xb2040647, -0x206ce76a, 0x96e6011b, 0x3c887208, 0x310b07be, -0xb746778c, 0x4b87cad7, 0x54a237d1, 0x066b00cb, -0x28538149, 0x3940fdec, 0x2543dd19, 0x0d61da95, -0x9f0ec2a8, 0x54732ac2, 0x1053c31c, 0x56c337c3, -0xe6d95ed6, 0x01e73c64, 0xa4d59927, 0x30a2e3f7, -0xe59ba358, 0xa92ab193, 0x85241ff4, 0x638a128e, -0xdf4eab89, 0x9e65421e, 0x28084665, 0x5f832ff0, -0xfe73bbca, 0xeb5751a2, 0x7e3a974a, 0x5a687c0e, -0x109846bd, 0xbb3b0fc2, 0xdfbb1d09, 0xc4163632, -0x0ae7d72c, 0xd743ccdd, 0x3d519ca5, 0xfc0fbc3f, -0x96b03f38, 0x7225eed6, 0x30d46019, 0xae6771be, -0xf3b67aca, 0xfd44fc17, 0x6692ee88, 0xf6e42543, -0x98a0c348, 0x0d80c75c, 0x52dffcc2, 0x9fc3e94c, -0x427e10dc, 0x718ce01c, 0x73c84733, 0x04486fab, -0x03bab408, 0x5f71e7ee, 0xa07afa0a, 0xb2a69b10, -0x1bd1cf67, 0xda5db20a, 0xebbd96a2, 0x3cd78b00, -0x62c8b708, 0xbef8048e, 0xc7ca75ad, 0x8bfeeb77, -0x331dfad9, 0x2ff4ad59, 0x95b01d87, 0x18409706, -0xb55e8dba, 0x12132190, 0x8e0700d2, 0xba0565df, -0xd2dddc9c, 0x2766fdaa, 0xcd18d6fa, 0x0741e268, -0xd7fb16a1, 0xe33101c5, 0x439a2d80, 0x3b6224bf, -0xc6a2fc64, 0xbcf4db84, 0x645332b2, 0x79df445e, -0x989de295, 0xa08eba68, 0x413e59d9, 0x63408606, -0xa4eeb5c0, 0xb7f4445c, 0x16ca78c5, 0xc60f1ee0, -0x997bfad1, 0x17837123, 0xb51d95e0, 0x95e64fb5, -0x8fb882cb, 0x2bbd1f6c, 0x366c6e1a, 0xdc6dbe79, -0x42f570b7, 0xe676de45, 0xf7e2bb40, 0xba4bbf81, -0xd3e23715, 0x71bee5c6, 0x5a309f9a, 0x90a51750, -0x1019b74f, 0xc14c3b92, 0xda315332, 0xe73ba69f, -0xe22e3c09, 0x6be8c884, 0x5b28f280, 0x617dd51a, -0x0d5fe9ae, 0x378b4af5, 0x59176371, 0x319e1b1d, -0x614b5f56, 0xba04e514, 0xf3185a28, 0x7db83997, -0x788058ff, 0x8ea09117, 0xeb391588, 0x3930cd79, -0x4079de1d, 0x7335d3e4, 0x40b92e55, 0xd81bfe8c, -0x8d2dfff8, 0xb20d1b95, 0x54fdd754, 0xccc79905, -0xb61264f3, 0xd3b56698, 0x292bbff0, 0x73f84171, -0x8e21d0c0, 0xd17a647f, 0x3ac23c3e, 0x5f087a6d, -0xe2c7ad20, 0x78da8742, 0x357d9ced, 0xfda05f27, -0x05790cb5, 0x0c3fa95d, 0x0f4b67ab, 0x939fc831, -0x555768d7, 0xefa7389d, 0xb2a5c860, 0x06fde838, -0x6dda0cc5, 0xcf642c58, 0xdac9a0c2, 0x5f78ce35, -0xd8c90c33, 0xb552d66e, 0x2b6d8254, 0xe5d46f62, -0xf530a048, 0xa890cd85, 0x0883b0f3, 0xcbbed658, -0xb7162101, 0x1388d3e7, 0xffd23960, 0xb2d05515, -0x1494a0f0, 0x70ff6dcc, 0x435f7ac7, 0x6452171b, -0x4f44b408, 0xe789e7c2, 0x6b1d6ef7, 0x290a0422, -0x17a804c2, 0x0f7eaa93, 0x45141c7b, 0x7dad39b7, -0xcfa376fe, 0x9f014db9, 0x4def7f13, 0xf05ed84d, -0xe68d6581, 0x87f57999, 0xa8dacc2d, 0x0a4d0884, -0x1cd652bf, 0x6666af57, 0xe11d3fa7, 0x7ca677c9, -0x4a406958, 0xfe4d9538, 0xc81f3bd1, 0xb8c5480f, -0x8018080e, 0xd98e1260, 0x0930bbbf, 0x7a3e1963, -0xfcfdbbab, 0xd5543f96, 0xa7412547, 0xc4f4e480, -0xe8833b7b, 0xb27f7407, 0x9ee703fa, 0x6cdda5fa, -0xf06a77e9, 0xc6fa88d2, 0xbed346f2, 0x82a0caeb, -0x69dfe65e, 0xbed71b5d, 0x34e8b801, 0xdfe35ba2, -0x0d1e9238, 0x5d21972e, 0xde0736e8, 0x238f99df, -0x5ab87993, 0x9571c1a2, 0xa1d8702a, 0x1ad317cc, -0x321feea6, 0xcb8c996b, 0x122666a1, 0xfb6c4458, -0x2ae14a6d, 0xabead237, 0x3fd75442, 0x9a766d96, -0x9ca52b16, 0xf354464e, 0xae3eb3e7, 0x389aa4d5, -0x41a7517c, 0x9d6c4d92, 0x711b1352, 0x887252e6, -0xe3509f42, 0xf1b54f84, 0x72be7fd1, 0x72237a99, -0x6b2c892c, 0x875b2b94, 0xf41c080e, 0x22092eeb, -0xad82168e, 0x3301eca8, 0x4e35d8c7, 0xc8a2273e, -0x3c0de91a, 0xba407dd1, 0xa499bb50, 0x0f110c3d, -0x73db5778, 0x3e1b9a0e, 0xcea88ecd, 0x7bfcbe0b, -0xf32142fa, 0x506c2fd1, 0xe6046028, 0xd1134c2c, -0x05e5d53d, 0xe7d1a97b, 0xb85d3858, 0x034ca401, -0x92092cbd, 0x9faf593b, 0x13d97d0a, 0x8e1eed08, -0x1782d1a7, 0x304b8b83, 0xdb0a2ccd, 0x1d753e9c, -0x56ac52f5, 0x6e2a00c2, 0xd3031671, 0x29a4fcf4, -0xee6554ed, 0x5f3364c3, 0x41e7d73d, 0x5f16e26a, -0x6fab74fc, 0x1115781e, 0x196e0126, 0x780a2f44, -0x64d7a035, 0x26a23228, 0x74c8e6b6, 0xbdae8e61, -0xd344cb25, 0xba579233, 0x0980842d, 0x05e7e7bc, -0xa77b76af, 0x31991c19, 0xedcc0b24, 0xc9e90421, -0x67a0b19e, 0x3b72ec88, 0x684a30a8, 0x5778b6e8, -0x35a53472, 0x2bd2408e, 0xabb6bfc4, 0x19688e2b, -0xe255d126, 0x40572791, 0x113dfda8, 0x897a52e8, -0xfde9c38d, 0xd1228692, 0xc70f9851, 0xf9d9d4a2, -0xc29cf646, 0x755a4cca, 0x7012d742, 0xeedd7a2f, -0x39e99f02, 0xca3518c4, 0x6c62db3c, 0xae8347d1, -0xb4a4ca4e, 0xc64a512f, 0x16fcfaaa, 0xcdde8bbc, -0x1271ba73, 0x471ec9c3, 0x3e3c087f, 0xe69344af, -0xf4810b4d, 0xa08afc1a, 0x170ed396, 0xe445eca8, -0xc44a6c42, 0x98877999, 0xc66b286c, 0x56589be4, -0x17150017, 0xe828efb8, 0x1fcba998, 0xcfa43243, -0x03af5042, 0x965f0685, 0xd9a74dd5, 0xd6a7b24f, -0x956e21b2, 0xe47d404a, 0x3f835460, 0xfb8b7f59, -0x66b0e63c, 0xea9af33c, 0xfa7dbc2c, 0xf1b2a493, -0x13ae6d5a, 0x630afed6, 0xa436c758, 0x87f8e0ba, -0x09494e7a, 0x33c84f04, 0x0d422a6e, 0x410d3f9f, -0xbb70026c, 0x2d98a96f, 0xe371c5e2, 0x0ee60c30, -0xed54db46, 0x081050a1, 0x8b0738ae, 0x5b8b5a7d, -0x3dc04f7f, 0x6d246b6c, 0x985f9f21, 0xdd0b2c2c, -0x5f21e42f, 0xb5b6f539, 0x980cc53a, 0x1e8e2249, -0x3546e403, 0xec013902, 0x560a843f, 0x2944ea5d, -0x74c0c422, 0x3ce517c7, 0x4b58a57e, 0x266442bf, -0x917ec876, 0x48feb4ce, 0xb8ac9d05, 0x838eb40e, -0xeb71e51f, 0x07ac1e72, 0x8df85d9e, 0x9d9420e0, -0x0a8caf4d, 0xb051f8bd, 0x20958e68, 0x65ca9d09, -0xab69979d, 0x9eef4746, 0xebfd4c40, 0xa5910cce, -0x94856ce5, 0xef0bd3fb, 0xdd37398e, 0xd6a0ae48, -0x3616a256, 0x3b826be9, 0x0ae2d65e, 0x747de7aa, -0x679cb2cf, 0x97b745bb, 0xa2c39fb9, 0xa370ba17, -0x6a44fd63, 0xd6e6dbaf, 0xe2b88ee2, 0x81b2ccc4, -0x3ed6f411, 0xb8c1f747, 0x1a26b61d, 0xb7bb5d8d, -0x4961a071, 0xa5b94fa7, 0x9a5db498, 0x4884c393, -0xc27ca65e, 0x5e6c85a0, 0x0284af73, 0x551de245, -0xc4248aac, 0x81a40900, 0xb582bc63, 0xaf1d91b9, -0x50d35db3, 0xdecf399c, 0x8e0138b6, 0x035ce3e9, -0xd57de4e1, 0x2cfaa915, 0x6e6b430a, 0xa23746b3, -0x9dd7a07a, 0x520d22a3, 0x57179e2b, 0xa61bb7c2, -0x4dc42f94, 0x1ad54708, 0x60f177c7, 0xcd26283c, -0x1f714776, 0x5cdb418b, 0x50ed5640, 0xe2f1338a, -0x0766d64f, 0xdf3f47d5, 0x48b35f6c, 0xeeb5bfa2, -0xdd0625e1, 0x1205cb01, 0x5459f09a, 0xdf37ef0b, -0x33efd549, 0x48022dcc, 0xe3beeec4, 0x7bb7ef93, -0x1aa865c1, 0x06298bfa, 0xe2df193c, 0xfbee059c, -0x8014cf05, 0x6ac5eeba, 0x0b374d48, 0x5c100a93, -0x37b094f9, 0xf7cac5b7, 0xd90e250c, 0xf344df92, -0xcb48416c, 0x767dc2c3, 0x137c636f, 0xe70892a7, -0x88bf9a5e, 0x33e3fa91, 0x1ba350bc, 0xd4c66de5, -0xccd785be, 0xefdd83d0, 0x985708c6, 0xd86c3fe8, -0xf48cfbcf, 0x822d6eee, 0xf1bdc5e2, 0x234b0ca7, -0x34c2a8df, 0x859e10a4, 0xa4f36c33, 0xc7ca9d2f, -0x7a33c391, 0xd6f873ad, 0x5db45802, 0x8703ecd9, -0xa241618d, 0x6ef5f30d, 0x9cac4d72, 0x9ab8ff48, -0x3b674718, 0x114649d6, 0x051a2751, 0x6e8c115b, -0x4abfa95d, 0xec794b4f, 0xc0d29913, 0xd61a3edc, -0x298298a3, 0xb8df31bc, 0x80d75b2d, 0xcb876b0a, -0xd68d9ae5, 0x0350cb1e, 0x55999dcc, 0x9612ea6c, -0x43e60e71, 0xdc765e82, 0xabea79af, 0x9eee03f3, -0x9bf69324, 0xb925c5e9, 0xe24118d2, 0x1861379e, -0x12e30e7d, 0xe6b416b5, 0xff3b80fa, 0xff42a94a, -0x50e10205, 0x54994cea, 0xf3eaf211, 0xe2fbf32f, -0x84b7ff4f, 0x916a7521, 0xa455a313, 0xe6d92df1, -0xc91d41bf, 0x114dfc74, 0x1d6999b2, 0x5c26f97a, -0xbab725e8, 0xb32a2d3c, 0x0307a40c, 0xe4271093, -0x92045936, 0x8ca2b515, 0x18d794ef, 0x47939914, -0xbf51a197, 0x91a22541, 0x1f68b311, 0xedb8eede, -0x37176b99, 0x14faedf3, 0x0d94ba34, 0x9417b5e7, -0x6f35a1f5, 0x40ebf845, 0xc573cc1c, 0xe918784d, -0x7e309151, 0x028f245b, 0xea57316a, 0x83e9fe65, -0x430ec7b7, 0x8edffd5d, 0x1b9285d6, 0x775483f5, -0xbf25de79, 0xea3e5597, 0x125e03f4, 0x1b35c0d0, -0x099c498f, 0x3f195b7c, 0xd4158c2e, 0x8afe62a7, -0x5d6885ac, 0x662e5f6f, 0x4095b7f3, 0xd6138da2, -0xd8039283, 0x29cca378, 0x6aeb8217, 0xe65c2353, -0x1a4f395e, 0xff2f8da8, 0x9884a2e5, 0xc8653607, -0x98f1cd10, 0x15a3f16c, 0xa5b504bb, 0xa69244d2, -0x30b515ff, 0x48c5fc15, 0xc79ca57f, 0xdccfb9fe, -0x67f9f819, 0x4a861cfe, 0x21e26124, 0x87078ac5, -0x174faa76, 0x821e9163, 0xacf019b6, 0x82507748, -0x32cc7372, 0xc8df14e4, 0xb4464e14, 0x09f3827d, -0x82cd1cd5, 0xa976a2f1, 0x64d8af28, 0x6bf7253e, -0xc7d83b28, 0x912f3d4a, 0x663f78c6, 0xdf414623, -0x5662a151, 0x94150dfd, 0x933823e0, 0xcfd57e46, -0x479efd9d, 0x7ab83b7b, 0x0211fd1b, 0x7fff5a38, -0xa6dd0fdf, 0x7f748fad, 0x882790ad, 0xd5a31c76, -0x40365964, 0xf9216396, 0x79fae1d5, 0x06f09d29, -0xc5d09113, 0x4731531e, 0x1e021de4, 0x35f3e2ae, -0x04417c8b, 0xd02a61a9, 0xb59eafd1, 0xcf596b80, -0xba8bb39d, 0xde20fd7d, 0xd5ca803a, 0x23e4afb4, -0xd7e150b3, 0x061a3f5e, 0x5ee4a633, 0x86f0e4cc, -0x9c4c275f, 0xbf9fff79, 0xe7ecb719, 0x50b8e55f, -0x7f1a0d9e, 0x5c5ae773, 0x34c1dd58, 0x39f756d0, -0x8a9cad37, 0x62f861b7, 0xe7ecf601, 0x9d802c76, -0x160e4b3a, 0x4c1d8c5f, 0xb632d845, 0x04db2756, -0xe1019198, 0x355ae148, 0x4e4921c0, 0x9868bada, -0x28a7bf1f, 0x8a26b181, 0x83aaf7b5, 0x07491ab3, -0xc00d9549, 0x5d6dfa4a, 0x8208a16b, 0x82e39247, -0xb0aca7b6, 0xacbd026a, 0xaac580f1, 0x0d6d3554, -0x8438be16, 0x47a774b5, 0x766ebffe, 0x5a4b46ea, -0xc3d7eaf7, 0x160b7149, 0xc3af7c90, 0x46fe9142, -0xb77b1c46, 0xdbe37777, 0xdaa9cc0b, 0x9389a49a, -0x99301a7a, 0x6a26bffc, 0xb4277408, 0x0650b2d9, -0x6eb0c00f, 0x9052ab67, 0xf5120b06, 0x28573a30, -0xf406f285, 0x89e5c29e, 0xe5cff0f6, 0x250cc621, -0x70d8a5cb, 0x8416bf7c, 0x83106b12, 0xeb3b526d, -0xf432a698, 0x36867ad0, 0x10de104a, 0xa07f3e5f, -0x3e7d3d8d, 0x86b8a759, 0xf0702b67, 0x470ab94e, -0x580bfb22, 0xc374c7b1, 0x75246adf, 0x5bd51f02, -0xc5d95b18, 0x743fb51c, 0x6aab07b3, 0xceffc70c, -0xddbe97de, 0xf6f99884, 0x0e0729e9, 0xd286ec31, -0xb0febd7c, 0x4ecfe0a5, 0x9a37d2bc, 0x1cf834dc, -0x37c33c53, 0xe7d2e3dd, 0xbfbd9d85, 0x626988c7, -0xa1213c3c, 0xdc0fb69d, 0xc2e9dd0d, 0x33f31739, -0x3deee07e, 0x87efb388, 0xa93b1d91, 0x9e50f839, -0x0dc63833, 0x783a7872, 0x8c741d4c, 0xa818de9a, -0x3d205673, 0x475cca13, 0x7fbbdb05, 0x7ecb965b, -0x7f950d80, 0x71a25912, 0x5004a2f1, 0x4179231e, -0xdf36eab1, 0xe4807629, 0xa0d07548, 0xa3e0b8d0, -0x5fcc1ccc, 0xb81b4545, 0x23ab93a9, 0x4564a9ca, -0x0f1dd8ac, 0xdc45fe55, 0x0d2e65b3, 0x955d6e7a, -0xe84cbe9f, 0x9e964088, 0x304bd3e1, 0x1cc3cfc5, -0xc55c632c, 0x5f8ef3e1, 0xd4203369, 0xca958ebc, -0xc93614bb, 0x66cb0764, 0x94214462, 0xa48d8cdb, -0xba5f4132, 0xe07cf8ec, 0xd850eeb4, 0x6baf5fe1, -0x7e5d604e, 0x6efc24c5, 0x6e6b53c7, 0xa2420aa1, -0xb2a8c5de, 0xc15dbdd6, 0x926f24e1, 0x525998cc, -0x86aa4552, 0xb5e59180, 0x841d5940, 0x491b8755, -0x31f77349, 0x29549877, 0x93bc87cb, 0xbd2f199a, -0xe0f4abfb, 0xe6b44ee8, 0xc5ddf892, 0xf59971e6, -0xa689f786, 0xb7002970, 0xdda6966e, 0x5cdca2bc, -0x9423a700, 0x4abca2f8, 0x8c013997, 0x7123371f, -0x5b91ab55, 0xc8f4c72a, 0x9ffb4cd6, 0x89cbe6f3, -0xa7dc084e, 0x983ab14d, 0x02d32d43, 0xa85d985b, -0xc20a229b, 0x11c58a2c, 0x369f3ee8, 0xff9ecce5, -0xff36c522, 0xc579cff7, 0x96711403, 0x5af1b9de, -0x5b673779, 0x41171d9a, 0x9e47fb55, 0x97e0d27a, -0x5e7914e3, 0x7bec8474, 0xa8cbc15b, 0x1c851225, -0xf35c299f, 0xcb34a523, 0x2bb0055c, 0x8250f873, -0xe1a3814f, 0x6fc60d80, 0x65500773, 0xeb32580f, -0x5c14dde0, 0x79bdd179, 0xe0865f38, 0x1c3742f4, -0x0666429e, 0xb107467d, 0x8d518cbc, 0x1f87d3ce, -0x375d54ba, 0x8b70ecbd, 0x781b798c, 0x27aafa61, -0xd27f5647, 0xf6334c28, 0x10e1006b, 0x60ae630c, -0xbfaba98c, 0x256c506c, 0x7f0fae28, 0x39a1f225, -0x550b4b2f, 0x04450602, 0xb8271ea6, 0x2f6c4168, -0x90349e62, 0xa968e792, 0xdb9bf413, 0x0f891508, -0x8ee3e00b, 0x50d18fdf, 0x97678d3e, 0xf81b9cd4, -0xdf6e787f, 0x06d2a920, 0x77bb6190, 0x813ebbc2, -0xe4183218, 0x4763265c, 0xdb1524ff, 0xdba8109f, -0x03a1a01e, 0xd76c06c7, 0xc36bafc4, 0x4a8d8ab6, -0x74f49113, 0xdc62d212, 0x92e6fd15, 0xb0946ff4, -0x9267d824, 0x6fb2bcbb, 0xe15924ee, 0xecb075a4, -0x43107e19, 0x2ad5ded7, 0xc274cb96, 0xa3950d41, -0x3a6a4a22, 0x6aabb6a3, 0xae799be7, 0xa7745a87, -0xbb35408b, 0xa5745578, 0xbe6c4ecf, 0x1be0ddcc, -0x625ebb5a, 0x889927a4, 0x2bc46ea9, 0x90bd15a8, -0x1f9eb4fc, 0xcfa6f6a0, 0x2ec1f672, 0x00ea93af, -0x369a0159, 0x359c8317, 0xae3d5e1a, 0xf3ca8b63, -0x36b0094b, 0x5a1b9ed0, 0x8b572549, 0x9bc8d7c6, -0x1fa667b7, 0x90694630, 0x9ece90a2, 0xe2dbef5e, -0xba9c5f09, 0x05398d19, 0x8bc517ea, 0x33228fa7, -0xfb926fea, 0xff843ae3, 0x6a186bb0, 0xde7afe08, -0x0221660b, 0x6fee7be9, 0x675ba672, 0x78ef21f2, -0x0482a952, 0x813df7d4, 0x4fa7c108, 0x5e54168c, -0x4f97dd3c, 0x9c0b7d0b, 0xda04a908, 0xe85a4393, -0x7359f445, 0x402b6bbc, 0xd853f0d6, 0xcfb91e74, -0xc6fcfb94, 0xdc4e476a, 0xbbabebf9, 0x62ec1404, -0x26254939, 0x75ce5938, 0x7b667825, 0x87b0aeaf, -0x21894081, 0x462db33b, 0x3ea8db39, 0x42870f70, -0x401237f3, 0xbdaee906, 0x25cd3525, 0x2c4d94e1, -0xf170325c, 0x90d64888, 0x51d3566c, 0x51e7e4b2, -0x23dd58d6, 0x59fca5b4, 0xedcd4758, 0x7dae77db, -0x9a717550, 0x701e2a13, 0x67c5f008, 0xd8e340bb, -0xbedd8f25, 0x8be12630, 0x7864cc2e, 0x840fae86, -0x38edad09, 0x73ab1799, 0xc93b52fd, 0xdd2f6ccf, -0x4c93c974, 0x1ac6d3d5, 0x03c42a8d, 0x511abc1d, -0x5a1fea3c, 0x4a64bd7a, 0x61f142f9, 0x6ab9f75e, -0xe5bde580, 0x569e6c54, 0xeeedac7d, 0x7b52ef6a, -0x8d27e251, 0xebc6ac95, 0x76258ae4, 0x8f0c5893, -0xa8eface8, 0x7f40945a, 0x2f66d6ee, 0x81679109, -0x1be8dd40, 0xbc24dd34, 0xa5119200, 0xd9ab7621, -0xdcb3dade, 0xa9471d19, 0x4b68b544, 0xf696af65, -0xeea60322, 0x1232eafe, 0x1249e8fd, 0x8f3a1f01, -0x25579529, 0x0d785d6f, 0x15564167, 0x9c5e03f4, -0xdf9fbfe4, 0x1e5487be, 0x688b944f, 0x8ce19bcb, -0xaf35dc5b, 0x10b64b81, 0x68ab2f39, 0x60dbaec1, -0xeac41162, 0x1ebaa56f, 0xbb69933d, 0x3326e091, -0x074746b4, 0x73661a93, 0xf9ec6abe, 0xcc848bef, -0x9a77158e, 0x9a3bd329, 0xa1a62cdf, 0x475a1801, -0xb33a91fd, 0x77ed9632, 0xbd39bb9c, 0x2ddfafac, -0xda5465e8, 0xb59c9d9b, 0xe52e287f, 0x3b6faeaa, -0x5a527d34, 0x58c776dc, 0xb6d24203, 0x8e917c76, -0x55dd9ce7, 0xa8d1b4e0, 0x5c86a5ed, 0x01d0905e, -0xd294b1a7, 0x5f3a2b77, 0x41bd36de, 0x1ed8e337, -0x318c7641, 0xc70bac54, 0x2069d024, 0xa1d95b6d, -0x3355c816, 0x31492af8, 0xa431c8a7, 0xdb2e1784, -0x25439c76, 0x6b35c542, 0x38d7ac8f, 0x34a0077b, -0xb56518aa, 0xc192f3ce, 0xecd37e8e, 0x235978ac, -0x060d1426, 0xe0122b3f, 0x0529a1e6, 0xabce9fac, -0xf9fe9079, 0x50ca70fc, 0x10bd9da2, 0xb11069f0, -0xa270dc6e, 0x4a855044, 0x282c8e4a, 0xa1cbebfc, -0x9c366915, 0xe69c5621, 0x4117ad9d, 0x92000f68, -0x62d06d71, 0xd57e92d6, 0x27658db3, 0xffc1d7f2, -0x2e758447, 0xcd3ccc8f, 0x351bf00d, 0x9c6946c2, -0x0a69924c, 0x426cc7b4, 0x0e6a41e3, 0xb10e9ab6, -0xc81eaee4, 0x822cad1e, 0x9ad6099b, 0x91deef2e, -0x23e3dccb, 0xadd9191f, 0x0b239f95, 0x59ca7f29, -/* 2626-m1010677705.inc */ -0x00000001, 0x00000705, 0x04282008, 0x00010677, -0xa6db99dd, 0x00000001, 0x00000010, 0x00001fd0, -0x00002000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000705, -0x00000037, 0x2e000000, 0x20080428, 0x00000311, -0x00000001, 0x00010677, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x2465f77f, 0x29566fcb, 0x8b1efedb, 0x7e3c309b, -0x04acb445, 0xaf8ec2b8, 0xff49b4de, 0x7bfa19c4, -0x170ce7c7, 0xd727c705, 0x019b1ba5, 0xe0414a29, -0x57d45458, 0x26a8a411, 0x9faad966, 0x095ec8b0, -0x083a7c2a, 0x17cfc70f, 0x3c8e78a8, 0xce18c419, -0x5f2ddeb7, 0xc9c95d71, 0x437a5116, 0xe0253ad0, -0xec78db42, 0x681e436f, 0x7fd028bb, 0x1149a501, -0x0bdf0d05, 0xc2321514, 0xd6866cd8, 0x64942685, -0x21e0276b, 0x0817a288, 0x09138669, 0x792985dc, -0xbd60d6aa, 0xfbf902ec, 0x43fee69d, 0x5c5823c0, -0x9dca1fe6, 0xb528b0c5, 0x22fd29ab, 0xac4fe251, -0x77207813, 0x0637a1f9, 0x16bfcf73, 0x80497f6b, -0xe5bca939, 0x1539fa1a, 0x66607fea, 0x2276c06f, -0xd003229e, 0x3622fda7, 0x18d0b8af, 0x9f399760, -0x3ac6387b, 0x6c7148fa, 0xfaf4df9f, 0x965db840, -0x7c142542, 0x7b805f4c, 0x3f2002a3, 0x061399ce, -0x2f1a03c4, 0x7f1c7616, 0xb2f9ab42, 0x4e6a92a2, -0xb44b96d6, 0xe1167017, 0xec4b2fb3, 0xa15376be, -0x00000011, 0x01322c69, 0xec40eef0, 0x26d2b395, -0xf847320d, 0x67cadb2d, 0x59b4b1f6, 0x9db9b1ad, -0x9768f4f3, 0x25bc8e45, 0x94aa7457, 0x0f4ccab5, -0x6d3fae4e, 0x3d84bd47, 0xa239c777, 0x020dc4a7, -0xe452a8d8, 0x93877636, 0xd73fbc5f, 0xdfb022de, -0x57225cd9, 0x7f44abb0, 0x6d2c1ad2, 0x27a1277d, -0xf5a06c32, 0xd20e7585, 0xdf96854d, 0xca36255c, -0x7e4e54f6, 0x45969264, 0x674f09f8, 0x0d3d80de, -0xc651ffc0, 0x630fd091, 0xde1b80b3, 0xb2d65941, -0x0316ed1b, 0x046c73b5, 0x2e509d5f, 0x03a5fddf, -0xe9ee87a1, 0xaf03d755, 0xa567aefd, 0xc5138599, -0x36bec572, 0x7d8e28ff, 0x52bb013a, 0x396a6ed5, -0x61ce6789, 0xbe8a1d4b, 0x986cbacc, 0xcf627b91, -0xa7fa17fb, 0xc91c5325, 0xccd6384b, 0x4b1e857f, -0xd1f7def9, 0x47594c88, 0x2a48e8b5, 0x0f3b1568, -0x1ad57438, 0xcd5c1a85, 0xb3f9c463, 0x70ac9f16, -0x39691227, 0xb4a6c7b9, 0x8196ec8c, 0x4c7c2906, -0x2480cd88, 0x00b7a245, 0xb6caef0a, 0x4424e38d, -0x59dfc329, 0x2161a44e, 0xdf66dab6, 0x19e6388e, -0xcf95df31, 0xe8da3ae6, 0xd26e8296, 0xd057b888, -0x7f726055, 0x3ef45cec, 0x047fff63, 0x312b17d3, -0x9f802a7c, 0x2b703a1a, 0x761f42c8, 0x0c236bd0, -0x8681c353, 0x997bf86a, 0xf2ffc240, 0x9b7020e4, -0xf4c45ef6, 0xc0df789a, 0xb111ebde, 0x0ccee80e, -0xa56b4c45, 0x7155193c, 0xcc82d657, 0xa630484c, -0x7f06b736, 0xf74fd515, 0xc0a87b1e, 0x1553e4b4, -0xcabad873, 0xd29c7d3f, 0xa08928d8, 0x75f9a195, -0xb904cb46, 0x44429cc9, 0xf88612f5, 0x14587413, -0x88d57872, 0xecf707c6, 0xe28d18b2, 0x5270c776, -0x9c1e144c, 0xc9649bbc, 0x9ff69bb9, 0x20b49543, -0xc43c0a9c, 0x2a1e3030, 0x8ae5113f, 0x06cb0653, -0xa9629173, 0xd582fdf3, 0xc88b7c00, 0x96060dcc, -0x6632ef6b, 0x76f26ff9, 0xac076055, 0xa8b50beb, -0xf8cffffd, 0x745e1003, 0xae8036ee, 0xef7a05c4, -0x5a376dd1, 0xda640a45, 0x9e09e92d, 0x686931f1, -0x39cdc780, 0x7e3e2020, 0x56701e4a, 0xf8678562, -0xd4156342, 0xbc06f43c, 0x4e1f1a67, 0x5466ebb4, -0x503bd187, 0x0b6e259e, 0x74dcaca7, 0x35819bd4, -0x117e597b, 0x3ac65452, 0xcc0730bb, 0xc6f5d655, -0x7d2a15d5, 0x3867c7da, 0xc8b083e6, 0x16224fdb, -0x47fa9de5, 0x00fde300, 0x4e01645a, 0x5dc9ff99, -0x86e3b1a6, 0x1a3bc3e1, 0xf70f532f, 0x4de7d113, -0x5a0d2d6b, 0x9afe6d2d, 0xdb3f4265, 0x505bcec7, -0xa53ab0e7, 0x1507db85, 0x3d0d32bf, 0xc0ceed74, -0x4db126e9, 0xb4f2e270, 0x68930871, 0x05d3b3d3, -0x66ccdb4c, 0xb57fb38a, 0x008233a3, 0x3fd5c019, -0x9a179689, 0x42c05ac7, 0xb87889af, 0x2913bb83, -0x477cdd20, 0x0d83544c, 0xaf0263c1, 0xb48935a5, -0x234208b2, 0x5b4a0f3e, 0x8f8cc13d, 0x9607f2de, -0x0c9cee16, 0x21d899c4, 0x09916e4b, 0xf306ddf1, -0x0c6b8280, 0xd181c117, 0x448c6ff8, 0xb72208b8, -0x0de93462, 0x377f99c6, 0x2221b8c7, 0x3c6ffb65, -0x3c6c2519, 0xa6d07e90, 0x7f94d907, 0x30479885, -0x21a8a9b8, 0x571a4b6a, 0x5f0797c9, 0x2dc87140, -0x71e4112c, 0xa8de9117, 0xe28b1e94, 0xfa674e2c, -0x02058bfa, 0xb7e95418, 0x3fd8210a, 0xd723d74c, -0x4239b510, 0xcfcc1628, 0xfd293123, 0x7e336796, -0xf17fa73a, 0x98345638, 0x388df464, 0xab7c90c7, -0xe2ee9b4c, 0xe5613767, 0x30d4426c, 0xb48aca9a, -0xffb90a1e, 0xa1661c42, 0x5abc5c98, 0x1abf514a, -0xaeff9c98, 0xa818b964, 0x536cc51e, 0xf6acce64, -0xe647d960, 0x7100da97, 0x341e8028, 0xa30bf79a, -0xeb1a84b1, 0xb134f78e, 0xfd95978a, 0xe27d0550, -0x1c84a059, 0xd0014ddc, 0xe74bf809, 0xa022e7ec, -0x64eab1fd, 0xff663e65, 0x0de0838f, 0x108d2e48, -0x9466817b, 0x3ed53d00, 0x8a4c5e3e, 0xab20c038, -0x7656a7b9, 0xa7dc8e0e, 0x045d34f2, 0xf845748b, -0x76d4778a, 0x28ffba14, 0xcadc3664, 0xc0285e31, -0xa6cb86a1, 0x5844494f, 0xbde9d164, 0x7d4dee77, -0xebf0b41c, 0x820faa44, 0xe26d0f5f, 0xa1b179a9, -0xcbfdf2ec, 0x6d161586, 0x1cefd06b, 0x7fefb5fe, -0x6d09d3f0, 0x99814fac, 0x17246f44, 0xa7399914, -0x5d56f5a8, 0x37f57549, 0x054d5499, 0xc1c6493c, -0x3b82f5b4, 0xb7aeeec8, 0x77b54215, 0xdf885a04, -0xc75877c2, 0xa5c69e72, 0x6e2488cc, 0xc20194d4, -0x124e6076, 0x07a413c5, 0x984a98bc, 0xcfe981af, -0xadc2db3f, 0x580d7229, 0x8901dfa9, 0x085c0c44, -0x9ce13381, 0xf21e780b, 0x72c0f22c, 0x4e181c4b, -0xc9cab0c8, 0x719bdec1, 0xe2ba4736, 0xf66ae16b, -0x9e255710, 0xbad58642, 0xd1db2722, 0xb77c5c28, -0x3ec638c2, 0x84bf6d4e, 0x8d3a5255, 0xde373b6a, -0xbaf80fd5, 0x8953d507, 0xc841de16, 0xea26e027, -0x173cf827, 0xaaebdb63, 0x0d7ebc10, 0xa72dc50e, -0x5006d59e, 0xe6fe0177, 0x498be8f1, 0xae15c231, -0xa3701dd7, 0x7a7f91fc, 0x4833aa91, 0xd79e9593, -0x77837ff2, 0x7eb31fc6, 0x7910b466, 0x142effc8, -0xabb9a498, 0x4d85e178, 0x55714305, 0x60855af9, -0xc1b1061f, 0x6feae06a, 0x33e0ab49, 0x8be46d25, -0x89230425, 0x81b5c821, 0x18231b42, 0xc17cc189, -0x6ae95bdd, 0x6f58e000, 0xe5990aa4, 0x86185e44, -0x84ad9646, 0xe49cd98f, 0x2919c95a, 0xfc9aead4, -0xea6c7985, 0x1d62c3d8, 0xf4d829f2, 0x805ba72e, -0x1400c3bd, 0xab6663f8, 0xeaf75f2d, 0x79d49590, -0x85c88dc7, 0xa9deba56, 0xc5eede1c, 0x91dd6229, -0xdfdde150, 0x61153322, 0x402dd8d3, 0x77505945, -0x723678b8, 0x5de1f01c, 0x815d5fa0, 0xe2102c9d, -0xf047b06f, 0xae404730, 0xb14ba807, 0x3dbc31c2, -0x2998e426, 0x497e04d9, 0x914afe55, 0xd14b4653, -0x0301cf11, 0x9ba705e9, 0x957fb189, 0x57b9be97, -0xa33b1429, 0x02e12332, 0x8cb58a43, 0x9c246884, -0xc07dd0bc, 0x42356d52, 0x2b51b5f0, 0x4d4805be, -0x0f815bf2, 0xdd7902da, 0x4f56f997, 0xfac6ef48, -0xdac3367e, 0xe5850b3f, 0x5d9c554b, 0x1b2f6756, -0x61842357, 0xfd336fe8, 0xa58ad4d6, 0x88f7bddb, -0x9ec7f8a2, 0x50bc3268, 0x942b0aba, 0xfb66a91c, -0xe3a73708, 0xe69e62fc, 0x69596c62, 0xf4be8c82, -0x621ca80c, 0x7a333295, 0x46254b04, 0x2f1555b2, -0xaabba398, 0x0c1108e7, 0x36a205ef, 0x9a4db339, -0x43a6840e, 0x10a209c6, 0xfb67b1c2, 0x4de09447, -0x9cb8be5d, 0xa188a137, 0xe9f2ad46, 0x2b1cab4d, -0x6220f654, 0xa4ac7969, 0xe339a780, 0x76a9ae54, -0xa8b7951f, 0x5748eb73, 0x3b46f69c, 0xc895b0b4, -0x358501a9, 0x99e8d1f2, 0x86bb9dbf, 0x02852e8e, -0x73d4d32e, 0xe6536877, 0xc2b8e7d7, 0x2088bc41, -0x5b9406e8, 0xdd47135f, 0xb217f649, 0x4dbc6f9f, -0xddf107c7, 0x97afdeda, 0x28623a0f, 0x343158a2, -0xc9c68f39, 0xaebd29be, 0x4ff115ff, 0xe4091f35, -0x669f615d, 0xfb6ced81, 0x93b7a705, 0x9e4433c1, -0xc5236c31, 0x686100a9, 0x6146d370, 0xbaba0da5, -0x87da0ffa, 0xae30f311, 0xfb3b87f4, 0x98488326, -0x7ebb06f2, 0x1c347bb6, 0x42671c9e, 0x999f0ad6, -0x0f7e2bc7, 0x2bbd7ab9, 0x8a831574, 0x9d730046, -0x118c8a3f, 0xc9e06b0e, 0xa62cf9a8, 0x9c448779, -0x04a03675, 0x3e400fed, 0xb2f2fa96, 0x2c359ef5, -0x8064b88a, 0xa0f57dac, 0xb69023c8, 0x75546772, -0x5f1054f7, 0x00298870, 0x99f91288, 0xc0868491, -0x31803de8, 0xaf510062, 0x4117fe12, 0x5dbce9be, -0x5e4051ed, 0xb1c91832, 0xea3e2894, 0x4b97dde0, -0xf4ff8774, 0x987bc043, 0x46a2a625, 0xd4041870, -0x78acfb0f, 0x15604cc3, 0x5e1aad14, 0x712d445d, -0x209bba33, 0xf6069eff, 0x749f8423, 0x112d4830, -0x9c0e6674, 0x913f83ba, 0xd2014e4f, 0x0f23e981, -0xa930f6da, 0x0cef6e1a, 0xb872b6ff, 0x4f69948d, -0x75e837bd, 0xbb24bea1, 0xb651b4fc, 0x10016b79, -0x2e60e398, 0x5b15f8f7, 0x7af24a35, 0xeb5dd61d, -0xdc15082a, 0xb0371fe1, 0x6585dbc1, 0xf625d84c, -0x97d410cb, 0x0a839640, 0x9b77d939, 0x2775e81f, -0xc8dea7b2, 0xadb662ed, 0xb8150bc6, 0x54f54b55, -0xe33cfb10, 0x65527001, 0xd581b314, 0xc2c44608, -0x1b382606, 0x500a36d3, 0xd00a5d2a, 0x8234308e, -0xdf8bca1f, 0xf14163df, 0x00fa7604, 0xe184defe, -0x2199ca1d, 0x2bf47708, 0x98c18fbd, 0x72506146, -0x45626a02, 0xb2dae16c, 0x958bdaad, 0x171f8643, -0x036ed338, 0x559f59e9, 0x7be8f130, 0x540df4c2, -0xe30f6819, 0x788f6bae, 0xf6352699, 0x91700d3a, -0x920c5eb1, 0x87725829, 0x085c56aa, 0xeaec2fcc, -0xf08594bd, 0x27ef4925, 0x41661c89, 0x3389ef83, -0x7da12071, 0x69112014, 0x9d29768a, 0x12ce3aed, -0x18db18d0, 0x501d13d8, 0x56cdebca, 0x8e8b683e, -0x4fcba747, 0xe7e1805b, 0x6addae9a, 0x540a90de, -0x47f2ee6c, 0xab3fabc6, 0xcb4f23f4, 0xd84e65ff, -0xbebfccc3, 0x1354b1cd, 0xd56ef86c, 0x4b6125f7, -0x8b5789c3, 0x4e97a781, 0xaa024674, 0x724cc993, -0x51cdf63e, 0xa9868189, 0xd27de1e5, 0xe1deebeb, -0x14a819d6, 0x7eac8bd4, 0x3f662ce9, 0x4c6ecca7, -0xff8e8bd9, 0x92f9399a, 0x9564f658, 0xccd7334b, -0x25ca62eb, 0x0d031f55, 0x391642f5, 0x4e593b4d, -0xfb988d6c, 0x1fe69f2c, 0x5b68b5d9, 0x839d5670, -0x872879f6, 0x5eaa8c8d, 0x8917a87f, 0x0bf61613, -0x34b5a8e2, 0x57d4fae3, 0xeac815d9, 0xf5eb0d2f, -0x59cd2cc5, 0xbaf5245b, 0x8c685639, 0x836c82e5, -0xd467b96f, 0x62e057cc, 0xcfe1839d, 0xa3b4a985, -0x1dbb0683, 0x8ef38d53, 0x34797901, 0x6ce5e28c, -0x54c1f3b8, 0x9061fdb0, 0x8309801c, 0x16af80bf, -0x6385a38c, 0x80f7f501, 0x454fd913, 0xc2c63349, -0x4275913f, 0xda274f1f, 0xd0eb541e, 0x6702d849, -0x52aaa032, 0x9ae95292, 0x6aab14aa, 0x26327c9f, -0xd18fabec, 0x2dcc9edb, 0xa17fd708, 0x7d74d975, -0x68f39951, 0x50c3cb45, 0x051c7f5d, 0xc2da8476, -0xb0289147, 0xa9908724, 0x06761e86, 0xa51a75d4, -0xfc693786, 0x008e9d6d, 0xa1cdf3d3, 0xa1c77e5a, -0x9f223352, 0x74e648e7, 0x3082f1d0, 0x6a89017b, -0x5dd2afc4, 0xd71618ac, 0xc87934bd, 0xe96101d1, -0x55d1976c, 0x471c8505, 0x7a36d839, 0x5d62a9ee, -0xf3c54a8a, 0xa2be15d9, 0x244087c9, 0x042c8037, -0x23224689, 0x281c5d73, 0x2139ecfc, 0xffb8bc8a, -0x834fdd11, 0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, -0x4ae2dbda, 0x86d90089, 0x6675dfce, 0x48876262, -0xcec72538, 0x11dc5c80, 0x86a730f9, 0x313565c9, -0xe3e5be11, 0x106d7cce, 0x752b8be2, 0x3d00a5bc, -0xe6f70e95, 0x44447ac8, 0x600df30c, 0x8335ac3b, -0x8816ddee, 0x700982fe, 0xee495741, 0x48c7e81c, -0xa3d55da2, 0xb0172982, 0x70ab2158, 0xd4460621, -0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, 0xa8454763, -0x70877bb6, 0x66005c97, 0xaf292c06, 0x7b843db1, -0xf343b59b, 0x25cdc7b5, 0xa41da617, 0x9e9d895e, -0xc936f475, 0x7270925a, 0x30024230, 0x8e72f53d, -0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, -0xaf377cc1, 0xbff09a78, 0x4b4e0814, 0x95a0b2c1, -0x270398de, 0x201fca94, 0x2a032a4f, 0x131542b4, -0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, -0xa3b3a991, 0x17ee60c2, 0x852c0b8d, 0x11e5853a, -0x762002a7, 0x92c5311d, 0x0d4bf7e1, 0xfffec870, -0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, 0x0111a772, -0x9808e780, 0x29c336e8, 0xe9bc05df, 0x5bedde11, -0x945565af, 0xaff808fe, 0x87e3423d, 0x4de6f98f, -0x93b4adef, 0xbf704fa4, 0x09120e91, 0xd54f3692, -0xdf8eab1e, 0xfabbf59c, 0xe74318be, 0xaab87ffc, -0x29fa791c, 0xe3915552, 0xa652cb9b, 0xa1252e74, -0xb35b723b, 0x542aa28b, 0x12fcc5b0, 0x3941f962, -0x82bcc6cc, 0x47b11974, 0xb821611f, 0x78b34250, -0xf1be5659, 0x561b9e61, 0x6f3bd501, 0x584e6f5c, -0xd54ed547, 0xacebcd21, 0x7b5ff816, 0xb64ad233, -0x9f2f330d, 0x69fb1ece, 0xac8710dd, 0x58dc6c60, -0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, -0xa733274f, 0x884d9b55, 0x42b08b63, 0xafa54a74, -0x1c7ccf64, 0x93a20191, 0xaaa3132e, 0xc69831d1, -0x54634889, 0xfbfe3efc, 0xd3cf68d4, 0x302e3117, -0xf5693131, 0xc3ce8c6c, 0x1f03cd89, 0x6243334c, -0xf16bc80f, 0xdca5f130, 0xcb2cd956, 0x4c1bb421, -0xe8de533c, 0x7f86703a, 0x29aa897e, 0xdd54acad, -0x76b2f2ae, 0x7ef82b71, 0x2e30970b, 0xba402597, -0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, -0x2363d147, 0x5327289a, 0xe89229f3, 0xd63a535c, -0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, -0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, 0x6d65db4c, -0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, -0x8488a45f, 0x8ebc2932, 0xd4767316, 0x3e8c4b8a, -0xbab7402c, 0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, -0xc88528e9, 0x4b2e4e8f, 0xdd938b86, 0x0c964f98, -0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, -0x4d40b3b3, 0xcf203155, 0x0d2fa621, 0x752d2c58, -0xb12bac12, 0x1e7e8c23, 0x94215d54, 0x9854a71c, -0x4de63c64, 0x7a012529, 0x9c171f8d, 0x9e71def7, -0x3bd17d50, 0x11f175d9, 0xec78abf3, 0x7b529eee, -0xd3a69fc3, 0x5b718676, 0x58214d29, 0xa8bd2c34, -0x41ea00ab, 0xa03f64d6, 0x4ee342b0, 0x32b1e444, -0x1c1801a4, 0xc8424702, 0x334a7e35, 0x50cf1543, -0x3b22b495, 0x88683776, 0x8e2e0154, 0x6155c033, -0x4e2fa6ac, 0x42ace700, 0x8d64f97c, 0xaf9ced17, -0xb2a5cb92, 0xa558582d, 0x88705de7, 0x9e528d59, -0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, -0x10462123, 0x30080f7d, 0xb346cd81, 0x0049c396, -0x4e24165f, 0xa7c66809, 0x2e60bdcf, 0xaad70a08, -0xa73ea713, 0xe28f97a7, 0x283a9eab, 0xd4366489, -0xe776f963, 0x64ffa8ae, 0xde717b50, 0xbd2ca2b5, -0x3bae5f6d, 0x8d2bbef1, 0x7e9181e6, 0xf06aa121, -0xd06b2d20, 0xa83ea826, 0xef935e4f, 0xdfd27456, -0xa3451468, 0xc6820a63, 0x43463105, 0x787697aa, -0xcba5543d, 0xdf7e1e2d, 0x6998a8af, 0x98ce6c08, -0x89de731a, 0x943a3510, 0xb36ead85, 0xd5258d4b, -0x1cd6df61, 0x82a5c59d, 0xd078e7a4, 0xa33d4317, -0x24dc45f8, 0x3f3daf27, 0x0478bc6f, 0x92dfa16c, -0x952a872e, 0x7a34e03f, 0x0f088084, 0xa40937fe, -0x38fc7749, 0xa157e8a4, 0xbce94344, 0x7045ff7b, -0xf3e1ab66, 0xe62a6058, 0x5564ff10, 0x38198f1e, -0xf326f0f1, 0xe262bc0c, 0x2f0b851a, 0xc7bcbe11, -0xe79f1d1a, 0xc2f93c29, 0x54f3ea9f, 0x8f8f9141, -0x9f45e13c, 0x7a5b86bd, 0xa764efd8, 0x35f04729, -0xdd8c4b54, 0x5fa12e51, 0xa5824af9, 0xad328f71, -0x0f11fbb9, 0x9048e950, 0x04d7a900, 0x02538d1f, -0x99f745b7, 0xe31f63bb, 0x2c4e3d78, 0x7cdb9245, -0xa3966ee7, 0x27c4433a, 0xe1d79f3e, 0xe640fa06, -0x79ce31eb, 0xf25634fa, 0xdd9ce5cb, 0xb7fab8d2, -0x2f1f0ff2, 0x2acb625c, 0xa0494989, 0x206d7f11, -0xf268b8ca, 0x292bbf9f, 0x763bd7d0, 0xea4b14fc, -0x9d3d6aeb, 0x64cca57e, 0x6fc3e29e, 0x3e7bf4bf, -0x90efc7e3, 0x08e39173, 0xd05bee2c, 0x5b3c8f37, -0x0921ec6f, 0x3371b715, 0xb324e114, 0xe3abc53f, -0x576b18f8, 0xc4469024, 0xb2ded6c6, 0xe7783782, -0xc0a1fd5d, 0xcf324bde, 0x97527c8e, 0x19f8f48c, -0x3e806a5d, 0x96cff225, 0xe3b9d04a, 0x0e5856ae, -0x781372f6, 0x9645f2b7, 0x95a743ed, 0xd0c7eded, -0x86ca3cd9, 0xbab94db0, 0x43a1233a, 0x89c55554, -0xee776239, 0x34aa0098, 0x66a6e1d4, 0xae0e233e, -0x717e7b29, 0xb403a4c1, 0x36eb96c5, 0x42140832, -0x04250936, 0xda375dca, 0x524cb2e6, 0x86deaa0c, -0x400dc9d1, 0x12c00364, 0xe3ca7cf5, 0x87f20da7, -0xf57df9ef, 0x580dbdfc, 0x0b3e0369, 0x014d27fd, -0x4afaf6a1, 0xd1f4ca09, 0x77abc831, 0x30e49729, -0xec61cd2c, 0x159c1e92, 0xb61b40b1, 0x17c66fd6, -0xde11c061, 0x79d7f792, 0xc709cbfa, 0x94201c89, -0xbe65137d, 0x18aea1b4, 0xf248bbc3, 0x465f957d, -0xcf4a9672, 0xbf293fd2, 0x2c5e31c9, 0xc2c73011, -0xfb29cbf2, 0x576f7f0b, 0x74de1745, 0xa76e172b, -0x99b96223, 0x14ce1502, 0x231013fb, 0x1d4df40a, -0x951b0c16, 0xab173e66, 0x4ff65f74, 0xc4a87a47, -0x09cc3370, 0x66385490, 0x73e09118, 0x4ee96432, -0x0164d347, 0x205069b5, 0x158dd226, 0xc932c238, -0xe9048fa2, 0x100b626a, 0x86ee08cd, 0xed87cb1c, -0x6353ec37, 0xa36edcc3, 0x8a16dd6b, 0xd28a4198, -0xebea1127, 0xca0b761a, 0x61c31acf, 0xced5ff4f, -0xbf4dbd8f, 0xd969d8a7, 0xb6e4e9e8, 0x8421c402, -0x809d7222, 0xabfd1d2f, 0xc1857ce5, 0x23958fd7, -0x3226f1d3, 0xd822b4cc, 0x2f1cc3aa, 0x501fe01e, -0xe36f8c94, 0x7ad27716, 0x3321308b, 0xa85b957b, -0x38cfdf6e, 0xc7497dd5, 0x2462090c, 0x8f9e42e7, -0xdf97684a, 0xac8af621, 0xd5224866, 0xc5f64e50, -0x9724f297, 0xc386097b, 0x48c6f98a, 0xe1478b1a, -0x2dd23fd8, 0x716b2d85, 0xa5c3789b, 0x53625e80, -0x9b8b312c, 0xce482165, 0x66161e35, 0x64ecb56a, -0x9981c46a, 0xe6cb6bb3, 0xe1983186, 0x75ed470f, -0x4adcbd27, 0x3efeda68, 0x4d193a2a, 0xbfdb3cd4, -0x7c6167b6, 0xdbddea68, 0x4b0d2d62, 0x00ba3860, -0x49ec2544, 0xa68698c9, 0x2ce7be1b, 0xf5afc9fc, -0x1cebf9c3, 0x350f8f5b, 0x893eefb8, 0x77414f6f, -0xe46f26fa, 0x67bf6398, 0xd6858f5d, 0xac73db2a, -0x58e20acc, 0x750dd76a, 0xb7930e80, 0x8a8796c0, -0x44c86997, 0xb1807742, 0x3c827dc1, 0x381aaa3c, -0x83ac76f3, 0x57f0a2d6, 0x18261009, 0xe107138f, -0x85711c22, 0x2e1d982f, 0x7062179a, 0xaedfa298, -0x62e438f2, 0x6d325a9a, 0x99b489d3, 0x1bf77b3a, -0x28ca20e8, 0x502d1b21, 0x74a833c0, 0xbeb91634, -0xf56ffef9, 0x05401164, 0xe5dbab51, 0x0a2b460d, -0x2f0d9c22, 0xc74472f9, 0x12da5199, 0x68b2d628, -0x9a118f9a, 0x9035d200, 0xcda0221f, 0x12430cde, -0x79a43fbb, 0x5bb5e1b7, 0xeab5ed62, 0xe6a11e32, -0x3118b0fa, 0xedbcfb64, 0xd2285490, 0x824023c6, -0x30311fb1, 0xa0a4a475, 0xbfa8ac55, 0xb8c8fbda, -0xdf3cab63, 0x8d805566, 0xf52c1b1a, 0xa3471090, -0x02328a4a, 0x5d1dce57, 0x196aea39, 0xcd0f640b, -0x2fa01c27, 0x6175f783, 0xb2b6a0e4, 0x02fe6171, -0x2d3cb20b, 0x25f331e6, 0xacfa8085, 0x46a09a58, -0x27bbfb9e, 0x3914f970, 0x73e35206, 0x8bb87194, -0xdb58fc4b, 0x62fd53ff, 0x2c942c7c, 0x3f4681ba, -0xeada1780, 0x5dfbb960, 0x8473948a, 0x80787902, -0x049c20ba, 0x9e95a4fc, 0x8526d8ac, 0x3dcdcd2d, -0xb9562f16, 0xc9c8eb08, 0x533ed0a2, 0xa34d5d73, -0x3e579c8e, 0x235bb378, 0x36576983, 0xc71f11b2, -0x035eae76, 0xbec23972, 0x8613e5e9, 0x3982899a, -0xe5a55d62, 0x3c45a7e9, 0xbd4d6def, 0x17ae0a5f, -0xf0f53bb8, 0xa3dd1e29, 0x36f9520b, 0x72cbd950, -0x4d762d12, 0xe03cb7a8, 0xf8c8c1fe, 0xa4ff17a1, -0xcc779472, 0x83f9b379, 0xa2fc038c, 0xdd3b8104, -0x95936bb0, 0xf36c9705, 0x93939e08, 0xc98576ac, -0xec9196d1, 0xc8bce622, 0xb48e1075, 0x98dbd77d, -0xd1b04c3d, 0x85d1d422, 0x20765885, 0xc6a17eb5, -0x8e913cdc, 0x3f7a6758, 0x08176f48, 0xba2ea15f, -0x3638114d, 0xf08cb49b, 0xb8b6d9ce, 0x4e55891a, -0x2775c022, 0xc8d45982, 0x529c2eb3, 0xde080e24, -0xdac9c028, 0xeec68934, 0x8eaace11, 0xe82e05aa, -0x00033a20, 0x4ec94b5e, 0x445f5562, 0xa5c58462, -0xb6942526, 0x44631607, 0x5065644c, 0x14946f9c, -0xa9cb0e63, 0x53dff50a, 0x3f18fa24, 0x20b3b811, -0x95c1e57b, 0x1523d301, 0xc4e24932, 0x41a9be80, -0x24fc45b0, 0xccff2cbc, 0x996af6a1, 0xe3f201c3, -0x0917ea23, 0xbf4a1ac3, 0xbb0db6f1, 0xd15772df, -0xb1465383, 0x61400275, 0x571f6b1d, 0x0a4407f7, -0x916cfbce, 0x114f042a, 0x1cb9b3a6, 0x1b34c85a, -0xe36acc8d, 0xab109469, 0x5af9a63a, 0xccd4defc, -0xb758adfd, 0xbd8ddecf, 0x5ffe8424, 0xd73e2a4b, -0xb41cb99e, 0x01a52553, 0xba70e749, 0xf81d7557, -0x2b4f0847, 0xa22e281f, 0x5c653c31, 0x89bdb546, -0xa596e592, 0xbca4cbf4, 0xc3d1dfe3, 0x64a21c2e, -0x159aa4b7, 0xed90f2d6, 0xb1164cb0, 0x86de0088, -0xfd4e49e6, 0x70702b0d, 0x946b532b, 0x03a0144e, -0x71fb19ed, 0x07c41763, 0x63312ce9, 0x0e2f5ee4, -0xc6501661, 0x09599e4e, 0x544fd5cc, 0x054d842c, -0x902bb57d, 0xdf82a365, 0xb7ae9427, 0xa6750881, -0xeee3c9cd, 0x6cbe0f45, 0x7f72d3f9, 0x430b786f, -0x162b6004, 0xbfcd440b, 0xdc4f5c81, 0x82249f6b, -0x98d1cdca, 0x2cc2692e, 0xf977f83a, 0x570c1e1f, -0x24ed6461, 0xcae5afea, 0x9cf06576, 0x9199d69c, -0x883febfe, 0x0f254c42, 0x6eb50978, 0xf91fade4, -0x9cfe5488, 0xfe3bf66b, 0x86ea94e3, 0x1bed23f5, -0x0bded397, 0x0cde064b, 0x7abd7a81, 0x8efb798e, -0x9a78e5f2, 0x7c46d76f, 0xcb3ae1ea, 0xc33e7ab1, -0x0c3993f0, 0x5b2d8de7, 0x24948ba8, 0xffce06e6, -0x0d3c2dc2, 0x3ae09142, 0x7e6b932e, 0xb3e22558, -0x9f7c425e, 0x8fa1329b, 0x24aa5012, 0xb9e49bc7, -0x787dd5a6, 0xf68c8171, 0x440d2146, 0x9734857f, -0x8c30c31a, 0xcb3352a1, 0x46b04f38, 0x72572ef8, -0xc90c56df, 0xe8103fa8, 0x04057577, 0xd1c250d9, -0x5cb390a9, 0xbdba74b9, 0x80012fa3, 0x408216c2, -0xadca83bc, 0x3c39bcdf, 0xf0da9459, 0x421d5a3d, -0xc5cf55c9, 0x2dcfa63d, 0xd852066b, 0x606b2204, -0x4d5e9576, 0xe8d6475f, 0xe46ec6b0, 0xf4e3c2c6, -0x1bfe1bb0, 0xc2803818, 0x2a3e4809, 0x947e50a1, -0x3a10e713, 0xc9e070cc, 0xa4244fe4, 0xa7f5d2e7, -0x194f77ee, 0x76754ab4, 0x75ed4e5f, 0x92ffdbaa, -0x1f5bce6a, 0x14aeeec7, 0x366fbb47, 0x44ecec7b, -0xbc31e911, 0xee6c224f, 0x0a6f7376, 0xbe79fce3, -0x53a18077, 0x6f6ad5fe, 0x945938bd, 0x61bb760c, -0xed26220f, 0x9f492f0a, 0xaf0f2d80, 0x265f5449, -0xae1f2dc3, 0xd235910c, 0x44a0f4a0, 0x36fcc004, -0x1e8fa223, 0xe7440ed0, 0xa8535548, 0x6d7e7029, -0x2e1b7968, 0xf3baa61d, 0xf447ef12, 0x701d62d6, -0x2da5dcf4, 0x44828196, 0x41af9c9a, 0xab210662, -0xa5ee18f2, 0xd45eb369, 0x947814fe, 0xeb62eb49, -0x30c555c6, 0xdc06ccbd, 0x786705d2, 0xd50c80d3, -0x266d8313, 0x68f63164, 0x1e3e4322, 0xfc23834e, -0xe879261f, 0x28992a8f, 0xab86dac9, 0x19f88d1a, -0x5110c867, 0x3c050155, 0xf9b1b3f5, 0x98909489, -0xfa0ee6bc, 0x038fb4ce, 0xbe1c9e33, 0x18f96bcd, -0xa1635c9a, 0xff3e9374, 0x5b033171, 0x0b84bfd9, -0x3c091bae, 0x6da61a4e, 0x07d81b5d, 0x3904ea3c, -0x75f4e7f1, 0x3e70c12e, 0x9c70d835, 0x9a1ea5a6, -0x4b99b705, 0x08f6ab89, 0x7649901c, 0xee3e7687, -0xa3deb48c, 0xd74e8c78, 0xe8e120c3, 0x425d3d96, -0x16f136bd, 0x0c7a32ef, 0x37a0ff53, 0x77b035e4, -0xba8808c1, 0x1d3d8330, 0x8d224cce, 0xed789fed, -0x550a8352, 0xe2715912, 0x185f62d1, 0xe301002a, -0xbe2ed99b, 0xbb1dfd60, 0x9d22d8f9, 0xcbfa36d5, -0xad7e92e0, 0xd2db61d4, 0x1df386f5, 0x92b5797c, -0x00ac8ed1, 0x2f7470b1, 0x674e258b, 0x6689df79, -0x135c5c1a, 0x87abbc50, 0x19ac082b, 0xe7f7d64c, -0x24fd4922, 0x7eeadc29, 0xa0910eaa, 0x763231d6, -0x23597ccb, 0x332f33c3, 0x93992b6a, 0x19c8937c, -0x75d6a9f4, 0x221395e1, 0x662914d0, 0x997d7860, -0xd196adeb, 0xa5402fd9, 0x8bd6f12f, 0xc31d97e0, -0x304dd9dc, 0x72f35c72, 0x8ced870e, 0x1eef8a14, -0x323321fa, 0xf193079f, 0x18026b1c, 0x5a1107a5, -0x54979f4b, 0x6afee492, 0x04c012e6, 0x3446250c, -0x25a691a8, 0xc19a76ea, 0x66bd5b14, 0x6250bd2d, -0xc6c082d9, 0x67ea1d78, 0xbe68a7ef, 0x03f50dc8, -0xd8f76566, 0xb6681752, 0x00e2b087, 0x7ed2e598, -0x8c9cbc83, 0x103b03f5, 0xee4d2723, 0x67b3903f, -0x1e057dec, 0xc5703ba6, 0xae0615f9, 0x1bce0df2, -0xfd041279, 0xc874a2c3, 0x0a91d2fa, 0xac098457, -0xc1efc5f9, 0xd48208eb, 0x72e9baa8, 0x184dc658, -0x3d26b8b4, 0x90e2469d, 0x6d07f351, 0x3f6898a7, -0x21e4de0b, 0x0fd04a43, 0x2c99cd2b, 0x44b28cdd, -0xaf5483a5, 0xe50b9a12, 0xd98fe031, 0x9d6e8f08, -0xf385ba19, 0x5e531cb0, 0xc545867a, 0x65f5ebf5, -0x9f27ad5a, 0x2de11f0d, 0xef6f0970, 0x973b11f2, -0x72228c07, 0xe13fdb84, 0xd2a7b46f, 0xc85a38db, -0x331a9807, 0x3be38ebc, 0x3e7bf15d, 0xa82a1e68, -0x4b42b5bc, 0x9871203e, 0x7d1e1e24, 0x12f57b6b, -0xf5403ec8, 0x28746c33, 0xae20522f, 0xf6042fba, -0x66bada5d, 0xbefe376f, 0xfd3773a5, 0xbb5fc6e8, -0x34c0433d, 0x3cfc83e9, 0xd096736a, 0xa53be016, -0xeba3dd6c, 0x2c626561, 0x3c160c8d, 0x8506c719, -0x802e7b47, 0x16079396, 0x6d29b175, 0x4e91abb4, -0xe350ce95, 0x0d481aa5, 0x94e95371, 0x10dc4dec, -0xbfeb3735, 0x3ce3cb4d, 0x32ff742a, 0xac5ad3cb, -0x1fceabbc, 0x87654d2d, 0x181519ff, 0x8d3b03a5, -0xb9e74795, 0xc69162c2, 0xaf4e5a8f, 0xfaf584e3, -0x22b2f19d, 0x732a6b62, 0xd0e4811b, 0x8144dbc0, -0xd1dd8b27, 0x215262f7, 0xa0485274, 0x238050ed, -0xa66b6ff2, 0x1bfab681, 0xb751b265, 0x56c41f3c, -0x4c775166, 0x984af30c, 0x32799078, 0x8e66d51e, -0x9b7d177c, 0x0cc8c727, 0x8596f9d5, 0xfd3250ee, -0x4c3549f9, 0x5c518453, 0xec32eaa9, 0xac939aa3, -0x2ab6735e, 0x511fe493, 0x71c30b4f, 0x53411fc6, -0xc53985d0, 0xba0108ae, 0x7ecb8ac7, 0x4cde9862, -0x49f91e51, 0x86ac3ae0, 0xe7b40273, 0x27049d28, -0xa2643fb7, 0x2067e8df, 0x0326f6c0, 0x21368505, -0x9588d4ad, 0x0fe38fea, 0x1a396d6c, 0xc5863cb6, -0x4eafc286, 0xd725098a, 0xc7ee2336, 0xe7c3ef94, -0x7dab017a, 0xe17759b2, 0xf24eb647, 0x9949505f, -0x8bd21859, 0x234c2067, 0x86abbcc7, 0xbcd3793c, -0xb6d80f08, 0x23817175, 0x2fdcb8d7, 0xb0836fb8, -0x688df395, 0x4c06c8af, 0xabac1b36, 0x42645858, -0xa23be2bd, 0x8eb720a5, 0x2c58a8e9, 0x29408f09, -0xe1b0aa49, 0x4722d05f, 0x910d54e2, 0x8491f888, -0xd0ae52c5, 0x18f6e065, 0x911a182f, 0x7f168700, -0x5123c966, 0x2a252296, 0xfee807f6, 0x26280152, -0x90652cfc, 0x35b183bf, 0xdcde9302, 0x74e8972a, -0xab7cc23e, 0x26eda460, 0xc001b128, 0x84707b0e, -0x539306e9, 0x913b0f90, 0x66e1ab96, 0xde542ae3, -0xdb6ce644, 0xb4d5599d, 0x7501c86c, 0x7b7ad8f6, -0x8fdb7ced, 0xc223cb51, 0x101d6f82, 0x2b4b4d40, -0xf316ca09, 0xf82448e4, 0xfdb78e8b, 0x43c97f26, -0x19fd1f6e, 0x35f7b494, 0xe554254b, 0x38e44005, -0x1cc52cf5, 0x9b18f9cf, 0xc8b4f497, 0x972beacd, -0xc7c02f7e, 0xc54b8178, 0x905d189d, 0x9377d0c7, -0x42cec05d, 0x368d5dde, 0x0831dda8, 0x91d0e463, -0x4f5b6bbe, 0xa30bc81e, 0xdc147871, 0xf5729c9e, -0xc9a8a1cb, 0x8a9e9acc, 0xa71f693a, 0xeaef07ed, -0x7b1b3bbc, 0x46be37be, 0xa0d15825, 0x8eec3706, -0x65d32239, 0x24266771, 0x3fd071ee, 0x9031fcfb, -0x7dbfe4cf, 0xc3da6ebc, 0x0f2ecd44, 0x52ae02ac, -0x49d9a1cd, 0x6b360578, 0xff162316, 0x5fd9a3c5, -0x066096d5, 0x85a9b332, 0x80cde40e, 0x8ad10782, -0xda0e7f22, 0x54a5062c, 0x64eebacd, 0xa909cec1, -0x1815c848, 0x3c82fce4, 0x263248dd, 0x001b049f, -0x6c7c9d0e, 0x6103f5b8, 0xc1751784, 0xe5c51efe, -0x67757506, 0x6f069d58, 0x8004bc6f, 0xcee45f60, -0xa8cd13d7, 0x73f12ca7, 0x086168bb, 0xf0696e47, -0x89df38ed, 0x47bac692, 0xbc1d6ac2, 0x201c6c7d, -0xb324d54e, 0x942dc7fb, 0x41fdfbb8, 0x3c6f9b31, -0xe561b931, 0x91b6c9d6, 0xa54bdd6c, 0xbf78b139, -0x84258eca, 0x5bd5bfec, 0x5065d94f, 0xacfe2889, -0x792d9965, 0x8a56940d, 0x3c8dba51, 0x5de60bfb, -0x2b9462c2, 0x644c7c78, 0x6c06baf8, 0x1704cf3d, -0x4c315039, 0xb6cee9ce, 0x0957c24f, 0x3f971eed, -0xa9b278ee, 0x1a0548a0, 0xe7ac0d12, 0xd45d647e, -0xbbba604a, 0x9624aaa4, 0x0928f918, 0xe7f9aa42, -0xe61c8a9e, 0xa24cba5b, 0xed023e67, 0xa38bb9c4, -0x620d22b2, 0x2ab0bc4b, 0xd0a23ea1, 0xf8e13620, -0x05b3ba18, 0x746e09d0, 0xd9e7eff1, 0x4e396da9, -0xa78066df, 0x8deb6add, 0xd866cef3, 0xe563bbda, -0xc22c3bdf, 0x10a89f2c, 0x4102ffd4, 0xe86208ed, -0x0e8efc89, 0x0e75078e, 0x7d59a077, 0x5986f2be, -0x1a3cbc73, 0x706e21bb, 0x16c06ae4, 0x89c7fca6, -/* 2623-m011067660C.inc */ -0x00000001, 0x0000060c, 0x01192008, 0x00010676, -0xfbac0f6c, 0x00000001, 0x00000001, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x0000060c, -0x00000035, 0x2e000000, 0x20080119, 0x00000301, -0x00000001, 0x00010676, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc8f5cd92, 0x30bd1beb, 0x77c4fb8b, 0xe899c960, -0xc729b4cd, 0x1d9b8923, 0xfcdfc554, 0x580d39f9, -0x170ce7c7, 0xd727c705, 0x019b1ba5, 0xe0414a29, -0x57d45458, 0x26a8a411, 0x9faad966, 0x095ec8b0, -0x083a7c2a, 0x17cfc70f, 0x3c8e78a8, 0xce18c419, -0x5f2ddeb7, 0xc9c95d71, 0x437a5116, 0xe0253ad0, -0xec78db42, 0x681e436f, 0x7fd028bb, 0x1149a501, -0x0bdf0d05, 0xc2321514, 0xd6866cd8, 0x64942685, -0x21e0276b, 0x0817a288, 0x09138669, 0x792985dc, -0xbd60d6aa, 0xfbf902ec, 0x43fee69d, 0x5c5823c0, -0x9dca1fe6, 0xb528b0c5, 0x22fd29ab, 0xac4fe251, -0x77207813, 0x0637a1f9, 0x16bfcf73, 0x80497f6b, -0xe5bca939, 0x1539fa1a, 0x66607fea, 0x2276c06f, -0xd003229e, 0x3622fda7, 0x18d0b8af, 0x9f399760, -0x3ac6387b, 0x6c7148fa, 0xfaf4df9f, 0x965db840, -0x7c142542, 0x7b805f4c, 0x3f2002a3, 0x061399ce, -0x2f1a03c4, 0x7f1c7616, 0xb2f9ab42, 0x4e6a92a2, -0xb44b96d6, 0xe1167017, 0xec4b2fb3, 0xa15376be, -0x00000011, 0x4872f26c, 0x88971c10, 0x66db1385, -0x1e532ab2, 0x7ccd2d72, 0x38dd766c, 0x131f4505, -0x7d5e1e0a, 0x1932938b, 0x79c1db9a, 0x9fe5b8bd, -0x07037c1a, 0x698cd351, 0xbadb5300, 0x063f17d9, -0x8558ada3, 0x224c2288, 0x26fa35b3, 0xe64efb19, -0x0e1b52db, 0x696d5461, 0x3a0f765c, 0x4b853dfe, -0x05147b28, 0xbe146518, 0xb61e1de2, 0xc342998e, -0x083d5f41, 0x737fdbb5, 0xdd812ce1, 0xa7b9549c, -0x164b5fbf, 0xaffd6139, 0x44154437, 0x23d44899, -0xbe41eae1, 0xeecc8d45, 0x31fc971a, 0x44475238, -0x5d4ab69c, 0x67f342a0, 0x118cb268, 0x513fb847, -0x0a86fce3, 0x23f22535, 0x5fa15360, 0x929aa833, -0x3cbd4138, 0xc1dead1e, 0x3efa210b, 0x9781a61d, -0x00b53f73, 0x07df4d30, 0xffe97322, 0xf7b12998, -0xba4d7316, 0x4b746898, 0x45ece500, 0x78cf31d5, -0x0208c1c6, 0xc3999e15, 0xce2f90f4, 0x7e130a0b, -0x3c74ce12, 0x37612fd2, 0x7ce3ae15, 0x99a26321, -0x52ac391f, 0xcb32f7e1, 0x0e50140d, 0x3a6bfc41, -0x497f7f9f, 0x334b7e17, 0xbcf4e41d, 0x3311b0db, -0x0dc65367, 0x44847807, 0x991c439a, 0xd2965df2, -0xfd72e4fd, 0x44b01f14, 0x5a0cf5c5, 0x70029e37, -0x92af3f34, 0x47949bdf, 0x771a3c07, 0x0874f372, -0x7a54670b, 0x7430b00b, 0x356234f3, 0x74edf1e6, -0xaaf60a4c, 0x2bb5eee4, 0xc2c1d43f, 0xc4ee788b, -0x4198fd90, 0x0aba19a3, 0xc251f028, 0xe42404df, -0xccbd25f2, 0xdb13eb69, 0x888f89a5, 0x5a6c8cd3, -0x1e3b469b, 0xe07e48c6, 0x87f25228, 0x64324c03, -0xe0426f9f, 0x148f828b, 0x4a3c82ab, 0x7d46539d, -0x0b5079ea, 0x2c675b3e, 0x83134717, 0xbe775c77, -0x74841ec3, 0x4470addb, 0xfabfa06d, 0x548757fb, -0x184ea712, 0x502765b5, 0xd7067ce2, 0x15afee11, -0x8a95590d, 0x3a1734cd, 0x212c7f7d, 0xe5aa3e5b, -0x9c7e75c3, 0x07486966, 0x5827bbea, 0x391e46fe, -0xc6acbc9e, 0x9761b6a9, 0x37bef8c4, 0x733eb81f, -0x7ac9a87a, 0xceacd157, 0xd931072a, 0x9383c10d, -0x5eae74ef, 0x5f82f6a0, 0xcf89077d, 0xbc641bd8, -0x1b7d1213, 0x980a4ed3, 0x410fa7e8, 0xaaa1a011, -0xa5e94ef2, 0x74937d5f, 0x3c109f67, 0x8e58bdcc, -0x2b43ad95, 0xaa516349, 0x6fa9cca2, 0x48a18062, -0x663c7fd7, 0xf3822d87, 0xbaaf1f97, 0x8da372b2, -0xa416831b, 0x6a645364, 0x9c7ac6fb, 0x3f5a9cab, -0x8cf6f4b4, 0x514fd1dc, 0x7e9d0918, 0x2075f774, -0xfda8677b, 0x3b5c16ac, 0xe887694b, 0x7d622e9f, -0x5427472d, 0x540e5c99, 0x2196e138, 0x5d5e9c58, -0x84a5fc17, 0xb17d6d41, 0x63273bdf, 0xfbb912b5, -0xaf16b7c1, 0xeb1914d7, 0x5d654b8f, 0xf4a594f6, -0x554a6311, 0xb391f519, 0xa5ad4acf, 0x9c052bb7, -0xea68faa7, 0x37399a25, 0x8f6f6d36, 0x47c20f2b, -0xf241ab98, 0x66da024d, 0xee90a06a, 0x33718b17, -0xaa89087e, 0x6dcca7f5, 0x43a59f0e, 0xcb2e3ab8, -0xb19126bb, 0xc56bccb3, 0x04f6fd9a, 0x0f63850e, -0xa2b6c85e, 0x309f9817, 0x7252b154, 0xcba20ff3, -0x143156b8, 0xcfcdc8ae, 0x13c2a75b, 0xea4bf1b8, -0x6e474959, 0xa9c376f5, 0x40d252b8, 0xb6209e70, -0x993efa22, 0x3d7e8007, 0x1857ba0d, 0x72f25310, -0x233a8f68, 0xeb4ca923, 0xb17917d1, 0x9ca3f4f6, -0xdecf1498, 0x99f5ddae, 0x8b6ba2b7, 0x54f41fb0, -0x1ec9ffa2, 0x74ad3bd6, 0x84fee3e6, 0x5294820d, -0x147e8b14, 0xd2dc15f4, 0x152fc744, 0x306bc043, -0xfdbb74d8, 0xf4ea207c, 0x53edfac5, 0x1b609795, -0xe990ee73, 0x749dbed4, 0xd1cefc95, 0x5c7b37f6, -0xc6b39045, 0x7281e3f7, 0xed0e6aa4, 0x590a246a, -0xe6e6a81d, 0x604491ac, 0x6cd14e8a, 0x7a19f5da, -0xf7c7326a, 0x0ef8029e, 0x0e741b48, 0xc962a062, -0x6f4ad86e, 0xa2729726, 0x93bcaf1f, 0x1bb56970, -0x12495cdc, 0x180512e7, 0xa1d68081, 0xb924c24b, -0x5a1461ca, 0x21438ca9, 0x5449ae48, 0x0f564503, -0xcec8df3c, 0x789f9b80, 0x5a708df1, 0x28735bfc, -0xcf11d2fc, 0xa5d01625, 0x80b0b533, 0xa09f026d, -0x1d22fdf2, 0x01928228, 0x8b6779ed, 0x04f7cc95, -0x581fe0b2, 0xcc9a66a4, 0x55b3f130, 0x0f22abed, -0x05b7e95d, 0xd8cc9c30, 0x0850ca8a, 0x34d729dd, -0x973300a7, 0x80ffedb1, 0xbf5b28e7, 0x135c8cc6, -0x4337b017, 0x31d8dd09, 0x35ed75a1, 0xb8f990b9, -0x4384dc18, 0x29d72b56, 0x021aa2b2, 0xa3248b3f, -0x5f4e7301, 0x29991927, 0x1cc50c18, 0x79fcc545, -0x56e2e683, 0xe5127777, 0x4b727957, 0x94d1bc22, -0xacd0da9e, 0xd24771fd, 0x5997ff0a, 0xb9947cb8, -0x8cb9bb5c, 0x16a4c5e0, 0x00d6995f, 0x1e05edff, -0x3a7f1af3, 0x445fd70d, 0x24a602c7, 0x6b50001a, -0x6c99f5e5, 0xad2c00c5, 0xbd16a90d, 0x3b7b6032, -0xa8dd4f8b, 0x437145f1, 0x5a593d5f, 0x749ee409, -0x9c6d8223, 0x40c1dad0, 0x578e7e1f, 0x89072e7b, -0x0ccf47c1, 0x427606d8, 0x4a7bb48c, 0xf85cc4e9, -0xca5ca3b6, 0x9b989f23, 0x6496403f, 0xdf8ef891, -0xf4458e90, 0x28eed125, 0xef91afe9, 0x97a8d65b, -0xe022b3dd, 0xc93c2adf, 0x520cbe7c, 0x58995018, -0x719a724a, 0x9258733f, 0x8df05767, 0x879b9ba1, -0x84684054, 0x71a62082, 0x5be959cd, 0x12c937ec, -0xc21fb3b8, 0x6738aa89, 0xb01d872b, 0x0ff6ec3c, -0x50fc63ea, 0x715b7c5d, 0x4e5d50c3, 0x086c862e, -0x34ec9201, 0xd41176ef, 0xd0238088, 0x53518100, -0x8e1500dd, 0xc6ea9594, 0x0359517e, 0x58d81a35, -0x48c40983, 0x2d562dc6, 0xecf5be9e, 0x4cd82ead, -0x45faeb2b, 0x1a66ec1c, 0x6b692a76, 0x6cb326b0, -0x3a6c362c, 0xf0174da3, 0x5e4549d9, 0xc12c5972, -0x73716059, 0xdd54591d, 0x32ee704b, 0x5a55c22d, -0x56bd1e7e, 0x2bd34024, 0xa42c85d2, 0xb1ce248a, -0x604a7570, 0xbbf4b3fb, 0xe0eeb866, 0x130b7dd4, -0xdb39dc1d, 0xd873b0c4, 0x3aedb6ef, 0x5efb2481, -0xbfaff9bc, 0xb94930d6, 0xa3fe71cc, 0x75867e01, -0x7c8ee191, 0xf38f4963, 0x8d077957, 0x658e7c2b, -0xc1bd58ed, 0xb86a20b2, 0xc624489c, 0x4624732d, -0xc11f1ee3, 0xf1874ed7, 0x173684cf, 0x0e5851d4, -0xc2662118, 0x13dbb926, 0x1668df5e, 0x00749d03, -0xab9530d2, 0x5758e602, 0x6db90ff1, 0x87270f9d, -0x774a52f5, 0xcd1b4b5a, 0xd706025e, 0xe3a51fc4, -0x31c5d55b, 0xbd0278a1, 0x16dce1bf, 0x75a3446f, -0xe030c121, 0xa6f6b3c8, 0x504e3b3b, 0x4c1428b1, -0x74229a60, 0x25d5b7b7, 0xea284c21, 0xf5f1c7cd, -0x0025e9fc, 0xa7db9e56, 0x4e3aeb90, 0x8bad0f3b, -0xc19e88eb, 0x8ea86b83, 0x25cf5d26, 0xca78504e, -0x94109c06, 0x60ad3975, 0x138b8038, 0x4c9d8fdd, -0x28a91526, 0x5d3d6c3a, 0xf81ab861, 0x8db34426, -0x35a3b398, 0xf3b40170, 0xb7e6994b, 0xea72c1f5, -0x63201cd4, 0x1c5749dc, 0x420ada27, 0x419f4847, -0x49244543, 0xb915645f, 0x3a00b3e2, 0x0122000b, -0x296b6bad, 0x7b45d76b, 0x5be8f025, 0x2a04919f, -0x8291fea4, 0xaae644f9, 0x7af3fb96, 0x77d9878c, -0xa8996848, 0xa9a0c1c3, 0xb47ae6d2, 0xc5b6cf90, -0xb04b4863, 0x43fa113b, 0x66ef4993, 0x03a5b4e9, -0x94b661dd, 0x145a5909, 0xd42f70cc, 0x6b816775, -0xfbc0cb04, 0x5e890eb1, 0xb6900305, 0xcd19304b, -0x85c67d21, 0x19e91907, 0x27b3898c, 0xe0ce6ba2, -0x4110d80d, 0x85953740, 0xba7a4225, 0x51db6dd9, -0x04c21ffe, 0xd34ef7cd, 0xeb13f075, 0xc1f8eb04, -0x19a1227a, 0x3e99efae, 0x318346e2, 0x3d4c73bb, -0x402dacc7, 0x5a9e892d, 0x01304401, 0xb3950c6f, -0x9254bea1, 0x5cc8f025, 0x53cb9416, 0x52d716c5, -0x3ff575a5, 0xede2046b, 0x2cbd6b85, 0x7e8feb25, -0xc2d35482, 0xa49b8495, 0x214fed4b, 0xc93ae54f, -0xde3d8a18, 0xe4456b47, 0x505555c1, 0x6418926d, -0x4b6ac1e7, 0x7ac213ea, 0xc081eea5, 0x467ff1c3, -0x1ed5d79d, 0x746dbb24, 0x38b1dbde, 0x4d495fc0, -0x7ddabfe1, 0xfbac0ba1, 0xd17cfc3b, 0x32c819f3, -0x1f4c39cd, 0x6fa5c3ed, 0x0d2e7f50, 0x1f5cb318, -0x1e1770d1, 0xef12c293, 0xb149ace5, 0x93df9bdf, -0x14a98319, 0x3374906f, 0x746d603f, 0x5a368e6d, -0x8dbaef76, 0xb7923f42, 0x607655cc, 0xd144703c, -0xa01fa0f6, 0xa83f4e65, 0x224bba03, 0x6e082d15, -0x11ef27eb, 0xad91427e, 0xd8f0e3bd, 0xba7bc3df, -0xdb031557, 0xf33052d0, 0x2bc3df37, 0xf55d25c2, -0x99af998a, 0x5819eb07, 0xe4b9ebc5, 0xbc3da46e, -0xde1abe71, 0xb8c66434, 0xe811e29d, 0xa48ee5e6, -0x7f961c60, 0x5500769f, 0x9c8e0d00, 0x94680cea, -0x2f7a0c5f, 0x9a058310, 0xd3ddca08, 0x74276c4c, -0x855ebef2, 0x61979f79, 0x09684303, 0x3ea777dd, -0xf700db1f, 0xdf7bcae0, 0x0fa7db2b, 0xd0115231, -0xc0015882, 0xe4af6f72, 0xb4388c7d, 0xfb5656bc, -0xbe1d38b3, 0xf59ae9d3, 0xddc692bf, 0x3aaef998, -0x561f993f, 0x4d191a40, 0x4492df05, 0x7eb17670, -0x0770001b, 0x9b320a87, 0xbc8a559a, 0x19781e02, -0x13c995b1, 0xcb8c1e47, 0x462019e3, 0x7ee6bcc1, -0x9da2afce, 0xee1dbf76, 0x3a72ad3f, 0x711f786a, -0x0c72d639, 0xa3455dc9, 0xef155308, 0x82f3e1c9, -0xc9540414, 0xcec2cde1, 0x748005bb, 0x24197d5d, -0x4b8b7f7b, 0x3dde3129, 0x9ac952c9, 0x6f7932a7, -0xa99005e4, 0x4261280d, 0xfad329af, 0x90bcacb3, -0xe1c4a202, 0x9200d928, 0xffe55142, 0xf69b2a40, -0x227783a3, 0xe4b0c9c4, 0xeca97ce9, 0x9245597d, -0xa922db08, 0x94bff912, 0xdbebd937, 0x5c658f30, -0xb3f4a726, 0x24e2ca27, 0x9ca037d7, 0x745d3d5e, -0x3e8c437e, 0xb807af86, 0xee5fa977, 0xfe335297, -0x5c0a6707, 0x8ab801af, 0x05d02766, 0xcd0906b4, -0x791b47d3, 0xff5a0291, 0x09465b16, 0xa7fff3a1, -0xe2e6d825, 0x7f4f2b9a, 0xc1f2e668, 0xa5cfe1d6, -0x95fd7bde, 0x38681314, 0xc3c7dce1, 0x7b82e044, -0x2c883c77, 0xe8aa72be, 0xd53867d7, 0x7022fdc3, -0x3b697ccd, 0xd71618ac, 0xc87934bd, 0xe96101d1, -0x55d1976c, 0x471c8505, 0x7a36d839, 0x5d62a9ee, -0xf3c54a8a, 0xa2be15d9, 0x244087c9, 0x042c8037, -0x23224689, 0x281c5d73, 0x2139ecfc, 0xffb8bc8a, -0x834fdd11, 0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, -0x4ae2dbda, 0x86d90089, 0x6675dfce, 0x48876262, -0xcec72538, 0x11dc5c80, 0x86a730f9, 0x313565c9, -0xe3e5be11, 0x106d7cce, 0x752b8be2, 0x3d00a5bc, -0xe6f70e95, 0x44447ac8, 0x600df30c, 0x8335ac3b, -0x8816ddee, 0x700982fe, 0xee495741, 0x48c7e81c, -0xa3d55da2, 0xb0172982, 0x70ab2158, 0xd4460621, -0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, 0xa8454763, -0x70877bb6, 0x66005c97, 0xaf292c06, 0x7b843db1, -0xf343b59b, 0x25cdc7b5, 0xa41da617, 0x9e9d895e, -0xc936f475, 0x7270925a, 0x30024230, 0x8e72f53d, -0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, -0xaf377cc1, 0xbff09a78, 0x4b4e0814, 0x95a0b2c1, -0x270398de, 0x201fca94, 0x2a032a4f, 0x131542b4, -0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, -0xa3b3a991, 0x17ee60c2, 0x852c0b8d, 0x11e5853a, -0x762002a7, 0x92c5311d, 0x0d4bf7e1, 0xfffec870, -0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, 0x0111a772, -0x9808e780, 0x29c336e8, 0xe9bc05df, 0x5bedde11, -0x945565af, 0xaff808fe, 0x87e3423d, 0x4de6f98f, -0x93b4adef, 0xbf704fa4, 0x09120e91, 0xd54f3692, -0xdf8eab1e, 0xfabbf59c, 0xe74318be, 0xaab87ffc, -0x29fa791c, 0xe3915552, 0xa652cb9b, 0xa1252e74, -0xb35b723b, 0x542aa28b, 0x12fcc5b0, 0x3941f962, -0x82bcc6cc, 0x47b11974, 0xb821611f, 0x78b34250, -0xf1be5659, 0x561b9e61, 0x6f3bd501, 0x584e6f5c, -0xd54ed547, 0xacebcd21, 0x7b5ff816, 0xb64ad233, -0x9f2f330d, 0x69fb1ece, 0xac8710dd, 0x58dc6c60, -0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, -0xa733274f, 0x884d9b55, 0x42b08b63, 0xafa54a74, -0x1c7ccf64, 0x93a20191, 0xaaa3132e, 0xc69831d1, -0x54634889, 0xfbfe3efc, 0xd3cf68d4, 0x302e3117, -0xf5693131, 0xc3ce8c6c, 0x1f03cd89, 0x6243334c, -0xf16bc80f, 0xdca5f130, 0xcb2cd956, 0x4c1bb421, -0xe8de533c, 0x7f86703a, 0x29aa897e, 0xdd54acad, -0x76b2f2ae, 0x7ef82b71, 0x2e30970b, 0xba402597, -0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, -0x2363d147, 0x5327289a, 0xe89229f3, 0xd63a535c, -0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, -0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, 0x6d65db4c, -0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, -0x8488a45f, 0x8ebc2932, 0xd4767316, 0x3e8c4b8a, -0xbab7402c, 0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, -0xc88528e9, 0x4b2e4e8f, 0xdd938b86, 0x0c964f98, -0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, -0x4d40b3b3, 0xcf203155, 0x0d2fa621, 0x752d2c58, -0xb12bac12, 0x1e7e8c23, 0x94215d54, 0x9854a71c, -0x4de63c64, 0x7a012529, 0x9c171f8d, 0x9e71def7, -0x3bd17d50, 0x11f175d9, 0xec78abf3, 0x7b529eee, -0xd3a69fc3, 0x5b718676, 0x58214d29, 0xa8bd2c34, -0x41ea00ab, 0xa03f64d6, 0x4ee342b0, 0x32b1e444, -0x1c1801a4, 0xc8424702, 0x334a7e35, 0x50cf1543, -0x3b22b495, 0x88683776, 0x8e2e0154, 0x6155c033, -0x4e2fa6ac, 0x42ace700, 0x8d64f97c, 0xaf9ced17, -0xb2a5cb92, 0xa558582d, 0x88705de7, 0x9e528d59, -0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, -0x10462123, 0x30080f7d, 0xb346cd81, 0x0049c396, -/* 1638-m01f6402.inc */ -0x00000001, 0x00000002, 0x12152005, 0x00000f64, -0x680b0995, 0x00000001, 0x00000001, 0x00000bd0, -0x00000c00, 0x00000000, 0x00000000, 0x00000000, -0x2aa0fbf9, 0x0920514d, 0x0f5f4463, 0x49035ded, -0x6522b40c, 0x0a3de93c, 0x28b44f2a, 0xa2a1b504, -0x685e4587, 0x991d06f2, 0x31beab6c, 0x3d1deeef, -0x2c1eba51, 0x7a1b9963, 0x291de54b, 0xbc3e2586, -0x0dcb034d, 0x28d224ee, 0x29e99d05, 0xe1a45aa4, -0xde6898fb, 0x805f3396, 0xbf00384e, 0xe23a9d63, -0x9d41b622, 0x70ae7613, 0x831bd461, 0xaad0d965, -0xbf2ae85a, 0xfa137a91, 0x85df55c1, 0xc1aea248, -0x8a813fe2, 0xe4185e04, 0xc27ca165, 0x89fa4907, -0x779e9d32, 0x73b04b9b, 0x6f5f3f42, 0xc0b7e114, -0x60321122, 0x55eae809, 0x9e3ce356, 0xb7de5c44, -0x27f03183, 0x883bab30, 0x72fdada5, 0xe08c88d5, -0xbfb70e47, 0x38135179, 0x97511d61, 0x7e96ebe6, -0x7336a70c, 0x9c23d4b6, 0xb45d2d9d, 0xc22ddf82, -0x149692a3, 0x71c4a8a1, 0x5895e53b, 0x219ed674, -0x68dcdd5a, 0xeda85f71, 0x90f7bc99, 0x52ae6b46, -0xedc55856, 0x8e1a9cd4, 0x77cf2d86, 0x0d412073, -0xe0068d6d, 0xe35ac61d, 0x5cfa5431, 0xad966a57, -0xe251e7dd, 0xccb4624a, 0xb5cba1db, 0xdc151b9d, -0xb1de5d60, 0xb8411488, 0xf02cf584, 0x1f5dab6b, -0x3d27af78, 0x31c58e8a, 0x5f19bbb0, 0x1d89667e, -0x26066d77, 0x7598664a, 0x71b427db, 0xf3331025, -0x20d589ce, 0xfe80da85, 0x2d471abb, 0xcc2cbf7c, -0x1c69cebf, 0xd91ee715, 0x86dba558, 0xed6dec4d, -0x9e05a3cf, 0x343028f4, 0x4b672fe4, 0x9b9a3d02, -0xbd8a9fdb, 0xe6d6bcda, 0x652e09c6, 0x7815a3da, -0xfc8ddfa6, 0x179f4178, 0x2b081ce5, 0xf62f9c48, -0x891144db, 0xf52ce311, 0x20d4bb33, 0x02264e2b, -0xacda3a1e, 0xc32c2309, 0x4d5f375a, 0x67778588, -0x23fd318a, 0xb186b35f, 0xb03dfd87, 0x96ce2b56, -0xc298c4ed, 0x5b2c00a9, 0x23e876cf, 0x87cc079f, -0xf73b41ce, 0x82848a82, 0x344587ca, 0xecef8ea4, -0xc4bd9118, 0x831dca57, 0x1de86e11, 0xba5aebbe, -0x5ed0eb16, 0x9d939161, 0xee43130b, 0xd67a1c2a, -0x6abd7cc8, 0x47f5540d, 0xeb7d000c, 0x1c3a6a85, -0xe84074ce, 0x3ad84c1a, 0xa1b1fa49, 0xff605725, -0x81fbe321, 0x3286160e, 0xcfef091f, 0x3526dbbc, -0xd3b2e8f3, 0xf4475cb8, 0xf0cd8d6e, 0xcd998bc8, -0x4a70fff8, 0xc8771b66, 0xe75e6cf2, 0x7bcd3c8c, -0xcf19fbf9, 0xb2c69de1, 0xfe572f00, 0x19c37ba5, -0xf482275a, 0x097442ba, 0xcff47908, 0x206214c1, -0xd53de8ab, 0x2e1fdc6f, 0xcd626594, 0x91b03f12, -0x442489fe, 0xfba5fb8e, 0x4b56f219, 0xc3857762, -0x4dc3f4d1, 0x9c824a53, 0x12f1288e, 0xb58d61fb, -0x77335b01, 0xf867712b, 0xfe3608fc, 0xd589039d, -0xee7efebd, 0xa533b187, 0x945ba37d, 0xe5e97e1b, -0xd039c7a1, 0xa62994bc, 0xf8d381da, 0x68a2aa06, -0xdd86907a, 0x56bc796c, 0xf22ba84f, 0xe1d1e168, -0x46fb8d21, 0x8d7042f4, 0x92092de4, 0xbe5325e1, -0xeecce748, 0x93b3dbbd, 0xa5d7de6a, 0xb4947424, -0xec1dd912, 0x9728193e, 0x7251c760, 0x4b58fc0e, -0x4bec8722, 0x194af36a, 0xa46a6dff, 0xfd37580d, -0xf3ea1f9a, 0xdeb7756d, 0x0f94c7cb, 0x4eaf5c3e, -0xe47b4cd6, 0x346c597e, 0x10f80e17, 0x79facd91, -0x40e8619d, 0xe8ae8d3e, 0x6376a64f, 0x372112fa, -0x0a5b03fc, 0x7e9dad8c, 0xb5a059b2, 0xc31ea7c0, -0xc0ec4256, 0x7848cdf0, 0xea5b6e70, 0xa6e2c4f3, -0xf42895e6, 0xbb2d8017, 0x53fa34c7, 0x872491ec, -0xd926211c, 0xad7a1784, 0x02a3eb5a, 0x7a631dd2, -0x7747a504, 0xfd6b8d11, 0x88cfdaf2, 0x0483946c, -0xe51ddc78, 0xe7c9ac65, 0xbeae254f, 0xccb8cc74, -0xe1d0cf5e, 0x1637fc82, 0xcefd605b, 0xba5c6bf2, -0x021670a4, 0xca0c87dc, 0xa998a05c, 0x371cfe63, -0x653595ab, 0x9b977d0a, 0xa2fe7aa7, 0xf299c041, -0x2cb80494, 0x4a2c724a, 0x5d91a463, 0x8ba91806, -0x1df92cc8, 0x05646e0b, 0x84c992de, 0x6583aa3b, -0xfef41b16, 0xe715b32d, 0xa82eb0a8, 0xd7b75129, -0xca4773ab, 0x711293b5, 0x9c8367c6, 0x0f23fdc2, -0x8e0468a8, 0x0ef8e40a, 0xdcc97a23, 0x216b9e7e, -0xde894a7a, 0x3b00e797, 0x39865b8e, 0xb9eab71d, -0x18651f98, 0x729584e1, 0xc4d2351a, 0x6be95b57, -0x2a4eb069, 0xff2eb911, 0xe701af65, 0x8fd6b486, -0xe68b3390, 0xde465144, 0xc33eaade, 0x0c5187ac, -0xf748bfbd, 0x17a7b2d2, 0x58e7dc21, 0x033a6699, -0xc54edd45, 0xb7aba6d1, 0xa5ae6431, 0xdeddedf0, -0x44bbd637, 0x3659c9e8, 0x70030194, 0x1083d96a, -0x2a232c89, 0x8e94b9b1, 0xa7fdb315, 0x0d48c881, -0x5100c635, 0x0c6b69b0, 0x75dad240, 0xf19f27ce, -0xd35b1f9a, 0x9de9ebd2, 0x77fa6c9c, 0x44fd5d62, -0x979af1da, 0xc650c06f, 0xc7e065ed, 0x3f2d1c33, -0x293d510f, 0xc64ec98a, 0x54f1c830, 0x293de2f6, -0x250de0d4, 0xb1dc4746, 0xa2935d05, 0x58736739, -0xbc555a89, 0x8b887d7a, 0xdff42f30, 0x0859eb5e, -0xbca8e48c, 0xf035f4e8, 0x43367c2a, 0xade42a6d, -0x086136fa, 0x2f33b875, 0x3b0929f1, 0x1ba4ca5c, -0xc1ca6291, 0xbf3b1b5b, 0x4f3dd6fe, 0x7e735ec4, -0x3c7c0df0, 0x971f7d71, 0x4e437259, 0x8a46664e, -0x9f954b5f, 0xadac3dfc, 0x32539e93, 0x4e1dc466, -0x1f7addbc, 0x2af6fbfc, 0x633dae60, 0x67e6fc87, -0x757a1372, 0xf6de0e7b, 0x946c644f, 0xe8e70544, -0x5ed94705, 0x27687c6d, 0x16275ba0, 0xc854565c, -0x08990758, 0x93853a95, 0x0d02f5be, 0xe1d83a60, -0xdf5b711b, 0xc54eba7c, 0xa854ebe4, 0xcf59362c, -0xcef1ef1e, 0xe95efd66, 0x41b2f303, 0x554c80c3, -0x24d9df54, 0x015a145e, 0x8b432368, 0x9a52ec77, -0xc5dc324b, 0x737a9b86, 0x8042868d, 0x6bc7a20d, -0xe0458277, 0x8fe3fe64, 0x0135a93c, 0x70c523ef, -0x0584da30, 0x30cf1d1f, 0x9a449c5c, 0xc2ac5466, -0x977092c2, 0x5b3d4e24, 0x6b0a8a7b, 0x422fd868, -0x303bf9b1, 0x481b7e10, 0xc7521b73, 0x22836ea0, -0xc2610907, 0x9d8d643f, 0x1a8fc938, 0xe89ee885, -0x014d696f, 0x280afeb3, 0x45a6abfe, 0xf006f2b2, -0x80cc5307, 0xd589a95d, 0x4cca87f9, 0x8d6644e9, -0x105a4fa2, 0xee41331a, 0x0bb7fafe, 0xd1fcaa5c, -0xb9bf50e9, 0x1407d551, 0xffca0924, 0xb08150de, -0xc8b0b4c1, 0xe3fa725b, 0x69d0c9e4, 0x9b8e168b, -0xaae29701, 0x0615c226, 0x107336c5, 0x90577f89, -0xa3c5bb82, 0xe445834d, 0xe18e8c0b, 0xd1bb9842, -0x150048e6, 0x07596bd5, 0x85e8eda5, 0xbbfbf266, -0xd7be05d8, 0x1322fe19, 0xe31e041e, 0x2812cbf1, -0x65feffa1, 0x1eb2adc2, 0xf7a3e79b, 0x2a25420f, -0x3a902032, 0x09c7ccb4, 0xe184546e, 0xc1ae299c, -0x7b0f9198, 0xa2abca00, 0x4583143e, 0xa11832e8, -0xee7437f1, 0x8f819a25, 0xf19b7816, 0xe0c05905, -0x74f40d3e, 0x5e7f4863, 0xfd5654c6, 0xbd2f35d4, -0x60db4685, 0x7c36155d, 0x6092824d, 0x18918ded, -0x5ce2e316, 0x91e3ec9f, 0xbfb36d5a, 0x717688af, -0xfa576502, 0x4c7b3248, 0xea419722, 0xd767e76f, -0xc7272aa0, 0xa38d67f7, 0xd20aecf0, 0x2f7fbd22, -0xa7df9b1b, 0xe097f950, 0x79df27eb, 0x5f39778e, -0x3ad5752a, 0x27aea5a4, 0x3a82e739, 0x25acf07e, -0xb3289d97, 0x8c4e174f, 0x7a65c0f5, 0x0371df23, -0xe25e8bd3, 0xee3eb9c4, 0x3c6fd5a1, 0x6e8d042d, -0x30fec942, 0x6ab2e45c, 0xfe066a50, 0xde0f38a8, -0x13a3af8f, 0x6a3361c0, 0x60ca1d2b, 0x07ad00fc, -0x50fe83ad, 0xa9396ff5, 0x50710edd, 0xbc27524a, -0x27d564c5, 0x0435f0fa, 0x3eb3dd20, 0xe8f1f061, -0x56d320e1, 0xdfaf3f32, 0xcb109961, 0xbb7350c4, -0x76f35f33, 0xf1db6cbb, 0x5f316bc6, 0xfc0ee2e2, -0xcc7cf565, 0xb6048c11, 0x09827822, 0x5cd98dd1, -0xe44a295b, 0x14955177, 0x1b77cbc6, 0x55a3a1ba, -0x166371fb, 0x7bb42477, 0x7b25d45f, 0x3489c70b, -0xfa02e8e6, 0x5809782f, 0x354432f9, 0x08a90382, -0x635638cb, 0x2f0ee04a, 0x8ae68f6c, 0xc4d31358, -0x13b8901c, 0x00c662c1, 0x2c631f55, 0xe455f4fa, -0x9ae3aa89, 0xe8b86e2c, 0xdb1306bb, 0x545bf955, -0x95e6a296, 0xc42d0046, 0xa530a448, 0x324a510c, -0xfc9c7421, 0x64d87b31, 0xb0593335, 0xfbea778b, -0x5099360c, 0xb25943b6, 0xcf0782fb, 0x16a23d00, -0x3afd30d2, 0x4fb1f531, 0xc79bca40, 0xe4b00f11, -0x0c3dcfc6, 0x7c6854ad, 0xf2a76964, 0x3a84cd59, -0x77a1e58c, 0x876465fe, 0x3d35c698, 0xb20e0e79, -0x6b12dc23, 0x3160ab74, 0x66cac826, 0x33a3fe97, -0xf89a265b, 0xc5d02b52, 0x861a3ee7, 0x2871ddb3, -0x2c078ca3, 0x0c1c252e, 0xafb33ab9, 0xb34d57c5, -0x8c1a4366, 0x943ffbf7, 0x165dbdf4, 0xdf640f5c, -0x5c8e5c82, 0xdda5428d, 0xa6a1e13c, 0xd38d2506, -0x3c202eb1, 0x1a919c94, 0x28b88521, 0x0406f03e, -0x805e913d, 0x2cc0ddca, 0x9aa888ff, 0xc08a34d6, -0x5c594f64, 0xc09b6e6e, 0x118a80d9, 0x362b8fca, -0x904207f3, 0xde0a40ad, 0x6704f390, 0x590ed66c, -0xca9bf353, 0x9ac7db3a, 0x662ce8a5, 0x01afb889, -0xa907c282, 0x3b0944d0, 0x574a26a3, 0x618fed95, -0xa3b49dda, 0x63c8cc70, 0x5e9c3d8f, 0x5ad8da59, -0x5774014c, 0x42be9ae3, 0x35d9ae0a, 0xce68e46d, -0x631ac0d7, 0xe5860908, 0xf710f514, 0x1a77a922, -0x2e003a2f, 0x798dc39a, 0x087c5233, 0x9d3af931, -0x97d3681c, 0x8ddd2762, 0xbeec6447, 0x63634eb7, -0x59c45121, 0xb8ff5a98, 0x0fb972c8, 0xff4f383f, -0xda9ff9da, 0xb5708dcd, 0x3f15cc70, 0xb09ad02e, -0x25bc07b9, 0xd0a8de39, 0x4e3d3172, 0xc6c92539, -0x954e86a4, 0x3cd5fe1b, 0xf7d174b4, 0xda209a60, -0x37f469f4, 0xbe461bd2, 0x102e07b3, 0x18fd0fe7, -0x5604a127, 0x9420586e, 0xb474ba16, 0x36b3fed0, -0x67d0bb5e, 0xfe037ee8, 0x79a250ab, 0xac848520, -0x3a2fd96f, 0xe660f9ab, 0x1d22d8f3, 0x18bd314d, -0xc1b69db4, 0x95f72d07, 0xa1fbe25b, 0xd139a56e, -0x3fe3ee80, 0xdaf8bca6, 0x3955a21e, 0x239d46c5, -0x5582946a, 0x89bae301, 0x907b5203, 0xca60d0d9, -0x9ca7262c, 0x06082c6c, 0x4db76a99, 0xb755c4c2, -0x50eaee11, 0x46cfda14, 0x083cda65, 0x985bbcc8, -0xef68ee29, 0xd7b067fa, 0xcb57af1d, 0x7b1b3146, -0x5546f9fc, 0xa1d6b862, 0x406bc5e2, 0x81ea8a9a, -0xcddece0b, 0x08663a0b, 0xaedaa192, 0x1c881ace, -0x8dbd163b, 0x9359b3e8, 0x7d962932, 0x9e604483, -0xbe3d3e56, 0xc2039fcd, 0x0bf135fa, 0xf408ca28, -0x3f73999d, 0x6c84009b, 0x16954d25, 0x4f879dc7, -0x84b652fc, 0x270ba149, 0x44395c75, 0x4a49e3b9, -0x45a51176, 0x316b10c9, 0xcb56a90b, 0xc830f743, -0x97865821, 0x882cd1b5, 0x834ee6e2, 0x5f2a7ed5, -0x9452d2d7, 0x0470a980, 0xbb4721e7, 0xa5cea044, -0xedce47e2, 0x2640b2c6, 0x44fd0fd5, 0xd6fa1c8d, -0x530dee05, 0xea4ead53, 0x60657d65, 0xb978aebe, -0x2b942957, 0x89d92de3, 0xab727498, 0xf5b21321, -0x4bb5677e, 0x85fac0eb, 0xfac033ae, 0xb87b4430, -0x3e76b019, 0x1c34a88a, 0xf88fb935, 0x38a90f7c, -0x1fad929d, 0x5bbe3de5, 0x9e2b1977, 0xe6817b9f, -0xf0377aa3, 0x9723c691, 0x2a96f63d, 0x5ea61072, -0xf3a2e3de, 0x5789aa3f, 0x4c2ed476, 0xfc943c4d, -/* 1466-m02f4116.inc */ -0x00000001, 0x00000016, 0x04212005, 0x00000f41, -0x0a12a70a, 0x00000001, 0x00000002, 0x000013d0, -0x00001400, 0x00000000, 0x00000000, 0x00000000, -0x23869663, 0x00e8d132, 0xded7a33f, 0x20662973, -0x949096f1, 0x63bc560b, 0x1649cf52, 0xda1410b5, -0xe2faf749, 0xb4913859, 0x679bebfd, 0x6ab2a769, -0x90c4108f, 0x80637ebc, 0xa09c95c7, 0x1244197f, -0xad414513, 0xb377c694, 0xf6515ef3, 0xd978899c, -0xec6e2ba7, 0x631b699a, 0xd91aaf84, 0xded4c08f, -0x99beedb9, 0x73701268, 0x0ddb3eb0, 0xa7f150ca, -0xcbba1f50, 0xbe41ed77, 0x3f67082c, 0x7444a7f8, -0x328ccea2, 0x8a4d432e, 0x20141112, 0x6e8ea818, -0xcc779408, 0xcb05521e, 0xce4cab4b, 0x7fc11e0c, -0xb8bcf352, 0x2116cfcf, 0x4a5f6828, 0x7bf277e2, -0xe8f61e84, 0x5494f402, 0x16818fdf, 0xb0f0094c, -0x5ef5b9ab, 0x44e58a4d, 0xcaeaf06e, 0xffbe13f1, -0xa272b4db, 0x2f2e1460, 0xf5c2353a, 0xfe3825af, -0x1db68bcf, 0x0cc12b45, 0x20ab67aa, 0x91ab4e08, -0xfaa46cbd, 0xcf5e6006, 0x06980e34, 0x18489795, -0xe4217f69, 0x6f7c566d, 0xf734be2a, 0x0d062834, -0xc23f2bdd, 0x9de5085d, 0xdfe30cb5, 0x40cab81c, -0x82cbd09e, 0x28846197, 0xd55b1faa, 0xb6800b2c, -0xa14b7d45, 0x7fae0619, 0x8f3d9a9f, 0xc023a5ae, -0x098c3336, 0x5dd86a06, 0x84259cb3, 0x4fd2c3da, -0x9a786bee, 0x2d883dd2, 0xbc819908, 0x64d9166e, -0x48ad8649, 0x748b022f, 0x072dbca3, 0xf0f98463, -0xf3887d52, 0x97f72615, 0x0ba8b369, 0xfa857e01, -0x06e45380, 0x6bb600b1, 0x3a6714a4, 0xec8cc32a, -0x7328645b, 0xe2da69fb, 0x9f935d2f, 0x8d5b0b67, -0xd7f889f3, 0x79d70f33, 0x11e17dd5, 0xffb3f194, -0x2c8dc263, 0x1d949384, 0x653bca90, 0x22dfc421, -0xb97d62ba, 0x23601fd7, 0xa411d616, 0xdd485975, -0x31525379, 0x860c97d2, 0xc8614c54, 0x93f25dfa, -0x6ca1c728, 0xf4bf089e, 0xa0fe052d, 0x781bfa09, -0xe8c27184, 0xd28fb8a2, 0x68ef03c5, 0x08f0d934, -0x71515534, 0xf8931da7, 0x09aec0cd, 0x2ce58a35, -0xc16fda14, 0x381844a5, 0x432c0e4f, 0x2b05676f, -0x76e4b1cb, 0xc5eafb96, 0xe57699c0, 0x2a6d6016, -0xfc536faa, 0xba6cd314, 0x74ef7abb, 0xfe27f9a2, -0x3efe7a09, 0x4ad2a897, 0x8afe50f6, 0x00dee9bf, -0x297ef8df, 0xb689118c, 0x48045b27, 0xccd4636b, -0xec098c3b, 0x3b3c2848, 0xb3ea4215, 0x9fd74b09, -0x521bcd18, 0xbabaf053, 0xab0e34a7, 0x97396e12, -0x0f145e91, 0x3b249de3, 0xd66367f3, 0x41f4c1e7, -0xa2cb58f5, 0x9710bcaf, 0x90a91bf7, 0xb09d0b34, -0x07fd9ad6, 0x0f3f0911, 0xe461eb38, 0x69031f51, -0x8188502d, 0x6c601820, 0xdcf5950c, 0x97ea6b0a, -0x0207b79e, 0xef5a8cf4, 0x6ab62c95, 0x462e7eb9, -0x75c7b30d, 0xc54d35b2, 0xe1bca821, 0xd242e982, -0x09f3d0a6, 0xc543ffc6, 0x0e685a9f, 0xa5b1b71b, -0xe5701af4, 0x2dc040a3, 0x53044929, 0x3e6f6e14, -0x6fbbf23e, 0xcac3733c, 0x3ba95030, 0x6e81be2e, -0xbc3834c9, 0xf2c28b28, 0xa9dfad41, 0x2635e8ee, -0x7078dc99, 0x1f7b87cd, 0x766422b0, 0x68209ce5, -0x72306bbc, 0x9cc6bf23, 0x26efd23a, 0x6fe8e3d9, -0x1062cfab, 0xd7e01157, 0xeb31e682, 0xa26d7555, -0xcc5e3d21, 0xdfa0225d, 0x5f5648ad, 0x2b509558, -0xcef77076, 0x859b7053, 0x3e98ad41, 0x21284f95, -0x8643f3ec, 0xf65a5913, 0x6885e3ba, 0x484a7388, -0xeee4f31e, 0x83b11f7d, 0x605fa7f0, 0xa3f75e1e, -0x1b543449, 0x65b1dfa0, 0xca68cae4, 0x95c2dcbf, -0x7040fdd4, 0xe9e1abc9, 0xd8b79e83, 0x80e0fc10, -0xe0978162, 0x791ae4f2, 0x6bdf0188, 0x889cda75, -0x6da66a3c, 0x1dfcc559, 0xdd6218e3, 0xe0aaf9d0, -0xf738daf5, 0x5201b42a, 0x64eb2511, 0x481bf645, -0x78d6a92b, 0x2773f693, 0x48523ff7, 0x30123068, -0x80e851ab, 0xdb56ba81, 0xc1f1e6af, 0x0b2d5ec5, -0x742ac78a, 0x95d62c16, 0x049b1344, 0x99df793f, -0x3faa4853, 0xc9f7beca, 0x6aafe81a, 0x4a5eba54, -0x46040095, 0xdc6db22c, 0x89809af6, 0xb7a2b1bc, -0x7e99aa22, 0x5b04008b, 0x7e301be5, 0xaa1b0d47, -0x97366416, 0x42dd637e, 0xeca9e894, 0x69d91e91, -0x5d2c0bce, 0x0c8d1af2, 0x730797d2, 0xf6323369, -0x8f1fb1a9, 0xbe6777ec, 0x0336f4b2, 0xbe63fa7e, -0x6a9f7f06, 0x80d12d3e, 0x1a31610d, 0x4da3a7b1, -0x8851d440, 0xb60d2846, 0x71a4b4b9, 0xcd750cca, -0x853a741a, 0x9376cac9, 0x85d1d64d, 0x840a6618, -0xf7a23082, 0x684a5321, 0xee7c1e76, 0x93c98ee7, -0x049ccc19, 0x0a874574, 0x660d1f0b, 0x6d5ee968, -0xc3b0a737, 0xe21294d6, 0x1f14b156, 0x60f3b43d, -0x0339d140, 0xa0d63dbc, 0x6c61e063, 0x38faeba2, -0x01e5639e, 0x2ceab905, 0xd8b02114, 0xa184b62f, -0x88e57cff, 0x23bc995b, 0x8ced5758, 0xfbb44f87, -0xb3bb6632, 0x3c0dee12, 0x334d1a59, 0xc09a90fd, -0x83f5a440, 0x1fc911bd, 0xf90e5fc6, 0xa7cb56f5, -0x4bfb8c77, 0xecb3dd24, 0xf5d7ea2f, 0x5640f72b, -0x8d9d7997, 0xb5157040, 0x49da93cb, 0x2ab58c5f, -0x2c09e41c, 0xbff9517f, 0x1fc15998, 0xfa2670c8, -0xfe8ce73e, 0xf1c5369e, 0x42d664fa, 0x4571e8ae, -0xdc91510a, 0xee671482, 0xf6880beb, 0x78f67258, -0xe4abd31c, 0x32973206, 0x5550afc7, 0x715de237, -0xd32593eb, 0x8471e4bf, 0x795a50c7, 0xe341eabd, -0x426741b5, 0xc6113c61, 0xaaaa8252, 0x9383558e, -0xe9feaa2e, 0x4212e709, 0x51bacee2, 0x4e592b93, -0xe93bf72c, 0x21b5e560, 0x7145b02f, 0x269362f4, -0xbd93b284, 0x2ee8c779, 0x75ae90b1, 0x45465f2f, -0x82ad3224, 0x9075c0b7, 0x5758c3df, 0x38f58b2e, -0x95a275dc, 0x19d3b3a1, 0xac225a5f, 0x6685a489, -0xbdae4b45, 0x4087b284, 0xd46de961, 0xc07859fb, -0x0d858371, 0xad60ea18, 0x63d5d2d9, 0xf3adb667, -0x2c0e5cf1, 0x2f41b7d4, 0x71f7be20, 0xf2959b52, -0x54dc88a6, 0x9b05e98a, 0xd4312afa, 0x8fa7b512, -0x6f3b2388, 0x56a31c8a, 0xddeb7a74, 0x674370b3, -0x1131841a, 0xa8cdf336, 0x30e43eb5, 0x1b3278b4, -0x33370b0f, 0xdbd64214, 0x4063ffe4, 0xa399a981, -0x3a49c034, 0x196e0ef9, 0x4b88a395, 0xb7c577bd, -0x0ddb86f5, 0x9a7bf933, 0x8e7c7a10, 0x70dc92f2, -0xd81f477e, 0x0ea89ab4, 0xf25df4dc, 0x82f3b135, -0x4fd628aa, 0xcd9a9138, 0x186f5e54, 0x50b713a5, -0xa43ce3b6, 0x85e91b7d, 0x8cfbf38a, 0x75ce54ab, -0xeec542c1, 0x6617c07f, 0x00cfbe4a, 0xe69a599f, -0x600e6b0c, 0x1a75ee91, 0xec0522a7, 0xb077743e, -0xa0b6a9f9, 0x345cc429, 0xce7f2f32, 0x440b3610, -0x8a9b0833, 0x00138162, 0xc846fc4b, 0x13e3782b, -0x5f83cacf, 0x87c13da0, 0xd0683250, 0x83c8b50d, -0xd68b0e65, 0xbd69f3f4, 0x700194d2, 0x6e508ab7, -0x3a4ac1b5, 0x387ada08, 0x2ee35fc3, 0x34f57311, -0x8fbe2ad1, 0x50f90bc9, 0xb809c7df, 0x32472ed3, -0x93ed3691, 0xfc348312, 0xf236338c, 0xe0be9f84, -0x52e72d2d, 0x76d771b2, 0x1c29999d, 0x7aef6bd6, -0x5d080f40, 0x5e1a76d4, 0x0a2ef953, 0xd8e6716a, -0x64d634d9, 0xd13bb501, 0x284be6e1, 0x214973af, -0xc21397f1, 0x7ed45554, 0x0cde11a3, 0xff0fbd85, -0xff0a75a7, 0xcbbdd6a2, 0x68fe6b57, 0x38127f96, -0xe4cef774, 0x08d367aa, 0x7956829f, 0xd4383253, -0xd80326be, 0x8df65472, 0x76f1b887, 0x0cb47fb6, -0xbf41b3b4, 0x682eb861, 0x1dcf062d, 0x47a7f587, -0x6214381c, 0xfa6d6e91, 0xf115be91, 0x12acb2d5, -0xac22fd35, 0x4818110e, 0xf5f96874, 0x2f12c993, -0xfe2b299c, 0x3d417ad4, 0xf5f71299, 0xb9e0a1f6, -0xd3c15c00, 0xe6fc81e5, 0x41b26e82, 0x14ee1db7, -0x2eff6b48, 0x4b59c2f3, 0x27650b49, 0xb70eac1f, -0x3c77f28e, 0x924b1c9c, 0xdb698759, 0x8386ec5f, -0x11c87ced, 0xec67257c, 0x8d71ca6e, 0xf9e85d88, -0x929b844f, 0xf4758869, 0x272e9997, 0xd9990b29, -0x271d98c2, 0xa7c555c2, 0x54883e20, 0x7bbda0b1, -0x0546ecba, 0x59894e06, 0x0d96ceed, 0xab7a199b, -0xc3203445, 0x89c2e098, 0xc1c5045b, 0x343a0c93, -0x629e64e7, 0xa789a25a, 0xa28e41c9, 0x47fe7e25, -0x90e0b0d1, 0xb7c30217, 0x3cb2d95a, 0xca27bc44, -0x72f064cc, 0xcdbadcb8, 0xc99b62a5, 0x149bfe49, -0x5fbf5a8b, 0x31eb5629, 0x6bf3668a, 0x0996e92b, -0x8c9fb29b, 0x8856800e, 0x40adad9e, 0x9a1834a6, -0xe7ef61f5, 0xc6d32680, 0xb6033994, 0x3aacc031, -0x4e84825e, 0xa7447e79, 0xdd79b632, 0xfda899f8, -0x28b5528b, 0x33de1f7e, 0xab492880, 0x02ebe69e, -0x8dcbbb58, 0x833e334e, 0x744a2149, 0x85547b7e, -0x034c1f38, 0x01adf1f3, 0x353beaea, 0x51dc9f09, -0xc4edc9f8, 0xa0df23b6, 0x1f05af3f, 0x97452b82, -0x392515bc, 0x2a733c59, 0xa11e6767, 0xdeeac3b1, -0xcb638c4d, 0xd5d52243, 0x1032c6f3, 0x0ed80e12, -0x4afcafe4, 0x52c5573e, 0xc5795e1a, 0x4e400d50, -0xf0133614, 0xc61aa3c3, 0xd1a60000, 0x94e59ade, -0xc5560cd3, 0x79f4f8e2, 0x0e7781bd, 0x150244da, -0x428cd2e1, 0x222c39f4, 0x475a02f9, 0xbf9dce73, -0xff3a14b0, 0x38e29835, 0xb72c499c, 0xcdf499bf, -0xcf98eb0b, 0x1803509b, 0x4c8ced2c, 0xc923b39c, -0x0ace36dd, 0xaa37d087, 0x30ad2238, 0x7d051b19, -0x43e8b4c7, 0xad468a93, 0xe999c950, 0xca9b9e93, -0x6f04e6b1, 0xea6583ea, 0xee0df515, 0x904405ea, -0xa45b3af8, 0x279e8ac8, 0x0763c001, 0x66bb3f63, -0x7fe0f14a, 0x32efe1ef, 0x68bf4ba6, 0x81ba9ab9, -0x3f5288ed, 0xcffcdc6a, 0x8ff7ca08, 0x701757e6, -0x16e1ef11, 0x3717fffc, 0xe1b1281a, 0x5946cf76, -0xdbdb0209, 0xc41f8ae9, 0xcf1c4b73, 0x69e0417b, -0xe8f17325, 0xeeacb3f4, 0xeb01b99e, 0xf4eba208, -0x145e1622, 0x2e9fd616, 0xaa5d32dd, 0x7feaee03, -0x505b67cc, 0xeb94e5e1, 0x177ab300, 0x2ebc3c4c, -0x05aa6bbf, 0xbf70a611, 0xbbe79e80, 0xe112be99, -0x54a7379f, 0x18132c4b, 0xf37cc097, 0xb17f1792, -0x83859454, 0xd49687fa, 0x21372bca, 0xdc6cdec7, -0x4ef72d47, 0x90539a91, 0x8b5964d9, 0xe9eb0a32, -0x7985783e, 0x168359d9, 0x66204173, 0x3507843e, -0xa29d8c80, 0x47a03287, 0x32a18cc0, 0xf455f3c2, -0xae0c363e, 0xaa1d07a0, 0xa1fde859, 0x0d30d7bf, -0x2ad9ceca, 0xb553e4cc, 0xc23ab889, 0x2cb4d9de, -0x5441e14f, 0xe7d4f715, 0xc0a5cc18, 0xca0bd221, -0x1215d5b6, 0x4b2f3a99, 0x9a660387, 0x9e87f59a, -0x5758957a, 0xd2dcac46, 0x991ca100, 0xc7b4baa9, -0xd1f02624, 0x94686298, 0xd33d55ef, 0x7c94ae91, -0x36df5431, 0x1bc27bf1, 0xd8b56d55, 0x8db4ccce, -0xa49330eb, 0xf644a0c6, 0xd14fb0c8, 0x69613044, -0x9bb35ae8, 0x9b645568, 0x21744066, 0xc123cd1d, -0x0a37ad93, 0x986f9c6c, 0x1eb569b8, 0xe0912ebc, -0x93862fea, 0xa59cf4a1, 0x83930f0f, 0x82831a00, -0x368f64ad, 0xb38fe25e, 0xd703a8d9, 0xea4dec67, -0x3ca5e491, 0x6a1a1ede, 0x71bfd651, 0x585f0430, -0x8b97c5ed, 0x3f954af6, 0x04ff33d6, 0xef43835b, -0x45b152b5, 0xa983eb83, 0xe8ca9e17, 0xa9011967, -0xacd4613a, 0x13329f8c, 0x7155f130, 0xa5fbcaa3, -0xe12ccc1c, 0x3f20509c, 0x0548cfeb, 0x1b2bb90b, -0x41991ead, 0xb9566731, 0xf279263b, 0x8da5e1a6, -0x5e45322d, 0x8f47e377, 0xaedb482a, 0x87e9f8e6, -0x00947524, 0xa7e0dcc8, 0xabb34885, 0xd1dcd303, -0x70e251f5, 0x408cb9ec, 0x17d64076, 0x4df80c9d, -0x2f735ff7, 0x437b2475, 0xbe40e517, 0xcf0826d9, -0x12adc075, 0x1f90f1c8, 0x9a33610c, 0x3135ac98, -0xc1f611bf, 0x461e90a1, 0x50d01fb0, 0xe8de5f49, -0xd70d74f3, 0x66cad8db, 0x461f3063, 0x1ccf8ca8, -0x5b647b9c, 0x9174cfbb, 0xc54b60ef, 0x641ad89d, -0x18c40de4, 0x82fd1342, 0xd0e9dd40, 0x97c0a8ae, -0x8f19cdae, 0x94fbbcb0, 0xf7cc523a, 0xe4056f6d, -0xd11a9886, 0x4dcd0af0, 0x3eba0d24, 0xbc35f7a6, -0x5e1e9b55, 0xd9a6a9ad, 0xe826e5ac, 0xcf41712e, -0xda14027f, 0xed4eb59d, 0xd194e410, 0x596ed5c0, -0x97fe12e3, 0x7d5c7ea6, 0xf104c5fc, 0x7e3a4fc0, -0xf50f46f1, 0x5b1a4dc4, 0x678b2de0, 0x4b4728c6, -0x4941792d, 0xd57a58e2, 0xfa51b95c, 0xd8333311, -0xf22f80d8, 0x0758ce33, 0xc9e66016, 0x4dd71068, -0xf3cfdf8d, 0x47aa22ce, 0x06c5bd1b, 0xf42f910a, -0x5663bc94, 0x02338eab, 0x558e36f3, 0xae1b97d8, -0x5b4d1db8, 0xf46500d4, 0xf211d2a9, 0x71bd292d, -0x61bbb9b6, 0xfbd2f77f, 0xd8910476, 0x12fd4201, -0x047eb58a, 0x9b1b5088, 0x69d12d58, 0x68acd33a, -0x0e8121a4, 0x05b682d6, 0x7c8c64fd, 0xbe7d5d91, -0x20d12b3f, 0x0f63c6f7, 0xf3a8b2cf, 0x92719835, -0x988fef61, 0x1d2e8383, 0xb6b2015e, 0x4b728ef2, -0x276e0063, 0x0c651aed, 0x5b87ce8d, 0x01b4c408, -0x2cbec2a6, 0x136cdf72, 0x575d2521, 0x8f188fd8, -0x172f1f30, 0x80b70377, 0x239b2a97, 0xc75f231a, -0xcb6ba1fb, 0xb15c58fe, 0x3d182903, 0xdecdec5a, -0x38a99106, 0xe5dbc841, 0x50d31735, 0xac230e84, -0x7a3e1dcc, 0xf03824eb, 0xd46166d9, 0x1711fa6c, -0xb8987575, 0xc0c63018, 0x21e70a2b, 0xd1d9865a, -0x0351a011, 0xd9ae70b3, 0x9da6dbc9, 0x64002142, -0x9a143ba2, 0xafec813e, 0xb385eec2, 0xe762b70c, -0xa3f7cb58, 0x6da88afd, 0xeb86918a, 0xcfa33f23, -0xeb3445d7, 0x95766c9b, 0x1d172a05, 0xea66e3b6, -0x089fbf2f, 0xa768c4aa, 0x9a8b5bfa, 0x30c69619, -0x6641a76d, 0x827b31d4, 0xff2bee87, 0xb1274106, -0x9a6bad7b, 0xf8093d03, 0xc7e7de22, 0x23e5c273, -0x11d92327, 0x014e2384, 0xd3f36ef3, 0xa03b2ab6, -0x469ea5be, 0x1965c8c8, 0xffd41409, 0x22d2edcb, -0x2cf4de92, 0x68f85640, 0x0d837b76, 0xd10345cc, -0x27eabb18, 0x4de85487, 0xf951a832, 0xaad7476b, -0x74f2dd14, 0x30bc2621, 0xbfbc3fef, 0x96c18c9a, -0xf8e45c8b, 0x2c0ca343, 0x676e3829, 0x933f4b30, -0x88671fee, 0x1fe89c5a, 0x6b856326, 0x1abe0ca9, -0xb162a5c9, 0x7983735e, 0x5fa0e048, 0x4a69d1b9, -0x56011d2b, 0x4f56cff3, 0x62b1b768, 0x4d690e24, -0xacd72d64, 0xf5578e63, 0xa31958b1, 0x43efff71, -0x6cb5ce8b, 0xbd5e9b14, 0xa522c571, 0x692412b3, -0xc1e0c058, 0x786473cc, 0xdfc9e3c9, 0xc5e1501a, -0xd484d0bb, 0x7d8979e1, 0xd273044e, 0xa73633d0, -0xfa9f1944, 0x639ad1d4, 0x9877fc4e, 0x7ddba96d, -0xc4c0616e, 0xde1a6e5e, 0x71cdd617, 0x6b99ee85, -0x27cc019f, 0x88371a20, 0x1be02a72, 0x80bd7747, -0x73ae67d3, 0x6c82f4cb, 0x0a10dfb3, 0x1276326e, -0x3fb8b0ad, 0x9aefa740, 0xbbd55ecd, 0x144146b8, -0xa113bcb2, 0xab221fbf, 0x546b07e1, 0x04cc6e34, -0xc5881158, 0x706b98de, 0x15fe7a47, 0xb37fa40c, -0xae60402d, 0xe883bc80, 0x7d75a155, 0x1c704783, -0xa2b9b905, 0x788ffafa, 0xe5c6d2e0, 0x6ed326a5, -0x2e671513, 0x2738d902, 0x48834b77, 0x515ae5d0, -0xfe196599, 0x8eac0ed8, 0x493de188, 0x4ced0f10, -0xef495d50, 0x1c8c11c9, 0xd72b7ad0, 0x6538db01, -0x28ab44b1, 0xf9027d82, 0x1bd0577c, 0x11cb527c, -0x3b27596a, 0xd661d021, 0x65e68d72, 0xa362b46e, -0xee0971af, 0x951f95dc, 0x61fa39af, 0xab0cc9b9, -0x1b3bfaee, 0xd0a60a2f, 0x528e0c41, 0x8ab00ea1, -0xfd0f286b, 0xc632b071, 0xc30294a7, 0x1e26a083, -0x5a54078e, 0xe654c188, 0xc8ee1653, 0x3010c906, -0x39dc7054, 0x4f0c1261, 0x449fe785, 0xecab6a6b, -0x213bfe2e, 0xe4c6f00c, 0x8eb07821, 0xe8ff2e93, -0xbe567ba2, 0xf4160cac, 0xc98728a6, 0x045ae96a, -0x83fbe2f7, 0xecfa20e9, 0x1f6fce35, 0x4bed73ad, -0xd51a6875, 0x6662b906, 0x5bfaec0c, 0x03db85a6, -0x56692fda, 0xedc67ad2, 0xd0fe4baa, 0xdaf2507b, -0xde7c400f, 0xc18897cf, 0x47c04fd9, 0x1ffc9b24, -0x5a35be70, 0x12f845ad, 0x2ebc0dd2, 0x6fecbbd2, -0x53fc663e, 0xc957a130, 0x9c194624, 0x9a500a78, -0x217f895c, 0x99da1f18, 0x804614e6, 0x839274d6, -0xe70a25b0, 0x3a61b3ae, 0xf4caf190, 0xfdb5166f, -0xccf9e73f, 0x6a24a966, 0x1a53d75d, 0x19e68fa1, -0x205c583f, 0xde045830, 0xf01d917e, 0xbffd767e, -0x2024d57a, 0x47163d6e, 0x86b38732, 0x282c8f9c, -0x7378559a, 0x45dc6404, 0xa9a5ee57, 0x24919062, -0x3f8069f0, 0xbbebed07, 0xaea56958, 0x9664d2d3, -0x9a48aff1, 0x04e9fa40, 0x9ffc45e6, 0x4c14d117, -0xc3077e50, 0x016f73f3, 0x165a64be, 0x4440bbbe, -0x7840fcd0, 0xc1f4a2d6, 0x56729873, 0x08ddb438, -0x6d13b48c, 0x0f40f626, 0x06807ab9, 0x7a575f43, -0xef5d43a9, 0x620a9fe5, 0x3419dfba, 0x86fafb2f, -0x999a7b40, 0x2f923040, 0x5b80d46b, 0x3a002116, -0x49829ffc, 0x2239340c, 0xb9b063cb, 0x46922d44, -0x86e5d048, 0xae719338, 0xfe7e7936, 0x8c94bf6d, -0x587f5cc6, 0xbf6ff0a1, 0x14d0f12b, 0xd7bdfcba, -0xe8908def, 0x32d08043, 0x708194bb, 0x4b9a9dfa, -0xeff352da, 0xf3088842, 0xbd617295, 0xf90e0a98, -0xa579a690, 0x939dfc23, 0xd896560f, 0x8e0454ed, -0x2bf14e16, 0xf86bec1b, 0xca5e6724, 0x27b44d2c, -0x36efe253, 0x5a40e0d0, 0x891d2354, 0x66794b58, -0xd19b490e, 0x7adfd7f4, 0x81bd700b, 0x1b7b1c39, -0xc8c27a49, 0xe55957af, 0xa200f22e, 0x1513e630, -0x5c22274f, 0xdfcf1977, 0xc25efc43, 0x97d8c849, -0x085fc28a, 0x8bd99f79, 0xacf9b6d6, 0x2c8e5105, -0xa853d807, 0xc5cc2ab3, 0x770cad5d, 0x341655e7, -0x73af0472, 0x47189361, 0x666002e9, 0xad0c8d0d, -0xca1daff1, 0x466863d1, 0x0e03fcba, 0x0540c799, -0x32263d84, 0x49207fb8, 0x69fa2acc, 0x6fb943c2, -0x2f7cec7e, 0xf0eee345, 0x8cd6167c, 0xfedc8ba9, -0x4c0c81f0, 0xe2465dbf, 0x196fdbc3, 0x4179df4c, -0xfe3a0bff, 0x105bce11, 0xcecae839, 0xefbf4abd, -0x7340ac0b, 0xf20928d9, 0x9afd8882, 0x8713b311, -0x4f6dd3c0, 0xad921e2e, 0x717434f7, 0xb8463091, -0x0ce295e7, 0xc38c6a55, 0x16e48e28, 0x27444bdc, -0x47370754, 0x622f18d0, 0xd1210799, 0x67de0531, -0xa6e5c785, 0x86a801b5, 0x405d33c4, 0x59dfdf7a, -0x4ec49bd3, 0x18068d3a, 0xcbf720aa, 0xe3b37191, -0x11b6f7e4, 0x8c015526, 0xf75dce7b, 0xb0fe290b, -0xe5cae19c, 0xfde92be1, 0x78155b31, 0x9257619f, -0x0da18a09, 0xea98832f, 0x34eb0ebc, 0x7bbffed4, -0x8bb52f6a, 0x752e26c7, 0x0c268fe0, 0xd0512fd5, -0xdaaa16df, 0x8b567986, 0x33f0a7c1, 0x5479080e, -0x347b8d2e, 0xdb56fd9f, 0x0b0bd7cc, 0x83a0bb77, -0x9dfd7320, 0x19f9ed59, 0xed13b232, 0x434494c7, -0x92d6daf1, 0xe03bc1c2, 0xe2099636, 0x7b3d5261, -0xd11c7151, 0xaa197ffb, 0xd978054b, 0xcf825914, -0x8e23bfa9, 0x9148a70d, 0xa4d164e5, 0x301f6dcc, -0x2f715b1c, 0xb300c085, 0xfceb2559, 0x1f084e6b, -/* 2381-m406f769.inc */ -0x00000001, 0x00000069, 0x09172007, 0x000006f7, -0x4e779cf4, 0x00000001, 0x00000040, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0xc8c262f4, 0xaf3e2b58, 0xffb85691, 0x37176b6a, -0xda8214a9, 0xc589d723, 0x955d8adc, 0xebf6dde6, -0x603ea97b, 0x9aaf8ddf, 0x1a4f99ba, 0x2bb46213, -0x457c0e43, 0x52b12095, 0xbea57bba, 0x539215e6, -0x87761b6f, 0xbe123f4d, 0x2eebcfd8, 0x508374db, -0x4b379fa7, 0x27b0b1df, 0x16a3d4a9, 0xd7cd9ae5, -0xbd40b857, 0xb8d6dfd5, 0x6e3e5f22, 0xd9e99573, -0x9feeac99, 0xcb522725, 0x39167848, 0x7cfdaddd, -0x8c45ccb0, 0xd3f11c87, 0x64fd55f4, 0xe53bd280, -0x97440a2f, 0x19b7b8f7, 0x78fbee9b, 0x806616a4, -0xa4e7267b, 0x8ccbd157, 0x13d4b457, 0x859a6169, -0x05cd40b6, 0x7157c954, 0x44857455, 0xcf2a8c25, -0xc6fb5f83, 0x97820f5f, 0xc6fa3e62, 0xf52fda3b, -0x00eec237, 0xa34d0f5e, 0x63b31adb, 0xb4922d9d, -0xa826fe4a, 0xcdae9df2, 0xc7fb4011, 0x6fa41ef3, -0x65de08e4, 0xf405be1b, 0xfea32384, 0xbefaecbb, -0x56ec5b78, 0xd29e4663, 0x64e0702d, 0x9cadc43a, -0xfee8e4e9, 0x6e776cfb, 0x28f86258, 0x3ec87236, -0xeba58f3c, 0xd4966f6c, 0xcaabc6c4, 0x25782c7d, -0x17007930, 0x8a9f3c13, 0x1e9842dc, 0x31f6a225, -0xc0b20b8d, 0xef8e129e, 0xb537896b, 0xdc62f098, -0xfa19e05b, 0x4b85ebaa, 0x71c05717, 0xa211e54b, -0x9ad57b82, 0x275c77e2, 0x3c2d3207, 0x41a4735f, -0x4ae5448e, 0x1a984ee2, 0x8f9dcff7, 0xa2f7b4fc, -0x8d807156, 0x8c7299c6, 0xe8f29d33, 0x60f5f7dd, -0xe21ee1e2, 0x36d3eea7, 0x89413378, 0x0711067f, -0x6980d2d7, 0x699020f3, 0x5cacc477, 0x9dd66dd7, -0xd657ff2a, 0xa04eaeb5, 0x3478cac0, 0x487fd6cd, -0x398dfce4, 0x89bf90bc, 0x22d8c1d2, 0x02acc684, -0x8ff16f07, 0x1dbe7919, 0xed8ee206, 0x3d6d6a36, -0x987cf1f5, 0xed743a25, 0x905f11af, 0xac5f3185, -0x392bbe45, 0x32e59314, 0xbde9f0e5, 0xbdda44b0, -0x6dd078cd, 0x3b5c4d4e, 0x47b48733, 0x4e3a8ca2, -0xb7f6df78, 0x94e8d403, 0xc737dfde, 0xdb90d991, -0x09a1976b, 0x4c8c9115, 0xb591d94e, 0x63e76efe, -0x356271e1, 0xe0747963, 0x78b2dc3d, 0x05469e8b, -0x30c92050, 0xae7dfab2, 0x3942e785, 0x99d36dd9, -0x2e033e50, 0xc3fae7bb, 0xc1334065, 0x8a1e7b14, -0xc97e6879, 0x3a620fb9, 0xac1e7c18, 0x5b5a6c58, -0x89312764, 0x08f41565, 0x800ae942, 0x12d47b83, -0x55600299, 0x50a3e02f, 0xf02db208, 0x779255f9, -0x5ce13e50, 0x40e62354, 0x7c8eb083, 0x1063ece2, -0x30421ddc, 0x3f2a76cd, 0xa9bb3c7c, 0x7dadc236, -0x6a57f6d0, 0x433eeb9d, 0xb495e0d0, 0x31a6b14b, -0x78196982, 0x6f6764a6, 0x2b2404a3, 0x0643cfe9, -0x566cf4d4, 0x2b47c9e7, 0xca6da375, 0xcb396117, -0x5045973b, 0xe10bdcd4, 0x7a484949, 0x9828c2d7, -0x25a89305, 0x260cce74, 0xf61f5b26, 0x3cc150e5, -0xc48f0bb2, 0x0e066d67, 0xf1865a1c, 0xc7b94ee1, -0xe23d20bb, 0x5642d1b3, 0xaac24ac9, 0x581218c1, -0xc09394a0, 0x544a38fe, 0x1737c1f8, 0xaf28fd90, -0xd05bc62c, 0x0cea3cd2, 0xe808ece5, 0xaebc9448, -0xd35c4afb, 0xd987fb71, 0xa7669b86, 0x5d24edc6, -0x44b630e5, 0xb8e9724d, 0xd13ef44b, 0xb0deb768, -0x6b8c7b57, 0xe83f5a88, 0xf5847bde, 0x837b62c6, -0x2291ea62, 0xb1ed5172, 0xd58984cd, 0x6127142a, -0x1fd80fdf, 0x3174500c, 0x3c337bef, 0x23ddc5af, -0x40c0faa8, 0x02bdd1fd, 0x14cc4d7c, 0xeca7e237, -0xcef074c2, 0x4359eced, 0xac4bf265, 0xd09c002f, -0xabd8ef91, 0x890b1e7c, 0x95639eba, 0xa0dad747, -0x060f7739, 0x0a7f675d, 0x044459c5, 0xb1d2ea6c, -0xfcf7a75b, 0xa2560237, 0xae4c9acd, 0x930e40ea, -0xa8b2c2dd, 0x657a0c99, 0xc3a721bd, 0xefecae8e, -0xde5d1b90, 0x64230532, 0xf5b37ad3, 0xb34f1d88, -0x7dbfb263, 0x6d8486b0, 0x703f5c9d, 0x36eb2571, -0xc2940ef4, 0xb24bd011, 0x0827bfe8, 0xe7dd58a4, -0x79fdb76c, 0xfaeff06c, 0xcb5e3de4, 0x54de184f, -0x83ce6b32, 0x243c665a, 0x6c785c26, 0x28f88347, -0x1b14e52b, 0xc489f983, 0x0ee1daa2, 0xa1e1c6bd, -0x19d47eca, 0x39827cc7, 0x1d36dcdc, 0xcb741131, -0xdaf56577, 0xd3ee6290, 0x259695ca, 0x2769ae6d, -0x63109c94, 0xe68e77fa, 0xa147f000, 0x457af6f5, -0xea812632, 0x23adac03, 0x8c0ec893, 0x89307048, -0x4e237a5c, 0x3ee6f784, 0xfb51c8cf, 0xa8f62ec5, -0xcef53a16, 0x62f4f325, 0x0007d164, 0xbc8c92b6, -0xc7debef4, 0xa46d2d21, 0x22232f4f, 0x7b064901, -0x5b69f49d, 0x1cf5cfd1, 0x395184d1, 0x7748d1e1, -0xe843ae68, 0x5e4feb6a, 0xd6f91e9a, 0x5976450a, -0x72befef9, 0x6bb0ba92, 0xd41d8e98, 0x91f2428a, -0x74102a90, 0x97c45f3f, 0x65a94ea6, 0xa21c4f15, -0xae89417b, 0x53443878, 0x681b766f, 0x2538df36, -0xa76f327e, 0x91d19797, 0x37ae54d0, 0x5cee2a7e, -0xa6019d14, 0xc0e21a17, 0x955af21e, 0x3cacd721, -0x2b381505, 0x2a49584c, 0xac2af949, 0x092e6946, -0xcb24706f, 0x60f5ed1f, 0x20bf6f0e, 0xbef94bbe, -0xf12c1bc4, 0xa6092fa8, 0x09534dce, 0x45d869ea, -0xfdb0b147, 0xa5f7568c, 0xc4b9820f, 0x236efcae, -0x06e1144f, 0x36498c2a, 0xd41cd998, 0x0624a018, -0xa536aebb, 0xcaa6dea0, 0x0fdf7c60, 0x46e185c4, -0xa764400f, 0x0271805b, 0x6e9fa85e, 0x5e6e4c76, -0xc1fd4fc9, 0x17597b33, 0xd8396e3e, 0x8edceb6f, -0x480da81d, 0xecf5ec45, 0xe813da33, 0x4d5b6ba1, -0x891460b6, 0x01093db7, 0xb7665f0a, 0xc6d99863, -0x6ca28f96, 0x1a74bc38, 0x043a8b7e, 0x4301146b, -0x04deb40e, 0x8c3a86de, 0x0185f532, 0x2f3ea326, -0xd3613a71, 0x5a353367, 0x37ec76f5, 0x11672cf8, -0x649ef06c, 0xd2a92c6f, 0x3bdb5372, 0x6debe631, -0xd4c3fb21, 0x159c1239, 0x47bfd8e9, 0xa00f6eb7, -0x59862e6a, 0x6d5a4902, 0x346cec3d, 0xda23310b, -0xbf7d5f70, 0x57d716eb, 0x1e6c229a, 0xcb51fb67, -0x40f0bf3b, 0x8759cb94, 0xe2e4727b, 0xa087e1d9, -0xf62bbbb3, 0x08e91708, 0x142bc6c6, 0xf010109c, -0xe861cac7, 0xadabb0b7, 0x0b550bfb, 0xb6e79d0a, -0xa6f20b8e, 0x8680ab31, 0xbb130ef2, 0xe6ea8723, -0xbab6ebe2, 0xa11975de, 0x28c5b0c0, 0x5f28330c, -0xe1a4a2b6, 0xb387cc95, 0xf368e7ba, 0xde0d3d88, -0xd62d48fe, 0xf7715ebd, 0x31e432df, 0x639f1f2a, -0x06b8de5b, 0x0aa3d9e7, 0x1e813f0f, 0x112212ac, -0x136f2701, 0x13d58f31, 0xb4d22d07, 0x012576f3, -0x795c943a, 0x6f6b419a, 0xf54e26a8, 0xbc94605d, -0x889bbea2, 0xc2bb5d4c, 0x896573a9, 0xf0862d97, -0x67b1ed18, 0x0dc64dfb, 0x3ccfc9ea, 0x987bd7bf, -0xe9aafb49, 0x760c693f, 0x331721cb, 0x3cf4473d, -0x0493cdbb, 0xa319be13, 0x0e280d97, 0xafc31837, -0xa3246067, 0x0fbeb037, 0x48a32b43, 0x3843b479, -0xc6a17c13, 0xe37707aa, 0x9779713f, 0x1b3e9a3f, -0x80f54ef6, 0xbc28fead, 0x7aad3334, 0x690e6843, -0x3e6953c7, 0x667bc8c3, 0x8c75819c, 0xa4752261, -0xd045b4e0, 0x420f7ea3, 0x78f9c7d9, 0xb26af8f0, -0xa758de96, 0x52344fec, 0x276b48fe, 0x9824567c, -0x98c56888, 0x85d9692d, 0x079e2ca4, 0x0e421ec9, -0x2e0634ba, 0xf5d84dd7, 0xc31e7500, 0x4c29cb36, -0x37bf0924, 0x00e8eecb, 0x4231ccab, 0x092e515d, -0x70215cf2, 0xf50f4e93, 0x4c57d581, 0x077458e1, -0xb4db8e49, 0x6e23ffeb, 0x59ed0cad, 0x47b580a0, -0x1cff6770, 0x223f5630, 0x0a5293c6, 0x2c95a85b, -0x88ed30cf, 0xc3b94d6d, 0x77397476, 0xba74703a, -0x1d32b740, 0x32ebcdfe, 0xc042c44b, 0x25ef75b5, -0xaa6c94e0, 0x17711e94, 0x053f729d, 0x193ac3ad, -0x1b849012, 0x7bd66e5e, 0xb012f683, 0x20f07ddd, -0x3078cb97, 0xa257bfc9, 0xaa18ad84, 0x29db62f1, -0x40fde5e7, 0x70f68dab, 0xaf0e6afc, 0x92c4fb07, -0x45be88eb, 0xe5502287, 0xf9fb6286, 0xb38524c1, -0x42f587db, 0x9120bac4, 0x4648b401, 0x46a6dd56, -0x6fe59481, 0xbe0bf594, 0x97fc271f, 0x24847776, -0x4b2c1cab, 0x512ccca5, 0x52b32399, 0x6a45b81d, -0x377a21d2, 0x89f876a8, 0xa0bc9ea4, 0x4ae10052, -0x46a452e9, 0x5a8513a3, 0x3eb3cfe6, 0x3b29d2d6, -0x913c030f, 0x0a8fb4af, 0x5f1d9ec0, 0x1b80eec7, -0xe2d47560, 0x4741a0f1, 0x1a8329b9, 0xd0d6d7dd, -0xe6dcb11f, 0x3884af15, 0x80125d63, 0xde9e0b52, -0xa488a326, 0x7ffeb1dc, 0x0d80179a, 0x2162b0c4, -0x5df6e6ca, 0x4c5acaf2, 0x63253910, 0x6926afeb, -0x70e91519, 0xf172affe, 0xb58059d5, 0x83a9c9bc, -0x80d339c8, 0x79d961c3, 0x709ccbab, 0x9f5f32c0, -0xdd816af3, 0x842fc048, 0x46fbf129, 0x7a2f0495, -0x104e5f40, 0x19efba34, 0x64982e8f, 0x76bca689, -0x0f2717b1, 0x56643869, 0x48e42c54, 0x5aa00ac4, -0xddb45c48, 0xd7b5c02a, 0xdc3ec963, 0x2608949b, -0xf4c77d4b, 0x6d5ba22d, 0x670ffe14, 0x9f999188, -0x7a25ff7e, 0xb2da6285, 0x75513c5c, 0x8b27c275, -0xfd721e86, 0xda8e2c90, 0xc39e8c9a, 0xad8f47e7, -0x39529e14, 0x4f196808, 0xb3b3b14b, 0x2cca6974, -0xb7c84fe1, 0x0b98cd21, 0x71c2dedc, 0xacd1d92e, -0x3dd3b6dd, 0xb93a0031, 0xd5fbd8a5, 0x9e1ef6ad, -0xd406500d, 0xf1abe592, 0xeda8d1a6, 0xdd25ee95, -0x6bb072e5, 0x5c0ac5d0, 0x42dbee39, 0xcca76d1b, -0x18ee78fc, 0x5fd26f99, 0x366ab232, 0xe2f511bd, -0x41835cd3, 0x9976967e, 0x1731ed57, 0x5b175f03, -0xca96195a, 0x302e8c64, 0x5e8805e4, 0x3eb5bcca, -0x1eeb6d77, 0x9467eecb, 0x2fb2fd5b, 0x53d01637, -0x684795d2, 0x8c1eb085, 0xa81e175c, 0xd6e97ab1, -0x079eba05, 0x320a8414, 0x9c4dc2c1, 0xd45247e3, -0xc528c31f, 0x8bd981e2, 0x69800473, 0x8f8e46c9, -0xc6b90d21, 0x0a5081b4, 0x2cff7dfb, 0xaafd8bb3, -0xf9172eb2, 0xdddaf3a9, 0x7e20392f, 0xaec06fa0, -0x301657ff, 0xb2204a88, 0x796d46d2, 0x24b39297, -0x7b5013c0, 0xa858aa4e, 0xeca0b835, 0xba9a55ba, -0xaab680ea, 0x702e24ea, 0xfec03648, 0x4f63c3ac, -0x4981c3d9, 0x7cbbc936, 0x70f159ef, 0x23cc02f2, -0x23e0a0e9, 0x28ea4632, 0x92cf78e7, 0xfdf45b4d, -0xa0d0171d, 0xe811909f, 0x3be83784, 0x932c14bd, -0xb3bc895b, 0xa1ee1399, 0xde0ce7d0, 0xaa4a8606, -0x2f93c916, 0x17e8004a, 0x95e34d47, 0xd7e039ee, -0x9397fbb4, 0x57023723, 0x66d5b72f, 0xf58e8181, -0x958082e1, 0x82ee9723, 0x995b1577, 0xb519154d, -0xb8bf7dd2, 0xf9311c7f, 0x1b1bbc78, 0x4f352ffc, -0xaab3b8a8, 0x7aecbb63, 0x8accee57, 0x66db792b, -0xe211b7a2, 0xc8f3f756, 0x4c18e95e, 0xe7a78e26, -0xe9a98c86, 0xeb6f152a, 0x16b5f4a7, 0x5a6e37f4, -0x4a20435a, 0x80efa08f, 0x7048030b, 0x372abe74, -0x7ef0b427, 0x4f9aec1b, 0xff5d2148, 0x33970d2d, -0xfa009f9a, 0xfd0437ce, 0x01d30808, 0xd38ed908, -0xb4837dc3, 0xe1bbe7d2, 0x049632a5, 0x702f1f6c, -0x8eca33a9, 0x8b691c43, 0x1a5f5681, 0x980cce54, -0xfdc3aa8f, 0x9d103356, 0xcc2e6bee, 0x2d81ba6e, -0x493f266b, 0x7f78b2e8, 0x45bad0a9, 0xdee465a8, -0xc7519329, 0x827b2df3, 0x6c432be0, 0x6a0248be, -0x9dafc378, 0x21744a65, 0x002e2c2f, 0x3cb353c3, -0x7350ea72, 0x5d255da5, 0xaf3f51cd, 0x9dde24aa, -0xfae42395, 0x2feff6ee, 0xafd18dee, 0x87fe0cf5, -0xa7927da5, 0x49f11c98, 0x0b58497a, 0xa66e42fc, -0x94947302, 0xd442d522, 0xe340db02, 0xfe4b3d12, -0xd7f8ce19, 0x31ef991d, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 1470-m9df4703.inc */ -0x00000001, 0x00000003, 0x04212005, 0x00000f47, -0xaf2cef0d, 0x00000001, 0x0000009d, 0x00000bd0, -0x00000c00, 0x00000000, 0x00000000, 0x00000000, -0xc2f82df4, 0xcc1f8c6e, 0x0e8a805d, 0x8e748392, -0x61d74f4e, 0x45c7e2e6, 0x2a47a317, 0xcc8680ea, -0x6afb5d2f, 0xe61b30de, 0xccf8ce6c, 0x063cd5a3, -0x992e1a8e, 0x917e2495, 0x0ec78d26, 0x3b11a087, -0x5cfd497e, 0x712e7a69, 0x19023605, 0x7e2d5382, -0x86f0ea44, 0x34c2dfe0, 0x111466d3, 0x1ca2dea9, -0x2db035cc, 0x0d756649, 0x5d817ad0, 0x8260bfd2, -0x8af6da2b, 0x6b6e56ed, 0x416d4cec, 0xd46eed66, -0x46895ede, 0xec4fa389, 0xfb2e5b37, 0x31191653, -0x899d2459, 0x969ba9a6, 0x2fdbd429, 0x00f926cf, -0x1763affd, 0x74ea8cf2, 0x52f9e657, 0x4a7b2371, -0xf5bca7c1, 0x6bcf1744, 0x5d3cb914, 0x5a2c0b69, -0xd4d6711b, 0x6379e8b7, 0xf7def9d8, 0x88fbde4f, -0x25c24564, 0x74fad07d, 0x68b6d12d, 0xd81b2962, -0x5f8114bd, 0x8b8c7590, 0x123f0889, 0x7c350756, -0x29440cf1, 0xa88333c8, 0x28c0b737, 0x7ea33d12, -0x9878f652, 0x4f41e6a9, 0x3e109379, 0x5f6af51b, -0xa3efee81, 0x18934e5c, 0x3bea09c4, 0x04b1f649, -0x51e21d0b, 0x2cdc6b67, 0xa93ae5f2, 0xc809a230, -0x93886909, 0x6bf788b9, 0x537391b5, 0xf0d7ef26, -0x71032e3d, 0xb1ab4d8a, 0x364c1a73, 0x333faac0, -0xe9ddc147, 0xec43d38a, 0xd69e9a38, 0x77dd0b85, -0x63798cd3, 0x6ffd694d, 0xbe947f6d, 0x0bd2df58, -0x3f4be601, 0x29753e63, 0x3f1db162, 0x1fa0bffd, -0xbd085ff4, 0x1627b890, 0x1f82c7c5, 0xabe18ae5, -0x6babcabc, 0x046aa047, 0x860ac96e, 0xd957718a, -0xf6a01a82, 0x827a81e1, 0xa4ffb338, 0x257e2b69, -0xa2ceba96, 0x91103b49, 0x87a44f56, 0x1cf230a5, -0x030467ae, 0x2b9476f0, 0x86a60c79, 0x45dca4ba, -0x8eb41f62, 0x6d006ab5, 0x79274a6a, 0x6de0d4ab, -0x3310417f, 0x7b8206fa, 0x35e20f1f, 0x0e41b2db, -0xb877daa8, 0x36be9c48, 0x70e7a9ca, 0x58911f5a, -0xabd853cb, 0x631286bd, 0x35714af4, 0x3d7eb1d8, -0x220dea6e, 0x21ed48f8, 0x917d52ab, 0x9cc0abf3, -0x4a7efd32, 0x7be24674, 0x9132e702, 0xc2b3e4fc, -0xae649b47, 0xd2caa94d, 0x2cda267e, 0x6e6b04c5, -0x9a440677, 0xd891c1b4, 0xecd4c280, 0x38b4e552, -0xd9b5a94b, 0x2a8cd551, 0xdef56497, 0x2a4be3d4, -0x9595e71f, 0x568721a8, 0x95d7a9fa, 0x51ae4f9f, -0xd42cda31, 0x2057ce0a, 0xf12c4ad2, 0xd131172f, -0x799d557e, 0x1f85fb72, 0x1a30f80b, 0xa81945dc, -0xdcfd4ea8, 0xe501109a, 0x8164abc7, 0x42bc7828, -0x0514889a, 0xcc4f3d70, 0x8fef5410, 0x01d78e74, -0xa5563afe, 0x3add8b75, 0xdfd82e52, 0x2022a5fc, -0xf56d7378, 0x37731dca, 0x4c60bcb6, 0x29170df7, -0x56c20033, 0x75b62940, 0x7ad58af9, 0xde25154c, -0x27dfd9ae, 0x208a894c, 0x51e81496, 0xc69d1dfa, -0x81d27b5c, 0xca12f782, 0xefd7d0b3, 0x3beab01c, -0xbc0eef39, 0xa5d7f2cf, 0x7dc4d451, 0x7069fb06, -0x45cb04f0, 0x1b5fc96c, 0x3cfb526c, 0x22495be6, -0xb0db5a44, 0x6aa6e09e, 0x63cf88c3, 0x44c49559, -0x2ea01cc0, 0x158d1203, 0xe0c8163a, 0xa076e84e, -0x873ea544, 0x51013068, 0x90d921df, 0xafb9ec15, -0x632a74d8, 0x8e870b20, 0x46a34395, 0x74534f55, -0x4002ac22, 0xbe7dd5b4, 0x913d7ba7, 0x77a0f6e7, -0xa3776b10, 0x00d73ac2, 0x72ec8ccb, 0x5c65d930, -0xceabd7df, 0x4586999d, 0xdf9c7e24, 0x1ffb96ff, -0xa945e189, 0x6f879555, 0x32aba213, 0x5e5f0ee5, -0x70e43350, 0x647279b7, 0xd4612221, 0x2c266f6c, -0x8576cd5b, 0x07047e7e, 0x10c377a0, 0x619d63b5, -0x21577c07, 0x617f97d7, 0xd95ee11f, 0xaf3eaf45, -0x2ac47d03, 0x5cf0d549, 0xf88a5dc6, 0xde12658e, -0x3e0fe2b7, 0xa5c883a0, 0x2c7670f8, 0x1ae5adb7, -0x0f7088ac, 0xeb5d1237, 0x17a2083a, 0x5de19b6e, -0xdf26bdab, 0x74176916, 0xe05319f2, 0x3d505666, -0xf7450820, 0x639bbc84, 0xc578452a, 0x4bac0414, -0x27e5d857, 0x4a7e7aa5, 0x2ece3ca9, 0xddd01d5c, -0x72909add, 0x32221600, 0x5bc02aa4, 0xe138a34e, -0xf375796b, 0xe28b23d2, 0xdb427098, 0x5a1f4e73, -0x33a5905c, 0xcb2b57bb, 0x4c480095, 0x2cd64244, -0xe924481b, 0x68fa0d30, 0x0a295560, 0x4cadc133, -0x02ab2b81, 0x493ff0e8, 0x8a905491, 0x5ffabb8c, -0x3894736b, 0x35ec4d84, 0x0835a1b1, 0x8b02df2c, -0xab53d500, 0x7582c169, 0x6ae766e1, 0xd75da68c, -0x14f541de, 0xf74512d5, 0x6e722764, 0x3e9c3d92, -0xabde8a97, 0x957ab2d8, 0xc6f26229, 0x75fa317f, -0xb14c870b, 0x7911fe5e, 0x3025fd3b, 0x65bb7420, -0xb4e1a2cd, 0x0ddc8170, 0xd68102c5, 0x560c25bf, -0xe54e94b9, 0x1cb3f345, 0x5e0bf4a2, 0x8774fe3e, -0x392a77de, 0x1ccc14e5, 0xb53b4fdc, 0x8536f959, -0x72a7db1d, 0x822b6030, 0x17604ab3, 0x6dd9537d, -0xafe21a4f, 0x93a65eb9, 0x55173802, 0x559cf7a1, -0xc13c20c1, 0x2909dfe8, 0xbd67d285, 0x2345c952, -0x62c9eaed, 0x7ad7d3cf, 0x1203b5c0, 0x706ff9f5, -0xb2e709f5, 0x0176239d, 0x0d1fdb60, 0x86d85cc0, -0x2000141a, 0x2ae2cda8, 0x668864df, 0x802503c4, -0xcda13b39, 0xe2a90e69, 0xf7a857de, 0x70cd90f7, -0x76dfd0bb, 0xef748228, 0x05a80fb5, 0x6c916906, -0xa186faf5, 0x09b3f6df, 0x07ac9a86, 0x0bc02765, -0x6ac940c6, 0x6dbe2bdd, 0xd173be7e, 0x5262b01a, -0x63394c1c, 0x5e9fa5b8, 0x047d32b3, 0xc145798f, -0x9baf5b51, 0x0611666d, 0x8ef11917, 0xb080c5b5, -0xa296c219, 0x9d380d47, 0xc8c15757, 0x5d2854a5, -0x664bea43, 0x9380ae2b, 0x5dbd12fe, 0x75cb9799, -0x476b278d, 0x051c6fcf, 0x0069c985, 0x4550dc3f, -0x05917659, 0x1ca91e59, 0x3f9a7668, 0x5e32f534, -0xf8189e65, 0x49eac6b6, 0x9f05bd02, 0xb4808883, -0xba55bc74, 0x6da7ad18, 0x5cb8e1be, 0xbd451bf7, -0x488cb3a6, 0xbc90c9cd, 0x264679a2, 0x59dd789f, -0x12811426, 0x81c3cd79, 0xf39e8dca, 0x33b6fc1c, -0x200eb4e5, 0x1b0dc455, 0xa5cd6307, 0x469cb2b9, -0x5918074d, 0x53202e4a, 0x271c8b79, 0x5c05a629, -0x645c0d01, 0x056c2d2f, 0x91850195, 0x9b95d3f2, -0xfe760e19, 0x131ea846, 0x5f02fda1, 0xbee758d8, -0xea1b1a1c, 0x9c0847d1, 0xfe534f41, 0x34a6bc3f, -0x782a53ba, 0xeb118177, 0x0231026f, 0x7c181da4, -0xba99d566, 0x63b3e9e7, 0x47d37a5d, 0x0a3dffd8, -0x479e6773, 0x5e6da4f4, 0x1d354ecd, 0x742eb5b2, -0x33027d7d, 0x078f2b38, 0x56bbae65, 0xcae0a598, -0x303ffa02, 0x665b0971, 0x6d32d6ff, 0xe5581657, -0xc003279b, 0xfc4e6ba9, 0xe3567dde, 0x37afd1c9, -0x8e928c52, 0x8db2e4b7, 0xad0eb068, 0x19258691, -0xae5c03a2, 0x468a97cf, 0x8cda06d3, 0x2263dcff, -0xaed65f19, 0x05b00086, 0x5a9e6281, 0x43b65e6c, -0x7eaa6443, 0x31bab45c, 0x51a9c54c, 0xde8ae47b, -0xd60a95cc, 0x1ba74a4c, 0x330827b2, 0x9b8df9ef, -0x0e74dd2f, 0xd6c9e271, 0xd0b77195, 0x10f6ff80, -0xf5b229c6, 0xc0fbf468, 0xdd616994, 0x35730277, -0x838da982, 0x28349728, 0x7b3a8b72, 0x2a4e3942, -0x04e3d703, 0x18684df3, 0x66ada9af, 0x52caad42, -0x3fab8e47, 0x7bfce626, 0xe231de2b, 0x8d48cca0, -0xa33962ca, 0x22261b94, 0xc9521872, 0xa7119363, -0x547d93b0, 0x916d5807, 0x1b28e860, 0x1bedc9d8, -0x50eb8ae2, 0xa1f78b7d, 0x93ec5d30, 0x99d0907a, -0x5d4eb7e9, 0x5bff668f, 0xbed1cddd, 0xd6855c2f, -0x080d4077, 0x9380ed95, 0x44fa1c58, 0x5bc86778, -0xe4043eb3, 0xdf55407e, 0x1a2ccc36, 0x0c237745, -0x951f59f9, 0x4c7c0e1d, 0x194bc507, 0x30047f1f, -0x4be6bdfe, 0x3cb966b2, 0x4c4a97e8, 0x3e2feeab, -0x5307c0ab, 0x6ce6928b, 0x2ef9433a, 0x889f8123, -0xd1714dde, 0x0ee72b88, 0xfa057aa1, 0xb464b160, -0xa01557ea, 0xbad0c31d, 0x86525519, 0x2626f1f7, -0x4562675a, 0x925acdfe, 0xd4056b9c, 0x7832aab9, -0xe15d9036, 0x70a863f9, 0xb5c05434, 0x56f0cb29, -0x97bf53c5, 0x59d22ae8, 0x8ecf3e47, 0x0ea14042, -0x4e9d7953, 0x6c3ac3af, 0x6b977cd4, 0xb4dc2fed, -0xe3b10fef, 0x01f5954b, 0x53ca7180, 0xe42e8969, -0xc150f227, 0xddf3c2f5, 0x5717f20e, 0x4ce5c5bc, -0xaf864cae, 0xf9707380, 0x91d63485, 0x41bcc1a2, -0x8abc0fff, 0x47f402e2, 0x3453acaf, 0x1a597f26, -0xa4f77d5b, 0x48c64ce0, 0xb57fe88b, 0x4a3388b1, -0x1de5a08d, 0x698f102c, 0x3d623ff7, 0xcfb6d7a6, -0x36fd6bc1, 0x55aaeef4, 0x7f080d25, 0xfd60d0e3, -0x460e89e4, 0xe149cd04, 0xd0f2e68e, 0x5b11fd91, -0xfb4754ee, 0x8251d89a, 0xe653ecb7, 0x1a1169e0, -0x1f6bc908, 0x17776d46, 0x4d6fa5ff, 0x5185c78a, -0xbcd18053, 0x79f86716, 0x77147b1d, 0x303ca9be, -0xd93aaff0, 0x6d9ffa8d, 0x6abeb7e8, 0xa6bce101, -0x5a80c655, 0x2ad2b1ac, 0x1c082a07, 0xf0e16482, -0xb4281f26, 0xbb1705e5, 0x0fee4e39, 0x0c17e5d0, -0x001cb676, 0x8e3a01d9, 0xc4f29c4e, 0x05c73985, -0x577acdfd, 0x2cb58a4f, 0x05d90b10, 0x0283e303, -0xc2037211, 0x15d23cb9, 0x7379a799, 0x10475d7d, -0x3dc893c3, 0x69964151, 0x52640806, 0xcdae2c07, -0xa6af8fb6, 0x3db5db62, 0xd1a330b8, 0x9be6acf7, -0x1b5692a9, 0x91effac3, 0x688e31ad, 0x4b9fafd6, -0x483f04b9, 0xad090032, 0x2756e97d, 0x7e23afd7, -0x34c133a7, 0x164e116f, 0xcdddeb7b, 0x28d7274d, -0x1aeb0c24, 0x76de689c, 0x88bc316b, 0x0ee3443f, -0x893a815b, 0x4e29f2f7, 0x191cb965, 0x7470aec7, -0x9d224d59, 0x22ebab10, 0xc313cad4, 0x1b82cf6b, -0xb490c745, 0x1f0a25a8, 0x2f89f1da, 0x1c763d3f, -0xad474ebb, 0x7e4deb59, 0xbf7b9fd2, 0xd47046c0, -0x30455625, 0x3a6c1a46, 0xdea1acb8, 0xe6430489, -0x6646ba4c, 0xb7da15cb, 0x37037c35, 0x7864c5f0, -0x82728ed2, 0xc9c68066, 0x8fa79986, 0x2ac1c078, -0xaa1796d9, 0xb2808f42, 0xdcaf399a, 0xf0785363, -0xa239879a, 0x64a16b18, 0x5729e475, 0x32051219, -0x7065be03, 0x3a312c5d, 0xf88668bd, 0x9dd1cde3, -0x92553032, 0x499e54a6, 0x039d24ea, 0xbedcdc89, -0x655f04e7, 0x3ff657e3, 0x2315ff30, 0xbb4f4ca1, -0xd8904f24, 0xf2640f41, 0xda3b34a5, 0x0039fca2, -0xc4a898ff, 0x1ed56af7, 0x3b457066, 0xaaad566b, -0xc4eb0098, 0x0e9f91a6, 0x4ab60ce9, 0xe0482f06, -0xee8b5568, 0x33aa937d, 0x379c5095, 0x250e0ec2, -0xd8123a70, 0x1c3671e7, 0xb2cb87b1, 0x3600b645, -0xd86442ba, 0x885fae6e, 0x02ab043b, 0xf5e2f4d2, -0xbd49b714, 0x9124831e, 0x5ff321bc, 0x650b8a2f, -0x38e50349, 0xd050c275, 0xe41b375c, 0x529db8e8, -0xdd18dc07, 0xbf9738ab, 0x8a4666d0, 0x649ef5f7, -0x22ace388, 0x062d548c, 0xcf5e83d1, 0x84384bcf, -0xfcdb8f55, 0xe2c8ca9c, 0xa31e2bc3, 0x25c542a6, -0xbd118909, 0xc4d68602, 0x1a34f2fa, 0xde180728, -0xf068bc08, 0x631e3f3e, 0x4b0cbcab, 0xfdfa5fe5, -0x0b3b6fe4, 0xe70ba1a3, 0xaeb907c2, 0xeabde1c8, -0x79d9861f, 0xef5c84e7, 0x9ca6e94a, 0x557f9027, -0x57766a22, 0x2a9c23fa, 0x92a922de, 0xdda1883b, -0xba13c759, 0x9a138b55, 0x8f06e35e, 0xc64618ee, -0xd35f1d08, 0xaa95b6f1, 0x947084cd, 0x4a5ac647, -/* 2499-m401067660C.inc */ -0x00000001, 0x0000060c, 0x01192008, 0x00010676, -0xfbac0f2d, 0x00000001, 0x00000040, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x0000060c, -0x00000035, 0x2e000000, 0x20080119, 0x00000301, -0x00000001, 0x00010676, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc8f5cd92, 0x30bd1beb, 0x77c4fb8b, 0xe899c960, -0xc729b4cd, 0x1d9b8923, 0xfcdfc554, 0x580d39f9, -0x170ce7c7, 0xd727c705, 0x019b1ba5, 0xe0414a29, -0x57d45458, 0x26a8a411, 0x9faad966, 0x095ec8b0, -0x083a7c2a, 0x17cfc70f, 0x3c8e78a8, 0xce18c419, -0x5f2ddeb7, 0xc9c95d71, 0x437a5116, 0xe0253ad0, -0xec78db42, 0x681e436f, 0x7fd028bb, 0x1149a501, -0x0bdf0d05, 0xc2321514, 0xd6866cd8, 0x64942685, -0x21e0276b, 0x0817a288, 0x09138669, 0x792985dc, -0xbd60d6aa, 0xfbf902ec, 0x43fee69d, 0x5c5823c0, -0x9dca1fe6, 0xb528b0c5, 0x22fd29ab, 0xac4fe251, -0x77207813, 0x0637a1f9, 0x16bfcf73, 0x80497f6b, -0xe5bca939, 0x1539fa1a, 0x66607fea, 0x2276c06f, -0xd003229e, 0x3622fda7, 0x18d0b8af, 0x9f399760, -0x3ac6387b, 0x6c7148fa, 0xfaf4df9f, 0x965db840, -0x7c142542, 0x7b805f4c, 0x3f2002a3, 0x061399ce, -0x2f1a03c4, 0x7f1c7616, 0xb2f9ab42, 0x4e6a92a2, -0xb44b96d6, 0xe1167017, 0xec4b2fb3, 0xa15376be, -0x00000011, 0x4872f26c, 0x88971c10, 0x66db1385, -0x1e532ab2, 0x7ccd2d72, 0x38dd766c, 0x131f4505, -0x7d5e1e0a, 0x1932938b, 0x79c1db9a, 0x9fe5b8bd, -0x07037c1a, 0x698cd351, 0xbadb5300, 0x063f17d9, -0x8558ada3, 0x224c2288, 0x26fa35b3, 0xe64efb19, -0x0e1b52db, 0x696d5461, 0x3a0f765c, 0x4b853dfe, -0x05147b28, 0xbe146518, 0xb61e1de2, 0xc342998e, -0x083d5f41, 0x737fdbb5, 0xdd812ce1, 0xa7b9549c, -0x164b5fbf, 0xaffd6139, 0x44154437, 0x23d44899, -0xbe41eae1, 0xeecc8d45, 0x31fc971a, 0x44475238, -0x5d4ab69c, 0x67f342a0, 0x118cb268, 0x513fb847, -0x0a86fce3, 0x23f22535, 0x5fa15360, 0x929aa833, -0x3cbd4138, 0xc1dead1e, 0x3efa210b, 0x9781a61d, -0x00b53f73, 0x07df4d30, 0xffe97322, 0xf7b12998, -0xba4d7316, 0x4b746898, 0x45ece500, 0x78cf31d5, -0x0208c1c6, 0xc3999e15, 0xce2f90f4, 0x7e130a0b, -0x3c74ce12, 0x37612fd2, 0x7ce3ae15, 0x99a26321, -0x52ac391f, 0xcb32f7e1, 0x0e50140d, 0x3a6bfc41, -0x497f7f9f, 0x334b7e17, 0xbcf4e41d, 0x3311b0db, -0x0dc65367, 0x44847807, 0x991c439a, 0xd2965df2, -0xfd72e4fd, 0x44b01f14, 0x5a0cf5c5, 0x70029e37, -0x92af3f34, 0x47949bdf, 0x771a3c07, 0x0874f372, -0x7a54670b, 0x7430b00b, 0x356234f3, 0x74edf1e6, -0xaaf60a4c, 0x2bb5eee4, 0xc2c1d43f, 0xc4ee788b, -0x4198fd90, 0x0aba19a3, 0xc251f028, 0xe42404df, -0xccbd25f2, 0xdb13eb69, 0x888f89a5, 0x5a6c8cd3, -0x1e3b469b, 0xe07e48c6, 0x87f25228, 0x64324c03, -0xe0426f9f, 0x148f828b, 0x4a3c82ab, 0x7d46539d, -0x0b5079ea, 0x2c675b3e, 0x83134717, 0xbe775c77, -0x74841ec3, 0x4470addb, 0xfabfa06d, 0x548757fb, -0x184ea712, 0x502765b5, 0xd7067ce2, 0x15afee11, -0x8a95590d, 0x3a1734cd, 0x212c7f7d, 0xe5aa3e5b, -0x9c7e75c3, 0x07486966, 0x5827bbea, 0x391e46fe, -0xc6acbc9e, 0x9761b6a9, 0x37bef8c4, 0x733eb81f, -0x7ac9a87a, 0xceacd157, 0xd931072a, 0x9383c10d, -0x5eae74ef, 0x5f82f6a0, 0xcf89077d, 0xbc641bd8, -0x1b7d1213, 0x980a4ed3, 0x410fa7e8, 0xaaa1a011, -0xa5e94ef2, 0x74937d5f, 0x3c109f67, 0x8e58bdcc, -0x2b43ad95, 0xaa516349, 0x6fa9cca2, 0x48a18062, -0x663c7fd7, 0xf3822d87, 0xbaaf1f97, 0x8da372b2, -0xa416831b, 0x6a645364, 0x9c7ac6fb, 0x3f5a9cab, -0x8cf6f4b4, 0x514fd1dc, 0x7e9d0918, 0x2075f774, -0xfda8677b, 0x3b5c16ac, 0xe887694b, 0x7d622e9f, -0x5427472d, 0x540e5c99, 0x2196e138, 0x5d5e9c58, -0x84a5fc17, 0xb17d6d41, 0x63273bdf, 0xfbb912b5, -0xaf16b7c1, 0xeb1914d7, 0x5d654b8f, 0xf4a594f6, -0x554a6311, 0xb391f519, 0xa5ad4acf, 0x9c052bb7, -0xea68faa7, 0x37399a25, 0x8f6f6d36, 0x47c20f2b, -0xf241ab98, 0x66da024d, 0xee90a06a, 0x33718b17, -0xaa89087e, 0x6dcca7f5, 0x43a59f0e, 0xcb2e3ab8, -0xb19126bb, 0xc56bccb3, 0x04f6fd9a, 0x0f63850e, -0xa2b6c85e, 0x309f9817, 0x7252b154, 0xcba20ff3, -0x143156b8, 0xcfcdc8ae, 0x13c2a75b, 0xea4bf1b8, -0x6e474959, 0xa9c376f5, 0x40d252b8, 0xb6209e70, -0x993efa22, 0x3d7e8007, 0x1857ba0d, 0x72f25310, -0x233a8f68, 0xeb4ca923, 0xb17917d1, 0x9ca3f4f6, -0xdecf1498, 0x99f5ddae, 0x8b6ba2b7, 0x54f41fb0, -0x1ec9ffa2, 0x74ad3bd6, 0x84fee3e6, 0x5294820d, -0x147e8b14, 0xd2dc15f4, 0x152fc744, 0x306bc043, -0xfdbb74d8, 0xf4ea207c, 0x53edfac5, 0x1b609795, -0xe990ee73, 0x749dbed4, 0xd1cefc95, 0x5c7b37f6, -0xc6b39045, 0x7281e3f7, 0xed0e6aa4, 0x590a246a, -0xe6e6a81d, 0x604491ac, 0x6cd14e8a, 0x7a19f5da, -0xf7c7326a, 0x0ef8029e, 0x0e741b48, 0xc962a062, -0x6f4ad86e, 0xa2729726, 0x93bcaf1f, 0x1bb56970, -0x12495cdc, 0x180512e7, 0xa1d68081, 0xb924c24b, -0x5a1461ca, 0x21438ca9, 0x5449ae48, 0x0f564503, -0xcec8df3c, 0x789f9b80, 0x5a708df1, 0x28735bfc, -0xcf11d2fc, 0xa5d01625, 0x80b0b533, 0xa09f026d, -0x1d22fdf2, 0x01928228, 0x8b6779ed, 0x04f7cc95, -0x581fe0b2, 0xcc9a66a4, 0x55b3f130, 0x0f22abed, -0x05b7e95d, 0xd8cc9c30, 0x0850ca8a, 0x34d729dd, -0x973300a7, 0x80ffedb1, 0xbf5b28e7, 0x135c8cc6, -0x4337b017, 0x31d8dd09, 0x35ed75a1, 0xb8f990b9, -0x4384dc18, 0x29d72b56, 0x021aa2b2, 0xa3248b3f, -0x5f4e7301, 0x29991927, 0x1cc50c18, 0x79fcc545, -0x56e2e683, 0xe5127777, 0x4b727957, 0x94d1bc22, -0xacd0da9e, 0xd24771fd, 0x5997ff0a, 0xb9947cb8, -0x8cb9bb5c, 0x16a4c5e0, 0x00d6995f, 0x1e05edff, -0x3a7f1af3, 0x445fd70d, 0x24a602c7, 0x6b50001a, -0x6c99f5e5, 0xad2c00c5, 0xbd16a90d, 0x3b7b6032, -0xa8dd4f8b, 0x437145f1, 0x5a593d5f, 0x749ee409, -0x9c6d8223, 0x40c1dad0, 0x578e7e1f, 0x89072e7b, -0x0ccf47c1, 0x427606d8, 0x4a7bb48c, 0xf85cc4e9, -0xca5ca3b6, 0x9b989f23, 0x6496403f, 0xdf8ef891, -0xf4458e90, 0x28eed125, 0xef91afe9, 0x97a8d65b, -0xe022b3dd, 0xc93c2adf, 0x520cbe7c, 0x58995018, -0x719a724a, 0x9258733f, 0x8df05767, 0x879b9ba1, -0x84684054, 0x71a62082, 0x5be959cd, 0x12c937ec, -0xc21fb3b8, 0x6738aa89, 0xb01d872b, 0x0ff6ec3c, -0x50fc63ea, 0x715b7c5d, 0x4e5d50c3, 0x086c862e, -0x34ec9201, 0xd41176ef, 0xd0238088, 0x53518100, -0x8e1500dd, 0xc6ea9594, 0x0359517e, 0x58d81a35, -0x48c40983, 0x2d562dc6, 0xecf5be9e, 0x4cd82ead, -0x45faeb2b, 0x1a66ec1c, 0x6b692a76, 0x6cb326b0, -0x3a6c362c, 0xf0174da3, 0x5e4549d9, 0xc12c5972, -0x73716059, 0xdd54591d, 0x32ee704b, 0x5a55c22d, -0x56bd1e7e, 0x2bd34024, 0xa42c85d2, 0xb1ce248a, -0x604a7570, 0xbbf4b3fb, 0xe0eeb866, 0x130b7dd4, -0xdb39dc1d, 0xd873b0c4, 0x3aedb6ef, 0x5efb2481, -0xbfaff9bc, 0xb94930d6, 0xa3fe71cc, 0x75867e01, -0x7c8ee191, 0xf38f4963, 0x8d077957, 0x658e7c2b, -0xc1bd58ed, 0xb86a20b2, 0xc624489c, 0x4624732d, -0xc11f1ee3, 0xf1874ed7, 0x173684cf, 0x0e5851d4, -0xc2662118, 0x13dbb926, 0x1668df5e, 0x00749d03, -0xab9530d2, 0x5758e602, 0x6db90ff1, 0x87270f9d, -0x774a52f5, 0xcd1b4b5a, 0xd706025e, 0xe3a51fc4, -0x31c5d55b, 0xbd0278a1, 0x16dce1bf, 0x75a3446f, -0xe030c121, 0xa6f6b3c8, 0x504e3b3b, 0x4c1428b1, -0x74229a60, 0x25d5b7b7, 0xea284c21, 0xf5f1c7cd, -0x0025e9fc, 0xa7db9e56, 0x4e3aeb90, 0x8bad0f3b, -0xc19e88eb, 0x8ea86b83, 0x25cf5d26, 0xca78504e, -0x94109c06, 0x60ad3975, 0x138b8038, 0x4c9d8fdd, -0x28a91526, 0x5d3d6c3a, 0xf81ab861, 0x8db34426, -0x35a3b398, 0xf3b40170, 0xb7e6994b, 0xea72c1f5, -0x63201cd4, 0x1c5749dc, 0x420ada27, 0x419f4847, -0x49244543, 0xb915645f, 0x3a00b3e2, 0x0122000b, -0x296b6bad, 0x7b45d76b, 0x5be8f025, 0x2a04919f, -0x8291fea4, 0xaae644f9, 0x7af3fb96, 0x77d9878c, -0xa8996848, 0xa9a0c1c3, 0xb47ae6d2, 0xc5b6cf90, -0xb04b4863, 0x43fa113b, 0x66ef4993, 0x03a5b4e9, -0x94b661dd, 0x145a5909, 0xd42f70cc, 0x6b816775, -0xfbc0cb04, 0x5e890eb1, 0xb6900305, 0xcd19304b, -0x85c67d21, 0x19e91907, 0x27b3898c, 0xe0ce6ba2, -0x4110d80d, 0x85953740, 0xba7a4225, 0x51db6dd9, -0x04c21ffe, 0xd34ef7cd, 0xeb13f075, 0xc1f8eb04, -0x19a1227a, 0x3e99efae, 0x318346e2, 0x3d4c73bb, -0x402dacc7, 0x5a9e892d, 0x01304401, 0xb3950c6f, -0x9254bea1, 0x5cc8f025, 0x53cb9416, 0x52d716c5, -0x3ff575a5, 0xede2046b, 0x2cbd6b85, 0x7e8feb25, -0xc2d35482, 0xa49b8495, 0x214fed4b, 0xc93ae54f, -0xde3d8a18, 0xe4456b47, 0x505555c1, 0x6418926d, -0x4b6ac1e7, 0x7ac213ea, 0xc081eea5, 0x467ff1c3, -0x1ed5d79d, 0x746dbb24, 0x38b1dbde, 0x4d495fc0, -0x7ddabfe1, 0xfbac0ba1, 0xd17cfc3b, 0x32c819f3, -0x1f4c39cd, 0x6fa5c3ed, 0x0d2e7f50, 0x1f5cb318, -0x1e1770d1, 0xef12c293, 0xb149ace5, 0x93df9bdf, -0x14a98319, 0x3374906f, 0x746d603f, 0x5a368e6d, -0x8dbaef76, 0xb7923f42, 0x607655cc, 0xd144703c, -0xa01fa0f6, 0xa83f4e65, 0x224bba03, 0x6e082d15, -0x11ef27eb, 0xad91427e, 0xd8f0e3bd, 0xba7bc3df, -0xdb031557, 0xf33052d0, 0x2bc3df37, 0xf55d25c2, -0x99af998a, 0x5819eb07, 0xe4b9ebc5, 0xbc3da46e, -0xde1abe71, 0xb8c66434, 0xe811e29d, 0xa48ee5e6, -0x7f961c60, 0x5500769f, 0x9c8e0d00, 0x94680cea, -0x2f7a0c5f, 0x9a058310, 0xd3ddca08, 0x74276c4c, -0x855ebef2, 0x61979f79, 0x09684303, 0x3ea777dd, -0xf700db1f, 0xdf7bcae0, 0x0fa7db2b, 0xd0115231, -0xc0015882, 0xe4af6f72, 0xb4388c7d, 0xfb5656bc, -0xbe1d38b3, 0xf59ae9d3, 0xddc692bf, 0x3aaef998, -0x561f993f, 0x4d191a40, 0x4492df05, 0x7eb17670, -0x0770001b, 0x9b320a87, 0xbc8a559a, 0x19781e02, -0x13c995b1, 0xcb8c1e47, 0x462019e3, 0x7ee6bcc1, -0x9da2afce, 0xee1dbf76, 0x3a72ad3f, 0x711f786a, -0x0c72d639, 0xa3455dc9, 0xef155308, 0x82f3e1c9, -0xc9540414, 0xcec2cde1, 0x748005bb, 0x24197d5d, -0x4b8b7f7b, 0x3dde3129, 0x9ac952c9, 0x6f7932a7, -0xa99005e4, 0x4261280d, 0xfad329af, 0x90bcacb3, -0xe1c4a202, 0x9200d928, 0xffe55142, 0xf69b2a40, -0x227783a3, 0xe4b0c9c4, 0xeca97ce9, 0x9245597d, -0xa922db08, 0x94bff912, 0xdbebd937, 0x5c658f30, -0xb3f4a726, 0x24e2ca27, 0x9ca037d7, 0x745d3d5e, -0x3e8c437e, 0xb807af86, 0xee5fa977, 0xfe335297, -0x5c0a6707, 0x8ab801af, 0x05d02766, 0xcd0906b4, -0x791b47d3, 0xff5a0291, 0x09465b16, 0xa7fff3a1, -0xe2e6d825, 0x7f4f2b9a, 0xc1f2e668, 0xa5cfe1d6, -0x95fd7bde, 0x38681314, 0xc3c7dce1, 0x7b82e044, -0x2c883c77, 0xe8aa72be, 0xd53867d7, 0x7022fdc3, -0x3b697ccd, 0xd71618ac, 0xc87934bd, 0xe96101d1, -0x55d1976c, 0x471c8505, 0x7a36d839, 0x5d62a9ee, -0xf3c54a8a, 0xa2be15d9, 0x244087c9, 0x042c8037, -0x23224689, 0x281c5d73, 0x2139ecfc, 0xffb8bc8a, -0x834fdd11, 0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, -0x4ae2dbda, 0x86d90089, 0x6675dfce, 0x48876262, -0xcec72538, 0x11dc5c80, 0x86a730f9, 0x313565c9, -0xe3e5be11, 0x106d7cce, 0x752b8be2, 0x3d00a5bc, -0xe6f70e95, 0x44447ac8, 0x600df30c, 0x8335ac3b, -0x8816ddee, 0x700982fe, 0xee495741, 0x48c7e81c, -0xa3d55da2, 0xb0172982, 0x70ab2158, 0xd4460621, -0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, 0xa8454763, -0x70877bb6, 0x66005c97, 0xaf292c06, 0x7b843db1, -0xf343b59b, 0x25cdc7b5, 0xa41da617, 0x9e9d895e, -0xc936f475, 0x7270925a, 0x30024230, 0x8e72f53d, -0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, -0xaf377cc1, 0xbff09a78, 0x4b4e0814, 0x95a0b2c1, -0x270398de, 0x201fca94, 0x2a032a4f, 0x131542b4, -0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, -0xa3b3a991, 0x17ee60c2, 0x852c0b8d, 0x11e5853a, -0x762002a7, 0x92c5311d, 0x0d4bf7e1, 0xfffec870, -0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, 0x0111a772, -0x9808e780, 0x29c336e8, 0xe9bc05df, 0x5bedde11, -0x945565af, 0xaff808fe, 0x87e3423d, 0x4de6f98f, -0x93b4adef, 0xbf704fa4, 0x09120e91, 0xd54f3692, -0xdf8eab1e, 0xfabbf59c, 0xe74318be, 0xaab87ffc, -0x29fa791c, 0xe3915552, 0xa652cb9b, 0xa1252e74, -0xb35b723b, 0x542aa28b, 0x12fcc5b0, 0x3941f962, -0x82bcc6cc, 0x47b11974, 0xb821611f, 0x78b34250, -0xf1be5659, 0x561b9e61, 0x6f3bd501, 0x584e6f5c, -0xd54ed547, 0xacebcd21, 0x7b5ff816, 0xb64ad233, -0x9f2f330d, 0x69fb1ece, 0xac8710dd, 0x58dc6c60, -0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, -0xa733274f, 0x884d9b55, 0x42b08b63, 0xafa54a74, -0x1c7ccf64, 0x93a20191, 0xaaa3132e, 0xc69831d1, -0x54634889, 0xfbfe3efc, 0xd3cf68d4, 0x302e3117, -0xf5693131, 0xc3ce8c6c, 0x1f03cd89, 0x6243334c, -0xf16bc80f, 0xdca5f130, 0xcb2cd956, 0x4c1bb421, -0xe8de533c, 0x7f86703a, 0x29aa897e, 0xdd54acad, -0x76b2f2ae, 0x7ef82b71, 0x2e30970b, 0xba402597, -0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, -0x2363d147, 0x5327289a, 0xe89229f3, 0xd63a535c, -0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, -0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, 0x6d65db4c, -0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, -0x8488a45f, 0x8ebc2932, 0xd4767316, 0x3e8c4b8a, -0xbab7402c, 0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, -0xc88528e9, 0x4b2e4e8f, 0xdd938b86, 0x0c964f98, -0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, -0x4d40b3b3, 0xcf203155, 0x0d2fa621, 0x752d2c58, -0xb12bac12, 0x1e7e8c23, 0x94215d54, 0x9854a71c, -0x4de63c64, 0x7a012529, 0x9c171f8d, 0x9e71def7, -0x3bd17d50, 0x11f175d9, 0xec78abf3, 0x7b529eee, -0xd3a69fc3, 0x5b718676, 0x58214d29, 0xa8bd2c34, -0x41ea00ab, 0xa03f64d6, 0x4ee342b0, 0x32b1e444, -0x1c1801a4, 0xc8424702, 0x334a7e35, 0x50cf1543, -0x3b22b495, 0x88683776, 0x8e2e0154, 0x6155c033, -0x4e2fa6ac, 0x42ace700, 0x8d64f97c, 0xaf9ced17, -0xb2a5cb92, 0xa558582d, 0x88705de7, 0x9e528d59, -0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, -0x10462123, 0x30080f7d, 0xb346cd81, 0x0049c396, -/* 2347-m206fda3.inc */ -0x00000001, 0x000000a3, 0x08132007, 0x000006fd, -0x89c0d07f, 0x00000001, 0x00000020, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x72cbc5d0, 0xa24e89bc, 0x074028ef, 0x2ad07a06, -0xdeb7acf5, 0x98912a6d, 0x295d17a5, 0xa3b8708f, -0x95c69839, 0xb2f655e2, 0xdce0fc75, 0xf92f04fd, -0x51b6b38e, 0xe7884365, 0x69dcc34e, 0xcfe67a6b, -0x5e421f0e, 0x51527923, 0xb63fceab, 0xae39d6c2, -0x5dc6865a, 0x5819082a, 0xcfcfc6eb, 0xc4ed71a8, -0x06e83b7b, 0x7cc5025b, 0x5fefb2c9, 0x3c02abbe, -0x42dba8cc, 0xfc966b64, 0x2acaa07e, 0x61d32476, -0x72fed3f8, 0x7ef26af7, 0x8086deb1, 0xd11fe511, -0x3dcc3e92, 0x202bf190, 0x17fbf18b, 0x4cd17950, -0x81299fb5, 0xac3d96a2, 0x389ff313, 0x85dd4b22, -0x4eaef9da, 0x623b133b, 0xe3d02b2c, 0x2290a31d, -0xc6f8c543, 0xf6c18f11, 0x8070c5d4, 0xc756e5c4, -0xf4a40060, 0xbf169c70, 0x62dd14d4, 0x729fefe0, -0x6594d275, 0xa5abc2e8, 0x720904e3, 0x5a5b42ad, -0x5e970808, 0x5a6ec767, 0x502a6d38, 0x88d24740, -0xb4739506, 0xe3f497a2, 0x2618e78d, 0xfb602c6c, -0x323fc08b, 0xf9cb3dfa, 0xc90130e6, 0xe373da35, -0xde024249, 0x490b1796, 0x93f157ee, 0x10f73761, -0x6dd5c0e4, 0x4a9fb1fd, 0xadc2ead7, 0xd13e442c, -0xbfbd007d, 0xc8de8a68, 0x09c630bc, 0x69e78a87, -0x4d64bab9, 0x81c58c9b, 0x0b693158, 0x2a40ee8f, -0x47153744, 0x2a32e243, 0xdde6b849, 0xa2c35ddb, -0xf8c10a60, 0xaf5796f6, 0x8a95da67, 0x013f80a1, -0x7f332110, 0x345e3e0f, 0xba8ca1f8, 0x373a3380, -0x97f10a50, 0x3e1e78a8, 0x097496d4, 0x60ef2ffb, -0x9421fb84, 0x03131ba9, 0x535e0247, 0xeda34f42, -0x7f34ebb7, 0xbcfd1c2d, 0x19b2c696, 0x7107aed5, -0xd5877fe2, 0x404186ae, 0xbc41a831, 0x1cd49fd3, -0x92ff4c85, 0x3f65b35e, 0x701ce1cd, 0xe3839c91, -0xab53cf2d, 0xdb124ec0, 0x7c012c6c, 0x432b628b, -0xac351ee6, 0x9da287ad, 0x0adc2580, 0x66f945ca, -0x36bd8108, 0xbce986ee, 0x8fc2d524, 0x06dbf665, -0xb4124dd5, 0xf15c2853, 0x4aaa9b46, 0x753c207d, -0xd7805517, 0xaa6f6dfe, 0xf6eb1ced, 0xe6a4f89c, -0x5cbf2b1f, 0x6889832b, 0xf121bc8e, 0x2d7e02e9, -0xedbc10d5, 0xf3974ab6, 0xf977d65d, 0x40ef2640, -0x9c5f3410, 0x7ce2bca8, 0xac2d2c23, 0x204d560f, -0x2dffb3b3, 0xb051fdc4, 0x76ef18ad, 0x1b13190f, -0xa08cd1d4, 0x1aa202b8, 0x1a5040f4, 0x23a24420, -0x22622bd2, 0x6e543121, 0xfe68651f, 0x4e0d3fd6, -0xda661e0b, 0xfb41bbdc, 0x5a6e0df0, 0x8c27383a, -0x91e24f94, 0xa5db6d2d, 0xc7684280, 0xfddaf106, -0x0ada8514, 0x5cb76df8, 0xea1242ce, 0xc5aca25f, -0x0821a5f3, 0x71e4de37, 0x89c9a2a8, 0x4d2231b4, -0xc3edc81c, 0x56f516f9, 0x7e95a590, 0xe00ea616, -0x827fd358, 0x4511b62d, 0x6cac7958, 0x8259e262, -0x9ee67b13, 0xe73bdab2, 0x811f51d7, 0x88e6196f, -0x642a4db5, 0x1ca77047, 0x5a095f6c, 0xa42ddb9a, -0x66321e3c, 0xeeed0f13, 0x72e48195, 0x988f23df, -0x3d058cd3, 0x45fed77a, 0xa20f4f80, 0xca873db9, -0xcfd4a890, 0xcb406f47, 0x56bd45eb, 0x8ca14876, -0x411da96d, 0xaabe66e1, 0x26ce3950, 0x40ceb4ab, -0xbbb2b914, 0xfd90126b, 0x74c60165, 0xcd2e00ff, -0xe0607bd7, 0x3dc3818d, 0x4102205b, 0x72cca471, -0x0864151a, 0x65c92538, 0x5bc44cfc, 0x406a9b62, -0x10e5aab2, 0x751f6321, 0x533ca54a, 0x335961a9, -0xa386abb2, 0x24f90a2b, 0x3d13ff7c, 0x35d454ef, -0xc236b524, 0x8cf68189, 0x6ba29c87, 0x3925aaae, -0xa12de178, 0x4610a2d1, 0xfe330eca, 0x8d657af3, -0x7f2f81f3, 0x46cd664c, 0x676003c0, 0xdf786970, -0xb240a066, 0x41f852f2, 0xb85e5eac, 0x8ba83def, -0xc12c498e, 0x02c5d742, 0x4b9df557, 0xd9f2ed28, -0x5f7cec4f, 0xf9ff3a0c, 0x457ac549, 0x133f5bd1, -0x951b6947, 0xf835f2df, 0xee51efd0, 0xe90b1bdc, -0xb76c1a80, 0xc3f209a0, 0xb175f774, 0xd8963aff, -0x3d458f2a, 0x9ba9ca53, 0x91561069, 0x444ac140, -0x87f53cb5, 0xc835bec0, 0x2b6906e1, 0x1f2201e6, -0x443bfce4, 0xd0e25486, 0x71ba244a, 0xa85e4fad, -0xb0a9df78, 0xbef803cb, 0x710cbd53, 0xd7ce50b3, -0x38f69e53, 0x5175759f, 0x987de9f5, 0xfc5f9332, -0x090ba2ef, 0xa059c8e0, 0x9efc20ca, 0xaead8853, -0x22cd4804, 0xb30dca16, 0xadbbdf33, 0x246cb36c, -0xec99405d, 0xfef7e46e, 0x454bf0a3, 0xa75d4072, -0x6859ad38, 0x3c6a15e8, 0x37bb8ecb, 0x05747a82, -0x97edcb0b, 0x5bff5a7d, 0x20cd1e91, 0x1e37277b, -0x4c0149e1, 0xc7d5e490, 0x253bcac9, 0xdffe64ac, -0xf7ce2179, 0xada80d94, 0x3653f166, 0x7271d8a4, -0x994f269f, 0x0841e81a, 0x709401cc, 0x0c9fefbb, -0x30fa89fd, 0x1fea8b70, 0xffc68c98, 0x2030e064, -0x8e28b2c7, 0x2750f01e, 0xceb4d955, 0xb86ee560, -0x7ca55701, 0x3a942ffe, 0xd6ad0e17, 0xe8cec9d1, -0x5a6954e8, 0xb14fe7c6, 0x6e7d5c90, 0x8481626b, -0x7c798699, 0xdb0b344a, 0xa721cdc5, 0x861db07a, -0x1844fca7, 0xde861a71, 0x770735c1, 0x3ab64f3e, -0xb352aeb8, 0x046529cf, 0x2fd753f9, 0xbb3cad72, -0x27b44c84, 0x58e77f53, 0x08840b3c, 0x75ceaa6a, -0xcfb8ec2f, 0x8877c4a8, 0xee6bf89f, 0xc6256203, -0x0bb3f6bc, 0x696fa2f3, 0xf04e8efb, 0x3fd0099b, -0x27a473cf, 0x87fe81c8, 0x35cface5, 0x8afad818, -0xb47534e9, 0x90b406aa, 0x7d7c2d15, 0xc9caf1ad, -0x9692ac7f, 0xa3bc5fc9, 0xfd41d0f4, 0xc47f86df, -0x60cbdd17, 0xc1fc9bb1, 0x518ec6f8, 0x45c7e024, -0x7db1e277, 0xd4d30cd3, 0x35bc1c5a, 0x60b61287, -0xfcecbc8b, 0xc6cb70e9, 0xc6280061, 0x9d0ac8ce, -0xfaf12df8, 0x9b3f092c, 0x979a43f8, 0xbbdbe0cc, -0x6274f1d9, 0x7322b577, 0x50589a1b, 0xbd0dca66, -0x2160d66b, 0x4ea6b9f3, 0xd942aa7a, 0x0c8e1c82, -0xc0a07833, 0x0fdb7b24, 0x012a56a1, 0x9d2b019b, -0xba7c66ee, 0xe6af3a73, 0x823e0207, 0xd9913462, -0x8896001b, 0x142af0f2, 0x52539dd9, 0x864a53f0, -0x6e85c62b, 0x66139be6, 0xadd260aa, 0x2a7a579a, -0xd0fe929c, 0x67052a99, 0x1bcb98e0, 0x8c58f5fa, -0xb32d4733, 0xb4e4e4c8, 0xb536ab23, 0xd00ef025, -0x05c4cb84, 0xbbc9b7d8, 0x175d6254, 0x5d8ebdb4, -0xe3f3e65a, 0x52177f95, 0xe85d812b, 0x87fb19ac, -0x88b80b16, 0xc570083b, 0x124da09f, 0xc8522543, -0x5f73aab0, 0x6c25b49f, 0xc8a03cb2, 0xd857bb2b, -0x16378b5d, 0x242f0e79, 0x02d5d491, 0x7fc8b85f, -0x48177825, 0xc70d4bce, 0xa23f5d56, 0xc7ebcb58, -0xaf3b143a, 0xc33e9d65, 0xc043e61d, 0xf05a3d2a, -0xd162c7d0, 0xdad944f7, 0x3226cdeb, 0xd0d044e3, -0x8012c5e8, 0x18524401, 0x2a4d751d, 0x95592574, -0x8e03592e, 0x68a72ded, 0x7d65ba50, 0xfa66bb37, -0x81250634, 0xe92c784a, 0xb585ae7c, 0xc6e350f1, -0x8d40d62d, 0x5b2ad4bc, 0xc87b65d1, 0x700191fb, -0x06015556, 0xaf94c477, 0xa63b5aa1, 0x28a7ab7a, -0x7cdb448e, 0x3819d9d0, 0xcb0dfe9b, 0x715dc992, -0x88f5e070, 0xa1f5ecb5, 0x8c9876ad, 0x44be717b, -0xda7487fe, 0xecc57fab, 0xfb6cd21e, 0x6de34108, -0xa98b84ed, 0xd755144c, 0xb24c242b, 0xa29eab2d, -0xb909c928, 0x077da28d, 0x549454df, 0x173b4e96, -0x5353fdfd, 0xcf06a087, 0x33acdb4a, 0x166b41a1, -0x45219876, 0x96eb46b1, 0xee5f18ad, 0x6a962b7a, -0x9914a217, 0xca72359c, 0x28f5a8f8, 0x9d0b43ac, -0x5fb6964f, 0x0b2685e0, 0xbda83a60, 0x464fbf9c, -0xfd8f4ec5, 0x9d16acdf, 0x1192191f, 0x119c43e0, -0xd0a2df66, 0x8c2cf306, 0x3da0f9f4, 0xf409a043, -0xcfc563b0, 0xf0be102c, 0x3252b4b7, 0x07076cbb, -0x355888f0, 0x4e4bc8d0, 0x1fd64ff5, 0x245147db, -0x9d757b6f, 0xfbaeee9f, 0x43d68df0, 0x2709be60, -0xd333fd6b, 0x79af3f65, 0xb52de3ea, 0x04d94eb8, -0x43865e4f, 0xc736c027, 0xfd180b96, 0x78caa82a, -0xd0021810, 0x9e514f99, 0x72f5067b, 0x7de6487f, -0x6cb34382, 0x0e01763a, 0x89976ae4, 0x7a8bbfa2, -0xa50291f9, 0x6407b33f, 0xf7ce016c, 0x2d586dd3, -0xac0a7612, 0x32fa7be1, 0x3ee474d4, 0xc795f431, -0xd6d0a977, 0xdc859d13, 0x446f01b1, 0xafc13014, -0x67bad636, 0xda3c5946, 0xe169c32f, 0xfe5c93b7, -0xac1b3104, 0x42a5c9ab, 0xc906dad0, 0xe4b213db, -0x6fefea5a, 0x35528fb5, 0x59cadba2, 0x5cbb0ea0, -0x2b01c14c, 0xaa438c3b, 0x6bbad300, 0x3d6d3409, -0xcc87ec95, 0x6f167576, 0x623c3b26, 0xab438ac1, -0x469b5486, 0xb7992347, 0x0418dd1e, 0x54e6ad5f, -0x44bff273, 0xbc97e1d7, 0x7c5c88da, 0xf7bbb29a, -0x48d01e8c, 0xaa4d4376, 0x9a99c998, 0x24d09e2f, -0x24480693, 0x84b6b905, 0xd0ff443b, 0x76605be6, -0x5c6af5bd, 0x5dd0c084, 0x4d162432, 0xed939cf2, -0x2d333e06, 0xd2144645, 0xb06a3583, 0xc1d6e232, -0x03883c1c, 0x6a3a1491, 0xe6b619d9, 0xfee3f413, -0x5e59c26c, 0x28684bc1, 0xca68c55b, 0xca395734, -0x95d8afd7, 0x8a94d5ce, 0x6d780b0d, 0x6ab50934, -0xf5121314, 0xb9ec2632, 0x1beb9a14, 0xcd950304, -0x6fd91394, 0x33f84e25, 0x546d4a4b, 0xc303eb86, -0xcfb7b409, 0xf852adeb, 0x65c4960a, 0x01878815, -0x4a6501d8, 0x5bb3a40f, 0x9414a799, 0xbbae4dea, -0xae9d7b0e, 0x761dcb06, 0x9581c2ff, 0x06edcb74, -0x0c06177d, 0xdc36931a, 0x751d52ea, 0x699dd531, -0x5285df50, 0x81990800, 0xa81d52e4, 0xf305b98e, -0x260f304c, 0xa9f5a19d, 0x702bf4d9, 0xc4e322c4, -0x05e38fbd, 0xf6997433, 0x938443b8, 0x33fe4ff4, -0xc0da5ba1, 0x1701d20f, 0x4f631fda, 0xd966d058, -0x847b08a0, 0x7719b2ac, 0xea7e817e, 0x3cc266f9, -0x39b94930, 0xd5a7c643, 0x831d614c, 0x486c87ea, -0xeb32ec07, 0x27ccfb31, 0x3618615c, 0x01c5284f, -0x138ba020, 0x7f316b7d, 0xf7049fff, 0x2acb57be, -0x156b6bb0, 0x03df196b, 0x72bfb285, 0x0d1fd58d, -0xcb86fb0c, 0x938e1a8d, 0xd387a3ab, 0x5fa1b627, -0x2c4d3f80, 0x0b4a7121, 0xbab5d24c, 0x4e14e39c, -0x19d839a3, 0x0b730800, 0xaabb2b8a, 0xa58aa531, -0xa82260bc, 0x21be659d, 0x714b34d8, 0xa89d111d, -0x02828552, 0xae10e3c9, 0xdd9ecd12, 0xe13beb47, -0x96818a52, 0xb5fcd9b2, 0xa8d0964f, 0xfcc0e896, -0x7ab323da, 0xb1bf60de, 0xdb70c0ac, 0x83373de9, -0x3513e4d5, 0x0634af3e, 0xc3052a5f, 0x3acb8ac9, -0xcf03743f, 0x15555b96, 0x929b04ff, 0xdb2a9428, -0xdce90ae4, 0xe414e73b, 0x5b6b19ff, 0x1a708067, -0x61329d15, 0xc4eb8336, 0x2d861d5e, 0xca108403, -0x0e9ab2d4, 0x04d3b3c4, 0x36ef280d, 0xfea6cee9, -0x80c30cad, 0x399d1c6d, 0x2b654d22, 0x204032fc, -0xee60e1c1, 0xb20fd9db, 0x087a91fd, 0x6a4e368b, -0xad3ca7e5, 0x5355a689, 0xd220e928, 0x925cb754, -0x677991e5, 0xb3941d98, 0xa3eb379a, 0xf0237d52, -0xe96b9e08, 0xb7ae3c7f, 0x7a84124d, 0x9cc15b58, -0x2ddafebf, 0x93a8990b, 0x1555212e, 0x7fe44a1c, -0x90851979, 0x62a143a7, 0x5ba95724, 0x4d8762c9, -0xee3a6f84, 0x0af45b74, 0xcfabce5c, 0x73ff8f3e, -0xa872ef47, 0xe97e60bb, 0x805c1800, 0x8d3b978f, -0xaf71cdb9, 0x4d8da1ec, 0xae5f2f19, 0xe57566f8, -0xa2003cdd, 0xe65293ce, 0x6970388a, 0x979c68dc, -0x2fcf8d5c, 0x61a603d3, 0x92158c18, 0xd2f53c34, -0x842dc4b1, 0x32f3df78, 0xc696ab26, 0x2be86b54, -0xd98bca91, 0x0415fca1, 0x5afc9076, 0x796a5ef4, -0x87a225b1, 0x6b5784b3, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2964-M04106C2218.inc */ -0x00000001, 0x00000218, 0x04102009, 0x000106c2, -0x8fb7c1ba, 0x00000001, 0x00000004, 0x000013d0, -0x00001400, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000218, -0x00000035, 0x000b01c0, 0x20090410, 0x00000401, -0x00000001, 0x000106c2, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xa6db561d, 0x55b01a3e, 0x529538dd, 0x7ce8ffd8, -0xecba7acf, 0x5d5aa633, 0x74dffacf, 0x9659ea50, -0x0882023d, 0x953684cb, 0x0abe06ee, 0xa7ef1798, -0x160d6cb8, 0x930cf745, 0xafc3fd79, 0xa70df3d5, -0xb0620f46, 0x70048a23, 0xbf95ecf0, 0x76c1b997, -0x5128616d, 0xb6b4b969, 0xcc69f71d, 0xdf7416e1, -0xdf9a571b, 0x50c0bcc8, 0x85e2b3cd, 0xc1927532, -0x7a04b6be, 0xe56b7f97, 0x524085c4, 0x668bf327, -0xb3eaa54c, 0xccde06f8, 0x09b4e42b, 0x033b0a46, -0x0f6e2fde, 0xb308ce53, 0x93eff03e, 0x8830014e, -0x5c8a6f22, 0x91d2f757, 0xf70b648d, 0x0789998a, -0xd84d4640, 0xe5f34e80, 0xf3357e64, 0xd1e2beea, -0xc7e95c3a, 0x30e57e4d, 0xec214356, 0x7e10859e, -0x1d5895d5, 0xdeeff6cb, 0xed1030ed, 0x827e603d, -0x6b4b2de3, 0x83ec6fd0, 0xa64092f3, 0x8d9887e4, -0xbefcbedd, 0x2111afef, 0xcb9abf96, 0x5c79ceac, -0x9bf8a57f, 0x5d0e44be, 0xdca3d3b6, 0x9072d1ca, -0x48e73a50, 0x8d0bc804, 0x6aea94d3, 0xc372403e, -0x00000011, 0x39ca895f, 0x93bb36ed, 0xc7115d19, -0x51306d80, 0xd428d120, 0x7a46a942, 0x14d5038a, -0x282d38f1, 0x11a99a17, 0x55957f14, 0x316eb5de, -0x92127b40, 0xe8d48b9d, 0xe4afdd47, 0x05767c4d, -0x0d8b0fe0, 0x58166187, 0x254aced0, 0xe583cfce, -0x8bb8b390, 0x9ff4d234, 0xa92c79b1, 0x88bd3e77, -0x5a6d726a, 0xc6d9d333, 0x27ff83dc, 0x5abee1c4, -0x7fbe2fcd, 0xcd7bd6ac, 0x5de3ee47, 0x9a0ca90e, -0xc18cc94f, 0xb69c5689, 0xad1cd0c2, 0x99d9bda8, -0x99c08dc9, 0xa5bb8cb4, 0x69be45d6, 0x66f262f4, -0xe64fb256, 0x2bd7ec3e, 0x6a0ec5e0, 0xcd8db34c, -0xd4449d54, 0x22359101, 0x47233556, 0xb251a6c5, -0x1b3285a3, 0xc9395aec, 0xd3e35f52, 0xda8fe59c, -0xa7fca4b1, 0xa5c83030, 0x1cc5573f, 0x0427645b, -0x81d54e96, 0x9048b253, 0x44dc83a0, 0xed189dc9, -0x75125d2c, 0x58a922bd, 0x899313ed, 0x8cf7f569, -0x384c4ec5, 0x9029ca75, 0x55e95f72, 0xd02062e5, -0x2e78d4ab, 0xed323243, 0xc433467d, 0xf9bb4b2c, -0xde6a1a94, 0x89a58012, 0x84e1d244, 0xdabf2e13, -0x6c47c470, 0xea2e2b7e, 0xec9eb0b0, 0x6765b902, -0x0c435289, 0xf61b95eb, 0x1a250eca, 0x4ce92ea2, -0x6e7142d6, 0x2ab22c57, 0xc8f57439, 0x59112122, -0x5884b3cf, 0x2deaa963, 0xc267e8a8, 0xfc7cb9d2, -0x7a7a5869, 0x75460f34, 0x1e114eba, 0x6af15809, -0xbae1a8ba, 0x28e84fbd, 0x85e41b2b, 0xac55bc22, -0xc55defa7, 0x2a97a719, 0x49215621, 0xd38639ea, -0xd57a918d, 0x368d9f19, 0xaaf3ef52, 0x69cc2858, -0x17b3adda, 0xbaee0227, 0x9820207d, 0xc522f5d4, -0xc27c4e18, 0x03f72fe0, 0xdc3cc908, 0xd6620755, -0xb2ed9a1a, 0x11023f9c, 0x73987f0e, 0x95317140, -0x2a38064f, 0x04e90339, 0x2be7e65e, 0x7ab82b38, -0x2e9941dd, 0xb5ff2903, 0x7abca5d9, 0x79544128, -0x39f13caa, 0x250f104b, 0xb3d608ab, 0xa7c203e8, -0xe46a126c, 0x1f0da2f4, 0xb6f10aab, 0x2a9dc6be, -0x85b72c86, 0xca0082a6, 0x023c7574, 0xc313e95d, -0x70f8b023, 0xf8c61769, 0x7c400ecb, 0x03d0c567, -0x3b95f0ca, 0x15b27b08, 0xf3c65508, 0xdc644fd1, -0x75811053, 0xe67c7ad2, 0x7d85c0b0, 0x0c9ff7d0, -0x2e685183, 0x095684fd, 0x6df37cfd, 0xa270f064, -0xf5569b4b, 0x06a86604, 0xdf4b2e38, 0xf20bf008, -0x6e251617, 0x9226f9f0, 0x51a0cccf, 0xdd4b8357, -0x9a0e19f2, 0x7ffbddef, 0xe8002b19, 0x405d642f, -0xd33d5090, 0xcb321356, 0x7fad1948, 0xb51c4994, -0x77c7a084, 0x846b88e3, 0xfa19afa5, 0x4c4fc587, -0xae1fe064, 0x7de11dc5, 0x83cd780a, 0x58c33432, -0xd294c3f0, 0x3a3de34d, 0x874e4202, 0x34bb7449, -0x397ce3eb, 0xdcd7c545, 0xf6ed2d79, 0xaf6713b4, -0xcaf9f286, 0x93f42d09, 0xfbbb0fc3, 0x959c402c, -0x2c062ee3, 0x051bf973, 0x74f08ab0, 0x2a0f9d85, -0x68403fa1, 0x767319f0, 0xe8586f1f, 0xfb547280, -0x129c8c94, 0x30ac6b95, 0xad044183, 0x8de52a1b, -0x42ac6ccb, 0xa2eb5eb7, 0xe086d12d, 0xb723b9c0, -0xf7b95359, 0x55e156e8, 0x01fd9084, 0xeeafe28f, -0x3c110061, 0x8a9d668e, 0xa1833a70, 0x0b301724, -0x3765fc04, 0xf43aae92, 0x0aa2793f, 0x208cf158, -0x8bb13e43, 0xd1231448, 0xba11c8f8, 0x6f779857, -0x7136f774, 0xd4c8e9e8, 0x7be08185, 0xecd7cca1, -0x4994bf33, 0xaa8886c2, 0xb76568df, 0x93271af1, -0x0df50828, 0x059d3379, 0x40a60ea0, 0x6bccdbb4, -0x776badf0, 0xaf2ccf83, 0xf81c05f3, 0x0732e9cf, -0xfa57202a, 0x1d9cf14a, 0x74b91f23, 0x94f991b2, -0xe844de4f, 0xf24aadee, 0x19ed94bf, 0x5508edc7, -0xe63f71a3, 0x36e88397, 0x231e9e3a, 0xf48327b0, -0xf0624859, 0x8f740e3c, 0x1cf3a3cd, 0xd115c768, -0x8fb3e37a, 0x0f3524a9, 0x7d23a03e, 0xfcf1e790, -0xd8b51c4b, 0x3b12793f, 0x3691a0a0, 0x0f2bfdfa, -0x985ce377, 0x7d4914ed, 0xbe3dbd98, 0xc197bd8e, -0xe54e329c, 0xf8188bc0, 0xd8e72a28, 0x3ba3f848, -0xbf1d7200, 0x3bf294cb, 0xa0b6e8b3, 0x95927dab, -0x12703692, 0xbf852302, 0x088454c3, 0xae6ce6fe, -0xa837368d, 0x369448e9, 0xa8e05701, 0x9a714b61, -0x3fd5d6b8, 0x51372f10, 0x77b0f2dc, 0xf946df23, -0xd0d5feb9, 0xe846fbc1, 0x989ee82a, 0x31eb985b, -0xf2025935, 0x36daa3fa, 0x73dc049a, 0x9a899e5d, -0x33187670, 0xe8cc693f, 0xb0415660, 0xb0919235, -0x252fd6a2, 0x02d472c7, 0xecd9f1c8, 0xdd2a87f0, -0x33ff1cd2, 0x1648f3fa, 0xb6d72128, 0xf9a2eb89, -0x17ece9b1, 0xa42fd9c7, 0x301afcda, 0x0ecf222c, -0x52625ca0, 0xac16aa96, 0x4d3be9d2, 0x8186b4e2, -0x99975b51, 0x328d10ff, 0x8424f1a1, 0x31e8162f, -0x3e9834b6, 0xbe9a18cd, 0xcaf7599a, 0x8b8530b5, -0xaa825750, 0xe22369dd, 0x447509c7, 0xec4d3e04, -0xa5bdc12e, 0xde7a3edb, 0x0d98de14, 0x9eb54881, -0x1924a171, 0x3bbc7362, 0x84714cf8, 0x96f82374, -0xd74108ee, 0xc7205a00, 0x38f9d0c3, 0x78f8f8ef, -0xdce3b41e, 0x026bd0db, 0x57a384c5, 0xd35b1158, -0x36655a61, 0x6f822cc5, 0xb6324298, 0x83bf6575, -0x15adf975, 0x6ce429dc, 0xa864560e, 0xc4da018d, -0xdc8de183, 0x74d85fb4, 0xf3c15cc9, 0x79c83077, -0x2e9c1446, 0x5e5b0871, 0x767a15f2, 0x5d3b47aa, -0x5c09d151, 0x123ad6b8, 0xa21a53a6, 0x0b0d8034, -0xc47f2d36, 0xc8389191, 0x209684e2, 0x05370aee, -0xc9644803, 0x920ac415, 0xbd925b8c, 0x3c9f0f78, -0xfab0acc6, 0xf2cfa403, 0xd2ac3d27, 0x25593cd8, -0x0beed015, 0x5ddf5503, 0x2239be7b, 0xd03011b9, -0xbe3b0df1, 0x95ab9bae, 0x27ac4734, 0x15742fb3, -0x9a921ca7, 0x67a9d933, 0xbcccf85f, 0x60914713, -0x12cdc887, 0x26c56b9b, 0x5fc7ee87, 0xc37272eb, -0x7826389e, 0x781d8805, 0xca082c0f, 0xbf33b0ed, -0x3c1010d2, 0x7513e78a, 0x02d1b14b, 0x68378b40, -0x80dae0ba, 0xc3c15022, 0x8e1e34ee, 0x8345f599, -0xa51b8941, 0xda9cc023, 0x61579c1d, 0x68e851cd, -0xbfafc3b7, 0x022d3734, 0x135f8d36, 0xcdc3cb1a, -0xc779738b, 0x7593033a, 0x8b4610f3, 0xf0158863, -0x16d784a3, 0xc0551682, 0x9622697b, 0x88db3bdf, -0x764b9d9d, 0x226c3e59, 0xf85f7fee, 0xd021a06b, -0x9a9ba15c, 0x6bc761c6, 0x8cbc8b23, 0xba4d5545, -0x693b8b99, 0x8d214381, 0xa32509a5, 0x7cac34bd, -0x9a4b6905, 0x352c232f, 0x3d82dda0, 0x34d2dd17, -0xefa03c83, 0x3ed1eee5, 0xbe2e5cb4, 0xfbc1f13f, -0x0950a15a, 0xed410662, 0xee3ef306, 0x1be6f7ce, -0xc27ffe48, 0x1afcab76, 0xcd1e0f8e, 0xa9f09079, -0x0eca2d93, 0xff550565, 0xfc7c1a3a, 0xa7d74f14, -0x73c655fb, 0x1719fb91, 0x8595fca5, 0x936ddfdd, -0xfa176b9f, 0x9b0d5133, 0xe451cc28, 0x382aa742, -0x9bfbe2d6, 0xad14a4d3, 0x6211ad39, 0xb5fae645, -0x3e93763c, 0xd7b4d001, 0x045443e6, 0xc9fffbfd, -0x10667b62, 0x98eff9e4, 0x7ceee6c2, 0x69086a1a, -0x4aa03683, 0x5cf254fd, 0xac81bcc7, 0x649d5af1, -0xa004c935, 0x421933f3, 0x0f5a412f, 0x945ccb31, -0xc87b4948, 0x9f7ee55e, 0xbd78b91d, 0x590ef798, -0x73001efc, 0x4c14b377, 0x1a45de15, 0xc8dda7e3, -0xde57e6d7, 0x47e65d31, 0x01b560f1, 0xa502f06f, -0xb6c5c16e, 0x7cb166dd, 0x7636c3c9, 0x4c108d98, -0x73904c23, 0x1f5f3761, 0xe52b2ae2, 0x78b5952b, -0x7fd50bb3, 0xae3bd1f2, 0x58ca3508, 0x0788523a, -0xfbb55497, 0xc2179fd7, 0x25fa5930, 0xf5aeec4b, -0x6082eb97, 0x1d9b4acd, 0x143b24b6, 0x34d507c6, -0xcacc92f2, 0xc17c3be3, 0x19cfcbac, 0x33dba256, -0x11825477, 0xdd6744ee, 0xf0b629b8, 0x57912940, -0x15733ef5, 0xe634d0d1, 0x2dfeba27, 0xc6319803, -0x7d15fc9d, 0x5c0b6eba, 0x0ecdde39, 0x32533d3b, -0xbcd7848f, 0x06d09630, 0x1d3412d0, 0xacb97d0d, -0xf54f8a7c, 0x3d3a85a3, 0x0e3fe0bd, 0x2e32d571, -0xcf361a7e, 0x4983831f, 0x9cb8aa09, 0x98bca187, -0x069db1a9, 0xe8134a79, 0xa7dd0172, 0xfe5fab97, -0x3423dab8, 0x1f936b9e, 0xbfcbb3d5, 0xb6d131f6, -0xd6aa2295, 0x63759bd3, 0x7bf69653, 0x07f4fd56, -0x725b3288, 0x27682bac, 0x8ac30a22, 0x5a7d0cb5, -0x9d3a0919, 0xe98f45a9, 0x62d8d92d, 0x641b53dc, -0xd4cdcfad, 0xfcf5f997, 0x8dbc5668, 0x9b4b2a80, -0xac909831, 0x44b9476f, 0xbb81e58b, 0x31a7c9e8, -0x3bb674e5, 0xbde06fc7, 0xa6be53a2, 0xa2a30c2a, -0x424aca03, 0xa408414e, 0x57cb60ef, 0xce46ef67, -0xd6b97b89, 0xb885648e, 0x3f24d054, 0x1617dfbf, -0x0650d6e3, 0x403e13d1, 0x4c18d9c5, 0xe64f77c2, -0x6957ebbf, 0x76f77d78, 0x4651ac3a, 0x746888a1, -0x86bdf428, 0xa7b61fa4, 0x69ec5eff, 0xebebde48, -0x7aaa695a, 0x2f462098, 0x94d27b1a, 0x6ea584d1, -0x0d9a3ace, 0x9cc23297, 0xc955b249, 0x131aaa99, -0xa0d752b7, 0xa5bea5e9, 0xccc20d9c, 0xff448a18, -0xecd6c82e, 0xc5ff74bd, 0x3b698564, 0x082f7980, -0x61a9409f, 0x145b5ec2, 0xa8d65bb3, 0xfb6dbde8, -0x404ed75f, 0xb32418af, 0x7df9ac58, 0x188aed62, -0x82b41c35, 0x1fcb7d6d, 0x221023ad, 0x33e759f4, -0xf4f7873d, 0x4874a5bf, 0xcebeec18, 0x16435619, -0xd660d5dc, 0xfdd40b0b, 0x3332ba2d, 0xb843d48f, -0x44a0390d, 0xc87ad47a, 0xbeb03e24, 0xb5cddd29, -0x978e0836, 0x8d0f976d, 0x65358bb2, 0xdab3c7db, -0xc1c1c421, 0xfbfcc560, 0xdcb21c05, 0x5db79c04, -0xd57ae181, 0xd3e12139, 0xf6804667, 0x1e22f5ef, -0xfa4e7bb8, 0xc734f8fe, 0xabc4eefd, 0x3e3edeef, -0xa7504f27, 0x7dd07de3, 0x049ecb0f, 0x4faa2e25, -0x0657d955, 0x3501f79b, 0xba88eb2b, 0x027ea7bd, -0xc07e1907, 0xbee45c09, 0xce5077ac, 0xc29ae2c8, -0xa5c529a5, 0x2240bd23, 0x003baa87, 0x94b0aa6a, -0x32838466, 0x1a1bee19, 0x9302635b, 0xee524d8f, -0x2c2ec677, 0x11ad493c, 0xef9d192d, 0x921064eb, -0xec46ada3, 0x8215b76c, 0x734ab486, 0x81898de9, -0xf686b56b, 0x8414b0bb, 0xd77227d2, 0xf89b8772, -0x0bc6741f, 0x92d33ef2, 0xdf29599d, 0x60aa30bf, -0x5c945cf1, 0xdfc639fb, 0x41921019, 0xb305311e, -0xed6e0141, 0x44429de2, 0x2814d5e2, 0x9f35cd5e, -0x2f5224b1, 0xce30fd34, 0x0db89af5, 0xc955122d, -0xd7e6914a, 0x337c95cb, 0x8e582ee8, 0xad51cc03, -0xced7bb1b, 0xcb839d39, 0x39eb6ff0, 0xfcd5f580, -0x011e814c, 0xb070711e, 0xf207b150, 0xa0433d3a, -0x9f88f7d1, 0x9560e6e0, 0xc4ff1232, 0xc87629cd, -0xae8d5db1, 0xabde125b, 0xcd6334fc, 0x31ff85cc, -0xe2c9a08a, 0x6c9b24dc, 0x402416b6, 0x9a9dd241, -0xefd2ba2a, 0x23525dd8, 0x894dc2c8, 0x05c0f81d, -0x7bcf377b, 0x91c874c9, 0x0b674950, 0x5292a9c5, -0xe3b515f1, 0x70beba49, 0xa7566083, 0x135871ea, -0xb3d56bbf, 0x88a9cfb5, 0x07c77cad, 0x6f827852, -0xca657453, 0xcd618db5, 0x72ad2a88, 0x458854e6, -0xdc73961d, 0x27fbb11c, 0x7a4ab77b, 0xbf253be1, -0x57d57ea1, 0x680716bd, 0x663fd18b, 0x82cc4443, -0x7c6102d8, 0xcb7ead69, 0x5f58e7f9, 0xc9e246dd, -0xf2917165, 0x9534d3a5, 0xd298fa34, 0xf089f01c, -0x9a7f2047, 0xc2061efb, 0xa94b24eb, 0x82755d44, -0xea8d7c42, 0x059039a9, 0xda9a3040, 0x1da6c3ba, -0x02b1f1ef, 0x77e5215c, 0x3050281d, 0x82bac2dc, -0xf932ad41, 0x836ff9d2, 0x34770bd8, 0x71c7cecf, -0xbbc52ea0, 0x5e4cec9c, 0x3f933fe5, 0x3d5156f2, -0x90321f7f, 0x8e2ee8e9, 0x6c5cc0b9, 0xf25c9ffe, -0x248295d5, 0x1973ca29, 0xe00a2db3, 0xed5d06a5, -0x7d5263de, 0x67fb1703, 0x5c740bee, 0xdc4c55fa, -0x69c44982, 0x9408eaf4, 0xc10cb46c, 0x34d77b3c, -0x80e4011d, 0x795d39cf, 0x90e77587, 0xf47e8370, -0x6eda0fa4, 0xbbe85a24, 0xa28d6e35, 0x1dc10b76, -0x7c1c1fe5, 0x2babdd46, 0xc81ed994, 0x1339ad2d, -0x2a9cc0c4, 0xed31b1e0, 0x5f4dba77, 0xc819f489, -0xe1c49619, 0x0d445dd0, 0xa7b5fcd4, 0xbd4c0d41, -0x42fba7b5, 0xa153350a, 0xaad15ccf, 0x573ba327, -0x2cbc5609, 0x69376a8f, 0x53653e67, 0xe20d51d9, -0x68559292, 0x4b04e15c, 0x05a91cd6, 0xa22f93b5, -0xf2ad015f, 0x2626efe2, 0xab47a122, 0x3d61d5f2, -0xda7f1d3f, 0xa1b3db0f, 0xb13b7071, 0xdf98f6f3, -0x5ad04aba, 0xcde20b06, 0x8392dd5e, 0x6bd5c0ab, -0x0caaaf64, 0x300608ab, 0x3bd4ba6a, 0xc9d03729, -0x4ac8132b, 0x32abcdec, 0xa445533f, 0x728d3434, -0xb1b02c22, 0x3d0d68d4, 0x4f8cc30b, 0x13c9f40e, -0x84e01ae1, 0x6081ee9e, 0xe194bdb1, 0x5ef8e834, -0x4bcb9347, 0x96eedc3d, 0xf97305aa, 0x6eccd9f3, -0x8764e599, 0x204dd0d4, 0xa5437540, 0x311c31b9, -0x62831f07, 0x0a36cf8e, 0x0ac92987, 0x0af77a46, -0x6fe4c62c, 0xcbab3c9c, 0xf33d62db, 0xd564aa11, -0x96857605, 0xcf480b90, 0x1a3720de, 0xcca17331, -0xcb2b2dea, 0x0be380a0, 0xe5dfce5d, 0x1cfd0619, -0x87ec28ee, 0xf23777ea, 0x187b3286, 0xefcfa123, -0x491a4c38, 0xf3c39433, 0xc6f15560, 0xe41cbc90, -0x802d41cd, 0x68882b7c, 0x289c1a7d, 0x05614a13, -0xa4343f16, 0xa38c2ba2, 0xafb73657, 0xa944b9df, -0x74e55f34, 0x2f4ff21d, 0xf131eef8, 0x0ef5b6ac, -0xa88cb8d0, 0x72bfcb9b, 0x3c50db0f, 0xfc8604f2, -0x888be3f3, 0xd65d8aa7, 0x077f9487, 0x475f1545, -0xfc1a7834, 0xfbb3c276, 0x29d4ae1b, 0x73ceb23b, -0x56914e3d, 0xd3349a98, 0x597b1180, 0x77a06b7a, -0xfc443657, 0x6ae4340f, 0xde105fdd, 0xd8e62895, -0x6347a3d8, 0x9c164dc1, 0x6ce3771d, 0x461b9f7c, -0x76e6af34, 0x7639d5b3, 0x7b6b4e26, 0xf2917def, -0x16ecddc1, 0x9a4dc498, 0x7efe74bc, 0xa0dd6ad7, -0x7da7b3bd, 0xb3fa8cc8, 0xc380b5c2, 0xfa5397d2, -0x55603955, 0xcd3d7de8, 0x2858a7a5, 0xc0f5f668, -0xe8be8599, 0x95a7f5d3, 0x72a1ca36, 0x5cc1803b, -0x07524f41, 0x1adfdde2, 0xe6c32b4f, 0x591b3d51, -0xbcf44935, 0x3a3fb989, 0xd5a2960f, 0xecadfdef, -0x4cfbca69, 0x44fb74c9, 0xe97b9340, 0x112c961a, -0x15ea13a2, 0x3e7b83ab, 0xa884aec7, 0x441c09f5, -0x123f039c, 0xcae13459, 0xf4db2c5d, 0x2c462c28, -0x6c91cf2a, 0xe8f3cc3b, 0xf88464ca, 0x78a05617, -0x785e5218, 0xffee9f91, 0x3b96f3d3, 0x4ecbe904, -0x64366c76, 0x9ee3ca17, 0x99beae1e, 0x88802e00, -0x252f9f1c, 0x88ba8606, 0x6bd00538, 0xd082f1b0, -0x6eccb905, 0x4cf85611, 0x80fc0efe, 0x6907dfd0, -0x05bfe654, 0xbad14db6, 0x72e5d49d, 0x067f2977, -0x5f2fd09c, 0xf13eba72, 0x76badc64, 0xb3496815, -0x4972bf43, 0xac0d4742, 0x0cf31094, 0x21dcf61a, -0x4e5bc5a0, 0xb3236af0, 0xd86c3480, 0x2c261d40, -0x9a910b98, 0xfe7b889b, 0x75030819, 0x8061817e, -0x78911c6d, 0x3681a10c, 0x5cdc0928, 0xa4a81683, -0xd949e676, 0xb5d8ca1d, 0xcaf8707c, 0x8bdab4c6, -0xf777b588, 0x16c6d8ec, 0x10d7982c, 0xefbc0a1f, -0xde2cf0a5, 0xa3a2c217, 0x042d6731, 0x855f28d7, -0x7e2dc2d7, 0xb7312a9c, 0x0103ad9e, 0xea345f2a, -0x091315be, 0x36b87acc, 0x7bbe8b8c, 0xd960484b, -0x7c4c63b6, 0xd51e7bbf, 0x45e40c13, 0xd2252eb5, -0xa17ee634, 0xbb931edb, 0x77950c79, 0xd98adee7, -0x4ce0840c, 0x896585bc, 0x671f56c9, 0x6a90f075, -0x4d71a26f, 0x5a16b821, 0x371a861d, 0xf9865262, -0x56599a46, 0xa5d5ac42, 0x4ae9d9bf, 0xa86e8ecb, -0x23ae12ae, 0x5de95cfc, 0x60a58b65, 0xeb79c0ba, -0x406be042, 0x9bb8a05d, 0x26b28bc1, 0xe5fc9e4b, -0x1e7947f6, 0x966f480a, 0xe29db78a, 0x39743fe4, -0xa4e3a331, 0x5877cbdf, 0x25f9a660, 0xd97174a6, -0xf3c561e5, 0xdb4b565a, 0x9d4d2383, 0x389b7af4, -0xe06f4662, 0xc5468145, 0xbc602fdf, 0xcbf3db0e, -0x97d8757f, 0x02836802, 0x6a681b64, 0x7337e8bd, -0xe85d9502, 0xd6efec0e, 0xd7e8d30b, 0xcdf11803, -0xef5fb0d5, 0xd5251f29, 0x574aefb2, 0xe691d7cc, -0x4a4bfec9, 0x5aa7bd81, 0x68716104, 0xe5c40c92, -0x7600d7b8, 0xcf95798a, 0x26e8bea6, 0xb1a38beb, -0xbacd5b95, 0xecff91d3, 0xf15958f2, 0x75b02107, -0xde523549, 0xba5fc05a, 0x7072115a, 0x1197a903, -0xd808d1fb, 0xc7e709de, 0x1a65d1bd, 0x562bbd0f, -0xf0541e82, 0x68a54aa6, 0xefad28ef, 0xc9262772, -0x053e7cc4, 0x54bc9528, 0x74c92196, 0x618a0741, -0x2b5421a7, 0x291c8e1d, 0xdbfdd7a1, 0x4fc60ddc, -0x844a6b5a, 0xaf7ee867, 0xe9749f8f, 0x6deda822, -0xf049feae, 0xb6a4fa4d, 0x5b2bc1c1, 0x65a52c54, -0x32209928, 0x88051c7e, 0x8590db07, 0xf2934c96, -0x39a98498, 0xb56f1a53, 0x64d2e2aa, 0xe9811515, -0x8b2e77e3, 0x0e5471d6, 0x9a23a520, 0xd571a3be, -0x259e6fb3, 0x09b878ec, 0xab8b31aa, 0x0d558e8a, -0xdcbda8cc, 0xd6ffb436, 0x63fc4813, 0x1e2d9446, -0xd7cd64cc, 0x9517c30b, 0x60cb42c7, 0x46cabadf, -0xc84080e0, 0xe4ab3b0b, 0xb0c34879, 0x8b5c6526, -0x77782561, 0x276aa4d0, 0xe86dbf8c, 0x989630f8, -0x7d9cf3eb, 0x43928216, 0x36490c88, 0x472395d7, -0x4f1e18ab, 0xb03ddcf6, 0xd10293b3, 0x119742d6, -0x515f82a4, 0xe429568f, 0x9101c537, 0x382521e8, -0x529345a7, 0xfdea02aa, 0xa5bba9cd, 0x9ecdad6e, -0x93ecc7a0, 0xa1da94bf, 0x1eb6f562, 0xabc2ec17, -/* 2129-m206f257.inc */ -0x00000001, 0x00000057, 0x03152007, 0x000006f2, -0x07e77759, 0x00000001, 0x00000020, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0xf0aefac0, 0x7c38e188, 0xba5a013f, 0xdfb167bf, -0x3c3fed5c, 0x9a7527d0, 0x7f3ae5a3, 0x8ab688d1, -0x348436ab, 0xdc4756d5, 0xfc2a0a22, 0x9f11b7bf, -0xa47e1335, 0xc1e04f7c, 0xdaaf86cf, 0xa870c161, -0x072e2279, 0x87ee60b8, 0x3e4b0622, 0x326b4d89, -0x0652f8e1, 0x2ea0c801, 0xbeaa5953, 0xdc1b6573, -0x701f392e, 0xed0630f9, 0xbc9b3dfa, 0x1640fe65, -0x571a23c1, 0x9d913021, 0x895d7d30, 0xd2d2d7d4, -0xd605ed58, 0x254a7575, 0x0cac66a8, 0xcfe8bbe5, -0xcdd30390, 0xbb2236d2, 0x4c5c5bee, 0x5aee0bec, -0xc7ccb2ce, 0x02e4a983, 0xc5920bf7, 0x4ce10d1f, -0x3fc17820, 0xda1b4e54, 0x3de20b4d, 0x5ff322d2, -0xd6de8959, 0xe35d9fbb, 0x7b450c74, 0xcdc09449, -0x25bb7745, 0x056e0ec0, 0x05c27088, 0xeece366b, -0xd99a08bd, 0xbf7aa5ff, 0xb99fb54a, 0x1e620294, -0x5498c8b6, 0x7e9feeb8, 0x0bd593db, 0x9ae9d723, -0xaf9ef586, 0xcf6b95a7, 0x8eb34bd2, 0x378c817a, -0xc0a0b5a8, 0xd92c8ec3, 0x756277de, 0x6c023ab6, -0x982be06c, 0xb8a70610, 0x7f5a8718, 0xa677cfa8, -0x2e7ade57, 0x3978eec5, 0xc34a97d1, 0x37733521, -0x5692ce95, 0x7b9fc090, 0x0d111e36, 0x6d9fb551, -0xc48f3b9e, 0x6a1b2dfc, 0x8ba4b179, 0xb00f6962, -0xfa149366, 0xbb1dc1b3, 0x23a921c0, 0xb96d73b7, -0xcd4dc6da, 0xfc5e8abb, 0xdb5fe0f2, 0xcb33f9dc, -0xaf75f866, 0x3dfd2478, 0xe7a5b475, 0x54a611b2, -0x73994c7d, 0x161b27bc, 0x7f810ba5, 0x8dd5733c, -0x72fe4c72, 0x2e76dbe3, 0x9f9f0c64, 0x0e21bdbd, -0x4331bf86, 0x879b1ddc, 0x40c84fce, 0x7c5d11c0, -0x3faf10ab, 0x3550eae6, 0x26996e67, 0x00ef27d2, -0xccda83ed, 0x11030e92, 0x757074d7, 0xc5a517dd, -0xfc3e7fd4, 0xc16d81ed, 0x9044cd87, 0x2d099580, -0xb25b9d47, 0x5b610359, 0x0e59eeb5, 0x7d19f029, -0x4cf9706f, 0x0f5c8597, 0xecf7aedb, 0x86d1ee8b, -0x2c85f041, 0x3015ac75, 0xa0db24d8, 0xa9f07271, -0xb78ec67e, 0xeca00670, 0xf7d05fe5, 0xdff30312, -0x6ae19969, 0x63375a04, 0x466a01f5, 0xc171c0da, -0x93ce8528, 0x703c1aed, 0xcd42cced, 0x32819c8d, -0xeb642286, 0x72723b25, 0x86c46d68, 0xb64d3c67, -0x3d3bb64c, 0x60eaf2be, 0x924b7f3d, 0x0bb38768, -0xaf2deef9, 0x2fa43b64, 0xdb0823ee, 0x7ddb339c, -0xea1cbf8a, 0xb19895d0, 0x1d6fd197, 0xb9a9343e, -0x31ce5f2e, 0x9399fc36, 0x14d6f1dd, 0xdd6ed0ac, -0xd9e8f45a, 0x56dba12c, 0xf5ef138a, 0x981a6eaf, -0x74fe5839, 0x370aab6a, 0x717df9f6, 0xa4dbc8d1, -0x3c665e8a, 0x07711522, 0x58911dfd, 0x9276384e, -0x70dd2327, 0x2613f4ad, 0x67043d57, 0x085bc73e, -0x13399b60, 0x28b0d7e3, 0xc7101b20, 0xa29550aa, -0x8177a1dc, 0x5bcc83b2, 0x1cf50fbc, 0x448c109a, -0x09288db1, 0x1700bdcf, 0xa119bf8e, 0xdaeb3c27, -0xf21a1004, 0x3490c7e4, 0x6562906d, 0x732225be, -0x4ca41b48, 0x9807ec37, 0x82c2c81a, 0x182ae052, -0x337f2a6c, 0x177a866f, 0xb0397a1e, 0x8aa9e3d2, -0xb596cae5, 0x52630925, 0x069e969f, 0xb8a6cf5d, -0xe206c823, 0x95768639, 0xeb9ef6c1, 0xdc879822, -0x805b7540, 0xdbdca41e, 0x92daf8aa, 0x2855131d, -0x98537e07, 0xf9f437ff, 0x4fd88be0, 0x07cadd26, -0x61c5f34a, 0xbb6a19cd, 0xc113d97e, 0xc2097fa8, -0x93df4c5c, 0x71f49496, 0xeeb280b9, 0xd8b31a12, -0x8c68fe2a, 0x6c85e6c5, 0x665d8833, 0xbf7ca2d8, -0x8ec9d5fb, 0x2d8ada4b, 0x1112da86, 0x1eadb344, -0x72bb72b4, 0x1146c42e, 0x9c4a1796, 0x103a8aa2, -0x4e22694d, 0xdabb9fb9, 0xa643d98b, 0xa1e82adb, -0x5e1f20ec, 0xc1179fc2, 0xdf5791d1, 0x1071ced5, -0x940a595b, 0x9d575c0c, 0x572a6eb6, 0x68866e0b, -0x2cc54642, 0xa0b47fe9, 0xd53f7591, 0x40c57980, -0x7e927dfc, 0xad644a5e, 0x2f6b3a0a, 0xb4c788d4, -0x59131505, 0xdf982aa7, 0x7eed9890, 0xc7a79316, -0xa390c1e8, 0xb6a81315, 0x8b6ecc2f, 0xa18d162e, -0xa96a54a1, 0xf9801a9e, 0x763aa20d, 0xfcba9e42, -0x1d8f9e51, 0xb63608fe, 0xd0bca8d5, 0xc05b6fc3, -0x1dabad44, 0x864011c5, 0x92a94ac3, 0x7e2bdb44, -0xf1e0e0a4, 0x4e988af4, 0x51934b03, 0xc2eb8a5d, -0xf58b0dfe, 0x88c9c264, 0xe81e0809, 0xb3087c8c, -0x1f0cdd31, 0xcab43925, 0x02120053, 0xd4d308cb, -0x5727a77a, 0xc0a58a07, 0x45b8004e, 0x4b887559, -0xd5a6cfbd, 0x096d6b43, 0x8f7c3cf9, 0x10a9f009, -0x8b55e8c8, 0x286cd461, 0x5d340d0f, 0x2e071f42, -0x3c156062, 0x4a2ba5ed, 0x466f979d, 0x36ad6534, -0x432a28d6, 0x23dd3681, 0xb782ecfd, 0x4ac65284, -0x190c3fe3, 0x32371293, 0x1b4a968c, 0x4d140c3b, -0xe9602892, 0xaa61bb7f, 0x87d82028, 0x833b076d, -0xf5dfc16a, 0xe7e7e8cc, 0x9b9b123d, 0xe55f7f06, -0x019ca425, 0x8c2ad978, 0x6e53312e, 0x4c68cc59, -0x1505573b, 0xe50246c3, 0xe13f8925, 0xb40d8c6a, -0x6df7688e, 0x64ddc299, 0xfa2de5ee, 0x8e22c09b, -0xfc43e080, 0x27bdf731, 0xbd811f19, 0x50eb4114, -0x33aefa80, 0x0dd5a922, 0xcb087d89, 0xf594aaaf, -0x469590d5, 0xc2610f7e, 0x357f27f1, 0xe30b5697, -0x744a47d4, 0x18703bcc, 0xbd00cbb4, 0x859b13b1, -0x83259929, 0x71700966, 0xa6586c05, 0x70a61cb9, -0x67af2d49, 0xbc1a3e58, 0xf6f3b5c7, 0x916983f3, -0x3b99438f, 0x993ea084, 0xd2e842ab, 0xaae24c93, -0x38902c9c, 0xcdcaa742, 0x1407900f, 0x4fa9a83f, -0x0d87845e, 0x3dab31dc, 0xd1f773ee, 0x0b5181b9, -0x0dd327f1, 0x9de29e99, 0x11d78ea2, 0xc66b0639, -0xc97fae80, 0xd352bbe1, 0xfc19afbc, 0x713381a9, -0x51b9502a, 0x355de567, 0x040ee678, 0xf4085bdf, -0xc8b52da4, 0x7b851dfd, 0x94f53879, 0x936c3596, -0x005b0eda, 0xb17d6d52, 0xf576900a, 0x99234c3d, -0xdd2388f3, 0x3920a2eb, 0xce320776, 0xbaa6bb20, -0x82ccef09, 0x15f3fa80, 0x30e218d5, 0x9f7c35f6, -0xfc422ad6, 0x697ba237, 0xe9bd989a, 0x20573da5, -0x526140be, 0x54023897, 0xd9ff4fbe, 0xee0c4495, -0xe62410a3, 0x5150c878, 0x9a2c671c, 0xf76de5ad, -0xd3eb74b4, 0x0688ec67, 0x7d4f12b3, 0x4fcbeb96, -0x81b9489b, 0x257b67a2, 0x0538b984, 0x4aeb1a19, -0xb3632b9f, 0x42148957, 0x71801f3e, 0x3ed494f4, -0xe1591118, 0xa4542eeb, 0xca3d0445, 0x03b948a9, -0x767a31b4, 0x090f62e1, 0x701890e7, 0x1cdf23f4, -0xaba00984, 0x1b42b0e0, 0xb5369d19, 0x0e582a3d, -0x079fc09d, 0x0a6b1256, 0x166e21c0, 0x4dfbf861, -0x68d90df7, 0x1392544f, 0x52e420f2, 0xaa437eb1, -0x355fe827, 0x5e5a497f, 0xb06b9003, 0x118c85ed, -0x7c8b1f9b, 0x710f30bf, 0xf42ad4e0, 0x70a17971, -0x3321840d, 0xebf2f3ca, 0x6820d080, 0xe5987997, -0xf1bcc9b5, 0x9357765e, 0x317884cf, 0x3449efff, -0x641d249c, 0x8dae0eec, 0xa5db1774, 0x1c06f4c6, -0x0dbd7c38, 0x18dd265a, 0x206eed23, 0x1b1f3780, -0x4e6b063c, 0x07169a13, 0x1b16ed6e, 0x87de6f65, -0xfe05eeca, 0xd3e6958f, 0xef53638e, 0xb8fa5b3a, -0xed4aa69c, 0xf229c96b, 0x922efea9, 0xf2e9f8d6, -0x7626207d, 0xac94bddd, 0xa055f4d1, 0x7cf49e93, -0xb68191fd, 0x5d1e0522, 0xb778bc1a, 0x667773ab, -0x0547d582, 0xb990ca6f, 0xae44199e, 0x090f8cbb, -0x66909346, 0x990b0a60, 0x866f804e, 0xafb29f1d, -0x85635204, 0x5531bc16, 0x766099af, 0x3128bdc5, -0x564838ac, 0x0f6a5d39, 0xc560f67b, 0xc7820c23, -0x05bb1328, 0x6f9484ee, 0x319809ab, 0xc0dead11, -0x30928a58, 0xcea6f365, 0xae4c63e2, 0x375bb2f5, -0x0d7b1cdb, 0x6777d042, 0x70d56f28, 0xa67ebccb, -0x1f02a61b, 0x148f5044, 0xa2ff3cd5, 0xdacfcf0e, -0xcec94c27, 0xee4af516, 0x0cddc248, 0x018cda30, -0x9d70143d, 0x197a6a8e, 0x6f651d33, 0x6faa4e8e, -0x8ebf8215, 0xead609df, 0xfd2f388b, 0xccb70ecc, -0x4a670925, 0xdd621f46, 0xb9e0bae9, 0xc9937471, -0x0a4232eb, 0xc7ba26cb, 0x8c3a7e17, 0xcef032c2, -0x73b75440, 0xcca87896, 0xb544c0d8, 0xcadfa89e, -0x3392961d, 0x5d99f95a, 0x00974612, 0xc5b871c6, -0x9336a0b2, 0x9dc01d28, 0xcf6f39e6, 0x847c7351, -0x0b990971, 0x70184dd8, 0xe5257c82, 0x721e7ef4, -0x8922a618, 0xacc61d52, 0xa31cb090, 0xec6e46bf, -0x0e22d152, 0x88c3a2f8, 0xd4cb10f6, 0x1e2bd43f, -0x67d26f37, 0xf6a2b4d3, 0xd4229cef, 0x89626856, -0x81400377, 0xa80b84d0, 0x1f5b6e64, 0xb5def54f, -0x8db7711e, 0x69b7f916, 0x1d3dda64, 0xe5c6d920, -0x6b3459ab, 0x5dc96ae2, 0x083308d7, 0xfa84b8a6, -0xb8f0a688, 0xa806c32f, 0x04d3a1a8, 0x58f5f04c, -0xf0233835, 0x7f5cb42f, 0x5eceef54, 0x577374c5, -0x51aa783b, 0x8ffe6da8, 0xc118f745, 0xe881675f, -0xb1e02bf3, 0x63db76ef, 0x8b0848ac, 0x0e0573ec, -0x1d4fc251, 0xf430354c, 0x38b5b60e, 0x0c942f9c, -0x67f1905c, 0x7428f8b0, 0x79297d7e, 0xa93f388c, -0x051e8616, 0x48e03984, 0x04d97406, 0x7413b6d4, -0x6a3f6f8d, 0xfaed5a44, 0xdc89c0a1, 0x1b2611d1, -0x21ca7dd6, 0x9c9d1448, 0xab3687c2, 0xc275130d, -0xbeec53d3, 0x93e05b62, 0xd164a9d6, 0x1418ada5, -0xcbb235da, 0x01cde834, 0x16d895fb, 0x5d916eeb, -0x2f8a4045, 0x671dd425, 0xab40ec3b, 0xed3eefda, -0xc1a93fd2, 0x348066fe, 0x538e9697, 0x3a73512a, -0x0eded14d, 0x7cc7085a, 0x1a769924, 0x8e11533c, -0xb961df1e, 0x73db50a8, 0xfe625496, 0x79b0bef6, -0x712f024b, 0x997a8bd8, 0x3009ce33, 0x38a922fa, -0x2f1b74d9, 0x70342c80, 0x587b1639, 0x9f02fd01, -0x5c8c4977, 0x6b0d1be1, 0xed9fb8fe, 0x0d1c9fa4, -0x3e51d08a, 0x2ecdd796, 0x71768e1b, 0x803c8b2d, -0xc009ac20, 0x242dc6ee, 0x6c9cfe25, 0x8cd3dbc4, -0xb35832db, 0x4613ba88, 0xab1274dd, 0xda19e833, -0x49c0fb40, 0xeb37ba33, 0xdf06e975, 0x90ad6d1b, -0x8aef380d, 0xa4cfb894, 0x107819ab, 0x01f89df1, -0x1ea242cc, 0x17626b76, 0x9568d1a8, 0x3e584238, -0x9c0ba10f, 0x3de6d8b8, 0xbcff277e, 0x94ba4d60, -0x24f88a80, 0x7d336afe, 0x04f4af38, 0xa435ae27, -0x82c5de40, 0x28b78b43, 0x5f4f3836, 0x809d1a13, -0xdb95ee3a, 0xacc8e9b4, 0xd0d6cf98, 0x9ba813cc, -0x6e89a462, 0x2afbe3c3, 0x5d662eef, 0x5365d477, -0x98bd0b86, 0x81c1601f, 0x15cd7693, 0x8b3d7ef9, -0xaf25331e, 0x49c24e40, 0xe6e8a26c, 0x0f083b65, -0xdcaa15a9, 0x26101687, 0x9dd1cad9, 0x80a9b15b, -0xac16e5e1, 0xb85861bd, 0x78c59bbe, 0x284648f0, -0x1f1af2cf, 0xbb834fbf, 0xd7d71460, 0xcf44c671, -0x573bd611, 0x76e94cde, 0x17c03286, 0x02621543, -0x705d0c85, 0x2b6d6b0f, 0xa8f17a22, 0xbde3ed1e, -0x09afd9cc, 0xf84955f8, 0xa7d1dabb, 0x82343b59, -0xa3fbc5f1, 0xfcdce701, 0xd600158c, 0x71262e33, -0xcb257268, 0xf3f17de9, 0x257ec37e, 0x366552f6, -0xd39c706d, 0x1372a7ef, 0x84fb48ea, 0xf1c4776a, -0x182f548f, 0xa5499971, 0x488e7904, 0x4167ba8d, -0x796aa238, 0x41eedf0e, 0xe65e7ffc, 0x7352ab66, -0x7ea8d981, 0x93c717f5, 0xc8124404, 0xa7447a65, -0x231dd863, 0x17581b25, 0xd10a9250, 0x5807994a, -0x12b18ae5, 0x80d03bbb, 0x7595c1b1, 0x6e878a42, -0xbc2db045, 0xde5c7e5d, 0x8f096855, 0x82dc150c, -0x7afd3dca, 0xf274e65a, 0x2abbe67f, 0x0145568c, -0x014dba37, 0x9a182028, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2492-m02f480e.inc */ -0x00000001, 0x0000000e, 0x01152008, 0x00000f48, -0x0e158e10, 0x00000001, 0x00000002, 0x00000bd0, -0x00000c00, 0x00000000, 0x00000000, 0x00000000, -0x26d329c9, 0x2a31e166, 0x64caf9e8, 0x20f1b670, -0xfdbf281b, 0x2af51e01, 0x72756a40, 0x3e4d0c5b, -0xcaeee752, 0x238030a7, 0xe2ce4e5a, 0x1fcfa6d3, -0x212a11eb, 0x27942a56, 0xfc6a38cd, 0xe34d32a3, -0x0135b4db, 0x1c3ea42e, 0x8c954d65, 0xe6bf8037, -0x5f2605e0, 0xe501cde9, 0xeab0c8b6, 0x10b3a2ce, -0xb7eea79e, 0xd44f406f, 0xa5594234, 0x42ab402a, -0xa1bfb70b, 0x3bb73da9, 0xde650246, 0x57bf4792, -0xb87196fe, 0x7d1ba897, 0xb9ef2ec5, 0x0947fe70, -0x26ac2342, 0x6b027d85, 0x49182232, 0xa216850a, -0xde95e8db, 0x2ba8a7a6, 0xd7766e2f, 0xad019a11, -0x086098c2, 0xb97ce7f3, 0x15b8e4be, 0x2bd14f31, -0x8651d72b, 0xa6baf5b0, 0xe91cbdbb, 0x3e4b99dc, -0x225f51de, 0x192dd4e3, 0xf3bc372d, 0x18fa15aa, -0xf3e31f51, 0x3b14d857, 0xe7fa8fa3, 0x0da2529e, -0x8e0ec6c4, 0x2a9f8fe5, 0xd4a45e9e, 0xd3e5ea7f, -0x579e5fc1, 0x0ee7b49a, 0xc3e1a74c, 0xfb79ea09, -0x880ba650, 0xe1f6d05e, 0xcfc8c022, 0x37c66627, -0xd75964b9, 0xf8aa3544, 0x36f59197, 0xfd60ee29, -0x7333fd01, 0x06e588e0, 0x7070e0f9, 0xd8a52405, -0x4552f44c, 0xd2b8ff77, 0x04f7ff67, 0x34a28a85, -0xa90ca13b, 0xda9da5d1, 0x6537651b, 0x6689fe66, -0x780b74d2, 0x29dcda62, 0xd752595c, 0x58fffec9, -0x29bc82d2, 0x580c129a, 0xe73ebb85, 0x14d7ca3c, -0xcd3d8678, 0x7ab2b0f3, 0x156b319d, 0xfbe3d5cf, -0x2238d540, 0x3a11150f, 0xb3e2a0ed, 0xc8574d79, -0xfca2b05b, 0xc00997f0, 0xace0c378, 0x1f44d4f4, -0x0b8b7c33, 0xe13b230a, 0xc2490427, 0x031bee7e, -0x2d612498, 0x3f0171d4, 0xe8072f7a, 0x397143f2, -0x84953dd9, 0x0b9dc83f, 0x300595d9, 0x389ceeed, -0x23d176ad, 0x051fab35, 0xab27ec76, 0xb98e9c4b, -0xdf2dfda2, 0x198d7e32, 0x1690c93f, 0x939444ca, -0xd2a58ee9, 0x80d9fca7, 0x972197c3, 0x3cb3902e, -0xe26ed52b, 0x93a6a765, 0x97f4845c, 0x2b2a56ed, -0xd47788f9, 0x29723637, 0x34f7675b, 0x19c38cc4, -0xab093705, 0x2d3e1fdf, 0xcffb6671, 0x3b6c43ed, -0x168b0f4e, 0x36798907, 0x0750d02a, 0xd47ac88e, -0x7c417cb4, 0x255aaf00, 0xa457d84b, 0xd6102100, -0x21b7eecb, 0xe91e4a6d, 0x689db121, 0x2f53b34c, -0xf49968de, 0xc3129683, 0xc775fb99, 0xc893db52, -0xfe7ffbc7, 0x300ea6eb, 0xc18686d0, 0xc32fa6c1, -0xd06c2a32, 0xee5b2e2c, 0xbaf7fe09, 0x007876f8, -0xfece2039, 0xcd363d13, 0x4c78a4c4, 0x6d35b3de, -0x6f6e97f6, 0x27cc312c, 0x13aa914f, 0x6b1ebd26, -0xd1cf582c, 0x70d65a3e, 0x418b9938, 0x3f45056f, -0x12a4936a, 0x7ff921c9, 0xc14f627d, 0xc95e29f7, -0x591a88f9, 0x28098309, 0xac37ccba, 0x430201a3, -0x91d4ccfd, 0xcb3c735a, 0x6245ebbf, 0x88b4fb5f, -0x18cfedb5, 0x5bab7c90, 0x246ea4fc, 0x4ac1a532, -0x2601517e, 0xae32740b, 0x56a159ff, 0xf324850a, -0xedc8802f, 0x5847b188, 0xf8ef6ac1, 0xa00d1e66, -0x678a4044, 0xda1aecff, 0x44bd1f23, 0xeb235eb2, -0xe00f1b18, 0xac4c0fca, 0xecaf8fd6, 0x7036dc67, -0xd5f37dc1, 0xf72976da, 0x4d6456cd, 0xad279354, -0xc1c5fddd, 0x56f9ce6e, 0x086448da, 0x1133cd3b, -0xba098b6d, 0x9acb3d7e, 0x253a1c15, 0x801f316d, -0x82ddd5a5, 0x1dbbe457, 0xc6f6e988, 0x902e4e3d, -0x9919be4d, 0xb7ed04ed, 0xfc5c9307, 0xf0242aee, -0x56fc8d05, 0x80cd70f8, 0x3813442a, 0x6c6dbf5e, -0x3216843c, 0xd4900c7d, 0x6545f49b, 0x928a68a3, -0x524a4f32, 0x7b3905b9, 0xa66a83ac, 0x2a9df94f, -0xb21baac5, 0x86a90f8f, 0xd9444a1a, 0x9aa56218, -0x10a058ef, 0x39bcf149, 0x96bc6beb, 0xb13c2c89, -0x08524f97, 0xab471f45, 0x3809188a, 0xf48e0587, -0x2815e009, 0xafd9eddb, 0xddc23417, 0x4afd35a9, -0xa97117f8, 0xd57a04a5, 0xbd112ff3, 0x869f93ee, -0xdc41bfaa, 0x53a50f37, 0xc4560207, 0x750c1513, -0x318ba469, 0x9bc9113d, 0x7566de7e, 0xe9342ec5, -0xc521eae8, 0x66fc9347, 0x6b9c5469, 0xb097ee33, -0xfb0ebe09, 0xdb230dfe, 0x7236dcb1, 0xa13bd311, -0xd090f61e, 0xb30a630a, 0x7e469844, 0x1574c338, -0x6637aafb, 0xa923111b, 0x8a3b735b, 0xa9ef6b12, -0xbd54b8f4, 0x31743069, 0xc51e14fe, 0x3cce36cf, -0xbbfe8925, 0x8348d42f, 0xa3582761, 0xb0d695a1, -0x041c41ae, 0x0ced43bd, 0x7894160d, 0x88dcae84, -0x705c8bf0, 0x9df891e5, 0x2e0b5b29, 0xd4d02b62, -0xef42b7b8, 0xab7fb5e0, 0xdf91d193, 0x44ae8a6e, -0x7db530e6, 0xd54e99cd, 0x814b796f, 0x80a57ccb, -0x613de203, 0x53d285ce, 0x2ba54805, 0xced4eaad, -0xaecdf197, 0xb619023e, 0x2cbb224f, 0x7e3361f0, -0xbfb38295, 0xfb8dc293, 0x21be50ff, 0x9b796fb4, -0xca0fab54, 0x649e7d59, 0x3b6119a5, 0x4751bf87, -0xfad7c36f, 0xb51a9528, 0xfca25ca7, 0xf1730857, -0x5072c2c8, 0x4236343a, 0x0fb02c81, 0x84ab3bce, -0x8ca08cbf, 0xd28234c1, 0x1a8a8e91, 0xb8108393, -0x5052d682, 0xa85bc44b, 0x8d422806, 0x2c9323a9, -0xdf62b41d, 0x9eb8bdce, 0x816a8338, 0xa7655082, -0x9d59bac0, 0x1efeb4f6, 0xc02dfa19, 0x7184335b, -0x769c612b, 0xbba63013, 0xcb8c503b, 0xcd535067, -0xcd5b29c5, 0x600f9b97, 0xe312a5b3, 0x882260ac, -0xd16df980, 0xc07031f7, 0x46844f67, 0xb667c308, -0x38a195da, 0xaf7cc01f, 0xedb0af82, 0x146868de, -0xef745dfb, 0xa3bb9477, 0x111f96dc, 0xadcf97c9, -0xa48abf8d, 0x1e6c5e79, 0x981b20d3, 0x607ed92d, -0x88dce122, 0x81b35fd8, 0x2a5bb215, 0xe4c557bb, -0x01b9f5ec, 0x6f31c367, 0xebd7a3a5, 0x87bcd4b2, -0x0e04acdb, 0xefd29047, 0xa19c4bb9, 0xd1de82e3, -0xe7170238, 0x950c1ea1, 0x6dce3702, 0x5e30c2da, -0xf786a74b, 0xf6fe2687, 0xbac9b605, 0xa26947a5, -0x0b395022, 0x604f5ae4, 0x7d2847fd, 0x432eeeb3, -0x1c09cf16, 0xa60b6e98, 0xee527eeb, 0xcecd3d22, -0xde22d726, 0x75624129, 0xe6f47f23, 0xa386fb10, -0xf95e758d, 0xf8a1f18d, 0x38f8ba6d, 0xff037cdc, -0xccb5ea45, 0x9ddc0def, 0x2c38a7fb, 0x4b1a63f3, -0xbe91dfa0, 0xf26ee0eb, 0xe525faa6, 0xba5015ed, -0xe9c34553, 0x4f02da17, 0x6da6c9c0, 0x4ab2989d, -0xd48c6d4f, 0xa20e07c1, 0x31025c39, 0xc24effd9, -0xd472d1a6, 0x70015259, 0xc9d61f68, 0x8f6bda07, -0xbf07f2ed, 0xf94e2538, 0x59cca88e, 0x7d31044f, -0x72bb31ae, 0xa97a9f31, 0x4684ae46, 0xe6a968c2, -0xa37ce630, 0x47cb0d2c, 0x57487010, 0xad79a0ad, -0xbefba442, 0xecd50f6f, 0x09ff40ab, 0xf00c2385, -0xad02800b, 0xa96538b1, 0x094d47f7, 0x55fca4c2, -0xdbe82bc8, 0xe05d82c2, 0x3684f7bc, 0xa1576624, -0xa33c406a, 0x4ddf61d6, 0x83bfb554, 0x463b70f7, -0xf73bce0d, 0xa9b08421, 0xd620965f, 0xd8c2edbb, -0xcf5db224, 0x78174e0e, 0x49f680bc, 0xbab62686, -0x5b6eac65, 0xf3a6efce, 0x35eff0b7, 0xc6b03da9, -0x77684b20, 0xb48cdb78, 0x4020f7e4, 0x659a3023, -0xe96aa5d2, 0xec28f986, 0xa92392e1, 0xaf6aedd8, -0x9261c6f5, 0x51e7ee22, 0x1cbbe21b, 0x12dfbf72, -0xe87ec370, 0xa53bedbd, 0xd87ba8e8, 0xa5362ee2, -0x01aebef0, 0x13c6a152, 0xf80c3a0f, 0xb6c35e7c, -0x8b2a8d15, 0x828d549a, 0xc0e5536e, 0xcd1426a8, -0xb220bba0, 0xb2bcdd47, 0x3cb67cf1, 0x5984accd, -0xff3c2260, 0xd69c2315, 0xf34b7ec0, 0xaa2ee403, -0x633e4f08, 0x4943378f, 0xf60dc7df, 0x6af330f0, -0x6fa7d05d, 0x99d2865b, 0xe0da1dcb, 0xebe60192, -0x7576458d, 0x74be16a3, 0xdfddcf36, 0xa949e0a5, -0x1f72671d, 0xccd794bf, 0x803405d3, 0x8c8c6eb6, -0xd1900d4c, 0xa2ac908f, 0xb5b7e8f0, 0x06763fcf, -0xe025fabc, 0xbd099c25, 0xe30e17ea, 0x930efe48, -0x39fc45a4, 0x2c78dacc, 0x1d41cbb3, 0x7ffcc8ef, -0x072cfa44, 0xacb0f715, 0x121a513c, 0xe83ff719, -0xc3565191, 0x7f44232d, 0x941b33f9, 0xa1e5f1fb, -0xaac18ea4, 0xe83de443, 0x5904f7aa, 0x9b193c83, -0xafeb41c0, 0xb0d4db80, 0x403544c3, 0x1e208572, -0x75914e29, 0xbb86975e, 0xe66fa54c, 0xa9165618, -0x635e2b4d, 0x2dc3456c, 0x64fb7834, 0xbae07479, -0x283a0bc7, 0xa2211209, 0xcda39444, 0x00502dde, -0xad8b539b, 0xb8a18c01, 0xd727d11d, 0xab35221f, -0x09a7dd1c, 0x3904551e, 0x26c7a4d4, 0x11c234a4, -0xf0560dc5, 0xb2af70b8, 0x4b7f6422, 0xabf74fd1, -0x2e32ea94, 0x136f4dca, 0x531e2580, 0xac64c2d3, -0x37f72d03, 0xa27d543a, 0x975dfbc1, 0xe32a2320, -0xcecad332, 0xb334e990, 0xec6e5e82, 0x7b39ad67, -0x9132dbed, 0xe74eb37f, 0x63f471c2, 0xad41d537, -0x6652a551, 0x50a379da, 0x4fd9e74a, 0x66d0fbe6, -0x784ce5ff, 0xbe5563f9, 0x4b284764, 0xe82b834a, -0x77cf145c, 0x4ef3a9c0, 0xfc55142c, 0xa6731995, -0xe486a03e, 0xc5ac0d3b, 0x96bd7e44, 0xfcf5ac60, -0x32bac91f, 0xa6330551, 0x2c3bce42, 0x6d227527, -0x4a7f47d2, 0xc9f95de3, 0x2e7f69c3, 0x977a83ef, -0xe8d20c95, 0x5b37f1dc, 0xd24cd253, 0x5695e75b, -0xc59d1bbb, 0x9e0c8899, 0xaf99fff8, 0xed06d8a3, -0x124cda7a, 0x61e14106, 0xb8eeace4, 0xbaaae21d, -0xa3edeaa3, 0xf025cfe8, 0x4f2d7c14, 0xa53fcbf2, -0x5cb87002, 0x88d1a87a, 0x9823105c, 0x0b5f2f3f, -0x3b4b6622, 0x8abe9d68, 0xb7b1a872, 0xb6a23ca5, -0x2f8af0aa, 0x01544728, 0x718ddea8, 0x852a466c, -0xcc32c43b, 0xa6ae2bf0, 0x60a276cd, 0x03cf1680, -0x090c769f, 0x97023bbb, 0x28dbc21b, 0xaee326da, -0xa17aea81, 0x3be0c263, 0x480c7990, 0x79eba014, -0x55fe3d34, 0xbdf26e31, 0x3262f1f3, 0xe6b1c5e9, -0x2e3ecf14, 0x4d358a4b, 0x5c53574e, 0xa5394bc6, -0x733d8452, 0xc09b4dd2, 0xe91efd31, 0x46ab9076, -0x0ee5a689, 0x9ce07e53, 0x2778e5c8, 0xeb2eb6db, -0xf258b653, 0x4ca89510, 0x3d169c4c, 0xa5dcee98, -0xe4f1cc45, 0xeaa1f475, 0x6aaf5b9c, 0x40e58956, -0xda8c24e8, 0xc88ad138, 0xd66fc509, 0x03580145, -0x778d829d, 0x0e2da91f, 0xea3dba0a, 0xacfd2069, -0x8b2168d7, 0x8d372293, 0xbba81d9d, 0xd810cf7c, -0x2449fc84, 0xb05c099a, 0xf1ee1a85, 0xe2c79e38, -0x3eb91494, 0xf54b159e, 0x0fd4eac2, 0x260a4242, -0x7c57334a, 0x7fd9b0c1, 0x0d687a4f, 0x72bc613d, -0xfa006dac, 0xb9457cd2, 0xfc4874ad, 0xe5242d02, -0x38794801, 0xf8e9f59b, 0xcb0a1361, 0xb42ec54f, -0x9cdd85bc, 0x27eabc2b, 0x84aff296, 0x8d245ebe, -0x301fe4fe, 0x6f4aa07c, 0x4a9f5c6f, 0xfe264902, -0x90212b27, 0xe8b57c59, 0x9557ef6d, 0x4c53ecc4, -0x5d1fe0ea, 0x7b94651a, 0x84d10139, 0xa5ac3520, -0x1eda05b3, 0xd98f2126, 0x4b82d50f, 0x39e35e82, -0x2347f4c4, 0x311a3e10, 0x3cb12406, 0x64820669, -0xc6be20ab, 0x37cf99fd, 0xe97426a0, 0x79ac1365, -0x522d9d9c, 0x4f3bfd0a, 0xdeb80b27, 0x66e2ebdb, -0xcae86c80, 0x65986163, 0xc341461b, 0xe7da47eb, -0x80882978, 0x4cf5eafc, 0x527d1664, 0x7225ff2d, -0x4872fa8e, 0x099cc50f, 0x21ca02b4, 0x42212ea1, -0xdacc30f1, 0x6c19271c, 0x7fa45b1e, 0xb9548b7c, -/* 1639-m04f620f.inc */ -0x00000001, 0x0000000f, 0x12152005, 0x00000f62, -0x0976d137, 0x00000001, 0x00000004, 0x00000bd0, -0x00000c00, 0x00000000, 0x00000000, 0x00000000, -0x079c01a3, 0x0353307f, 0x9f2d61e9, 0xc9bc7bb6, -0x4c3f5514, 0xddcdf1bf, 0x796bdaa9, 0x6885f272, -0xcf82d5a6, 0xe6e11751, 0x2dcbd45c, 0x92d5b5cf, -0x14c8eff0, 0x5a2ebb8e, 0x699b3315, 0x31cda045, -0xaf39358e, 0xfb88852f, 0x84d9cbde, 0xd008420a, -0x9e14933c, 0x5005b587, 0x265b560d, 0x88b45401, -0x3db4376c, 0xf3f79b35, 0x2e880d76, 0xf60af783, -0xc950aae0, 0xce74e979, 0xf88d288f, 0x334463f6, -0xa391b222, 0xb3cfef4b, 0x4387ef52, 0xf1fd64f5, -0x98f2e242, 0x6c195d07, 0xa103b386, 0xb21c18f8, -0xed98390a, 0xd8719982, 0xe2800fb5, 0x17fc134e, -0x14f46f1b, 0xe8f9eacc, 0x1cde3d76, 0x9100aa0d, -0x257befff, 0x38217d57, 0xf31d4bd1, 0x49bcc233, -0xe5393634, 0x8fc329bd, 0xb35ba88e, 0x99b8fd15, -0x9a01df11, 0x2a76b86f, 0xa682cd02, 0x935ddfd4, -0xfa72fb2d, 0x80db3c42, 0x36e47622, 0xb3a6f36a, -0x4671849c, 0x91d16781, 0xbba06637, 0x7e37edfb, -0x2ccd2524, 0xf4443b1c, 0x06830ded, 0x904b4e32, -0x4ee11f48, 0x4daa5dfd, 0x11bc492a, 0x1922fd17, -0xcc75e432, 0xed116cf0, 0xa0e0113e, 0xf8acf6d9, -0x6ad73c09, 0x4af6e3c7, 0xbecbc42c, 0xfb0711e8, -0x84a65d47, 0xcce2f84f, 0x0a5a4e42, 0xf476ba11, -0x1ac1fbfa, 0xd1e94c4e, 0xdae73ff5, 0x1b7deaa9, -0x96802f95, 0x8cf02beb, 0x06bc77a3, 0x83042fdb, -0xd7ee25f2, 0x3f08a260, 0x349a0189, 0x5c24f6af, -0x1b193357, 0xf019c6b8, 0xa17f893b, 0xa44689cf, -0x34d24660, 0x01dacfe3, 0x3a5ac728, 0xdff3ab65, -0x7fbc327d, 0xdc31170a, 0x8f15f039, 0x70295888, -0xa07831f6, 0xae028e16, 0x4334d1d0, 0xab0d8997, -0x13edff8f, 0x31670671, 0x4ac37665, 0x95470a96, -0x84f9fa5c, 0xbe9b64e4, 0xdb5e8716, 0x459502a2, -0x23e3d532, 0xfe3148e3, 0x1d926a12, 0xc95a0e79, -0x4b15cd06, 0x632ccf12, 0x64fd574c, 0x8632ac6f, -0xe868cfce, 0x978aa19f, 0xce09dce3, 0x0a1a6114, -0x2edef69c, 0xc2546701, 0xc6c4b109, 0xf12cf971, -0x46e87058, 0x743ee6c7, 0x7bf6da59, 0xb18caa8a, -0xdc2197b9, 0xcc19f69c, 0xa951720a, 0xb32f3161, -0x9b586bf4, 0x9ff5cf93, 0x04021381, 0x606dfe1d, -0x8ebc4d43, 0xbd1cebaa, 0x72eedf93, 0xd03db0a9, -0x59b4da5c, 0x59d43c83, 0xb4ac5556, 0x055dc173, -0x838adbe0, 0xa12316e2, 0xbc60700c, 0xfded2a3d, -0xd9df157d, 0x6fdbf9b9, 0xfbffc545, 0xf22dfcbd, -0x3c77564a, 0xf1fb1b1e, 0x401ed79e, 0xa36609fd, -0xf39d8dcb, 0xfa2cb380, 0x66811682, 0x3cdfc05b, -0xafcccab5, 0xce2c98d0, 0xc8d0e851, 0xdb81968b, -0x134685d6, 0x3c6c45e7, 0x5fcbd17b, 0x30d08f18, -0xcb9e1446, 0xc7adb350, 0x65a79ad0, 0xcda41490, -0xaee792fb, 0x5241f445, 0x71c48675, 0xa78cd129, -0xe541ad27, 0xd6bc1ca1, 0x480fc0df, 0xcb9cf305, -0x4996f7cc, 0xff9e3f01, 0x05ccac41, 0x161934a5, -0xd0b03bd3, 0xd58a3a02, 0x126724ce, 0xadb20a85, -0x02752804, 0x02712acb, 0x8434c339, 0x78844df7, -0xb27f4ee4, 0xc5d58849, 0x184eb918, 0xb16a1dbf, -0x684a4dd6, 0x03c5ac04, 0xc4180c07, 0xefbaf11f, -0x04d3f7b3, 0xc5752583, 0xc590d505, 0x28eda7b3, -0xc9aedc42, 0xfba64706, 0xef2fd235, 0xc6e4a9e5, -0x2aa9d982, 0x3929d684, 0xedc5b51e, 0xd39a3265, -0x5234f55b, 0xdbb0194e, 0x2e592cc1, 0x9796ac96, -0x5c7b7f18, 0xe7220322, 0x5fec91c5, 0x7808be2e, -0xcbf84e17, 0xcb206709, 0x0a33410e, 0x9154529b, -0xc791cfad, 0x2bba4ba8, 0x047d3038, 0x669fe057, -0xce47ceba, 0xae313cdc, 0xadcb0822, 0xc2f4cce3, -0x64aad3cb, 0x23395f39, 0xc2d5855f, 0xc6abd99f, -0x8bd7b406, 0xdf6fa78d, 0x7a68d1ad, 0xb9848827, -0x98879f1e, 0xa2a228fb, 0x8864c4cc, 0x403f134e, -0x6b2a3c2f, 0x8189b731, 0x4aa211b0, 0xd5ab46d2, -0x016aaae5, 0x38412302, 0x21735864, 0x76990d2e, -0x7ad5c38e, 0xf1de119f, 0x7fb97adb, 0xc03f14bf, -0x1ec325ff, 0x5c6399b3, 0x1c34ff30, 0xdc9e1126, -0x58f27c73, 0xa42a637a, 0xce737308, 0xa622084c, -0xbdc9fd1f, 0xad338020, 0x7ac184b6, 0x26c25827, -0xec60bc8b, 0x9c252076, 0xa551ab40, 0x9813c123, -0xeeab98c3, 0x28ad53b6, 0x4eac1aa4, 0x220105b0, -0xc2f74506, 0xb4f7f998, 0xba1358c3, 0xcf4c6634, -0x5adff246, 0x50cf6389, 0x84ee828b, 0x95e0a1c7, -0x5fd638d5, 0xbf6e3564, 0x5939772d, 0x9453c904, -0xaf0b58e3, 0x8811c17c, 0x38aa6f27, 0x01aae9cd, -0xa9764575, 0x93b305ee, 0xd1ac2711, 0xb61384b4, -0xc3abcfee, 0x70e4968e, 0x8a3249e3, 0x00c1a972, -0x35d4c7b4, 0x9f202a7e, 0xfe289f0b, 0xef2ae587, -0x51c84c23, 0x060e0ab4, 0xb56a1f30, 0xcd529163, -0x2806e4d0, 0x8f19ef5d, 0xa2dabe85, 0x8460d851, -0x4f3dea07, 0x8988188c, 0x5dc55461, 0x135b4d98, -0x84fad778, 0x8c8578cd, 0x16521e39, 0xa555d07f, -0x2b19b4b2, 0x04591254, 0x9716390a, 0x1ab2775d, -0x31feb476, 0xa37eaa9e, 0x0f0f895c, 0xc904bfca, -0xb4443314, 0x620baec2, 0x8095cc33, 0x8359e18e, -0xfeefedf3, 0xbedb5cda, 0xe48c8e42, 0xd801b5bb, -0x6ae5652c, 0xada71e49, 0x1002ee61, 0x6837f4a7, -0xaec9e878, 0xe0a113f1, 0x6eb50c7f, 0xc73298ad, -0xdc65074a, 0x5324f157, 0xa3481903, 0x30b42b6e, -0xc9dbbe10, 0xf57e0521, 0xba6979c0, 0xa7cb1280, -0x0cb958f0, 0x54a1b9aa, 0xde550bdd, 0xaad13cbf, -0xce8bb569, 0x96b320c7, 0x8bb06f0f, 0xabf15707, -0xc6b5a4b7, 0xa6a757cc, 0xbfb15928, 0x21544a2b, -0x652ab0a3, 0xd5f078a0, 0xb01ff0d9, 0xd65872a0, -0xcf01c4c9, 0x114a21db, 0x650011bb, 0x2ad5c391, -0x11f518cb, 0xf83502d8, 0x5a305fd7, 0xf0394012, -0xf6f98bbc, 0x4edacf2f, 0xa9c64510, 0xaa227c7e, -0xdb2f65ab, 0xfe26050b, 0x7b5c8fcb, 0xa29881f4, -0xd6543f4b, 0xc0f698ac, 0x51c24c0d, 0x0b735fdb, -0x8f2daaae, 0xc4052284, 0xba78f9cd, 0xa2865212, -0xb71856c0, 0x2762980f, 0x97702bab, 0x3a688b17, -0x927270bb, 0xe3d0f5b6, 0xc315ff30, 0xeeb7ef2b, -0xd462d9d3, 0x385ebc07, 0xfcb62579, 0xf490bf8a, -0x76c3283c, 0xbdb05430, 0x75e8213f, 0xc5e13e0c, -0x96dc3a85, 0x880cb544, 0xf4a4f709, 0x39fd8052, -0xa88a29dd, 0x8dc11af9, 0xbb7826f0, 0xaebaa4fb, -0x5e6dafb9, 0x7a8b599c, 0xa01ba407, 0x1a56cfc0, -0x02899491, 0xbb02370c, 0x99238411, 0x827db739, -0x770c261b, 0x1bfc807c, 0x50e2ab68, 0xb6401646, -0x1582959d, 0xc444763c, 0x3e04d247, 0xaf129243, -0x82cdac0b, 0x808c980a, 0x5212d28d, 0x6da57e19, -0xec269840, 0xdc305225, 0x9aa9d9e9, 0xf3697b4d, -0xed3a5774, 0x5ae44236, 0x435def9f, 0x797b1306, -0xc2b851c0, 0xf77be6ee, 0x481340ee, 0xde96a3ed, -0x50e6007b, 0x120d6071, 0x023b8bba, 0xfa34be6e, -0x3f7ba882, 0xd701296f, 0x5b13815d, 0xcfec237e, -0xd5064859, 0xadf39484, 0x2a0d30ae, 0x5b288451, -0xf8bddad1, 0xa9f56808, 0x194329e3, 0x8d530d3f, -0x2a9d9ffd, 0x2b209802, 0xc174a89e, 0x1b5ecb66, -0x0a6b4c4a, 0x87e205e5, 0x68e3a54f, 0xd8b48307, -0x8b682b3d, 0x7319d4cc, 0x548583cd, 0xa6aa0f42, -0x84ff4719, 0xf2e6a5fc, 0x579f5df8, 0x82d20e49, -0x31949672, 0x8d4de34e, 0x03d66490, 0xf40da9f6, -0x57af91d2, 0xa19f8331, 0xea3db1e9, 0x26db27ec, -0xaebf9256, 0xef61a064, 0xdb729ae0, 0x79b351d8, -0x2a513920, 0x2509a12e, 0x3ec0bbcc, 0x46907b1c, -0x1b61d3e5, 0x6b5590f8, 0x005db70c, 0x7e9da806, -0x8daaba05, 0x1502afa3, 0xf41b7a25, 0xc9d6e25e, -0x2c5744b7, 0x5449e3a7, 0x57fd0466, 0xa67a8da3, -0x77e1efcf, 0xcc98aa81, 0x574403a9, 0x63d08091, -0xbe195afa, 0xb5be6b6b, 0x25a7caf7, 0x7343e73b, -0x2e374ae0, 0x64d5991f, 0xedd0c342, 0x43c7aab7, -0xb3212e30, 0x245ffde8, 0x3e5150b4, 0x534e55af, -0xbd2e469e, 0x7544eb37, 0xcab94de1, 0xd7eb1fb0, -0x697b1db8, 0x74038a9a, 0xdaeda845, 0xa38486b4, -0x2acbbf12, 0xecf97abe, 0x627cdfd9, 0x59e00bf8, -0xbfb5e5a9, 0x8a3a4430, 0xfc9b09ae, 0x30327c7c, -0x076567dc, 0x270bb072, 0xba5c30f1, 0x36727013, -0x8046b121, 0x67e490d6, 0xc4198ba7, 0x2e01a391, -0x540d7742, 0x634a8354, 0x528fb00f, 0xaea64e1b, -0xc093c800, 0x29380444, 0x5662143e, 0xaadf7595, -0x6a91bf03, 0xa955d46e, 0x906efbe3, 0x22cf54b1, -0x9e232d46, 0xb8986bac, 0xc778c74b, 0x3455d7df, -0xbf7896cd, 0x299adc29, 0x2499f881, 0x1f1f5c71, -0xcda05901, 0x6bd96c81, 0xa66c34af, 0x20562f55, -0x518b08a2, 0x4675f3b6, 0xa09ab736, 0x99a60e21, -0x081af44c, 0x10b6ac26, 0xf1c5bde1, 0xc0557aef, -0x40474b3f, 0x9a6d6a41, 0x1cb43960, 0x25c8ad47, -0x5ec31be3, 0xa8d333f8, 0x7dd97516, 0xfde24ca8, -0xb05f764a, 0x21fe8a04, 0x68e327fb, 0xa1340a6d, -0x5279353d, 0xd915cabc, 0xcc1caa72, 0x38ab6a0a, -0x514323f8, 0xa6c488ec, 0xdb9b34e5, 0xaa657176, -0xb8c021db, 0x7f320113, 0x1b17e33b, 0xc816156b, -0x390de864, 0x94a84ac4, 0xa2707d4e, 0x4a78abea, -0xfca81af4, 0x869dc73f, 0xfc63ffb7, 0xd3857b8b, -0x0010604b, 0x0d0effdc, 0xd582767f, 0xb3bf6ead, -0xa34cb0c7, 0xbbab800d, 0xf840adf5, 0x5cf3c030, -0x53025198, 0xfbfaa341, 0xe974fb1d, 0x243c33a0, -0xe510c751, 0x3236022c, 0xd82b92e5, 0x6285176c, -0x037eb1b3, 0x20802435, 0xc250407e, 0x324410de, -0x722fb8f7, 0x4543923c, 0xe968953b, 0xbcdd7e38, -0x9b627167, 0x0910ccb2, 0xf4c4af8d, 0xa31a2eb4, -0x3f4d441b, 0xee2e9aff, 0xf312c850, 0x61fdc34e, -0xc52406e7, 0xd5351cd8, 0x92596e87, 0xcb933833, -0x321e5e2a, 0x4840b034, 0x22aecfb5, 0xab5a1ea0, -0x6923b7c6, 0xcd242b95, 0x12e95d8c, 0x2892a638, -0x8d8ae7b8, 0xe73c2e44, 0x4bf4561a, 0x251ef7d0, -0xbd3bb469, 0x2e930b87, 0xfeb4148b, 0x7bd702ff, -0xbc4ca00b, 0x2cc32008, 0xa3e89154, 0x5a5d94df, -0x44ed5070, 0x3044b36f, 0x6304c927, 0x1f434e68, -0x9a23729a, 0x1f986343, 0x7f0e81d6, 0xc5f2e305, -0x12a3eff1, 0xcc07bbb6, 0xa88d5da6, 0x744859b0, -0xb288563f, 0x4182b155, 0x91bef572, 0xacd49e0a, -0x48707490, 0x9630395e, 0xb09bfb7e, 0x7c113da7, -0x11e5d433, 0x113c6ab6, 0x9fdb7464, 0xc074a781, -0x39db10e7, 0xac094b44, 0x6935b70f, 0x047e142c, -0xe934cc8b, 0xd9786ef8, 0xde746266, 0xa8a5143e, -0xa560e079, 0x059d6083, 0x876cf517, 0x565bc532, -0x652a6519, 0x8ecd2aa0, 0x9ba76f50, 0x20a3ece8, -0xaa485db8, 0xe52b31b4, 0x7ba94c54, 0xb4ea4e85, -0xf01eb4c4, 0xed092e23, 0x78839d0b, 0xf82161b6, -0x8bcbdcb1, 0xc2c4ddd5, 0x35bc5c1a, 0x42b763d8, -0x9ae64844, 0xc2059773, 0xffdfd33a, 0x1093cdcc, -0xe17166cd, 0x74742ff0, 0xf901bd03, 0xe7dffad2, -0x90597170, 0x69beff0b, 0x084027a4, 0x67497019, -0x7009b4ef, 0x75fd24f4, 0x914f8430, 0x58770935, -0x11409cba, 0x3bd2f3a6, 0x563ed273, 0x88569092, -/* 2376-m46f6cd.inc */ -0x00000001, 0x000000cd, 0x09162007, 0x000006f6, -0xa77fc94b, 0x00000001, 0x00000004, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x069de10f, 0x231acfec, 0xb14d18de, 0xfff6e27c, -0x47f9f050, 0x93e4ab75, 0xc5b027f8, 0x5d0af696, -0xae8c0180, 0xd2bd00de, 0x54589c4c, 0x8a304494, -0xf62f1f4c, 0x54951068, 0xae698c80, 0xd0495a6f, -0x41252806, 0x8a3929ce, 0xf5da0a40, 0x7b37235a, -0xd3e66940, 0xee4bd80e, 0x2c8c9cef, 0xdbbc8c44, -0xd93c981c, 0x3653aa83, 0xf38ac2b8, 0xeb772793, -0xb02e5b5b, 0xca076ad4, 0x2f72e48c, 0xa8598c92, -0x86235029, 0x06136faa, 0x847ba9e0, 0xa12b22bd, -0x8675ac47, 0x9c88b30e, 0x5f6bf4bc, 0xb4490e67, -0xe14615a3, 0x47914f9a, 0xa906d616, 0xd926d1c3, -0xe3c475ec, 0x805ece3b, 0x03e32c4c, 0xd0d49809, -0xf80587bc, 0x0d147769, 0xf754e7af, 0xd8f9e4e3, -0x0652985b, 0xc47d60fa, 0xf7ee4161, 0x208f5cce, -0xc0207b34, 0xcfc0b155, 0x131344a3, 0xc8151215, -0xfd64a827, 0x0b46e3a9, 0xf13b69d6, 0xe3f034f3, -0x214a31ca, 0xd6ddb66c, 0xdc325966, 0x3cb35d51, -0xef9c208b, 0xc74e3d36, 0x2cf09e5d, 0xdb2a20dd, -0xe75f3cbf, 0x094301ea, 0xd215ea97, 0xeb9907d8, -0x3d69506e, 0xe6ea09ed, 0xfb868e50, 0x33d62866, -0xef755902, 0xee6079a1, 0x193e9133, 0xf849f9dd, -0xec089a93, 0x3919d90d, 0xcdcb2ca9, 0xdc6d5ad9, -0x0eb6f22a, 0xdb9e6033, 0xc91db934, 0x39eeb1b1, -0x7ff82cb6, 0xf23be65f, 0xbedbbf55, 0x7cf22a24, -0xf7bb7f92, 0x93b08ce3, 0x4aadb8fc, 0xd7e8fb49, -0x52b41550, 0x6a6deddc, 0x1cf9fcae, 0x50e7dd5f, -0x40a3c0e3, 0x1e990ebb, 0x67789222, 0x660180f9, -0x6d283a27, 0x6b59f4fd, 0x2681057c, 0x7fd28ba6, -0x7b29c3f8, 0x06f3cabf, 0x753070b1, 0x6f35b09a, -0xcd1bcf2b, 0x5558faa9, 0xde88dc0f, 0xd5a96254, -0x2a437c53, 0xed8e7708, 0xc671efc3, 0x23634321, -0xade99512, 0xd6c582f0, 0x63f9e461, 0xa076a3f7, -0xc7bd36d2, 0x4b4d9413, 0x9304492f, 0xf13d3b94, -0x9412f88b, 0xa2fe563a, 0x58d4f309, 0x8bb4ff69, -0xf1b8f459, 0x5c1bc95e, 0x94923096, 0xc42f1043, -0x4e558014, 0x927525c7, 0xb1b01a10, 0x6b6e236c, -0xcbfae624, 0x90165fc5, 0x4ab743df, 0xf01aa3d5, -0x8407f56b, 0x5a6f41ea, 0x8db4e144, 0x938fd696, -0x1b05c5ac, 0x891c3318, 0x883d70e0, 0x034ef879, -0x9f364d96, 0x9ac1d849, 0x52935d76, 0x92b1d7f7, -0xb241d6c6, 0x7a466608, 0xf5971834, 0xa5b88250, -0x475d7738, 0xdc4285cc, 0x953d3f20, 0x73dd0ab7, -0xd7c07f38, 0xba153744, 0x5662025d, 0xffcac9ab, -0xb5f14ff8, 0x788ae76c, 0xa3add19c, 0xb9f4e614, -0x2684d144, 0x9954d047, 0xa5fa8658, 0x2e98742f, -0xbd93d843, 0x9004abe1, 0x5dce2625, 0xb07ce2cd, -0xe45a23de, 0x5fc7d4f1, 0x9f6cd823, 0xca45faac, -0x77ed9a41, 0x863eb485, 0xbe5ee6d9, 0x7163f443, -0xf0f13fd0, 0x803146bc, 0x5a8a5234, 0xc6f23b27, -0xa4be8f1a, 0x7f543252, 0xf48c1088, 0x88f0f42c, -0x508dcc60, 0xdce3dd19, 0x9621736d, 0x61e9f832, -0xe49ad73e, 0x839ddc15, 0x0320088d, 0xe4e07850, -0xe6081f95, 0x212f40ee, 0xe5ec02fc, 0xeb3ec560, -0x21c799fd, 0xf616092e, 0x8c246959, 0x369e4e78, -0x95b8b0d7, 0xb2ac56e4, 0x11533370, 0xaa6d732f, -0x96da9f5d, 0x2c15d26c, 0xefc38a7d, 0xb411422b, -0x5ed512a2, 0xd0f6bdc7, 0x848402f5, 0x557a9d6b, -0xf6d6bfb4, 0xbae8326c, 0x44d2711e, 0xca0b1c1e, -0x818d6489, 0x674fdf62, 0xeba712c9, 0x8600fc72, -0x46c4091e, 0xc0dd6afa, 0x86d0ce6d, 0x73db482a, -0xf422ed0e, 0x814f50d3, 0x6a8f5f4b, 0xf8839c31, -0xb2f9ba8f, 0x63f77f84, 0xf2feb43c, 0x8267b66a, -0x4c1e25a6, 0xf5d369e0, 0xbfffcfbb, 0x72a2342f, -0xd2138eb0, 0x94f439ed, 0x75cf2660, 0xf4e13865, -0x99cc2799, 0x601f4b94, 0xef7da960, 0x9cbd1464, -0xbb1eecaf, 0xd505e594, 0x634b8c91, 0xbf437ddc, -0xe84a6b03, 0x647c259b, 0xaeef8ebc, 0xc2f8231b, -0x1ec35135, 0x82a90e21, 0x92abcc48, 0x11339939, -0xb38a8e03, 0xb3173d16, 0x1d456a2f, 0x884647c1, -0xa0796e8e, 0x2dbe5e87, 0xd724eb78, 0x850f2323, -0x67d0dabf, 0xffbefce9, 0x94ba824e, 0x4dad31d7, -0x41866002, 0xbc02ef63, 0xc714a08a, 0x4cbbf0a0, -0xb0711591, 0xd356135f, 0x66c868a7, 0xef093288, -0xc0f20e6d, 0x08d1e5b6, 0xf57c95b6, 0xda4abe4e, -0x53e01eb9, 0xdb1fc9a1, 0x914a0d4d, 0x72835fd2, -0xc48c91da, 0x90179816, 0x58e935cb, 0xc9ffcc97, -0x81a20a84, 0x4873eaa5, 0xeb2e34df, 0x9eaee870, -0x473a53b0, 0xe896b132, 0xa1da6125, 0x53907d39, -0xf2c0101a, 0xb400f023, 0x5c8405fc, 0xe56b9ff9, -0xafe70304, 0x61efed87, 0xfe2c1d6f, 0xa137799b, -0x6099842e, 0xc535ce7c, 0x813b7a56, 0x4fbfa56e, -0xd00b6167, 0x94047c4a, 0x7f2d2caf, 0xe779ed1e, -0x91f8ad3d, 0x4819be3c, 0xeb7c3f7f, 0xafde58c8, -0x416ba349, 0xe54b1a61, 0x84bf1cee, 0x6a49a45a, -0xcb279f1e, 0x94a64ea8, 0x50c52323, 0xf2bb1e1d, -0xb3369a76, 0x6b7bd4ba, 0xa5a883c5, 0x9920d82b, -0x1ad509e3, 0xb6603840, 0x9cf6fa7b, 0x37f38611, -0x8ac50d7c, 0xa00722bb, 0x1c530a5c, 0xaaaf42ea, -0xab934993, 0x3a763beb, 0x85920bf8, 0xba2f9222, -0x0803ab8f, 0xb65644be, 0xc1468e02, 0x0fcc5ad3, -0xca511fb9, 0xdecc45dc, 0x164ebc01, 0xda810b73, -0xe514c39a, 0x2d65d0c4, 0x92620d3a, 0xe52f6c2d, -0x6660cd07, 0x9e3f024b, 0xe75f21f2, 0x4b369f5f, -0x552e761f, 0xe3245f99, 0xc4a8d36d, 0x79150e9e, -0xafd6be8b, 0xd3079f1c, 0x741da83e, 0xbeb8bade, -0xef56cdec, 0x797d768d, 0xb812e70e, 0xda2b8b18, -0x60b40484, 0xb86adad7, 0xeec53ea7, 0x57d642cc, -0x917691fc, 0xe1d2bc90, 0x4f47b3a2, 0x98510bfa, -0xc38f58f3, 0x749b0440, 0xb5399e12, 0xfa8f3814, -0x45577b99, 0x8911964b, 0xce5b480e, 0x7bb71f83, -0xbaf64cd2, 0xd708ad19, 0x6ab5affa, 0x9958f2bb, -0xd0ca7465, 0x78bef153, 0x9aa7e50d, 0xd59589f5, -0x27a84f81, 0xb4e5ca62, 0xb11e75fb, 0x2f959347, -0xb6908b81, 0xa0dc5495, 0x15d063b8, 0xbac68fb2, -0xa842417d, 0x0e679113, 0x858d3a24, 0xb28c6d81, -0xa63ff7c4, 0xb6162705, 0x3d418eed, 0xb35998f0, -0x982bd927, 0x18e15412, 0xa6191a2b, 0x88059de0, -0x37b687e0, 0x99a0d2e3, 0xc2270bb3, 0x1c2efde7, -0xef4e85dc, 0xdd5cdd23, 0x2b93f297, 0xe69f6615, -0xdc707a03, 0x0b424b20, 0xd24bada3, 0xec108aca, -0x1eee4859, 0xfc337cb4, 0xf677d3be, 0x3bc9fcf3, -0xf0bf3560, 0xd76e5902, 0x07249f10, 0xcd0c1aed, -0xe68d1f68, 0x3bf09532, 0xc7dff675, 0xf627f8b2, -0x27925559, 0xf735c609, 0xf0bf366c, 0x340b0650, -0xfdddfeea, 0xfed89dc1, 0x0704611b, 0xd4a4353b, -0xf81a7fa3, 0x04f46a9d, 0xc8b9ebe2, 0xfc13091a, -0x071d6bf6, 0xd07f4f4c, 0xd4620b62, 0x0b0ae427, -0xae03a28c, 0xd7dc1e3a, 0x22c2eaad, 0xa5c8e3f1, -0xa2834902, 0x19faf326, 0x8ae4ddda, 0x8a732cb9, -0x240bc2f2, 0xbaea93a2, 0xd8049b07, 0x3f38948e, -0xc0e9c772, 0xc8b6c1b2, 0x082490d3, 0xfce9f20c, -0x10722c35, 0x28b52bc3, 0x272477f7, 0x31dbb406, -0x220e8872, 0x099fbaf0, 0x39a10e00, 0x1960c5d9, -0x3f5bfba6, 0x0123b1ff, 0x3a7b0cdc, 0x3f29d8f4, -0x021e948e, 0x15367a71, 0x1d660894, 0x01060e64, -0x0a47a953, 0x3d7f7646, 0x5c2e3326, 0x2f0b52c7, -0x5c4ce5a0, 0x6b4d4526, 0x24cdcc9e, 0x4b9b5edf, -0x6a80a105, 0x013180e9, 0x4269c090, 0x4b9eda81, -0x1f586fd8, 0x5329bfcc, 0x6cef8d7b, 0x3450dab5, -0x7e54bdb0, 0x342ae8b2, 0x77459bb2, 0x1bbbed96, -0x1d31aaea, 0x57be8663, 0x7fcb476d, 0x2af95451, -0x10b5fe50, 0x723b1d0b, 0x68e8fdb6, 0x1ba86347, -0x28197557, 0xfe83bafd, 0x71da9ee4, 0xb290db8e, -0xc3e3329e, 0x2d7999c1, 0x9e5078ab, 0xb03ce933, -0x44964e69, 0x85c9a1e3, 0xdb0b04de, 0x7705bff8, -0xcc509f50, 0xe1baa519, 0x33a76486, 0xd20807da, -0xff31a538, 0x2824987a, 0xfd55dca9, 0xc6c75eed, -0x6e09a934, 0xc28e5766, 0xa51425cf, 0x44ed113d, -0xd8a7e6d2, 0x1a93ea5c, 0x5d13c219, 0x420713e1, -0x08dd1ad5, 0x5f4a4e98, 0x4854b87f, 0x3d8ffc1d, -0x780ec676, 0xe5f156e4, 0x11b5a68b, 0xec86f0d9, -0xd08d6490, 0xc73546d5, 0xc9cc9af4, 0x2a179fdd, -0xc9fa7139, 0xed1e1f85, 0x358bedf7, 0xf85d053d, -0xc40d6cab, 0x1be9e76a, 0xf65d3c04, 0xf8e2cf43, -0x7e7d8de2, 0x8ce53551, 0xb9c28202, 0x1e3dd0a2, -0xeb7e16c3, 0x7d2332aa, 0x7c310b4e, 0x06cf6714, -0x736cd20f, 0x87197a64, 0x30fecd51, 0xa2171877, -0xffbd4e01, 0xe7bdcfe3, 0xfaf63afb, 0x103dc98c, -0x8df92486, 0x9f18a46b, 0x62e21409, 0xff9bd459, -0xea06dbb2, 0xa4aed423, 0xbb907994, 0x015b7beb, -0xe7b5d965, 0x3c7baa4d, 0x6e639c70, 0x6a63e04c, -0x4737f3f7, 0xb3b30f63, 0x2bea37d8, 0x84a8b29b, -0xfef6dfd7, 0x1cd52427, 0xcb3b7267, 0xe40c2eb0, -0x68b8b070, 0xc123305d, 0x89843b7b, 0x470534d6, -0xf81d8b07, 0x26d4b20d, 0x5a234265, 0x6ad94a6e, -0x11c357f9, 0x854a4eea, 0x7d2a7644, 0x05d3f0ee, -0xb074a203, 0x8b9e2e78, 0x181f15f5, 0x68d76981, -0xa7496454, 0xd6b494c3, 0x4b9586d3, 0x7cf5f67d, -0xfdd40e83, 0x203ed59f, 0x4f79e5d2, 0xbe585702, -0x27c5a87e, 0x7c8904cb, 0xad3bd485, 0x03c2c4d5, -0x5fc5ca27, 0x3d9bc4ff, 0x2ab90d3e, 0xfeae7801, -0x30f86b75, 0xe16eff78, 0xe2a35865, 0xe4f1632b, -0xfa4c9f3e, 0x39995cc5, 0xd413439c, 0x26409cb0, -0x2c0a191e, 0x3ddb38f1, 0x13844831, 0xe491b98e, -0x3502853b, 0x7ce54372, 0xeb146bc9, 0x0528ced7, -0x3706e43f, 0x6407efbd, 0x6d0fdd4b, 0xc5ad8378, -0x7f68d6c2, 0x2c776f23, 0xd84159e4, 0x1136149d, -0x1850c335, 0xed7200c8, 0x38862fc1, 0x31144436, -0xd55f3539, 0x7095ced0, 0x28d6c71e, 0x9a7e1c59, -0x738f287b, 0xcfc36dbc, 0xa352b20a, 0x94b46685, -0xff21c397, 0x45a639e7, 0x97dce079, 0x0339e07d, -0x6c63181e, 0xd1695983, 0x0f3f9949, 0xe79cbc93, -0x2ba92b63, 0x07aec366, 0x069d04f2, 0x1cd9921d, -0xe1552bb3, 0x274ff779, 0xf129e10f, 0xc676d005, -0xd94949c2, 0x4b05e853, 0x16a2b4f8, 0x7c8607d4, -0xc0c7225b, 0x8bb48a31, 0xffe935aa, 0x4e4d2f9c, -0x74472edf, 0x27fd27d3, 0xb0edb970, 0xae7aad7d, -0x7ed3c3e5, 0x51544c0b, 0xe1160c3c, 0x8898d872, -0xa49ec27b, 0x4b8b71ad, 0x7c011baf, 0x0136cb03, -0x89f0c23e, 0xb09b12aa, 0xf54e7879, 0x7b159d26, -0xd0274c76, 0x06a11c54, 0x32417ff5, 0x22f9ac87, -0xd04c7f93, 0xb4d64581, 0xda8e836b, 0x727833ae, -0xe10f52ad, 0xd5d9b8ca, 0x137439d1, 0xe6480fd4, -0x5920d3a3, 0x224e70cd, 0x6a9f8b40, 0x523313cb, -0xd933079c, 0xeb1ce420, 0x932c88d8, 0x621ba7c4, -0x398699e1, 0x91790ab0, 0xb72e91fd, 0x0c717172, -0xfd51b6b1, 0x103361c5, 0x6b81ca06, 0x54ab7ce7, -0x1a676e96, 0x7b064711, 0x40fbe8a1, 0x13b58a47, -0x654dada0, 0x1497f23f, 0x17853e67, 0x34793aad, -0x9a35153d, 0x2757793b, 0x86dd1d1f, 0xb5830eb5, -0x8624a4e4, 0xf8827b80, 0x1bbe08b1, 0xfa388a75, -0xa12f653b, 0x0cc7d6e2, 0x8e34dadc, 0xaf97070e, -0x027ee8d8, 0x94b956a5, 0xbb256a5a, 0x3bef3e55, -0xa2ba9e38, 0x4b1d8640, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2965-M08106C2219.inc */ -0x00000001, 0x00000219, 0x04102009, 0x000106c2, -0x556338c1, 0x00000001, 0x00000008, 0x000013d0, -0x00001400, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000219, -0x00000040, 0x000e0190, 0x20090410, 0x00000401, -0x00000001, 0x000106c2, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc90b16b3, 0x43609e61, 0xa4e6bb06, 0x8d22d7db, -0x375d7808, 0x02531ddb, 0x5f66ebad, 0x3f73276c, -0x0882023d, 0x953684cb, 0x0abe06ee, 0xa7ef1798, -0x160d6cb8, 0x930cf745, 0xafc3fd79, 0xa70df3d5, -0xb0620f46, 0x70048a23, 0xbf95ecf0, 0x76c1b997, -0x5128616d, 0xb6b4b969, 0xcc69f71d, 0xdf7416e1, -0xdf9a571b, 0x50c0bcc8, 0x85e2b3cd, 0xc1927532, -0x7a04b6be, 0xe56b7f97, 0x524085c4, 0x668bf327, -0xb3eaa54c, 0xccde06f8, 0x09b4e42b, 0x033b0a46, -0x0f6e2fde, 0xb308ce53, 0x93eff03e, 0x8830014e, -0x5c8a6f22, 0x91d2f757, 0xf70b648d, 0x0789998a, -0xd84d4640, 0xe5f34e80, 0xf3357e64, 0xd1e2beea, -0xc7e95c3a, 0x30e57e4d, 0xec214356, 0x7e10859e, -0x1d5895d5, 0xdeeff6cb, 0xed1030ed, 0x827e603d, -0x6b4b2de3, 0x83ec6fd0, 0xa64092f3, 0x8d9887e4, -0xbefcbedd, 0x2111afef, 0xcb9abf96, 0x5c79ceac, -0x9bf8a57f, 0x5d0e44be, 0xdca3d3b6, 0x9072d1ca, -0x48e73a50, 0x8d0bc804, 0x6aea94d3, 0xc372403e, -0x00000011, 0xfc992688, 0x23e600a8, 0x14f6cd28, -0x93bc5dc5, 0xa5495696, 0x6c07abae, 0x67d10a74, -0x945ac057, 0xb8473344, 0x472f30fb, 0x5b9c2ee7, -0x221b770d, 0x112eb268, 0x3724b0bd, 0x58ba84c3, -0x00e42136, 0x81477cb7, 0x85f5e1ee, 0x84d4a044, -0x79c3d88b, 0xfd5e4dbb, 0xffb5ec86, 0x622f59f0, -0x7bfe0e7f, 0xc355acac, 0xa4fb3619, 0x7339556b, -0xeabc4d3d, 0x6ab08a75, 0x7b59ae8b, 0x8aec0425, -0xd939122e, 0x8c0de100, 0xb6a824b8, 0x4fe6b900, -0xc4c994be, 0x8efffe65, 0x59c6b401, 0x7cd816b6, -0x7731727b, 0xc8612d27, 0xe889c3d7, 0x37bb7222, -0x184d0b87, 0x5228bc87, 0x222623d4, 0x6b7c86ff, -0x2ef75b0a, 0x0c2a56a3, 0x343d7ca0, 0xb4a609bc, -0xad047dc1, 0x402baa40, 0xeb1ddca1, 0x54466185, -0x40de7012, 0x33382ce6, 0x1c410b88, 0x77a4b6b6, -0x24dca2fa, 0x6553c356, 0x387d1121, 0x342ef68d, -0xbe569906, 0xb2ac2d4d, 0x781e3db3, 0xf1e39ef2, -0xcfe8ce3e, 0x3007b67b, 0x66f1673b, 0x1cad08f6, -0x3a455aac, 0x83a00fb2, 0xb3b6cc3e, 0x38172e9a, -0x99bf9d0e, 0x65be725d, 0x51f39d60, 0x29e48dc7, -0x68e1ea47, 0x05002e5c, 0xe2d9338f, 0x209f4e82, -0xa77b3188, 0x78c30d8a, 0xf5ca40c0, 0x5c3ea07d, -0xd4141b88, 0x05e2522e, 0x31c4d8d8, 0xcfd4b204, -0xa449934f, 0x4a88b5c0, 0xb474e3ee, 0x8e5b7950, -0xf7db2f3d, 0x1f0a8f3a, 0x0ba8557d, 0x7d47154e, -0xbc3c9775, 0xb52a9e82, 0x7c4f2d6f, 0xfeca6bcc, -0x16ef5c58, 0xedd2d873, 0xf9197095, 0x72bed70d, -0x0548445b, 0x12f3f734, 0x88d07e72, 0x0febabce, -0x2572952b, 0x3cdf2a42, 0x4193b60e, 0x4d812f9e, -0xffe96805, 0x978273e5, 0x6da0ec06, 0xe15d94d9, -0xb2b1c0d0, 0x940b6110, 0x89c7df3d, 0x70114c8f, -0x4bf8f46a, 0xd5f7bb83, 0xab457d17, 0x1e06b3b7, -0x36e7913c, 0x7fb0fa65, 0xa674d689, 0x1869ef0a, -0x5dc7b15a, 0x5da35a26, 0xe920832e, 0xc4de494a, -0x5e5d2ed5, 0x6c4737e0, 0xdf5ec30c, 0x8091f7a3, -0xb8c97091, 0x2b3aeab2, 0x7423a605, 0xa2ba859c, -0x485b398e, 0x9ab35881, 0x523441eb, 0x0385484d, -0x2a044c2a, 0xe306184e, 0xd1b28d17, 0xb8170bc8, -0x94aac536, 0xb5394448, 0x07262f8c, 0x637568b8, -0x494294a6, 0xfb1db2a0, 0x443f53fe, 0xd92d404a, -0xb5297cac, 0x5dedc37a, 0x0daac347, 0x7ac1ae2d, -0xea83ec15, 0xd322d35f, 0xc73d2bff, 0x0d431332, -0x07c14d37, 0x1ad1aa51, 0x9929b721, 0x97482314, -0x83340e21, 0xed080218, 0x4258da61, 0x439ea85f, -0xc71172a1, 0x0d22feba, 0x3a6de23a, 0x83b8fe9f, -0x876eeabc, 0xf775ba44, 0xa80def3a, 0x3fdc0d52, -0x2614ec7d, 0x6b4cf2a8, 0x9fb7a74e, 0x1757d1a9, -0x20d4010b, 0x151de99d, 0x4bd6bdaa, 0x0f7547df, -0xacc9570e, 0x8416d2ea, 0x988f578e, 0xa287907c, -0x863378bd, 0x78396f5a, 0xed570e5f, 0xa6845d46, -0xa513f5a6, 0x8283abf1, 0x25396b2c, 0x6347886a, -0x17fead7f, 0xdb650cfe, 0xcb24f93f, 0x368cac11, -0xfce10cc6, 0xf285252c, 0x981a327f, 0x3d4019ef, -0x99ceb802, 0x570a0285, 0x5f2a4ed3, 0x5f9b1600, -0x001841f8, 0x959b0805, 0xb3bbc0ab, 0x7101f85e, -0x0db99182, 0xf96d3262, 0xbf8b4f1e, 0xe2ec5696, -0xe80c0fe5, 0x98eda3c8, 0xbc4e96f1, 0xb011a977, -0x069f4fde, 0x79837aa8, 0x03543201, 0x77041b22, -0xcd556d8d, 0x001955be, 0xc9f1aeab, 0x73dacc9b, -0x2a0d9a46, 0xc9f740b3, 0x12c74546, 0x7a77b5cb, -0x46cd0c07, 0x33c49919, 0xb720c3f0, 0x1cf9f386, -0xa333685a, 0xd57eba74, 0x9a739818, 0x5349c0a8, -0x9f03edb5, 0x3ec21311, 0x49afc855, 0x70da0455, -0xa5298dad, 0xc2c3ed06, 0x83b2f5b7, 0xa9c3a934, -0xd9bad4fe, 0xb3529d95, 0xf7935ce1, 0xac181422, -0x6e67b6ca, 0xb053f52c, 0xc835c485, 0x1e4f3f3a, -0xd922de6c, 0xcca7947a, 0x7a689229, 0xe647fe13, -0x3aca8264, 0xf866ff46, 0xf999c6cf, 0xed01e84e, -0xf7b0199e, 0xec3e3356, 0x0f420d30, 0xc327971b, -0x4d7aed1d, 0x4baba227, 0x752a3764, 0x75d94365, -0x52416050, 0xbe1050db, 0x9ec1196d, 0x4b5e25e6, -0x34dc29b2, 0xaac206da, 0x2c87595f, 0x02e7e586, -0xf87e1f28, 0x90264c1d, 0xb86c314d, 0xb69cfaba, -0x19c4f9b3, 0xbb0caa02, 0xaa1e2461, 0x19ddc16f, -0x6df5f184, 0xf8bb463f, 0x5fd25e64, 0x86d7c76b, -0x5f6914b0, 0x57e88828, 0xc98df09b, 0x37138009, -0xb369b31f, 0xe7045bee, 0x29a8f874, 0x4b650bbf, -0x2f6287b4, 0xa549a544, 0x9265e74b, 0x8b37f6bf, -0xcd56bfa9, 0xfa258838, 0xd610488c, 0xa5cdc5dd, -0x9d845e17, 0x3aa87384, 0x24560eb4, 0x3544672d, -0xaa83f643, 0x4e689a3f, 0x72b5d70c, 0x86d3fd5d, -0xe67bf049, 0xaceadfac, 0x04ee56b4, 0x194a0835, -0x6dbf07fa, 0xdb51992f, 0xa2956de0, 0x331cf4c9, -0xc3d8c10f, 0x5ef580dc, 0x0fcf0f7f, 0x83702f3d, -0xcdcfcb70, 0x2475e23b, 0x95701afb, 0x725bfd6b, -0x4d47f669, 0xf3596431, 0xaee46e06, 0x5a4ab3b0, -0xb3c7c69b, 0x2f0a1bf2, 0xdc6de955, 0x254d56ad, -0xc0683c95, 0x7c3d0e31, 0x2bc97c44, 0xe3e6db29, -0xc2a8d98c, 0x357c97ce, 0x397db584, 0x2bd797c8, -0x8825efb6, 0x5d35cf51, 0xe80b2df6, 0xe67f6e97, -0x1c3401d3, 0xdab40712, 0xdd6d0cfd, 0xd8790e1b, -0xb0cf68d9, 0x986671f6, 0xf3cb7b14, 0x407e81e4, -0xeba6f4cc, 0x3774a142, 0x54e698a5, 0xb0203303, -0xd51b3f85, 0x697020d3, 0x3810c326, 0xe85cb4ec, -0xc472098c, 0x7368a46f, 0xabc51178, 0xce0ccf5e, -0xc8fac25b, 0x2a4be3aa, 0x0de1fd65, 0x795c2e54, -0x882244b7, 0x9576e013, 0x6e670e35, 0x58e4f198, -0x39b34336, 0x7646f12b, 0xb5c5bf0a, 0x16b37b1a, -0x21270db0, 0xb8214968, 0x29e314c8, 0xbcfb2f86, -0x1605b1b0, 0x4476decf, 0x827449f0, 0x77520628, -0x69b16de7, 0xcf8c24b8, 0x4f8ac7c4, 0x5906e5f3, -0x18fbe3da, 0x1efa44fc, 0x27cd16b6, 0x2e5b9451, -0xb8b47a15, 0x5e0275d9, 0x98ba61bf, 0x276fcd7e, -0xc45d474c, 0x3a6ec43d, 0x247b0578, 0x39023efd, -0xf4c1b8b0, 0x93118f01, 0x7d0bd14d, 0x5b2ccf75, -0xcc9caf6f, 0x8fcc1dbc, 0xc2a182ea, 0xa9d5ea77, -0xb67fb193, 0xc8afeb62, 0x979f4e4e, 0x23ddc2c0, -0x229b8670, 0xc2e45d21, 0x2f402e32, 0x44e37134, -0x0d97b5f4, 0xb451fbe9, 0xa6f8b847, 0x1242f580, -0x4ab7acc6, 0x46d21bb2, 0x73834518, 0x834624d5, -0xd16b2272, 0xc706f4b5, 0x499e3397, 0x2b8f3113, -0x2973cccb, 0x67c79188, 0x7603acfb, 0x492b6c55, -0xfb00c5e7, 0x53cfe2f7, 0x5b8c503b, 0x2a8551bd, -0x5933fa39, 0xd007c1cc, 0x134460bd, 0x4ebb4795, -0x4e6e56c7, 0x1249ec55, 0xf9d8474b, 0x03d33b72, -0x67370679, 0xc5816cbf, 0xb7e40ace, 0x2f3fd6cd, -0xafa9ff3d, 0x783c3ce8, 0x918f2c76, 0x95356478, -0x0fe91058, 0xab48087f, 0x59ece9da, 0x7db981fc, -0xe70556e7, 0x58ed65f6, 0x97e45645, 0xc6857a6d, -0xaec1bf29, 0x7bf82ad1, 0xee35e6fb, 0xd534ad65, -0x932dd280, 0xe0c2af09, 0x2338de06, 0x5e5b88c8, -0x46f4ea36, 0x58fbd024, 0xfdd2c4d1, 0xb61624ce, -0x772d74b1, 0x4f10fd11, 0x6b803a7d, 0xd2866afe, -0xcc943b2e, 0x35a9d42a, 0x483ef574, 0x04ed18ca, -0xc543ead9, 0xdb2ad8cb, 0xef6830d4, 0x60d7b29a, -0xb47c1e1e, 0x31ca0a9a, 0x1688576c, 0x5a282e51, -0x66400faa, 0xefc36a93, 0x96667b2a, 0xa659d1c0, -0xf810ece8, 0xcd731027, 0x3b19c944, 0x525b9a96, -0xa1155ff4, 0xe9377579, 0xd05e954f, 0xbc344ce0, -0xf2a435af, 0x69314efc, 0x0a7d7457, 0x29ba1cf8, -0xa01c70f3, 0x03f0f2eb, 0x4ea9fe78, 0x1463b4cc, -0x53026868, 0x5f6a2d02, 0x58efb550, 0xa4a0e3f4, -0xc9bb5cd7, 0x3c1fc3cb, 0xa3d0503f, 0xd7e7ecfd, -0xbe128e38, 0x5ff74ff0, 0xfe74923a, 0x0e03446c, -0x5cba99f5, 0x3b892c32, 0xf5155e4a, 0x5e3efa2b, -0x9119f586, 0x59604588, 0x6d7423ce, 0x8cda5b72, -0x267a0a74, 0x9b70a177, 0xc6834dde, 0x6ab9755b, -0x1488d548, 0x0d8df88c, 0xd237aa90, 0x473df401, -0x0fdd9dfc, 0x1d2cf3f0, 0x174cec53, 0x6be5058e, -0xd4901408, 0x6c05259a, 0x11cca689, 0x2806cc29, -0x7489990a, 0x43198c42, 0xe591f7ac, 0x572495d1, -0x59fea9a1, 0x3fb91523, 0xd197ad93, 0x771a4b14, -0xdd87d853, 0x52b0384d, 0xea4c7fbf, 0xbabef627, -0x1b1edfc1, 0x4affe39a, 0x3a337568, 0xf3a8077d, -0x567c9e5c, 0xe2f44db1, 0x4cfcc36e, 0x28884ef0, -0x57dbdbb2, 0x11aed7f5, 0x8ba4eb36, 0xde120de5, -0x49b381aa, 0x32fa79bc, 0x5aebcc3d, 0xf647e76c, -0xb99ff536, 0xc8f6b229, 0xfb6eb426, 0x5b756b63, -0xa6bea77e, 0x6d1479e6, 0xdef68b02, 0xb9951a00, -0x4240cb0f, 0x094b7ca3, 0x2262064b, 0x6f604f98, -0x0f06c41d, 0x1bef6e8c, 0xed8a279e, 0xdc559fbc, -0xb0bfe389, 0x0442de4c, 0x4d9f5d73, 0x6a93f15a, -0xb289c316, 0x3515ff17, 0x9681572c, 0x3680c1e2, -0xa96b2dac, 0x9a06d703, 0xa94a17cf, 0x11535aae, -0x01654322, 0xe4f831ea, 0x6d686f3a, 0x76c75680, -0xa3e98a65, 0xd59aec33, 0x7130033d, 0x6196781a, -0xcc28635a, 0xbee752b6, 0xb2946205, 0xae7c3c44, -0x809b350c, 0xa5ff2e45, 0x742f4b4f, 0x75910861, -0x0f9a7372, 0x4e24b6f5, 0xd968a8db, 0xe22c5ba9, -0x54f08a31, 0x6cc17c5b, 0x08f940fd, 0x6cdfa456, -0x29a4c0d8, 0x4246cac7, 0xe398f00e, 0x52d0654c, -0x3610b2d1, 0xf84cd3f7, 0x00293b7c, 0xabb4b35b, -0x58a7e82e, 0x1fc3c6c9, 0xc886dd9d, 0xbc25d985, -0x4c5cd2fc, 0x3141f73a, 0x633ddaa9, 0x576f5fdf, -0x7cc3a440, 0x14ddef25, 0x59d7d213, 0x29c80bca, -0x0df80f67, 0x60711264, 0x050b3db3, 0x7b4d0800, -0xd7350b2b, 0x507ccfbf, 0xc5a91aae, 0x7efed8c8, -0xbb4bf7dd, 0x617ac182, 0xeee14407, 0xe5c634dd, -0xcd0664cd, 0x1829ff02, 0x2e2073d2, 0x2ddcd5a2, -0xcb1afbf1, 0x096866b5, 0x26ff945e, 0xc4a2172e, -0xb4089d08, 0x4acf74ce, 0x169986c5, 0x61a28165, -0xd26cc027, 0x78c799d6, 0xd800ddc9, 0x53754eff, -0xf1141877, 0x48728ad0, 0x8a22c851, 0x858e70a7, -0xab80b4ca, 0xfc0e733c, 0xcae85996, 0xe07f723b, -0x4b81ce69, 0xc0ab303c, 0xb0eed408, 0xb89bc5ae, -0x6711353e, 0x87d4675c, 0x89d7df88, 0x37206487, -0x95e90c88, 0x63d48b34, 0xe7ba4599, 0x68a67592, -0xfe0341de, 0x7fec0b1d, 0xb8f33820, 0x767319e3, -0xd2044f54, 0xa4d341a9, 0xa45a2c9d, 0x098393da, -0xd0654e51, 0xa737aa45, 0x9d2900e7, 0xfe7eb80c, -0xceb9f445, 0x6c2c8690, 0xf8f98f3d, 0xa2d2bf07, -0x927b1a93, 0x920852f7, 0xcb403552, 0x183882a6, -0x92ead8e0, 0xb40b930f, 0x74c2c0a2, 0xa7b1c6cf, -0x57e3535a, 0xe565ddec, 0x7332c331, 0x1872fd33, -0x3e324a99, 0x17c9765e, 0xb0822c49, 0xff6abe65, -0x6997ce5c, 0x73ed562e, 0x4efd661c, 0x10d8b025, -0x2fd1eaf4, 0xb349f0c8, 0xe60fdd8e, 0x23fffbd0, -0xa15bf609, 0xddd9e32f, 0x057abc03, 0x22802461, -0xb279326b, 0x22ff69f2, 0xa0c580b1, 0xd991829b, -0x0943eb85, 0x53cb5a35, 0x979217e3, 0xf7197b81, -0x7a923206, 0x64bcece1, 0x404c97a7, 0x8c011352, -0x8e84ac4d, 0x16bb918b, 0x05fdddb5, 0x227fb22b, -0xb095fb07, 0x6b556afc, 0x9745a80a, 0x5f190072, -0xc95b78d6, 0x76464295, 0x1e526ddc, 0x2bc7432f, -0x52b3672c, 0xe5e477e7, 0xdade2243, 0x25ad56f1, -0x5b75b5e8, 0x37865e3c, 0x286d27ea, 0x08c7d60f, -0x0db0520c, 0xecad5b5f, 0x26d21fbc, 0x5f18707c, -0xb2084911, 0x6b616c35, 0xd86e229d, 0xe8ed9694, -0xd9872d8f, 0x13dd2a30, 0x67ffc707, 0x15c88108, -0xcfba534d, 0x268bc3af, 0xdf10f336, 0xe3242124, -0x3c83e736, 0x8a4ddf60, 0x9c8b418a, 0x9cfb165e, -0x700d43a5, 0x9a974722, 0x55c8cd11, 0xb23ee685, -0xb09c7f07, 0x75d6b52d, 0xd844b6dc, 0xfdb7d587, -0x86500091, 0x752adf1f, 0x9d4e4d80, 0x180235a0, -0x80951d7d, 0xf1d957ce, 0xfa9508f5, 0xcc891c1a, -0xeb51f76d, 0x8b0e0f09, 0x93049970, 0x661542f7, -0x07be174b, 0xed8c35fc, 0x85c13234, 0x0a72b1f6, -0x8466dd86, 0x69fe80ec, 0x48e71a37, 0x40b32073, -0xc06e1e53, 0x89b98205, 0xc69b2371, 0x5e75a364, -0x07f7fff4, 0xcab47414, 0x85d5ccc5, 0x2cfbbe74, -0xfe0f282e, 0xd20eec1c, 0x3b6d0540, 0x033ac156, -0x91a56f71, 0xd7296dd4, 0x804871dc, 0x67d827cf, -0xba1396b9, 0x9bb94134, 0xeffe0534, 0x2cbd5727, -0x0b948509, 0x20a97dd4, 0x0605e6fe, 0xee7d930e, -0xf1892f40, 0xd10a4b44, 0x87690a5d, 0x413019cb, -0x4b4a4321, 0xfd1ad47d, 0xfb4b0fae, 0x6247d99f, -0xf9e55be9, 0x74b94b74, 0xd13002fa, 0x031fd808, -0x7f558bca, 0xafd37ef2, 0xdac30332, 0x4b8ec189, -0x22864b78, 0xa294c296, 0x4e300c94, 0x351586a4, -0x64b3c126, 0xe14af07c, 0xbcf3fd2b, 0xec9f8ba2, -0xacaae0c5, 0xfd8416f1, 0xf86aec61, 0x827af51c, -0x1db95b54, 0xd5b44400, 0x3189f284, 0x51ee744d, -0x6b8e0ec5, 0x7c8fce74, 0x4bda1d3a, 0x4cb4bb40, -0x94a80692, 0xe5d5cff6, 0xeee460bf, 0x5103d4ce, -0x9ef7a762, 0xe1cdfa53, 0xe66c40e6, 0x9a4d5fb7, -0x24190f5d, 0x0a8a1133, 0x244d0192, 0x1e27f111, -0x2e7cfe2e, 0x437c86a0, 0xd5601c01, 0x95b9ea18, -0x594baa9a, 0xa1beb6e4, 0xfc10208b, 0xd629fe46, -0xc7a73322, 0x344cf9dd, 0x3b2025ed, 0x01b7e289, -0xd4172aa0, 0x7fa0edb0, 0xa2bad69c, 0x32ce7645, -0x2eb25170, 0x599b7e7d, 0xc0405765, 0x26292f80, -0x796ccce7, 0xa0954fca, 0x4ee053d9, 0x13fda549, -0xf8d89b3e, 0xf2468c6c, 0x96a61f8d, 0x33db3a7a, -0xe69d7666, 0xa35e6d42, 0xe2b0346f, 0xaa0ba4db, -0x67f642c9, 0x990654c7, 0x7598e386, 0x126ecb72, -0xac24bf48, 0x6b12cbbd, 0x0ca2ac55, 0x3776e42c, -0x27c182fa, 0x58cc7a01, 0x6f4f58a0, 0x229bc239, -0xa0a025f4, 0x251594fb, 0xb4399cdd, 0xec1bb182, -0x89832726, 0x8cc29f1d, 0xbbb6fd97, 0x33cf4317, -0xfae44075, 0x6d2559f8, 0xa7c3242f, 0x7e8a8b83, -0xbf1bbedc, 0xb5f1835b, 0xbfffdc15, 0xcd127b15, -0xc322734e, 0xaf108cf0, 0x7fe1e0b6, 0xc294fef6, -0x40c7b005, 0xf002f4d9, 0x84347361, 0x9a178122, -0x221f84fc, 0xa3de3cba, 0xaca75f4a, 0xfb702420, -0x716b0d5b, 0x5a14b3ac, 0x0d0da0f6, 0x799dbe99, -0x23da1e6a, 0xb18a5e94, 0x3964553c, 0x259f218a, -0x30d107e7, 0xa0a4415b, 0x0efae30e, 0x2a259b4b, -0xb2a3545d, 0xfa5e2261, 0x5c22825a, 0xd5b0f032, -0xc0e4974d, 0x158e98db, 0xaf5a511a, 0xd1fe28e7, -0xcfb755c3, 0x28dacd50, 0x25dc16e6, 0x88d89d44, -0xa2d7f529, 0x031ccaee, 0x48eaa62f, 0xdfa589e0, -0x4e335b00, 0x452896fb, 0xe865796b, 0x8455451d, -0x51438741, 0x272e7afa, 0x6868b95b, 0xff76cfb8, -0x9596f219, 0x213704f3, 0x270848a0, 0xa0ad03e2, -0xfc32d4b7, 0x8372384b, 0x7668bff4, 0x23b50cc4, -0x30abc3e8, 0x285440bb, 0x26d17518, 0x9dc01773, -0xac30222d, 0xefb1afc5, 0xc360b5cc, 0xdbe15554, -0x2de4ee23, 0x9f6ae434, 0x73984eff, 0xdcad6ece, -0x713950c7, 0x1b39b20d, 0xeae34762, 0x78716c5e, -0x96300e70, 0xa2cdb877, 0xeeb863b8, 0x9c8ae2ef, -0x82ad9c30, 0xea440a13, 0xc31799f6, 0xb7c9d784, -0x7f451a4d, 0x6e93e324, 0x3c790775, 0x16f05511, -0x7530d389, 0x5c8f2024, 0x4d5d4d91, 0xf99d1697, -0x7e552001, 0xbe8ffe1a, 0xa52f66ac, 0x195bee69, -0xeb7ea942, 0x69f1654f, 0x5d211509, 0x358dba8d, -0x80450c6a, 0x52d895a7, 0xbf16fb92, 0xf862bd4e, -0x6737b5eb, 0x820f8354, 0xe9f63fdc, 0x323317d3, -0x4c4891c9, 0xe5dd8920, 0x75d3437f, 0xf9c0ebce, -0x1e96c9f0, 0x9c224cf3, 0x41d0921a, 0xb96a502b, -0x36004b70, 0x2122c9ef, 0x44b19035, 0x922ccbbc, -0xfc2c2a46, 0x03d16aad, 0x907bc61f, 0xc7006fe2, -0xc3fc3a73, 0x5d78f50c, 0xb894d12c, 0x140ef41f, -0x2d7c5412, 0x501abfff, 0x7148145b, 0xeea55a86, -0x4fc8b732, 0x3bdd42ec, 0x8e9e30c2, 0xac01ac1e, -0xe599e322, 0x315f84fd, 0x7fe91ced, 0x76444300, -0xe451f3e3, 0x63e049dd, 0x04826158, 0xc830df5b, -0x38b83783, 0x036f106e, 0x1d858f4c, 0xe19c6b28, -0xdfd72c0f, 0xf4a80ece, 0x2f967664, 0x4780d7b6, -0x35a375df, 0x50b64e4b, 0xdefaebc6, 0xec40e6c7, -0x1e419ceb, 0x7585e090, 0x6f90257c, 0x0d8ff886, -0xa23d7ede, 0xb37cdeb4, 0x5961bafe, 0x2ee11dfd, -0xb0f162b4, 0x5319797a, 0x51fd4b3c, 0xd88bb741, -0xffe57978, 0xc237d953, 0x41b29753, 0xece0cb2a, -0x690656fc, 0x360ee38c, 0x7b65902e, 0x75de0d97, -0xbcd48c2e, 0xf3ed312f, 0x14a96440, 0xc755303d, -0xb9120bd0, 0xc06e9afa, 0x6b2f099b, 0xb2a1a0f3, -0xb76d613a, 0xa9acb4f6, 0xbbe10f9b, 0x52443f6f, -0xb345ffed, 0x7e846b24, 0x2f25b24e, 0xa4fcdb76, -0x788511ac, 0xca23a7a6, 0xe51838dd, 0xc9437374, -0x291627cb, 0x18518202, 0x5bc7973f, 0x2b3b3265, -0xc9981377, 0x9c36edbb, 0x00b51a3f, 0x60661320, -0x3140e7a9, 0x109a3604, 0xde37943d, 0xbdd0d5f1, -0x8bfdc673, 0xcdbfcaba, 0x1c700fd6, 0xee7b9c6e, -/* 2501-m801067660C.inc */ -0x00000001, 0x0000060c, 0x01192008, 0x00010676, -0xfbac0eed, 0x00000001, 0x00000080, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x0000060c, -0x00000035, 0x2e000000, 0x20080119, 0x00000301, -0x00000001, 0x00010676, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc8f5cd92, 0x30bd1beb, 0x77c4fb8b, 0xe899c960, -0xc729b4cd, 0x1d9b8923, 0xfcdfc554, 0x580d39f9, -0x170ce7c7, 0xd727c705, 0x019b1ba5, 0xe0414a29, -0x57d45458, 0x26a8a411, 0x9faad966, 0x095ec8b0, -0x083a7c2a, 0x17cfc70f, 0x3c8e78a8, 0xce18c419, -0x5f2ddeb7, 0xc9c95d71, 0x437a5116, 0xe0253ad0, -0xec78db42, 0x681e436f, 0x7fd028bb, 0x1149a501, -0x0bdf0d05, 0xc2321514, 0xd6866cd8, 0x64942685, -0x21e0276b, 0x0817a288, 0x09138669, 0x792985dc, -0xbd60d6aa, 0xfbf902ec, 0x43fee69d, 0x5c5823c0, -0x9dca1fe6, 0xb528b0c5, 0x22fd29ab, 0xac4fe251, -0x77207813, 0x0637a1f9, 0x16bfcf73, 0x80497f6b, -0xe5bca939, 0x1539fa1a, 0x66607fea, 0x2276c06f, -0xd003229e, 0x3622fda7, 0x18d0b8af, 0x9f399760, -0x3ac6387b, 0x6c7148fa, 0xfaf4df9f, 0x965db840, -0x7c142542, 0x7b805f4c, 0x3f2002a3, 0x061399ce, -0x2f1a03c4, 0x7f1c7616, 0xb2f9ab42, 0x4e6a92a2, -0xb44b96d6, 0xe1167017, 0xec4b2fb3, 0xa15376be, -0x00000011, 0x4872f26c, 0x88971c10, 0x66db1385, -0x1e532ab2, 0x7ccd2d72, 0x38dd766c, 0x131f4505, -0x7d5e1e0a, 0x1932938b, 0x79c1db9a, 0x9fe5b8bd, -0x07037c1a, 0x698cd351, 0xbadb5300, 0x063f17d9, -0x8558ada3, 0x224c2288, 0x26fa35b3, 0xe64efb19, -0x0e1b52db, 0x696d5461, 0x3a0f765c, 0x4b853dfe, -0x05147b28, 0xbe146518, 0xb61e1de2, 0xc342998e, -0x083d5f41, 0x737fdbb5, 0xdd812ce1, 0xa7b9549c, -0x164b5fbf, 0xaffd6139, 0x44154437, 0x23d44899, -0xbe41eae1, 0xeecc8d45, 0x31fc971a, 0x44475238, -0x5d4ab69c, 0x67f342a0, 0x118cb268, 0x513fb847, -0x0a86fce3, 0x23f22535, 0x5fa15360, 0x929aa833, -0x3cbd4138, 0xc1dead1e, 0x3efa210b, 0x9781a61d, -0x00b53f73, 0x07df4d30, 0xffe97322, 0xf7b12998, -0xba4d7316, 0x4b746898, 0x45ece500, 0x78cf31d5, -0x0208c1c6, 0xc3999e15, 0xce2f90f4, 0x7e130a0b, -0x3c74ce12, 0x37612fd2, 0x7ce3ae15, 0x99a26321, -0x52ac391f, 0xcb32f7e1, 0x0e50140d, 0x3a6bfc41, -0x497f7f9f, 0x334b7e17, 0xbcf4e41d, 0x3311b0db, -0x0dc65367, 0x44847807, 0x991c439a, 0xd2965df2, -0xfd72e4fd, 0x44b01f14, 0x5a0cf5c5, 0x70029e37, -0x92af3f34, 0x47949bdf, 0x771a3c07, 0x0874f372, -0x7a54670b, 0x7430b00b, 0x356234f3, 0x74edf1e6, -0xaaf60a4c, 0x2bb5eee4, 0xc2c1d43f, 0xc4ee788b, -0x4198fd90, 0x0aba19a3, 0xc251f028, 0xe42404df, -0xccbd25f2, 0xdb13eb69, 0x888f89a5, 0x5a6c8cd3, -0x1e3b469b, 0xe07e48c6, 0x87f25228, 0x64324c03, -0xe0426f9f, 0x148f828b, 0x4a3c82ab, 0x7d46539d, -0x0b5079ea, 0x2c675b3e, 0x83134717, 0xbe775c77, -0x74841ec3, 0x4470addb, 0xfabfa06d, 0x548757fb, -0x184ea712, 0x502765b5, 0xd7067ce2, 0x15afee11, -0x8a95590d, 0x3a1734cd, 0x212c7f7d, 0xe5aa3e5b, -0x9c7e75c3, 0x07486966, 0x5827bbea, 0x391e46fe, -0xc6acbc9e, 0x9761b6a9, 0x37bef8c4, 0x733eb81f, -0x7ac9a87a, 0xceacd157, 0xd931072a, 0x9383c10d, -0x5eae74ef, 0x5f82f6a0, 0xcf89077d, 0xbc641bd8, -0x1b7d1213, 0x980a4ed3, 0x410fa7e8, 0xaaa1a011, -0xa5e94ef2, 0x74937d5f, 0x3c109f67, 0x8e58bdcc, -0x2b43ad95, 0xaa516349, 0x6fa9cca2, 0x48a18062, -0x663c7fd7, 0xf3822d87, 0xbaaf1f97, 0x8da372b2, -0xa416831b, 0x6a645364, 0x9c7ac6fb, 0x3f5a9cab, -0x8cf6f4b4, 0x514fd1dc, 0x7e9d0918, 0x2075f774, -0xfda8677b, 0x3b5c16ac, 0xe887694b, 0x7d622e9f, -0x5427472d, 0x540e5c99, 0x2196e138, 0x5d5e9c58, -0x84a5fc17, 0xb17d6d41, 0x63273bdf, 0xfbb912b5, -0xaf16b7c1, 0xeb1914d7, 0x5d654b8f, 0xf4a594f6, -0x554a6311, 0xb391f519, 0xa5ad4acf, 0x9c052bb7, -0xea68faa7, 0x37399a25, 0x8f6f6d36, 0x47c20f2b, -0xf241ab98, 0x66da024d, 0xee90a06a, 0x33718b17, -0xaa89087e, 0x6dcca7f5, 0x43a59f0e, 0xcb2e3ab8, -0xb19126bb, 0xc56bccb3, 0x04f6fd9a, 0x0f63850e, -0xa2b6c85e, 0x309f9817, 0x7252b154, 0xcba20ff3, -0x143156b8, 0xcfcdc8ae, 0x13c2a75b, 0xea4bf1b8, -0x6e474959, 0xa9c376f5, 0x40d252b8, 0xb6209e70, -0x993efa22, 0x3d7e8007, 0x1857ba0d, 0x72f25310, -0x233a8f68, 0xeb4ca923, 0xb17917d1, 0x9ca3f4f6, -0xdecf1498, 0x99f5ddae, 0x8b6ba2b7, 0x54f41fb0, -0x1ec9ffa2, 0x74ad3bd6, 0x84fee3e6, 0x5294820d, -0x147e8b14, 0xd2dc15f4, 0x152fc744, 0x306bc043, -0xfdbb74d8, 0xf4ea207c, 0x53edfac5, 0x1b609795, -0xe990ee73, 0x749dbed4, 0xd1cefc95, 0x5c7b37f6, -0xc6b39045, 0x7281e3f7, 0xed0e6aa4, 0x590a246a, -0xe6e6a81d, 0x604491ac, 0x6cd14e8a, 0x7a19f5da, -0xf7c7326a, 0x0ef8029e, 0x0e741b48, 0xc962a062, -0x6f4ad86e, 0xa2729726, 0x93bcaf1f, 0x1bb56970, -0x12495cdc, 0x180512e7, 0xa1d68081, 0xb924c24b, -0x5a1461ca, 0x21438ca9, 0x5449ae48, 0x0f564503, -0xcec8df3c, 0x789f9b80, 0x5a708df1, 0x28735bfc, -0xcf11d2fc, 0xa5d01625, 0x80b0b533, 0xa09f026d, -0x1d22fdf2, 0x01928228, 0x8b6779ed, 0x04f7cc95, -0x581fe0b2, 0xcc9a66a4, 0x55b3f130, 0x0f22abed, -0x05b7e95d, 0xd8cc9c30, 0x0850ca8a, 0x34d729dd, -0x973300a7, 0x80ffedb1, 0xbf5b28e7, 0x135c8cc6, -0x4337b017, 0x31d8dd09, 0x35ed75a1, 0xb8f990b9, -0x4384dc18, 0x29d72b56, 0x021aa2b2, 0xa3248b3f, -0x5f4e7301, 0x29991927, 0x1cc50c18, 0x79fcc545, -0x56e2e683, 0xe5127777, 0x4b727957, 0x94d1bc22, -0xacd0da9e, 0xd24771fd, 0x5997ff0a, 0xb9947cb8, -0x8cb9bb5c, 0x16a4c5e0, 0x00d6995f, 0x1e05edff, -0x3a7f1af3, 0x445fd70d, 0x24a602c7, 0x6b50001a, -0x6c99f5e5, 0xad2c00c5, 0xbd16a90d, 0x3b7b6032, -0xa8dd4f8b, 0x437145f1, 0x5a593d5f, 0x749ee409, -0x9c6d8223, 0x40c1dad0, 0x578e7e1f, 0x89072e7b, -0x0ccf47c1, 0x427606d8, 0x4a7bb48c, 0xf85cc4e9, -0xca5ca3b6, 0x9b989f23, 0x6496403f, 0xdf8ef891, -0xf4458e90, 0x28eed125, 0xef91afe9, 0x97a8d65b, -0xe022b3dd, 0xc93c2adf, 0x520cbe7c, 0x58995018, -0x719a724a, 0x9258733f, 0x8df05767, 0x879b9ba1, -0x84684054, 0x71a62082, 0x5be959cd, 0x12c937ec, -0xc21fb3b8, 0x6738aa89, 0xb01d872b, 0x0ff6ec3c, -0x50fc63ea, 0x715b7c5d, 0x4e5d50c3, 0x086c862e, -0x34ec9201, 0xd41176ef, 0xd0238088, 0x53518100, -0x8e1500dd, 0xc6ea9594, 0x0359517e, 0x58d81a35, -0x48c40983, 0x2d562dc6, 0xecf5be9e, 0x4cd82ead, -0x45faeb2b, 0x1a66ec1c, 0x6b692a76, 0x6cb326b0, -0x3a6c362c, 0xf0174da3, 0x5e4549d9, 0xc12c5972, -0x73716059, 0xdd54591d, 0x32ee704b, 0x5a55c22d, -0x56bd1e7e, 0x2bd34024, 0xa42c85d2, 0xb1ce248a, -0x604a7570, 0xbbf4b3fb, 0xe0eeb866, 0x130b7dd4, -0xdb39dc1d, 0xd873b0c4, 0x3aedb6ef, 0x5efb2481, -0xbfaff9bc, 0xb94930d6, 0xa3fe71cc, 0x75867e01, -0x7c8ee191, 0xf38f4963, 0x8d077957, 0x658e7c2b, -0xc1bd58ed, 0xb86a20b2, 0xc624489c, 0x4624732d, -0xc11f1ee3, 0xf1874ed7, 0x173684cf, 0x0e5851d4, -0xc2662118, 0x13dbb926, 0x1668df5e, 0x00749d03, -0xab9530d2, 0x5758e602, 0x6db90ff1, 0x87270f9d, -0x774a52f5, 0xcd1b4b5a, 0xd706025e, 0xe3a51fc4, -0x31c5d55b, 0xbd0278a1, 0x16dce1bf, 0x75a3446f, -0xe030c121, 0xa6f6b3c8, 0x504e3b3b, 0x4c1428b1, -0x74229a60, 0x25d5b7b7, 0xea284c21, 0xf5f1c7cd, -0x0025e9fc, 0xa7db9e56, 0x4e3aeb90, 0x8bad0f3b, -0xc19e88eb, 0x8ea86b83, 0x25cf5d26, 0xca78504e, -0x94109c06, 0x60ad3975, 0x138b8038, 0x4c9d8fdd, -0x28a91526, 0x5d3d6c3a, 0xf81ab861, 0x8db34426, -0x35a3b398, 0xf3b40170, 0xb7e6994b, 0xea72c1f5, -0x63201cd4, 0x1c5749dc, 0x420ada27, 0x419f4847, -0x49244543, 0xb915645f, 0x3a00b3e2, 0x0122000b, -0x296b6bad, 0x7b45d76b, 0x5be8f025, 0x2a04919f, -0x8291fea4, 0xaae644f9, 0x7af3fb96, 0x77d9878c, -0xa8996848, 0xa9a0c1c3, 0xb47ae6d2, 0xc5b6cf90, -0xb04b4863, 0x43fa113b, 0x66ef4993, 0x03a5b4e9, -0x94b661dd, 0x145a5909, 0xd42f70cc, 0x6b816775, -0xfbc0cb04, 0x5e890eb1, 0xb6900305, 0xcd19304b, -0x85c67d21, 0x19e91907, 0x27b3898c, 0xe0ce6ba2, -0x4110d80d, 0x85953740, 0xba7a4225, 0x51db6dd9, -0x04c21ffe, 0xd34ef7cd, 0xeb13f075, 0xc1f8eb04, -0x19a1227a, 0x3e99efae, 0x318346e2, 0x3d4c73bb, -0x402dacc7, 0x5a9e892d, 0x01304401, 0xb3950c6f, -0x9254bea1, 0x5cc8f025, 0x53cb9416, 0x52d716c5, -0x3ff575a5, 0xede2046b, 0x2cbd6b85, 0x7e8feb25, -0xc2d35482, 0xa49b8495, 0x214fed4b, 0xc93ae54f, -0xde3d8a18, 0xe4456b47, 0x505555c1, 0x6418926d, -0x4b6ac1e7, 0x7ac213ea, 0xc081eea5, 0x467ff1c3, -0x1ed5d79d, 0x746dbb24, 0x38b1dbde, 0x4d495fc0, -0x7ddabfe1, 0xfbac0ba1, 0xd17cfc3b, 0x32c819f3, -0x1f4c39cd, 0x6fa5c3ed, 0x0d2e7f50, 0x1f5cb318, -0x1e1770d1, 0xef12c293, 0xb149ace5, 0x93df9bdf, -0x14a98319, 0x3374906f, 0x746d603f, 0x5a368e6d, -0x8dbaef76, 0xb7923f42, 0x607655cc, 0xd144703c, -0xa01fa0f6, 0xa83f4e65, 0x224bba03, 0x6e082d15, -0x11ef27eb, 0xad91427e, 0xd8f0e3bd, 0xba7bc3df, -0xdb031557, 0xf33052d0, 0x2bc3df37, 0xf55d25c2, -0x99af998a, 0x5819eb07, 0xe4b9ebc5, 0xbc3da46e, -0xde1abe71, 0xb8c66434, 0xe811e29d, 0xa48ee5e6, -0x7f961c60, 0x5500769f, 0x9c8e0d00, 0x94680cea, -0x2f7a0c5f, 0x9a058310, 0xd3ddca08, 0x74276c4c, -0x855ebef2, 0x61979f79, 0x09684303, 0x3ea777dd, -0xf700db1f, 0xdf7bcae0, 0x0fa7db2b, 0xd0115231, -0xc0015882, 0xe4af6f72, 0xb4388c7d, 0xfb5656bc, -0xbe1d38b3, 0xf59ae9d3, 0xddc692bf, 0x3aaef998, -0x561f993f, 0x4d191a40, 0x4492df05, 0x7eb17670, -0x0770001b, 0x9b320a87, 0xbc8a559a, 0x19781e02, -0x13c995b1, 0xcb8c1e47, 0x462019e3, 0x7ee6bcc1, -0x9da2afce, 0xee1dbf76, 0x3a72ad3f, 0x711f786a, -0x0c72d639, 0xa3455dc9, 0xef155308, 0x82f3e1c9, -0xc9540414, 0xcec2cde1, 0x748005bb, 0x24197d5d, -0x4b8b7f7b, 0x3dde3129, 0x9ac952c9, 0x6f7932a7, -0xa99005e4, 0x4261280d, 0xfad329af, 0x90bcacb3, -0xe1c4a202, 0x9200d928, 0xffe55142, 0xf69b2a40, -0x227783a3, 0xe4b0c9c4, 0xeca97ce9, 0x9245597d, -0xa922db08, 0x94bff912, 0xdbebd937, 0x5c658f30, -0xb3f4a726, 0x24e2ca27, 0x9ca037d7, 0x745d3d5e, -0x3e8c437e, 0xb807af86, 0xee5fa977, 0xfe335297, -0x5c0a6707, 0x8ab801af, 0x05d02766, 0xcd0906b4, -0x791b47d3, 0xff5a0291, 0x09465b16, 0xa7fff3a1, -0xe2e6d825, 0x7f4f2b9a, 0xc1f2e668, 0xa5cfe1d6, -0x95fd7bde, 0x38681314, 0xc3c7dce1, 0x7b82e044, -0x2c883c77, 0xe8aa72be, 0xd53867d7, 0x7022fdc3, -0x3b697ccd, 0xd71618ac, 0xc87934bd, 0xe96101d1, -0x55d1976c, 0x471c8505, 0x7a36d839, 0x5d62a9ee, -0xf3c54a8a, 0xa2be15d9, 0x244087c9, 0x042c8037, -0x23224689, 0x281c5d73, 0x2139ecfc, 0xffb8bc8a, -0x834fdd11, 0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, -0x4ae2dbda, 0x86d90089, 0x6675dfce, 0x48876262, -0xcec72538, 0x11dc5c80, 0x86a730f9, 0x313565c9, -0xe3e5be11, 0x106d7cce, 0x752b8be2, 0x3d00a5bc, -0xe6f70e95, 0x44447ac8, 0x600df30c, 0x8335ac3b, -0x8816ddee, 0x700982fe, 0xee495741, 0x48c7e81c, -0xa3d55da2, 0xb0172982, 0x70ab2158, 0xd4460621, -0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, 0xa8454763, -0x70877bb6, 0x66005c97, 0xaf292c06, 0x7b843db1, -0xf343b59b, 0x25cdc7b5, 0xa41da617, 0x9e9d895e, -0xc936f475, 0x7270925a, 0x30024230, 0x8e72f53d, -0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, -0xaf377cc1, 0xbff09a78, 0x4b4e0814, 0x95a0b2c1, -0x270398de, 0x201fca94, 0x2a032a4f, 0x131542b4, -0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, -0xa3b3a991, 0x17ee60c2, 0x852c0b8d, 0x11e5853a, -0x762002a7, 0x92c5311d, 0x0d4bf7e1, 0xfffec870, -0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, 0x0111a772, -0x9808e780, 0x29c336e8, 0xe9bc05df, 0x5bedde11, -0x945565af, 0xaff808fe, 0x87e3423d, 0x4de6f98f, -0x93b4adef, 0xbf704fa4, 0x09120e91, 0xd54f3692, -0xdf8eab1e, 0xfabbf59c, 0xe74318be, 0xaab87ffc, -0x29fa791c, 0xe3915552, 0xa652cb9b, 0xa1252e74, -0xb35b723b, 0x542aa28b, 0x12fcc5b0, 0x3941f962, -0x82bcc6cc, 0x47b11974, 0xb821611f, 0x78b34250, -0xf1be5659, 0x561b9e61, 0x6f3bd501, 0x584e6f5c, -0xd54ed547, 0xacebcd21, 0x7b5ff816, 0xb64ad233, -0x9f2f330d, 0x69fb1ece, 0xac8710dd, 0x58dc6c60, -0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, -0xa733274f, 0x884d9b55, 0x42b08b63, 0xafa54a74, -0x1c7ccf64, 0x93a20191, 0xaaa3132e, 0xc69831d1, -0x54634889, 0xfbfe3efc, 0xd3cf68d4, 0x302e3117, -0xf5693131, 0xc3ce8c6c, 0x1f03cd89, 0x6243334c, -0xf16bc80f, 0xdca5f130, 0xcb2cd956, 0x4c1bb421, -0xe8de533c, 0x7f86703a, 0x29aa897e, 0xdd54acad, -0x76b2f2ae, 0x7ef82b71, 0x2e30970b, 0xba402597, -0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, -0x2363d147, 0x5327289a, 0xe89229f3, 0xd63a535c, -0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, -0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, 0x6d65db4c, -0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, -0x8488a45f, 0x8ebc2932, 0xd4767316, 0x3e8c4b8a, -0xbab7402c, 0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, -0xc88528e9, 0x4b2e4e8f, 0xdd938b86, 0x0c964f98, -0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, -0x4d40b3b3, 0xcf203155, 0x0d2fa621, 0x752d2c58, -0xb12bac12, 0x1e7e8c23, 0x94215d54, 0x9854a71c, -0x4de63c64, 0x7a012529, 0x9c171f8d, 0x9e71def7, -0x3bd17d50, 0x11f175d9, 0xec78abf3, 0x7b529eee, -0xd3a69fc3, 0x5b718676, 0x58214d29, 0xa8bd2c34, -0x41ea00ab, 0xa03f64d6, 0x4ee342b0, 0x32b1e444, -0x1c1801a4, 0xc8424702, 0x334a7e35, 0x50cf1543, -0x3b22b495, 0x88683776, 0x8e2e0154, 0x6155c033, -0x4e2fa6ac, 0x42ace700, 0x8d64f97c, 0xaf9ced17, -0xb2a5cb92, 0xa558582d, 0x88705de7, 0x9e528d59, -0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, -0x10462123, 0x30080f7d, 0xb346cd81, 0x0049c396, -/* 2374-m16f6cb.inc */ -0x00000001, 0x000000cb, 0x09162007, 0x000006f6, -0x6f5dfa09, 0x00000001, 0x00000001, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x8cc99628, 0xdd93d064, 0xeacbe655, 0x0f2e237f, -0xed4e652a, 0x1a3f2706, 0xc4ac514f, 0x9aa90c36, -0xb808bbc5, 0x43bb567b, 0xbfea430d, 0xaceacc6f, -0xa03a6fc5, 0xce471ef1, 0x3b414283, 0x2e6afbf0, -0x26b83316, 0xd2200e5a, 0x4baba0ee, 0x4e928f40, -0xbcd3d907, 0x2dcdd606, 0xabf25452, 0x0752ed4f, -0x671b3afb, 0xc8d02d3f, 0xd4261c4c, 0xe3999096, -0xf030cd34, 0x00959162, 0xe1fcad06, 0xaa39436e, -0x1967eeed, 0x3c36361b, 0xb03c7119, 0xed21d6ab, -0x64e77067, 0xf8251213, 0x92b71464, 0x9627993c, -0xd0f6329e, 0xfb756405, 0x64bd21d7, 0xc58c9e01, -0x64c5c82f, 0x0a4ea25c, 0x023df5e1, 0xe53b65df, -0x103c6d92, 0x85806ef2, 0x53174db3, 0x86eb50d5, -0x6e472e0b, 0xae1b1232, 0x70c8ef6f, 0xbd53d673, -0xe36a3752, 0x57b967a0, 0x1ef229e0, 0xb5205fa0, -0x8a1b8605, 0xd5e0f464, 0x950ae36b, 0x98d0a673, -0x8f0daad5, 0xac17892e, 0xaf25b16f, 0x4656a1af, -0xe86de91f, 0x3eac43d0, 0xf3158fe4, 0x4475650a, -0x1028fd42, 0xf75508a9, 0xacafbb7e, 0x95c83a04, -0x47b7f70f, 0x3c4078f0, 0x8455af31, 0x7664ceda, -0x689b2778, 0xfb4057c0, 0x5bf83a36, 0xf3560a91, -0x6e5155a7, 0x27dae434, 0x0e583b31, 0x73ea435b, -0xfd4d2097, 0x84d77cba, 0x1cc336eb, 0x5d924138, -0x474fac1b, 0x496736b7, 0x8166361d, 0x724a2336, -0x57372e63, 0xc72e0f0b, 0x0e442bbd, 0x0d3fdee8, -0xf5c61af3, 0xe15d745f, 0x8b3646bd, 0x6aeeb4bf, -0xa5d8fc0d, 0x1371ed89, 0xc0d4de01, 0x201c36c2, -0x055a8591, 0x57690227, 0x357c8aa1, 0xa7f7dc08, -0x4e7abcf8, 0x7f1d9554, 0x1ca865d6, 0x94bc649b, -0x261df890, 0x229e0361, 0x8dc3c9a6, 0xe9849f75, -0x7f3e006a, 0xbf0eadb3, 0x31209c06, 0x20d8ce6b, -0x9e9f9876, 0xe45461a0, 0x0577d8aa, 0xc7b34c81, -0x5f34b5b7, 0x4921ca3f, 0x8024451d, 0x77957caa, -0x50224c71, 0x2dc6d58d, 0x1dcc39f3, 0xe4f6072d, -0x96c5ebfe, 0x9bfa46de, 0x693c63b0, 0x36d3d7d4, -0xa8cd7320, 0x1fbbbac1, 0x299f98dd, 0x30c11f3f, -0xc2f3768c, 0x206af5b6, 0x2957b013, 0xfe45cdee, -0x1b0ed424, 0xb292ed29, 0xd75c4e75, 0xdb829ddb, -0x4f1408d9, 0x10c912c5, 0x3f1412d7, 0x172bc236, -0x6714ce89, 0x5e788c51, 0xa9185b5b, 0x1e559cae, -0x3e5e1e03, 0x42b069ab, 0x3ed34c33, 0x27fa8f53, -0xa1d4d045, 0x7f3a55e8, 0xe4dc36f6, 0x25bcdc0e, -0x8b370262, 0xace3a7ca, 0xc93cb529, 0x57377a07, -0xe94c4b8c, 0x84c19a43, 0xfe87ecde, 0x10ecd4cb, -0x85ab4702, 0xbbcdfacf, 0xfd12ef31, 0x330d5a61, -0xeb57c1cb, 0xd1ca61f1, 0xa7e32012, 0xc5273d7a, -0x8ce6f8ec, 0xb6f02288, 0x8b38ed67, 0xfad9cc58, -0x39e7fa49, 0xfb3d9704, 0xd7dd5146, 0xfe61fac2, -0xc456e412, 0x51899aa6, 0x7c1e63fa, 0x37179d80, -0xecb61178, 0x8f44f5c9, 0xa9b952b6, 0xce36ea2c, -0x899ebbef, 0x08c13867, 0x285a7693, 0x30d16f3e, -0xa0c38351, 0x61b6771e, 0x10232f08, 0x260aa3c1, -0x46289838, 0x11c7a747, 0x442bbb7a, 0x4566010e, -0x0d911958, 0x905492fc, 0xe277fc99, 0xc3f49fa7, -0x116f2325, 0xe804886d, 0xefeaec69, 0x48aa6147, -0x36c224ba, 0xbbf0f900, 0xb60f663d, 0xf7dfe70a, -0x539f05f9, 0x08817226, 0x05221b62, 0x48b61680, -0x29ea4964, 0x633bff58, 0x7eeab12a, 0x74623b22, -0xf3d5752b, 0xc5c19a97, 0xa87f85d2, 0xf3943291, -0xbaff1f30, 0x6c7f3697, 0x1376d156, 0x3b95e18a, -0x678779a9, 0x094ea73d, 0xb15571cb, 0x2500d79a, -0x1722f328, 0xb67d6753, 0xf492d6bf, 0x8a090f83, -0x2b95e523, 0xec19679b, 0x1f25ec56, 0xf3a79e0e, -0x7d795c32, 0xf961eec4, 0x57d2781f, 0xdc2dccf8, -0x71412727, 0x3a5840ff, 0xe433fa73, 0xad17f321, -0xc8c8c87e, 0xeebbb101, 0xa00bc7f5, 0x49fc605c, -0x6e8de8ef, 0x6140052d, 0x7abfdebf, 0x8e8205c2, -0x6ef7b48c, 0x7c89a48b, 0x0b70c768, 0xc924a889, -0xf62ddb12, 0xb0a31334, 0xda0ad64b, 0xce05fd6a, -0xc14ab235, 0x793c3c5c, 0xe097f8cd, 0x557d7ab4, -0x0f774f23, 0xaba657ea, 0x68445529, 0xda624520, -0x87b5ac57, 0xfe0fefdc, 0xd68fb057, 0xbef6bade, -0x0c93027b, 0x91c4aff9, 0xe59b7798, 0xfdf29517, -0x6ffc358c, 0x19b1ad64, 0xbe6ae4f3, 0x83809cf5, -0x57971a97, 0x3b2d4a05, 0xb2385257, 0xb168d28e, -0xbfc2c743, 0xf0a26979, 0x75a599db, 0x9e0fbd84, -0x984219a7, 0x9fd76c11, 0xe9543726, 0x04a3aa88, -0x0464f668, 0x00ce157c, 0x54867a61, 0xf189c8ab, -0xefb98743, 0xee120915, 0x64412b15, 0x15e592c4, -0x512e1b2b, 0x9b89ca4e, 0xc31f2572, 0xc04856d8, -0x18f7c195, 0x20e9138f, 0x5060c183, 0xc6b3504e, -0x8564aa44, 0xde498682, 0xe0c8b0a1, 0x2817ba17, -0x67948b99, 0xda17b086, 0xd49e7e8a, 0xf76cacfb, -0xfef3e62b, 0x49d844ac, 0x00779390, 0xd64f6467, -0x5c7919fe, 0xc655db71, 0xf96627db, 0x2b69cdfa, -0x04f0e69a, 0x403cd655, 0x94daf134, 0x61b19de3, -0x2659bf25, 0x70b55cbf, 0x2795450e, 0xbd2d93d8, -0x9fdf44af, 0xd26cf2d8, 0x767dcc5a, 0x349e0083, -0x8713f27b, 0xd9785b33, 0x33761b40, 0xeea10521, -0x4ffd5554, 0x8bde0d09, 0xabda65c2, 0xcb313439, -0x5e38f460, 0xcea63946, 0xcd454c65, 0x61ea3130, -0xd6bf676f, 0x9fe33190, 0x805599a0, 0x2b4d71bb, -0xd6ef6d75, 0xa1dc7b50, 0x532dae93, 0xe5b3bcba, -0x67bfd0fb, 0xe657b81a, 0x941df750, 0xfe355d3a, -0x83be456d, 0x70c7f3b9, 0x16d7c736, 0xe1677e4e, -0x66050649, 0xa5130662, 0xfc7b1f88, 0x936e7a2a, -0x5b83c459, 0x66459c28, 0xe95c7a78, 0x5e4b4012, -0x6163b0b9, 0xdc59f22f, 0x43554c8c, 0x1e600eed, -0xeaa25fdb, 0xc6b0f2a2, 0xa91cd5e8, 0x78118159, -0x1fd3b9b0, 0x33ec8d9c, 0x98b5f83c, 0x4bea93ce, -0x8f1508ab, 0x3b8ebf4f, 0xa6f58dd5, 0xf527f240, -0xba863b2e, 0x6cdefb2d, 0xc0bc3710, 0xc405d374, -0xe20e18c2, 0x98aeb97c, 0xb7e7334d, 0xaed99f08, -0x5db6a85a, 0x29f49035, 0x6aa56f8b, 0x42119bd5, -0xddfb18cc, 0xbbc497db, 0x6b1bdeb8, 0x87a7effa, -0x26cc2ef6, 0xebb44d0e, 0x86d98ee9, 0xe5ed8a54, -0xd89e77b0, 0x3d70edaa, 0x397122c8, 0x01373cdc, -0xd20990ac, 0x8dd8f0cf, 0xc0b85880, 0x98d34d2b, -0xea9c54fa, 0x01154926, 0xf97b07b5, 0xf8acc1fb, -0xe2772a2f, 0x0b72e223, 0x0d5a5bf0, 0xbd5a79fc, -0x164a0de1, 0xba318e96, 0xf181613f, 0x4e415e2a, -0x3c0e50c0, 0x203a9454, 0xebfd74f5, 0xb4eab52e, -0x077fb33b, 0x82875c19, 0x710fa091, 0x9f90e318, -0x1e85d567, 0x0d87c6d0, 0xd4aac2e3, 0x08f33bd2, -0x912b7cd1, 0xc0221fef, 0x0b1ac4ff, 0xa4b5e363, -0x76fe31bb, 0xda70ad1c, 0x35391da6, 0xfc7e096d, -0x1b92bd89, 0x06a15c01, 0x71bea62b, 0x7e02d846, -0xcad0b5a3, 0x85314e36, 0xff7c3e21, 0x05a26a1a, -0x4991d458, 0xc31312de, 0x7f3d5ba6, 0x482af963, -0xa64eabfb, 0xa156004e, 0xf7bd66a0, 0x596ed6aa, -0x299c5948, 0x83e3090c, 0xc7ff0db5, 0xf7f04b07, -0xea6f26c2, 0x2202ff95, 0xdb1be869, 0x570d2bc8, -0xb6b2d6b6, 0x06a93efb, 0x6e21fcc6, 0x8873a3c1, -0x4e83b301, 0x9fee4803, 0xeec62f43, 0x48527fc0, -0x423cf782, 0x5d619cfb, 0x62af27a8, 0x907ccbe1, -0x90ccdc3c, 0x596e345f, 0xff6777f1, 0x734506db, -0xf2251e7b, 0x8c1d119c, 0xde4a8d7a, 0x3491f6c9, -0x1d236690, 0xca9ea54d, 0x0b041fb4, 0x5e0952e9, -0x3a2a9fd6, 0xa9f9b1f7, 0xa6a2ef4e, 0x9a10b33f, -0x68874a04, 0xea79b7c9, 0xc9b880be, 0x5d840cee, -0xe271c855, 0x115ebc21, 0x4413b163, 0x2092ae0c, -0xabf457b1, 0xa4e624d7, 0x6162c7b8, 0x48a3d1b0, -0xf5576ae2, 0xd2c50b2a, 0x8d280a22, 0x317b2aa9, -0x86081f3e, 0x5b16558b, 0xe929c9a3, 0x024d87d9, -0x4e028055, 0x8a4f2cdf, 0x0074cf1f, 0x94c333fa, -0x5ce57075, 0xc7f96cfa, 0x9cae5fb3, 0x883dae8e, -0x366856b7, 0x9caf63c4, 0xb9dede87, 0xf33e6f03, -0x12043886, 0x7c491aa0, 0xa893dec8, 0x48c770b1, -0x53b5b08a, 0x305c2fc3, 0x8acf8a9b, 0x34eeb82b, -0xb8788ec1, 0xc94bab28, 0x01ba344d, 0x01443e32, -0x7a02a450, 0x7c753958, 0x1538ac60, 0x780495a8, -0x6100c375, 0x087b32cc, 0xdc1a012f, 0x6177bccf, -0x1a73ed83, 0x70c1673b, 0x4a611622, 0xc38cd364, -0xec01a740, 0x9d8b70ba, 0x4167b81f, 0x32aa3a67, -0x01f53fa1, 0x2970f763, 0x96d632f2, 0x6bb81493, -0xf0271789, 0x8d50a57e, 0x6844d683, 0x4e810ac2, -0xecb47ada, 0x4aae5190, 0x597fe8c9, 0x932e6295, -0xb7bb5fa1, 0x3bf834e9, 0xe67989ad, 0x245e7f0a, -0xe754455a, 0x157e56bd, 0x57d18987, 0xedfbd198, -0xdfac9f5d, 0xd8ae6b4e, 0x34ff0f87, 0x5a941474, -0x829936da, 0x3a64c085, 0xee7114ac, 0x9f6c5b61, -0x966e4768, 0x42e63da2, 0x2ac3cdbf, 0x009868bf, -0xacf2c492, 0x71825064, 0xd9a18aa8, 0xf9056101, -0x4cc3cd56, 0x38ce86e4, 0xe7622a3c, 0x3cc073c4, -0xc366b756, 0xb4ea6da6, 0x0797eefb, 0xa4701b26, -0x2e8e7cff, 0xb5168bff, 0xc524e609, 0x959ed99a, -0x696cc74d, 0xba540d34, 0x56ed1fe2, 0x243ee688, -0x9f9b6e64, 0xafd12b43, 0x14b69f11, 0xdb4c6915, -0x2a0a17ab, 0x7800111b, 0xbb45464d, 0x322ffe3b, -0x81e5c756, 0xbf97c084, 0x6e603423, 0x040aaa9c, -0x244c254b, 0x792f2cb9, 0xc2697b28, 0x6cd584cb, -0xa8dd616f, 0x13e0b67d, 0x6344c177, 0x456e2291, -0xf79a69b0, 0x287b0c41, 0xf129f53a, 0x5ab58b96, -0xd6b5ebaf, 0x3e869e34, 0x1ed31326, 0x99a139c0, -0xead1e32b, 0x9ae80270, 0x6d50908a, 0xfe3a8682, -0xc300928c, 0x07a9d067, 0xf95fb96a, 0x9124d845, -0x950bb64e, 0xd759b736, 0x63af09bb, 0x77992644, -0x6585fd18, 0x90c8a962, 0x58280f9a, 0x3b33b693, -0xe69fac20, 0x40e9da52, 0x58af61c7, 0xd0fb5fd2, -0xe7c4904e, 0x89a89562, 0xcfeddf61, 0x78a6a53b, -0x46cbcb5e, 0x98830a71, 0x45476951, 0x29007807, -0x1892d5e3, 0xec8f4748, 0x6eae03dc, 0x68106a0b, -0xc7b79f3c, 0xcf67dfaa, 0x76d01d92, 0xe83302ca, -0xbe89cb53, 0x8e99b9c6, 0x1b329e36, 0xa6201431, -0xcb5e3ca1, 0xabfa3732, 0xc6d861c7, 0xff827943, -0x8baa8d8d, 0x44124268, 0xb52d38f6, 0xe1b543d7, -0x350eb505, 0x8aaad0ab, 0x64d2d1f7, 0x1f78037c, -0x15e4d29a, 0x8de0fde2, 0x0c67bd7d, 0x9217b97f, -0xa51ff353, 0x7e6e317c, 0xf912efc7, 0x6370513f, -0xf3c39d12, 0x9f72b794, 0x04d0c86e, 0x6df3411c, -0x3886f1ca, 0x1bc7617f, 0x1828cc69, 0xa99b3d47, -0x639eb77c, 0x1e8ddb3c, 0x24a52535, 0xdd236edf, -0xf982fbac, 0xc1888b0f, 0xb346e7ff, 0x0b3dd6a7, -0x136a9ca9, 0x929ad1d6, 0x0c8a0974, 0x2d7bf023, -0x0c5e5a30, 0x903dd14c, 0x528c952f, 0xa1cf54e6, -0xf12b6408, 0xf12e92d5, 0xeaf353fd, 0xe6fe1ee4, -0xae452344, 0xff0439cc, 0x10e66738, 0x8fe58135, -0xc4da00c1, 0x652e5e2c, 0xed3da3b1, 0x466fdbc9, -0xafb0be28, 0x096e3c7d, 0xae36530e, 0x48ece09f, -0xeea64c15, 0x2fbdb9af, 0xd3aec625, 0x283bc6e2, -0xdb9fb831, 0xd9a2a76d, 0xbed7481c, 0x5b125110, -0x9727c61a, 0xd0b68c17, 0x63308054, 0x0afc462c, -0xdcf6fbf6, 0x6bd99600, 0x5d2cafba, 0x32540b05, -0x71a05d58, 0x57c91984, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2348-m806fda3.inc */ -0x00000001, 0x000000a3, 0x08132007, 0x000006fd, -0x89c0d01f, 0x00000001, 0x00000080, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x72cbc5d0, 0xa24e89bc, 0x074028ef, 0x2ad07a06, -0xdeb7acf5, 0x98912a6d, 0x295d17a5, 0xa3b8708f, -0x95c69839, 0xb2f655e2, 0xdce0fc75, 0xf92f04fd, -0x51b6b38e, 0xe7884365, 0x69dcc34e, 0xcfe67a6b, -0x5e421f0e, 0x51527923, 0xb63fceab, 0xae39d6c2, -0x5dc6865a, 0x5819082a, 0xcfcfc6eb, 0xc4ed71a8, -0x06e83b7b, 0x7cc5025b, 0x5fefb2c9, 0x3c02abbe, -0x42dba8cc, 0xfc966b64, 0x2acaa07e, 0x61d32476, -0x72fed3f8, 0x7ef26af7, 0x8086deb1, 0xd11fe511, -0x3dcc3e92, 0x202bf190, 0x17fbf18b, 0x4cd17950, -0x81299fb5, 0xac3d96a2, 0x389ff313, 0x85dd4b22, -0x4eaef9da, 0x623b133b, 0xe3d02b2c, 0x2290a31d, -0xc6f8c543, 0xf6c18f11, 0x8070c5d4, 0xc756e5c4, -0xf4a40060, 0xbf169c70, 0x62dd14d4, 0x729fefe0, -0x6594d275, 0xa5abc2e8, 0x720904e3, 0x5a5b42ad, -0x5e970808, 0x5a6ec767, 0x502a6d38, 0x88d24740, -0xb4739506, 0xe3f497a2, 0x2618e78d, 0xfb602c6c, -0x323fc08b, 0xf9cb3dfa, 0xc90130e6, 0xe373da35, -0xde024249, 0x490b1796, 0x93f157ee, 0x10f73761, -0x6dd5c0e4, 0x4a9fb1fd, 0xadc2ead7, 0xd13e442c, -0xbfbd007d, 0xc8de8a68, 0x09c630bc, 0x69e78a87, -0x4d64bab9, 0x81c58c9b, 0x0b693158, 0x2a40ee8f, -0x47153744, 0x2a32e243, 0xdde6b849, 0xa2c35ddb, -0xf8c10a60, 0xaf5796f6, 0x8a95da67, 0x013f80a1, -0x7f332110, 0x345e3e0f, 0xba8ca1f8, 0x373a3380, -0x97f10a50, 0x3e1e78a8, 0x097496d4, 0x60ef2ffb, -0x9421fb84, 0x03131ba9, 0x535e0247, 0xeda34f42, -0x7f34ebb7, 0xbcfd1c2d, 0x19b2c696, 0x7107aed5, -0xd5877fe2, 0x404186ae, 0xbc41a831, 0x1cd49fd3, -0x92ff4c85, 0x3f65b35e, 0x701ce1cd, 0xe3839c91, -0xab53cf2d, 0xdb124ec0, 0x7c012c6c, 0x432b628b, -0xac351ee6, 0x9da287ad, 0x0adc2580, 0x66f945ca, -0x36bd8108, 0xbce986ee, 0x8fc2d524, 0x06dbf665, -0xb4124dd5, 0xf15c2853, 0x4aaa9b46, 0x753c207d, -0xd7805517, 0xaa6f6dfe, 0xf6eb1ced, 0xe6a4f89c, -0x5cbf2b1f, 0x6889832b, 0xf121bc8e, 0x2d7e02e9, -0xedbc10d5, 0xf3974ab6, 0xf977d65d, 0x40ef2640, -0x9c5f3410, 0x7ce2bca8, 0xac2d2c23, 0x204d560f, -0x2dffb3b3, 0xb051fdc4, 0x76ef18ad, 0x1b13190f, -0xa08cd1d4, 0x1aa202b8, 0x1a5040f4, 0x23a24420, -0x22622bd2, 0x6e543121, 0xfe68651f, 0x4e0d3fd6, -0xda661e0b, 0xfb41bbdc, 0x5a6e0df0, 0x8c27383a, -0x91e24f94, 0xa5db6d2d, 0xc7684280, 0xfddaf106, -0x0ada8514, 0x5cb76df8, 0xea1242ce, 0xc5aca25f, -0x0821a5f3, 0x71e4de37, 0x89c9a2a8, 0x4d2231b4, -0xc3edc81c, 0x56f516f9, 0x7e95a590, 0xe00ea616, -0x827fd358, 0x4511b62d, 0x6cac7958, 0x8259e262, -0x9ee67b13, 0xe73bdab2, 0x811f51d7, 0x88e6196f, -0x642a4db5, 0x1ca77047, 0x5a095f6c, 0xa42ddb9a, -0x66321e3c, 0xeeed0f13, 0x72e48195, 0x988f23df, -0x3d058cd3, 0x45fed77a, 0xa20f4f80, 0xca873db9, -0xcfd4a890, 0xcb406f47, 0x56bd45eb, 0x8ca14876, -0x411da96d, 0xaabe66e1, 0x26ce3950, 0x40ceb4ab, -0xbbb2b914, 0xfd90126b, 0x74c60165, 0xcd2e00ff, -0xe0607bd7, 0x3dc3818d, 0x4102205b, 0x72cca471, -0x0864151a, 0x65c92538, 0x5bc44cfc, 0x406a9b62, -0x10e5aab2, 0x751f6321, 0x533ca54a, 0x335961a9, -0xa386abb2, 0x24f90a2b, 0x3d13ff7c, 0x35d454ef, -0xc236b524, 0x8cf68189, 0x6ba29c87, 0x3925aaae, -0xa12de178, 0x4610a2d1, 0xfe330eca, 0x8d657af3, -0x7f2f81f3, 0x46cd664c, 0x676003c0, 0xdf786970, -0xb240a066, 0x41f852f2, 0xb85e5eac, 0x8ba83def, -0xc12c498e, 0x02c5d742, 0x4b9df557, 0xd9f2ed28, -0x5f7cec4f, 0xf9ff3a0c, 0x457ac549, 0x133f5bd1, -0x951b6947, 0xf835f2df, 0xee51efd0, 0xe90b1bdc, -0xb76c1a80, 0xc3f209a0, 0xb175f774, 0xd8963aff, -0x3d458f2a, 0x9ba9ca53, 0x91561069, 0x444ac140, -0x87f53cb5, 0xc835bec0, 0x2b6906e1, 0x1f2201e6, -0x443bfce4, 0xd0e25486, 0x71ba244a, 0xa85e4fad, -0xb0a9df78, 0xbef803cb, 0x710cbd53, 0xd7ce50b3, -0x38f69e53, 0x5175759f, 0x987de9f5, 0xfc5f9332, -0x090ba2ef, 0xa059c8e0, 0x9efc20ca, 0xaead8853, -0x22cd4804, 0xb30dca16, 0xadbbdf33, 0x246cb36c, -0xec99405d, 0xfef7e46e, 0x454bf0a3, 0xa75d4072, -0x6859ad38, 0x3c6a15e8, 0x37bb8ecb, 0x05747a82, -0x97edcb0b, 0x5bff5a7d, 0x20cd1e91, 0x1e37277b, -0x4c0149e1, 0xc7d5e490, 0x253bcac9, 0xdffe64ac, -0xf7ce2179, 0xada80d94, 0x3653f166, 0x7271d8a4, -0x994f269f, 0x0841e81a, 0x709401cc, 0x0c9fefbb, -0x30fa89fd, 0x1fea8b70, 0xffc68c98, 0x2030e064, -0x8e28b2c7, 0x2750f01e, 0xceb4d955, 0xb86ee560, -0x7ca55701, 0x3a942ffe, 0xd6ad0e17, 0xe8cec9d1, -0x5a6954e8, 0xb14fe7c6, 0x6e7d5c90, 0x8481626b, -0x7c798699, 0xdb0b344a, 0xa721cdc5, 0x861db07a, -0x1844fca7, 0xde861a71, 0x770735c1, 0x3ab64f3e, -0xb352aeb8, 0x046529cf, 0x2fd753f9, 0xbb3cad72, -0x27b44c84, 0x58e77f53, 0x08840b3c, 0x75ceaa6a, -0xcfb8ec2f, 0x8877c4a8, 0xee6bf89f, 0xc6256203, -0x0bb3f6bc, 0x696fa2f3, 0xf04e8efb, 0x3fd0099b, -0x27a473cf, 0x87fe81c8, 0x35cface5, 0x8afad818, -0xb47534e9, 0x90b406aa, 0x7d7c2d15, 0xc9caf1ad, -0x9692ac7f, 0xa3bc5fc9, 0xfd41d0f4, 0xc47f86df, -0x60cbdd17, 0xc1fc9bb1, 0x518ec6f8, 0x45c7e024, -0x7db1e277, 0xd4d30cd3, 0x35bc1c5a, 0x60b61287, -0xfcecbc8b, 0xc6cb70e9, 0xc6280061, 0x9d0ac8ce, -0xfaf12df8, 0x9b3f092c, 0x979a43f8, 0xbbdbe0cc, -0x6274f1d9, 0x7322b577, 0x50589a1b, 0xbd0dca66, -0x2160d66b, 0x4ea6b9f3, 0xd942aa7a, 0x0c8e1c82, -0xc0a07833, 0x0fdb7b24, 0x012a56a1, 0x9d2b019b, -0xba7c66ee, 0xe6af3a73, 0x823e0207, 0xd9913462, -0x8896001b, 0x142af0f2, 0x52539dd9, 0x864a53f0, -0x6e85c62b, 0x66139be6, 0xadd260aa, 0x2a7a579a, -0xd0fe929c, 0x67052a99, 0x1bcb98e0, 0x8c58f5fa, -0xb32d4733, 0xb4e4e4c8, 0xb536ab23, 0xd00ef025, -0x05c4cb84, 0xbbc9b7d8, 0x175d6254, 0x5d8ebdb4, -0xe3f3e65a, 0x52177f95, 0xe85d812b, 0x87fb19ac, -0x88b80b16, 0xc570083b, 0x124da09f, 0xc8522543, -0x5f73aab0, 0x6c25b49f, 0xc8a03cb2, 0xd857bb2b, -0x16378b5d, 0x242f0e79, 0x02d5d491, 0x7fc8b85f, -0x48177825, 0xc70d4bce, 0xa23f5d56, 0xc7ebcb58, -0xaf3b143a, 0xc33e9d65, 0xc043e61d, 0xf05a3d2a, -0xd162c7d0, 0xdad944f7, 0x3226cdeb, 0xd0d044e3, -0x8012c5e8, 0x18524401, 0x2a4d751d, 0x95592574, -0x8e03592e, 0x68a72ded, 0x7d65ba50, 0xfa66bb37, -0x81250634, 0xe92c784a, 0xb585ae7c, 0xc6e350f1, -0x8d40d62d, 0x5b2ad4bc, 0xc87b65d1, 0x700191fb, -0x06015556, 0xaf94c477, 0xa63b5aa1, 0x28a7ab7a, -0x7cdb448e, 0x3819d9d0, 0xcb0dfe9b, 0x715dc992, -0x88f5e070, 0xa1f5ecb5, 0x8c9876ad, 0x44be717b, -0xda7487fe, 0xecc57fab, 0xfb6cd21e, 0x6de34108, -0xa98b84ed, 0xd755144c, 0xb24c242b, 0xa29eab2d, -0xb909c928, 0x077da28d, 0x549454df, 0x173b4e96, -0x5353fdfd, 0xcf06a087, 0x33acdb4a, 0x166b41a1, -0x45219876, 0x96eb46b1, 0xee5f18ad, 0x6a962b7a, -0x9914a217, 0xca72359c, 0x28f5a8f8, 0x9d0b43ac, -0x5fb6964f, 0x0b2685e0, 0xbda83a60, 0x464fbf9c, -0xfd8f4ec5, 0x9d16acdf, 0x1192191f, 0x119c43e0, -0xd0a2df66, 0x8c2cf306, 0x3da0f9f4, 0xf409a043, -0xcfc563b0, 0xf0be102c, 0x3252b4b7, 0x07076cbb, -0x355888f0, 0x4e4bc8d0, 0x1fd64ff5, 0x245147db, -0x9d757b6f, 0xfbaeee9f, 0x43d68df0, 0x2709be60, -0xd333fd6b, 0x79af3f65, 0xb52de3ea, 0x04d94eb8, -0x43865e4f, 0xc736c027, 0xfd180b96, 0x78caa82a, -0xd0021810, 0x9e514f99, 0x72f5067b, 0x7de6487f, -0x6cb34382, 0x0e01763a, 0x89976ae4, 0x7a8bbfa2, -0xa50291f9, 0x6407b33f, 0xf7ce016c, 0x2d586dd3, -0xac0a7612, 0x32fa7be1, 0x3ee474d4, 0xc795f431, -0xd6d0a977, 0xdc859d13, 0x446f01b1, 0xafc13014, -0x67bad636, 0xda3c5946, 0xe169c32f, 0xfe5c93b7, -0xac1b3104, 0x42a5c9ab, 0xc906dad0, 0xe4b213db, -0x6fefea5a, 0x35528fb5, 0x59cadba2, 0x5cbb0ea0, -0x2b01c14c, 0xaa438c3b, 0x6bbad300, 0x3d6d3409, -0xcc87ec95, 0x6f167576, 0x623c3b26, 0xab438ac1, -0x469b5486, 0xb7992347, 0x0418dd1e, 0x54e6ad5f, -0x44bff273, 0xbc97e1d7, 0x7c5c88da, 0xf7bbb29a, -0x48d01e8c, 0xaa4d4376, 0x9a99c998, 0x24d09e2f, -0x24480693, 0x84b6b905, 0xd0ff443b, 0x76605be6, -0x5c6af5bd, 0x5dd0c084, 0x4d162432, 0xed939cf2, -0x2d333e06, 0xd2144645, 0xb06a3583, 0xc1d6e232, -0x03883c1c, 0x6a3a1491, 0xe6b619d9, 0xfee3f413, -0x5e59c26c, 0x28684bc1, 0xca68c55b, 0xca395734, -0x95d8afd7, 0x8a94d5ce, 0x6d780b0d, 0x6ab50934, -0xf5121314, 0xb9ec2632, 0x1beb9a14, 0xcd950304, -0x6fd91394, 0x33f84e25, 0x546d4a4b, 0xc303eb86, -0xcfb7b409, 0xf852adeb, 0x65c4960a, 0x01878815, -0x4a6501d8, 0x5bb3a40f, 0x9414a799, 0xbbae4dea, -0xae9d7b0e, 0x761dcb06, 0x9581c2ff, 0x06edcb74, -0x0c06177d, 0xdc36931a, 0x751d52ea, 0x699dd531, -0x5285df50, 0x81990800, 0xa81d52e4, 0xf305b98e, -0x260f304c, 0xa9f5a19d, 0x702bf4d9, 0xc4e322c4, -0x05e38fbd, 0xf6997433, 0x938443b8, 0x33fe4ff4, -0xc0da5ba1, 0x1701d20f, 0x4f631fda, 0xd966d058, -0x847b08a0, 0x7719b2ac, 0xea7e817e, 0x3cc266f9, -0x39b94930, 0xd5a7c643, 0x831d614c, 0x486c87ea, -0xeb32ec07, 0x27ccfb31, 0x3618615c, 0x01c5284f, -0x138ba020, 0x7f316b7d, 0xf7049fff, 0x2acb57be, -0x156b6bb0, 0x03df196b, 0x72bfb285, 0x0d1fd58d, -0xcb86fb0c, 0x938e1a8d, 0xd387a3ab, 0x5fa1b627, -0x2c4d3f80, 0x0b4a7121, 0xbab5d24c, 0x4e14e39c, -0x19d839a3, 0x0b730800, 0xaabb2b8a, 0xa58aa531, -0xa82260bc, 0x21be659d, 0x714b34d8, 0xa89d111d, -0x02828552, 0xae10e3c9, 0xdd9ecd12, 0xe13beb47, -0x96818a52, 0xb5fcd9b2, 0xa8d0964f, 0xfcc0e896, -0x7ab323da, 0xb1bf60de, 0xdb70c0ac, 0x83373de9, -0x3513e4d5, 0x0634af3e, 0xc3052a5f, 0x3acb8ac9, -0xcf03743f, 0x15555b96, 0x929b04ff, 0xdb2a9428, -0xdce90ae4, 0xe414e73b, 0x5b6b19ff, 0x1a708067, -0x61329d15, 0xc4eb8336, 0x2d861d5e, 0xca108403, -0x0e9ab2d4, 0x04d3b3c4, 0x36ef280d, 0xfea6cee9, -0x80c30cad, 0x399d1c6d, 0x2b654d22, 0x204032fc, -0xee60e1c1, 0xb20fd9db, 0x087a91fd, 0x6a4e368b, -0xad3ca7e5, 0x5355a689, 0xd220e928, 0x925cb754, -0x677991e5, 0xb3941d98, 0xa3eb379a, 0xf0237d52, -0xe96b9e08, 0xb7ae3c7f, 0x7a84124d, 0x9cc15b58, -0x2ddafebf, 0x93a8990b, 0x1555212e, 0x7fe44a1c, -0x90851979, 0x62a143a7, 0x5ba95724, 0x4d8762c9, -0xee3a6f84, 0x0af45b74, 0xcfabce5c, 0x73ff8f3e, -0xa872ef47, 0xe97e60bb, 0x805c1800, 0x8d3b978f, -0xaf71cdb9, 0x4d8da1ec, 0xae5f2f19, 0xe57566f8, -0xa2003cdd, 0xe65293ce, 0x6970388a, 0x979c68dc, -0x2fcf8d5c, 0x61a603d3, 0x92158c18, 0xd2f53c34, -0x842dc4b1, 0x32f3df78, 0xc696ab26, 0x2be86b54, -0xd98bca91, 0x0415fca1, 0x5afc9076, 0x796a5ef4, -0x87a225b1, 0x6b5784b3, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 1735-m01f480c.inc */ -0x00000001, 0x0000000c, 0x05082006, 0x00000f48, -0x5b9afec7, 0x00000001, 0x00000001, 0x00000bd0, -0x00000c00, 0x00000000, 0x00000000, 0x00000000, -0x26d329c9, 0x2a31e166, 0x66c2f9e9, 0x20f1b672, -0x8d3c77ed, 0x239833ff, 0x707d6a41, 0x3e4d0c59, -0x5d47bea3, 0x37368a7c, 0x07ec485c, 0x021431f4, -0x740853ab, 0x0e1e664e, 0xb37508b0, 0xa10916e3, -0x061f9f93, 0x1fe2bbdf, 0x7f1d60ab, 0x9a7b706b, -0x195bde13, 0xac2bcbb5, 0x2612228d, 0x2a9ee1c9, -0xe468d9f0, 0xbb43af00, 0x8f3f1a7f, 0x712ff1b5, -0x1212e591, 0x3b849a2d, 0xcf6d6b66, 0x6090be89, -0xbedd5cf4, 0x741d373d, 0x1b0a5595, 0x14dcc781, -0x39894c95, 0x64ce0417, 0x0fe0bac6, 0xd86b6406, -0x569f7a4d, 0x0f2a7353, 0x713d3c12, 0xf5de289d, -0x4309ec38, 0xd4093f8c, 0x9e920c0b, 0x0c7c318f, -0xe233bedf, 0xc183eed4, 0x58f9a71b, 0x4a999e3f, -0x793e1ed7, 0x04570728, 0x6491ebbb, 0x6d4766be, -0x5c406a38, 0x59f9d68e, 0x2da064be, 0x2fb6525e, -0xff5f4104, 0x7b627201, 0xc9cc0ca8, 0xbe19b83a, -0xddcd290c, 0x2bf63b7b, 0x0169516b, 0x9104527d, -0x18dfd2e8, 0xa1d57e4f, 0x743c1688, 0x33ce65ad, -0xb934f7b1, 0xa6364928, 0x43e5c1a5, 0x0ebe786f, -0x02877d68, 0x0be7ed3c, 0x9ee46654, 0x061b14b9, -0xa9d75799, 0x3461aeb1, 0x13824d89, 0x1ea4144e, -0x9cc9f188, 0x2e4b9cf1, 0x3dc01855, 0xe6c641a8, -0xe2bb2feb, 0x3dbf0b40, 0xb9ad30c6, 0xc2dfee01, -0x7b8a7f33, 0xd543428a, 0x6135b343, 0x048d4466, -0x9c35512c, 0xfef7544b, 0x6c41c9c8, 0xd0441cdb, -0xf46d7ab0, 0x0420c0c6, 0x92406962, 0xc827fc36, -0xa2d92446, 0xe4b07159, 0x379e3932, 0x212d21be, -0xf3579f1a, 0xf056d68a, 0xa2e901c8, 0x5105a222, -0xd505865e, 0x1d09a0dc, 0x3a246045, 0x7f8eefba, -0x707bca5d, 0x5cbe01cb, 0xfd10124a, 0x00f5a0d7, -0xe3c0171c, 0x524fa175, 0xdb3853d5, 0xfeb3df4c, -0x11bdefaf, 0x2ab213a9, 0x968d5e50, 0xeb0f1584, -0x24257428, 0xf6b43949, 0x5b69a8e8, 0x146f3475, -0x36afc131, 0xdfc35141, 0x992054a6, 0x13cfd4e7, -0xabfe12ac, 0x0519d8cb, 0x1b40cdb2, 0x306887d1, -0x1f8b8c5a, 0x09a1c1b6, 0x8d10622a, 0x3437e5cd, -0x60f65684, 0x3127a82d, 0x1a7b07a8, 0xdcb853e7, -0xe9ad88f4, 0x3ae8e45b, 0xde20b069, 0xc2dd9993, -0x9d4d818d, 0xff289e3b, 0xcf3a6f51, 0x3048973c, -0xd9329452, 0xe2b8f7c4, 0xb9c420ed, 0x2ce4f2e8, -0x32d24483, 0x0b75bdd5, 0xdae9c61d, 0x192caaf6, -0x3d70d1ee, 0x0cf75f99, 0x2a3ab102, 0x0d3e68db, -0x2f1ddeab, 0x2dc88c1b, 0xa8ab7528, 0xe443fd87, -0x6116afaf, 0x33247d35, 0x4282e07c, 0xcb56f01e, -0xf474f2ba, 0xc2795388, 0x56708a34, 0x1ebb090e, -0x1fe0267a, 0xc44dd6bd, 0x5567c1f0, 0x1a1bde80, -0x815164b4, 0x28a703eb, 0xa7ea0d67, 0x059d987a, -0xff0bd083, 0x2000f293, 0xf0fc10cd, 0x2297d629, -0x8f66ca3c, 0x2b5c9fa7, 0x8f548249, 0xd2f1f177, -0xb01b3a1c, 0x18790f23, 0x948bce5e, 0xe809fe28, -0x77c1333f, 0xe465a83c, 0x7e833fff, 0x0279feb7, -0xb0ad01a6, 0xd1b7acf5, 0x8207232f, 0x6abab29c, -0x65423460, 0x05e6d63a, 0xb6bb2cbe, 0x7a980894, -0xd105ef23, 0x733aa9a2, 0xe49afa4f, 0x030cf958, -0xd6923461, 0x6f5189ec, 0x3ab12460, 0xdc667d63, -0xb15adba4, 0x29c6b05c, 0x75c8a9db, 0xd42d58d3, -0x660ed0a6, 0xc3b45804, 0x7a62b809, 0x2ddb74b6, -0xc907dc4a, 0xd221dfb4, 0x8c3b5f72, 0x00d214e0, -0x8e454034, 0x1fe6b683, 0xfbb425a0, 0x1ff24e08, -0x31fdc388, 0x090e492b, 0xbe7a1211, 0x1bdcc839, -0x6f1289b1, 0x37552a7a, 0xe9fe3c7e, 0xc59c4a56, -0x2e9e8cb2, 0x3dbe475d, 0x38b2009b, 0xf68b548f, -0x650360b6, 0xe279109f, 0x08f585c0, 0x13137c4f, -0x9dbb8035, 0xe0559d22, 0x27ba1ef2, 0x7115bcbc, -0xeab32d06, 0x3ba5a83b, 0xf4b26c6f, 0x4af2299b, -0x53ff1a47, 0x7bea180f, 0x9a1f17c5, 0x3e73bb67, -0x1de5a33a, 0x4f8236d4, 0xcc0375a3, 0x9308a031, -0x729b2a82, 0x3b6e7bc3, 0x29622d7c, 0xa12e5e81, -0x5ed9b4db, 0xa252bc45, 0x36b4cfc6, 0x0785005a, -0x153c81ea, 0x97f9ff5e, 0xa1f2ddfe, 0x005a5f2a, -0x8d7f98d4, 0x008fda90, 0xe98725da, 0x351c9240, -0xebc7d996, 0x3ab05185, 0x7a1670ea, 0x21f7d7d4, -0xbd2ff954, 0x21885949, 0x6740e0d1, 0xde024a2e, -0xf1eaaa3b, 0x016d3215, 0xd03643c5, 0xdc3d4493, -0xf3aa90cd, 0xf9e0f628, 0xb1a08f8a, 0x10b128d4, -0xa47437de, 0xfb9d9cdf, 0x03db607d, 0x5c01ee58, -0x1b653dba, 0x161e084a, 0xb3bc1b7f, 0x5f465cf6, -0xc7a4de33, 0x4b4a5fe0, 0x993d4a03, 0x1f6f7caa, -0x7254c72b, 0x4a8273b8, 0x13451fa8, 0xbeb71239, -0x4aead099, 0x20cca393, 0x9c20f5fc, 0xb0e800e1, -0x42f6eebf, 0x9dd9f9ad, 0x2fcd338a, 0x1c8f542f, -0x2a70cec8, 0xa8323157, 0xdd4f014b, 0x4811806a, -0xe29ee9d1, 0x10fd4851, 0xa1856fe7, 0x74c54af3, -0x0b1f4fc1, 0x62e0bfbc, 0x2a34ac31, 0x37ceeba7, -0x0bc88ba4, 0x6a0da39c, 0xb8f20401, 0xda103375, -0x5ad37148, 0x3d48670f, 0x10dd360a, 0xc430ca3b, -0xb5d84eb5, 0xdff3efed, 0x0d366e3f, 0x0fcc7479, -0x144ea51c, 0xd1c15a95, 0xf33083e6, 0x47de9a48, -0x36b1735d, 0x1fc429af, 0x06063db1, 0x52502b06, -0x4dce576f, 0x55935a74, 0x05bb9df1, 0x35672ace, -0x54672062, 0x6fc72283, 0x11bb39b2, 0xba7a8765, -0x8adcfb49, 0x1e77de0a, 0x23121a6e, 0x9622be4a, -0x645e970f, 0x8c338693, 0xc7d4d53d, 0x0fbbf9e3, -0x012c640f, 0x942e04e6, 0x7b954afc, 0x03fe7cc1, -0x41bf63d5, 0x2cb4e87b, 0x9b22a6c2, 0x268b8300, -0x4a60d8eb, 0x1d85d604, 0x542a63a3, 0x176dbbc7, -0xaf4a47ff, 0x3f413e8e, 0x4a6e58fa, 0xfb53830d, -0x013882df, 0x0cb45d80, 0x7d8251c3, 0xd015f916, -0x97a2c17e, 0xe72bc8dd, 0x6dd76e80, 0x3d567dc7, -0xf34ada7c, 0xef2d13a3, 0x7f43c2fb, 0x5ebfa522, -0xedff273a, 0x0f9661ca, 0x8620d029, 0x7e753aee, -0xd084fe4d, 0x788bf5f0, 0x486306b5, 0x3f7f7267, -0xf1379628, 0x7e582e54, 0x7129c293, 0x8a2e2c72, -0xfccaad76, 0x296e76a4, 0x86c00f66, 0xa07d9b46, -0x3d86ea2d, 0xa08b7461, 0xad433700, 0x15c5d238, -0x47589fa7, 0x87cc4eeb, 0x95a5592c, 0x30963e85, -0x24718ecb, 0x02788155, 0xb0450b0b, 0x1bea2d69, -0x8bfb61b0, 0x2cbd4982, 0xb4e202e8, 0x0b210f6a, -0x1f5f8a14, 0x34764f12, 0x867e7ae5, 0xd849c20a, -0xae17e666, 0x230ffd00, 0x530835f9, 0xcf165d20, -0x4c8de748, 0xe70efe14, 0x57defefc, 0x0a89c95d, -0x2d652e79, 0xf6693116, 0x22fbb58f, 0x27f9276c, -0x420b3b12, 0x0dd2a030, 0xcade871e, 0x2de4379b, -0x0dd79b21, 0x237405c8, 0xcf569f57, 0x1089c7f7, -0x0b7a0f86, 0x35a38012, 0x14336c03, 0x9abb16fc, -0xa2bae61b, 0x011259a5, 0x06255f6e, 0x89146af4, -0x57177372, 0x99f5bdca, 0x3756e46c, 0x208c3294, -0xd57654ee, 0x936046e1, 0x703d3f59, 0xbb4d8e7e, -0x19322623, 0x3e939f15, 0x130c9156, 0xbe3ba4b3, -0x4fea9380, 0xbf169ed9, 0x977e90e1, 0x0e5a602b, -0x8854d38d, 0xb809f172, 0x4c0e3de4, 0x4c553817, -0x85b25de2, 0x0bf1bd3a, 0xb8b1e414, 0x573925d0, -0x155f0b56, 0x7d3e8581, 0xa3109199, 0x14a3e01d, -0x326c8cb8, 0x6aca28f5, 0xd242ac23, 0xd776334f, -0xf1e8093d, 0x3755e677, 0x03b1091c, 0xc8f8294f, -0x813570ee, 0xdc565678, 0x0e3f1356, 0x2840bbe8, -0x532d033e, 0xe4a47224, 0x51281b88, 0x57e43e10, -0xf84157ec, 0x39586b89, 0xbfd62b1c, 0x5dac030b, -0xd5656981, 0x64fa0e98, 0xbceebbc8, 0x1803f2aa, -0x5a121ca0, 0x40167138, 0xb90acc0a, 0xc35a9707, -0xf9d848a3, 0x20ddfd6b, 0x0228d345, 0xdb0fdc3a, -0xb61a8dc4, 0xc3b9327b, 0x059ab851, 0x0bb9a025, -0x6d3ef669, 0xf50fbfeb, 0xc1bb3994, 0x8292cf89, -0x3e3759be, 0x1073081a, 0x4f8921eb, 0xa46ff9b8, -0x968d5993, 0xae888650, 0xaa61d0ea, 0x337deff7, -0xe1821ca2, 0x8c80546d, 0x0d1ed478, 0x76b7aed8, -0xcea89eb0, 0x09d3f378, 0x97c96536, 0x64b48cf4, -0xc2ec8718, 0x65fa7e73, 0xdc925cf1, 0x01b8467f, -0xea923bb9, 0x7ce164bc, 0xe1a337df, 0x9f59fd44, -0x1ab74283, 0x10ad4e3d, 0x05e77e77, 0x961b3cdd, -0xc980d676, 0x9df98056, 0x72f10fc9, 0x23d418db, -0x35dc8c9d, 0xa57d8025, 0xfcd53d46, 0x022b7914, -0x9908dd5a, 0x2b2f00dc, 0x400f20e0, 0x04263507, -0x8538056b, 0x39498c7e, 0xbf7bd527, 0x18a632a7, -0x75556a46, 0x1f4f6ff1, 0x7d2b11df, 0xe39303d5, -0x5dce0fb3, 0x34d1a951, 0xa70757ef, 0xf791d144, -0x8955e59d, 0xf7cbd790, 0x6e4e638a, 0x24304133, -0xf691ceb1, 0xd8c6b687, 0x40ebd347, 0x68f3bd1c, -0x94dd90d0, 0x3d00c8ff, 0x62eee056, 0x5218066f, -0x15381e95, 0x655c1766, 0x3435acaa, 0x0b600634, -0xe3596a35, 0x5584d1fe, 0x6807aa2b, 0xd4d9fde7, -0x719b309c, 0x24c658b4, 0x5af9bc14, 0xc805d68d, -0x8a80494c, 0xdaf4c624, 0x77abf58f, 0x363931e8, -0x56cb9c63, 0xc6b111fd, 0x06f44fb4, 0x1d1a309f, -0x9379fd1a, 0x15c5881f, 0x2c585ee6, 0x143b8e4f, -0x9a041aed, 0x1e6ea9b2, 0x9db0dedd, 0x094cb86d, -0x705b5c51, 0x293e4cea, 0xfca2567f, 0xe72104dd, -0x379974d2, 0x0b966e93, 0x9edfa253, 0xccb8d8d5, -0x89c4aabd, 0xec3fc740, 0xb558b061, 0x1ef4c43c, -0xa4c0a068, 0xfa1a4c45, 0x88cc3639, 0xca0dcb62, -0x1135a02b, 0x12996aa4, 0x4a95ee56, 0xc2124ef6, -0xec2f887f, 0xec365501, 0x3b13bae7, 0x32fb1069, -0x23fb5000, 0xdb047f70, 0x1f6b72b7, 0x484c331a, -0x1b52bba2, 0x3468046b, 0xbdcd005a, 0x5dce1386, -0x62cba2fd, 0x7d058cd9, 0x6cd00bd0, 0x032a1fcf, -0xde6d05fd, 0x50729978, 0xbf94d156, 0xde54e24e, -0xe4f44caa, 0x2fcd84c4, 0x34e2d48b, 0xe89f3a2f, -0xe1ef6ac2, 0xe2ddb72c, 0xbf0a7360, 0x0ff92181, -0x1dae30ef, 0xce13c949, 0xa6a47e72, 0xb3c94f45, -0x3c763829, 0x1abdc257, 0xd17fcdc2, 0xb7424765, -0xf7a5f541, 0x97061a67, 0x370849e2, 0x019a0284, -0x30f0d0ca, 0x94ee0ea1, 0xcb25cc50, 0x78d3ede6, -0x821a9f30, 0x034c5444, 0xe84cb902, 0x1d010bec, -0x83b3a984, 0xdf19de18, 0x33c92c5d, 0xee64a937, -0xe4629381, 0x2567d2ac, 0x99b3f403, 0x5ce0f594, -0x15c70152, 0x9e3aa859, 0xf24186a2, 0xbfbf96cb, -0xaa23ff50, 0x7e4c6845, 0xa6af9a2b, 0x06987623, -0xc4242a47, 0x74598d03, 0x5b14ca3d, 0xd37d1846, -0x28911f3e, 0xd0432281, 0xcf43549c, 0xf2a2479a, -0x29aa5cff, 0xa32c596e, 0x12c61119, 0x75055eda, -0x8bfdb594, 0x1b32dde0, 0x041ebdea, 0x0c9f43b5, -0x692789e1, 0x06b14551, 0xae1bcdc0, 0x01ccd8ed, -0x2669ee97, 0xa006c95a, 0x343da055, 0x6db53327, -0x69dd21b1, 0x9a056e86, 0x3bc8035b, 0xdf4890c3, -0x772b96c5, 0xbe21b193, 0x0bc89355, 0x825ade87, -0x24b1e95c, 0xf63e33f4, 0x5bc8933f, 0x8346f42f, -0x2b1aa1b3, 0x9662f4f3, 0x9d61d442, 0x499f314f, -0x6a801dee, 0x91c70d52, 0xd207bec1, 0xd79961a8, -0x1a0489dd, 0xb0fae274, 0x4aae84f8, 0xdc465d50, -/* 3101-M04106CA107.inc */ -0x00000001, 0x00000107, 0x08252009, 0x000106ca, -0x7deb58b2, 0x00000001, 0x00000004, 0x000013d0, -0x00001400, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000107, -0x00000010, 0x000500b0, 0x20090820, 0x00000401, -0x00000001, 0x000106ca, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x2beaa92c, 0xfc3395b7, 0x10be81a0, 0xb318e067, -0x723923f0, 0xb297dc63, 0x7d52bc4b, 0xc6ef362f, -0x0882023d, 0x953684cb, 0x0abe06ee, 0xa7ef1798, -0x160d6cb8, 0x930cf745, 0xafc3fd79, 0xa70df3d5, -0xb0620f46, 0x70048a23, 0xbf95ecf0, 0x76c1b997, -0x5128616d, 0xb6b4b969, 0xcc69f71d, 0xdf7416e1, -0xdf9a571b, 0x50c0bcc8, 0x85e2b3cd, 0xc1927532, -0x7a04b6be, 0xe56b7f97, 0x524085c4, 0x668bf327, -0xb3eaa54c, 0xccde06f8, 0x09b4e42b, 0x033b0a46, -0x0f6e2fde, 0xb308ce53, 0x93eff03e, 0x8830014e, -0x5c8a6f22, 0x91d2f757, 0xf70b648d, 0x0789998a, -0xd84d4640, 0xe5f34e80, 0xf3357e64, 0xd1e2beea, -0xc7e95c3a, 0x30e57e4d, 0xec214356, 0x7e10859e, -0x1d5895d5, 0xdeeff6cb, 0xed1030ed, 0x827e603d, -0x6b4b2de3, 0x83ec6fd0, 0xa64092f3, 0x8d9887e4, -0xbefcbedd, 0x2111afef, 0xcb9abf96, 0x5c79ceac, -0x9bf8a57f, 0x5d0e44be, 0xdca3d3b6, 0x9072d1ca, -0x48e73a50, 0x8d0bc804, 0x6aea94d3, 0xc372403e, -0x00000011, 0x3b994153, 0x23faa5e1, 0xc3feae68, -0x76d5e67d, 0xbd696479, 0x138a05ef, 0xf2b5de22, -0x4ccba0ed, 0x333cc95c, 0x8d98a2ae, 0x0bf1fa24, -0x239f1fbf, 0x44701d3b, 0xb176783f, 0x20eff2cc, -0x0cf93bf9, 0x4e6ace41, 0xe346d231, 0x11d560af, -0xae8874a2, 0xe344fa92, 0x0056d268, 0xd8068d91, -0xf336cf97, 0x45c54f6d, 0xc0650992, 0xa3f86cb2, -0xc73d3aac, 0xc7654f1f, 0x385777ad, 0x20928850, -0x47509cab, 0xf40f9ba6, 0x34efbe6c, 0x1fe3b873, -0xfb39bd58, 0xa50b6367, 0x66c20e63, 0x49a4e1ee, -0xe490ed5a, 0x98c340fa, 0x30bfe19d, 0x4c17d142, -0xea54c4e2, 0x8c00e086, 0x219dee1b, 0x739a2fc1, -0x1e07b80f, 0xea6f4799, 0xb4684fc2, 0x42fc725a, -0x1d3c7413, 0x188b6f3c, 0x2c0e440f, 0xc6ad011d, -0x2048625b, 0x3be9d940, 0x0a932622, 0x1fafce30, -0x1cfa4c90, 0xd0e9f989, 0x31c0c399, 0xad0c597d, -0x48a94bb5, 0x109da683, 0xcdc197aa, 0x7bf7ef14, -0xebf3afa0, 0xde4ff7d3, 0x02a79e3f, 0x4d77f0e5, -0xd0c1fd98, 0xdb342a5b, 0x7f753eca, 0xb710c135, -0xacb3b9c0, 0x5e89ece7, 0x2ca4fe84, 0x4f22e461, -0xa6a633fb, 0x508fb453, 0xfe1f342d, 0x79bcff1f, -0x0c776771, 0xd6c5db47, 0xfe4d8cc5, 0x68b9f655, -0x447b7366, 0xddde31ad, 0x8e3496df, 0xe091f8dd, -0x78eb0fe2, 0x9e08c72d, 0x6909c46b, 0x92ca6b4a, -0xfb7a0efb, 0x55f65148, 0x9fcc90e1, 0x254f5f40, -0x0690dcd5, 0xc6a67013, 0xda2e35a9, 0x9171cb50, -0xe477a087, 0xc0f89e14, 0xc1221ebf, 0xf032e99f, -0xc8883a7e, 0xba4b17c9, 0xb0ef0962, 0x6ea751f6, -0xfc8c336c, 0xd1966bf1, 0x26d57e1d, 0x952e847d, -0xccdaf0c9, 0xd0aaee65, 0xb2f22a59, 0xc74bc035, -0x900ef42a, 0xeb1e7bfe, 0xfc465b3a, 0x0cd002ce, -0x560f5d4b, 0xecbc2658, 0x9f38856a, 0xa3f77ba1, -0x3ee18273, 0x7ab97b2c, 0x0f5843cc, 0xdb648b0a, -0x8e450381, 0x80176891, 0x05e3e6d2, 0x36593afe, -0xebe78fce, 0x53d7f64c, 0x2dde1104, 0x293cd7e2, -0x4f430fa6, 0xf3a8cdb0, 0xd28f6535, 0x9159d53b, -0xac66a916, 0x8f77be38, 0xa16b9dad, 0x1a4699d0, -0xe278df12, 0x2c336789, 0xb668fe15, 0x099fa98c, -0x4fe5ef10, 0xf4692cda, 0xb86d4040, 0xb6dce0eb, -0x6c5ef896, 0xdef35c52, 0xc02a04a4, 0xed99c619, -0xd91721b2, 0xa2fac92a, 0x5ab9c724, 0x0ee25329, -0xc2029fce, 0xc847bfbd, 0x3b97ddcb, 0x4aaaa55a, -0xa16e313a, 0x06e4b6cc, 0xc0e56598, 0x60ebfadb, -0x88841f3a, 0x7c6b65ef, 0x15542ce1, 0x70b88b78, -0x382d1155, 0xe73c900c, 0xd8b6409e, 0xf1cc5406, -0x64fc3223, 0x43cb616c, 0x17e3a1ac, 0xa9aba529, -0x8dd83b32, 0xb625cd1d, 0xbcb4b0ed, 0x685cc4b2, -0x803e35f8, 0x4e679481, 0xc7dd7591, 0xf8676b62, -0xac25b6c8, 0xb0211931, 0x5c5df337, 0x3bde6fb6, -0xbc433992, 0xf7315d49, 0x028e112f, 0xe3d59076, -0x7757e95b, 0xe5c5a193, 0x59b243a0, 0x341f33d2, -0x7c0d591d, 0x5f96d138, 0x5116c490, 0x747caf2f, -0x6da223f1, 0xcbe30d11, 0xe10b6b28, 0xa09328e1, -0xdf1b94ee, 0x163b48b9, 0x72e7a36a, 0x78eda572, -0x393f0ad2, 0xf85561ea, 0x6e7ca7c8, 0x352cb3b4, -0xb75bf9f3, 0x97ebcf76, 0x932b8b91, 0x937f1fab, -0x6ef1e868, 0xce84fc3a, 0x9dd09a21, 0xa8f3be36, -0x244834e9, 0xd871f223, 0xdef842f3, 0x787eaf73, -0xf2326bca, 0xd2c3ae20, 0x48dc7621, 0x91419afe, -0x23a44b12, 0xce0443d7, 0x4a6f1d9f, 0x1ea8cf7a, -0xb6b7694d, 0xf29e3e25, 0x51665303, 0x33581b86, -0xc762d72f, 0xaa658158, 0xcddb7354, 0xdacfd75f, -0x9ec31b1c, 0xf8aa3154, 0xfdeeb2e0, 0x9cb52f84, -0x16ce9fa4, 0x25050178, 0x2ef25d50, 0xcf4b4d41, -0xf27d5684, 0x7bae3f36, 0x05b50e59, 0x91d23add, -0xdbdee4ac, 0xe16994b5, 0x0a5481c3, 0x3deb8a17, -0xb8844d77, 0xcbce6140, 0xbd748572, 0x6531627f, -0x2137be68, 0xf46f8aa9, 0x6d2526a0, 0xe72aa307, -0xb361a2c8, 0xed9c2987, 0x75ddeb95, 0x637d3cad, -0x2c4dfd37, 0x01f0e2bd, 0xa521a1a4, 0x1194ab8a, -0x96d7b9c2, 0x94cee6e5, 0x454cc836, 0xa5c0fac3, -0xf6e9fe9b, 0x3107c251, 0x14c8c6a6, 0xd727c1e1, -0x339f2742, 0xb0a033de, 0x56fc9280, 0x36a907cd, -0xb74acdde, 0xe8122571, 0xd0116007, 0x238b3d4f, -0x34532ebe, 0x1c534370, 0xd1eb258d, 0x354b2289, -0x6007a18c, 0x58dcee7f, 0xa033ee94, 0xa5e1145f, -0xe345c315, 0x58510592, 0x33d9db2b, 0x7ea86edf, -0xce60a8ad, 0x2d9a8919, 0xb5e2840e, 0x020e6e15, -0xaff8660e, 0x402c12da, 0xfaea95a5, 0x6ffb0748, -0xc4c730a4, 0x1f57ead7, 0x2cc6d295, 0x0ef4bdb6, -0x01a7368a, 0x52e88f43, 0xf1b14c65, 0x38018686, -0x0c70ee45, 0x271b1fe2, 0x0eea950e, 0x61a6f56a, -0x842497a5, 0xfbcf0f4a, 0x35132cbb, 0x4f2eb1ce, -0x24fb1bc7, 0x343ec960, 0xda94e0a2, 0xf1206e0b, -0x80bf8007, 0x7e09d8d8, 0xba6bc1ff, 0x892c956c, -0x4ceaa5e8, 0x871f3358, 0xe802a1a4, 0x7fa29ced, -0xea8616cb, 0xc1999088, 0xc5baf089, 0xd1490754, -0x091f6f21, 0x9a3e3c4f, 0x1eb11650, 0x13fd05fc, -0x5e9d5b0e, 0xd1485d34, 0x474feaae, 0xc211a60f, -0xa609643e, 0x07052bb2, 0xa7bfb285, 0x30bbc170, -0x9ebe8d27, 0x5207a9ee, 0xfc12bd0e, 0x7fa428af, -0x2d1c8a2d, 0x6f15c0d6, 0xdaf0ee75, 0xd32bb1d1, -0x694463f5, 0xa1ebdae4, 0xeaa3d0b2, 0x954077de, -0x181da0bb, 0x4556808d, 0x46e80a64, 0x0c017172, -0xd8ef8702, 0xa0e6d100, 0x90b0a9f0, 0x4a13a407, -0xf1675dde, 0x5110d8c8, 0x1c028526, 0x7774581f, -0x9d3d8c23, 0xcaf8b632, 0xf401a52f, 0xa5d14a5c, -0xebed6c1b, 0x2ec618ad, 0x5b63935e, 0x89508732, -0x43a48b2e, 0x87535b2b, 0x0ffb28c2, 0x1fd1becd, -0xd2b2a18d, 0x45dccb4c, 0xad41a54b, 0x7ffa2fed, -0xddd18aa1, 0x1db06a98, 0x860d6b58, 0x2997109e, -0x80a2300e, 0x0cc52e7a, 0x15b24c31, 0x8f717016, -0xa425cac3, 0x8153e1bf, 0x5e91fd89, 0x04b17f35, -0x150fd30c, 0xc7309d31, 0x63dce1b0, 0x162eb854, -0x8093904e, 0xf7b4399d, 0xb23fa735, 0x67509c6c, -0x5380dec9, 0xb79172a8, 0xb6c249d1, 0xcd040b42, -0x4efe12f8, 0x63ce3363, 0x406d1666, 0xf8e9bc95, -0x99cbff2c, 0xaf0cac38, 0xe6556ddf, 0x9bb2a399, -0x43387c9e, 0x4951f5ac, 0xfa4ddb69, 0x562ec852, -0xa2e3e441, 0x32a80b75, 0xd88361c5, 0xf04b7ac9, -0xb0ea18bb, 0xf5035c94, 0x520c9c12, 0xb4c7e15c, -0x6f72c4bc, 0x80f2112a, 0x4e4bbb87, 0x7bb5ee1f, -0x54eb313e, 0x18cb6cb9, 0xca5ff580, 0x2538d798, -0x2b813681, 0x58c11a6c, 0x68ae4070, 0x40799341, -0xa740f86a, 0x722ca7ef, 0x815c71c7, 0xe663c6f7, -0x5e249b96, 0xe97e3b71, 0xb7ee5a12, 0xd5f065bd, -0xaa642191, 0x9864e095, 0x0c087780, 0x0fc0d969, -0xf6b82791, 0x04aa55f8, 0x872c7cd1, 0x43bc93b0, -0x12fe4c05, 0x16f15229, 0x06161603, 0x6e76239d, -0x90ea9c62, 0xecf642df, 0xb52a8db6, 0x2e0c5d58, -0x10f09bbc, 0x1bb1b2a3, 0x7132167b, 0x291d5f16, -0xd7814a9e, 0x79e52dbf, 0xef6b61e8, 0x585b920a, -0x18ea4e61, 0x72ce62fc, 0x59ed8e9f, 0x610564d3, -0x40f4f145, 0x0a2f60c1, 0xec64ebc3, 0x8ad5b251, -0xb471e120, 0xb899cffd, 0x2b81118a, 0xa3b591a8, -0xdeced3ab, 0xcb9aacb8, 0xba53fbdd, 0x6e49e298, -0x75fa6c19, 0xd11cfe98, 0xd29ce7fc, 0x7471df09, -0xb59b2474, 0xdff0b07d, 0xae92c4b7, 0x6414ee6b, -0x6acba1a5, 0xed9c0b5b, 0x728f7644, 0xf6d20c7a, -0xf03ad03e, 0x6612b0c3, 0xe156c417, 0x9aec4a8d, -0x02be86ff, 0xe11d1660, 0xefeba14a, 0x7d275f33, -0x16acabb2, 0x7ac99cd7, 0xd18566e4, 0x3bce4ca1, -0xb0312f16, 0x5700f72c, 0x345864bd, 0x917a4db2, -0xaa22b7f0, 0xc66eb69c, 0x62f8a99e, 0x6364a44f, -0x956d2cd2, 0xfa64b7df, 0x47238b18, 0xddebaeff, -0x39c9d16b, 0xaa1487cb, 0xc6f91d13, 0x8191316d, -0xbf5d7ddd, 0xc907cbb1, 0x7a283ba3, 0x0365e6a3, -0x2fbb3185, 0x159d0436, 0xb55b6990, 0xf0935005, -0x441e4fc8, 0xd1dfdc91, 0xdd9ff8bc, 0x95c88203, -0xa8029310, 0x62501ff4, 0xf838a813, 0xfb66d5ce, -0xe6bb8354, 0xe2afb832, 0x55dcf796, 0x315f28cf, -0x400de577, 0x3ad89b1b, 0xeee943aa, 0xbd5d9001, -0x8dd4771b, 0x21ad481c, 0x504d6222, 0xfc0e6728, -0x7abe5d62, 0x332f8309, 0x50d8c688, 0x4b686808, -0xbe6395ec, 0x5153b67c, 0x04144a35, 0xa85077ca, -0xa3775cda, 0x838556dc, 0x973c2222, 0xf5037c9f, -0xd02b0c87, 0xa3e69f8f, 0xdf68cce7, 0x9490d31f, -0x3d9c5cf2, 0x939e7823, 0xc51b9a2d, 0x2e802e27, -0x65079a36, 0x3b6e3d79, 0x5fafbac6, 0x9973bc64, -0xfc4e7124, 0x56e1fad3, 0x10ec049f, 0xefa79c0b, -0xcde48353, 0x3fa7f449, 0x07cb1a31, 0xf6ba0053, -0xe5af7b10, 0x9e2dc089, 0x290f3fa4, 0x116da472, -0x7a006f5b, 0x727205bf, 0x7c59870d, 0x968c6000, -0x3ed4fd57, 0xe423effe, 0xc352ef7a, 0xd23d00e5, -0xbded3a50, 0xedcdc3d0, 0x3a517a74, 0xbdfc58cc, -0x24b2371f, 0xf967f533, 0x26069547, 0x2114e85e, -0xa1953f56, 0xf0c52ebf, 0x235320ae, 0x35600f33, -0x5c1ca2b7, 0xe89db0da, 0x08ce35aa, 0xc66cef79, -0xacd41ce4, 0x865f4c69, 0x15a3376b, 0xdee5d7a1, -0x6fdd6362, 0xa4125977, 0xcb61bae2, 0x5e3da819, -0xc6d2e56a, 0xde1807f2, 0xb30c3473, 0x1c4038c5, -0xbf8afac6, 0x37423d2d, 0x72d9da33, 0x39e95bf5, -0xd6a91cc8, 0xbbf4c2d8, 0x7c9d4b21, 0x13c514d5, -0xcae41aac, 0x07b97f18, 0x0cdfbdee, 0xe7a9020b, -0x1839f082, 0x7c414530, 0x43ba1070, 0x95945971, -0x82e31721, 0x2fb159e5, 0x225c2158, 0xfadf74f6, -0x788387d6, 0xb40c98fe, 0x0c75ba9d, 0x0487eb2f, -0x7e9a1b0e, 0x5c442185, 0xcf1dffde, 0x39f9bc44, -0x46b961d3, 0x9a14b19a, 0xe284d2ac, 0x52151caa, -0x67f34f5e, 0xf4042d4f, 0xa28a223d, 0x3deb23f1, -0x12d14b6f, 0x18901f31, 0xb3c7950a, 0xfb7d3557, -0xb83e457f, 0xb6e13f07, 0xd26f5435, 0x83f05e15, -0xf549a030, 0x6d1122d0, 0x540b3ef9, 0x8ecdac22, -0xdabe1b2d, 0xf4913cc0, 0x579f9d77, 0xd4725d33, -0x76b7abb0, 0x03452691, 0x4d52fff6, 0x12e95a96, -0x42131074, 0xbb3eaa95, 0xb775618e, 0x6325764e, -0xeb847c5a, 0xeb7b9c6d, 0xd01dd328, 0x547269e1, -0x2cebecd3, 0xcbb0ed0f, 0xcc87e62c, 0x8e6b0ce0, -0x8a8f9f06, 0x689e0c4f, 0xb3a1fe5a, 0xed84a0a2, -0x66187741, 0x62a4475b, 0x5c4c31bb, 0xea000d76, -0x8676c757, 0xd59cc6bd, 0x52f107ff, 0x1f4a0c66, -0x7af566ef, 0x4af3586c, 0x11d5cd6f, 0x6b8bc81a, -0x480eed48, 0x2ec7c65e, 0x6c0f3253, 0x100f2794, -0x18d6c62a, 0x338f59f6, 0x8e6e2f9e, 0x75fccfd7, -0xbc80ea7a, 0xa90f1473, 0xfa9d22c4, 0x3ccdaa53, -0xe568fef6, 0x6a761fd4, 0x61c26b23, 0xabc31163, -0x3b840e9e, 0xee864319, 0x84f93208, 0x743a780e, -0x1507a3bf, 0x147dad13, 0x8952177f, 0xbeb40da7, -0x699af39e, 0x6d22bdfb, 0x5fe8112c, 0xdb3f8dbb, -0x026f8ff2, 0x6bf9658d, 0x9faabf0d, 0x6a2f3989, -0x5be4a617, 0x9e55f0c3, 0x70510d75, 0x0fd92413, -0x63d1d3c7, 0x68cf84bd, 0xbbff5901, 0xb0434b77, -0x8564b88f, 0x06eddac5, 0xde2a66b6, 0xc1835355, -0x5566bb1e, 0xbaa890cd, 0x108c6f70, 0x7e80dfcc, -0xb8c03bb3, 0x14bdcbe0, 0x5037daf9, 0xee02697a, -0x3326280f, 0x4f04c814, 0x4f640444, 0xbfa9229e, -0x131c7ba0, 0x5fbcf1ba, 0xebe01998, 0x2a813a9b, -0x3f27c028, 0xf77a6d00, 0xac0ddee5, 0x1b6e52d9, -0xdac4bb99, 0x54a32f86, 0x26bfd80f, 0xf5debd9c, -0x06536e13, 0x9498a87e, 0x3f9e8812, 0x53e0fdee, -0xc08c3c8a, 0x2148b33c, 0x3932e37b, 0xad084cc7, -0xe77a0048, 0x89addf10, 0xb2542186, 0xc4c0be6c, -0xfbc626ce, 0x20a28446, 0x0f29f8f1, 0xbbef5d50, -0x288b8070, 0x31aa2900, 0x4a538fbe, 0xcd344ca3, -0x05170c9d, 0x06c51082, 0xc414194a, 0x6689a2cb, -0x7618c884, 0x412ac324, 0xb0d952d0, 0xfb88757c, -0xaacbb987, 0x92218ac5, 0x032a3895, 0x2e3a7dfd, -0x4bb37e4e, 0x52342695, 0xa699f5b9, 0x45748066, -0x7822f59e, 0x68a55092, 0xf049444b, 0xf274d694, -0x0524ed76, 0x884c3732, 0x22fa43bb, 0x3b97d921, -0x210b8c99, 0xc4ffdf26, 0x17ba16ed, 0xfcdfc437, -0x0b8e2d8a, 0x7b019bb2, 0xd525e662, 0x03346249, -0x7af3c1cd, 0xbf42dbac, 0xb6197a31, 0xebff8e32, -0x84f9980c, 0xa225a4b0, 0xa9f3d94d, 0x8a3da052, -0xc17241e7, 0xf133ce7f, 0x4d4542f0, 0xd884f2f8, -0xa1633ebe, 0xd5c5e6e5, 0x7fce2fca, 0x8ad84a55, -0xfdd96c9f, 0xa60d6f4f, 0xe025d2f2, 0x8be1b787, -0x87a036a7, 0x23819cb9, 0x5967650e, 0x5d549108, -0x57167175, 0x2f94c450, 0xbb536b04, 0xfb381d15, -0x405bd359, 0x3ef9491b, 0xa9834cb1, 0x2cc5151c, -0x148cd3cd, 0x0565ecb0, 0x8e596741, 0xf6d7f089, -0x9e3524fe, 0xf4224e20, 0x583302fa, 0xebe46409, -0x7bfe793a, 0x7d511902, 0x1e4a80dd, 0x53a280cb, -0xa2d81d96, 0xe29b8f4e, 0x877789e5, 0x838ee539, -0x35f9feb5, 0xa5bb1d43, 0xb24d7510, 0x67cd14d7, -0x7cfac97e, 0xf6c72b9b, 0x302f9115, 0x1932060c, -0x0a786f90, 0x85a88dd1, 0x322ef274, 0xb0f8af47, -0xbb5e6bfb, 0x3f1505c5, 0x33b28086, 0x18025326, -0x73293fb1, 0xbd813762, 0xad751414, 0xd533bccc, -0x393b81fe, 0x5b3b79e3, 0x2221dc65, 0x4bf8124d, -0x26df557e, 0xcb9320a3, 0x9e6e762f, 0x2a800bbf, -0xbd30558c, 0xc6b2ebe7, 0x204b2c78, 0x3e55767c, -0xe8dca1c3, 0x74f53ec2, 0x6cf84866, 0xa81afd41, -0x96b192bd, 0x8a4cb44b, 0x7761db77, 0x0ba97dc7, -0x374256d8, 0x9d11f228, 0x4135e235, 0x4ebca1ed, -0x339af391, 0xbf656129, 0xa8e362b2, 0x8ed470b3, -0x88405f8c, 0x285b7b3e, 0x1098ef48, 0xfdf3a059, -0x1472f471, 0x402079de, 0x531c86f5, 0xe267b1d8, -0xa5dd94bf, 0x4659558a, 0xee6ebad7, 0x3f90fd4f, -0xa16b3fea, 0xa89ff7e3, 0x2bb842e2, 0x6352305a, -0xbf5caa7d, 0x247738c8, 0xb3463b13, 0xacf9e658, -0x2c186efc, 0x3d10d5f5, 0x4aba3167, 0xe3c50980, -0x62584b2e, 0x62bb0b9b, 0x728bfbbc, 0x5c4392df, -0x3e9d9ca4, 0x66d7cb6b, 0x3795fbda, 0xfd57060e, -0x1f14ee11, 0x7ca5c691, 0xd45606d2, 0xee8aacc3, -0x5e58e64f, 0x14539605, 0xacf9940c, 0x5aea1d0e, -0x1abd48aa, 0x531443b7, 0xc877270c, 0x3cb0fc56, -0x06fef541, 0xc82d4e20, 0x2850164f, 0x976d3800, -0xf49bf720, 0x4441f680, 0x47ace05d, 0xdf6613c3, -0xe326ace7, 0x65434171, 0x99f32f60, 0x8e74748b, -0xa345f78e, 0x7ed8882f, 0x18147a58, 0x0f88b600, -0x87511a26, 0x0421d011, 0xcb18e24d, 0x3b9d1f91, -0x2eaf943a, 0x7d1954a8, 0xc9ca788c, 0x9bd0b50d, -0x345cbf85, 0x5f15c80e, 0x4e688a4b, 0x85cea5b5, -0x6c4858c6, 0xd511c3b7, 0x60c4dccf, 0xf0e203c0, -0x66725a5a, 0xa1cdbb6e, 0x1050f46d, 0x9349b556, -0x21f7ae54, 0xcaec7ac3, 0x60d78f75, 0x70a1b6eb, -0x35663cdf, 0xa995cc91, 0xdc076d61, 0x838bcdf5, -0x351bba87, 0x525362ed, 0x30f74979, 0x95e1b1ff, -0xcb855936, 0x031f6d10, 0x6a499f0b, 0xac0b7909, -0xca741d8c, 0x6be27fa9, 0x0aab5c9c, 0xa167bb23, -0x77e81960, 0x32e08b0c, 0xcebc1a19, 0xb4c16851, -0x7c062b03, 0x0bb891c0, 0xeaaeb569, 0xcd44b2a6, -0x21202023, 0x150ea8e2, 0x59186783, 0x318ab582, -0x09ed39dd, 0xf60982c4, 0x37d47336, 0x437da9fd, -0x1d710edc, 0x621c5b61, 0x3ef57dff, 0x955c7f72, -0x2b26a727, 0x3edd94f5, 0x150d7200, 0x55089618, -0xb56e6c4d, 0xa4deaa5d, 0xa3597762, 0x9c5320af, -0x635127cf, 0x59cb5391, 0x93ab2255, 0xae245934, -0xd618c84a, 0x2f35cfc2, 0xd0f061f1, 0x89853b8b, -0x025b054d, 0xe6d93f9a, 0x3adc0b16, 0x84fae023, -0xb7633864, 0xda51d106, 0xbbff09a4, 0xd5b9d78d, -0xb328e13d, 0xa96a350c, 0x9950512c, 0xff9e0ef0, -0x7c35497c, 0x9f926f22, 0x21049558, 0x2beecc60, -0x3e2e9bf9, 0x5639847e, 0xd619a13d, 0x4e583906, -0x10df8249, 0x56e7e8df, 0xd514d3eb, 0xd0acb620, -0x64fcfa06, 0x2579bd35, 0x75bfd73d, 0x3749e0bd, -0xccfe92cf, 0x27d80baf, 0x1ce9155a, 0xd137af32, -0xfbc1a48f, 0x55f823a8, 0xc881bff9, 0x10667a5a, -0x9ddb4cca, 0x7a130ee0, 0x1f936bb5, 0x97900b6b, -0xa5c120be, 0x0e5bd07a, 0xb6d55095, 0x64b9ee81, -0xbe3880f4, 0x7298b54b, 0xca023019, 0xc04350c1, -0xd9b65a0a, 0x497773d4, 0xe114aff1, 0xc20a9812, -0x4093dd5f, 0x4a763172, 0xb81ea793, 0x4f1aa963, -0x133d5b74, 0xbab2b93e, 0x475c6e06, 0x6bce797b, -0xf0dde898, 0x0c154806, 0xf8aba3ea, 0x9f900b3e, -0x5616d3b5, 0xd77f47e3, 0xeea5452c, 0xf06a6573, -0x52ad35dc, 0x841d2ce7, 0xc0d9fc67, 0xae2a50f2, -0x68770060, 0x72e75b45, 0x3811c15a, 0xddd4d732, -0xc0cdee22, 0x72f2968f, 0x6483ba86, 0x97968042, -0x693e9be4, 0x9832f05c, 0xdf622948, 0x127f360a, -0xf364ca2b, 0x4bb883ee, 0x282dd695, 0x6aa679e4, -0xa71f6a9c, 0x91988331, 0xd5b30591, 0x67994077, -/* 3194-m04206e6_00000002.inc */ -0x00000001, 0x00000002, 0x12082009, 0x000206e6, -0x92caf080, 0x00000001, 0x00000004, 0x000017d0, -0x00001800, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000002, -0x00000000, 0x00000000, 0x20091208, 0x00000531, -0x00000001, 0x000206e6, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x554d7ed5, 0x669e080e, 0x7b6530af, 0xbd691191, -0x414675f8, 0x71ac9d1c, 0x76196264, 0x79f54e78, -0x6436118f, 0xe83b26fb, 0x89e2d93c, 0xebb749ab, -0x0190d468, 0xe584e6a1, 0x28772386, 0x0d0ebcca, -0xb4f014cd, 0xa5890101, 0x11d7d636, 0x9aad0a93, -0x0910ce34, 0x6821000b, 0x2bd997d1, 0x29cf7e21, -0xeb3c278f, 0x440488fb, 0xf860c513, 0xf88bf0da, -0x3d416f98, 0xce6c8f70, 0xd7115a85, 0xf6a1b31f, -0x33dba23d, 0xfa8b79fb, 0x26ad1822, 0x6c4e9dcf, -0xe6371cdd, 0x783c0a50, 0xdc3504bd, 0xda13c17d, -0x17a558ad, 0x026e352c, 0xd26213d7, 0x55e16644, -0x4fa2de6d, 0xa8ca6c51, 0x4b21340f, 0xb94bbf0f, -0x6872b7b5, 0x37d60b5e, 0x215002eb, 0x15392b63, -0x29583544, 0x3058eb2f, 0x5f6c0dd6, 0x20804929, -0x537b57e5, 0x5587c2c9, 0x48757ebb, 0xf49d77c7, -0x20e10d60, 0xd33817d3, 0xdd042189, 0x6872f19a, -0x206221ee, 0x32728ca3, 0x8f8cc0fd, 0x5a411550, -0x4b9e55ff, 0x362fb7e9, 0x25942339, 0x8e8a0516, -0x00000011, 0x6129e1cb, 0x40b107ac, 0xa182f2ae, -0x862688b8, 0xf5d79270, 0xcc062ef3, 0x2d63e650, -0x620c4fd9, 0x7d26788d, 0xda8856a9, 0xcd2e7f25, -0xf028c1db, 0xc9b5b19c, 0x9cc11d1e, 0x17fc4eb3, -0x083a55c1, 0xf95d5018, 0x0e7fc362, 0x27e4a3d0, -0x9daf9dbd, 0x6b1c5b8c, 0x75a7157f, 0x14d0805c, -0xd8c38e23, 0x87767f17, 0x9317961e, 0xd3d4249b, -0x11346e7d, 0x06077b83, 0xdee3b48b, 0xac1be5aa, -0x9481a06f, 0x69c628b0, 0xb64cc045, 0xc3887b67, -0x7034da0f, 0x7c47df75, 0x4d8b0936, 0x5f1b0c15, -0x41e4b6c1, 0xb5fe086c, 0xf268d26d, 0x6baa2515, -0x553a544c, 0x7c641177, 0x9a8037e0, 0x9b92c8c2, -0xf5e8a4d6, 0x9d692beb, 0xadb877b3, 0x4a938122, -0xc1ddf270, 0x981e02e8, 0x50d458e0, 0xeb33ad57, -0x9bf9bb65, 0xc4146e7d, 0xfd88b0b5, 0x3acfff82, -0xb38d3e1b, 0x5d06af54, 0x2d2b5720, 0xa5562b09, -0x0808e16f, 0xbd185839, 0x99487a39, 0xd2a9d6c2, -0x5426e7f9, 0xb954a952, 0xc7a6f80c, 0xe05ad340, -0x8a5d3200, 0xfb1615f3, 0x4ee7c429, 0xf8c81a07, -0x86aee293, 0xa95b53a3, 0x62ec8ab9, 0x34babd11, -0x9ed772d5, 0xa59c08eb, 0x2bdf85ad, 0xaf26bc34, -0xc3507e71, 0x6796ca9f, 0x3b734539, 0x7299eaf9, -0x9f25a5cf, 0xbf053f8c, 0xafbb9d66, 0x1d3ba93e, -0xeb7ab63e, 0x51043286, 0x683c6f4e, 0xfce2aa3f, -0x7154da69, 0x9a43da0a, 0x3fc405fc, 0x5bfc4ff9, -0xb477fe0e, 0x1bed77d1, 0xe098924f, 0x426b1249, -0xac8d6002, 0x730d00f4, 0x5f7104c4, 0x8ba591ba, -0xbd52da74, 0xd36deee2, 0x8157fb13, 0x95159b55, -0x8daa3b7c, 0x00ded644, 0x43aec14c, 0xf86eae7c, -0xb0e168a5, 0xc20552d3, 0x29f94c9b, 0x22b69379, -0x81eb9065, 0x4d4a793e, 0x0d95d727, 0x8f53cf6c, -0xdb500369, 0xa5622333, 0xe8fe9beb, 0x211a7a71, -0xc836b921, 0x14d417ea, 0x580f643c, 0x30353194, -0x14c07baa, 0xbb453eee, 0xb6fef6c8, 0x985e35d4, -0x653bd701, 0x6e965c2f, 0x445c2e7b, 0xbe5b8c57, -0x79221999, 0x9c3db252, 0x02d6155e, 0x3d5482d1, -0x4440002e, 0x60fe8ce2, 0x93c25834, 0x6f88b4e3, -0x861fc9f5, 0xef028cab, 0x6ea4e2ca, 0x7c1ebe6a, -0xd9e89820, 0xf2d166f4, 0xb2fdc39b, 0x75d5ac84, -0x9a1d2ad6, 0x20d41e50, 0x83b071be, 0x11600584, -0x1147ef9f, 0x5bcc3535, 0x0b87a0e3, 0xa3f07a2a, -0xa598a091, 0xec9b2001, 0x8804aa4f, 0xa0fa9727, -0x30f52dda, 0xb7252273, 0x9975c075, 0x900cc829, -0xcdd22025, 0xb6e76468, 0xd5469557, 0xd8059a5d, -0x3e7734dc, 0x7f896a73, 0xce0cadb1, 0xf40c932f, -0xca215284, 0xa0c7cc46, 0x2f814498, 0x9ad8370f, -0xfafe33f8, 0xf24c7bb7, 0x0f0fd1e9, 0xccbf403f, -0xc5866e7e, 0x35db462e, 0x90560362, 0x06c03fc1, -0x424aae88, 0xc7c1feb0, 0x72d95f51, 0x89ceb78e, -0x0dcf2053, 0x99152843, 0x04f8a363, 0xd4437b86, -0x7821687c, 0x29e970f3, 0x18fb54f2, 0x0cfcd17d, -0x66986e2d, 0x427e4ef7, 0xc689d398, 0x24ca9ba9, -0xf18ce741, 0x04c038ec, 0x9f4b7156, 0x98634873, -0xe124ec04, 0x2f141657, 0x77496d39, 0x66c56fd0, -0xf04fafc0, 0xbb597f92, 0x7879f39d, 0xa5f875f7, -0xeb57e6cf, 0x13026c82, 0xf2e9f5d3, 0x97aa1899, -0x9733c606, 0xa2152c29, 0x72a51621, 0x43f8728c, -0x533c1a7a, 0xa5ace4ae, 0xcf0a1e7b, 0x2143ff28, -0x01dde13c, 0x7715315d, 0x532781f3, 0x964244b7, -0x776fe7ae, 0xf8bd455c, 0x415cd20c, 0x34f7d0bd, -0x77453f4d, 0x023a9f2a, 0x22c9b5ca, 0xf8d6d4b2, -0x06326771, 0xe030b438, 0xc4cd01b5, 0x8c80c103, -0x25baaf97, 0xe830044f, 0x5cbdc2ad, 0xc2552072, -0x060d9e89, 0x44a1c833, 0x09d9dd0e, 0xa967b0a5, -0xb8e92779, 0x283e0404, 0xd31795ca, 0x9e5610bd, -0x4669e5b9, 0x8795d86e, 0x0852fe0b, 0xd4ec32ad, -0x68d7ea10, 0x79efd968, 0xfe7a65ed, 0x63df8546, -0x16ee816f, 0x9e1278ec, 0x43164d5b, 0xf704c2cb, -0x1ef62eb9, 0xf9029d24, 0x582401fd, 0x05d0ee32, -0xa9973044, 0xceec4cd9, 0x3384282b, 0x6be257ea, -0x3f3c0f99, 0xff758c4b, 0x620e4cd6, 0xa047e4e9, -0xe1d7d065, 0xc282825b, 0x46ffe5b8, 0x43ec99dc, -0x8b6d30fb, 0xe4f2b2e2, 0xdc7a9ad9, 0xb458a033, -0xf7647c44, 0xe55dd454, 0x6f947c99, 0x07e3f13d, -0x25aa6cc8, 0x3f34c943, 0x98f09a43, 0x35db6af1, -0x9bb18fff, 0x060ecdc4, 0xa5c41f09, 0xfdc076c2, -0xed849561, 0xa3aa672f, 0x113e142f, 0xac5200e6, -0x2d261183, 0xf4364afb, 0xacdb0c01, 0x151aaf33, -0xf365431d, 0x3f5cb13f, 0xc1b92d13, 0x32398234, -0x35fd68b7, 0x9b5778a9, 0x450a8ab9, 0xea43da58, -0xed69c047, 0x274bf7e0, 0xde38d8f6, 0xe1875914, -0xdd2e172a, 0xff433cee, 0xdf918c11, 0x50c6719c, -0x65930485, 0x86c8c097, 0xe505a0e0, 0x54726eca, -0xc22284ed, 0xa3f0057b, 0x572a6ae7, 0xcb4cf730, -0xb46b5de4, 0xb843a551, 0x1f6ef73f, 0xa29e4c78, -0x5cde3614, 0x5cdfb859, 0xbdb4c913, 0x25db064e, -0x9476624d, 0x8d4e690c, 0xc64dc8cc, 0x09e38429, -0xc30742c6, 0x8edd132f, 0xbfef6262, 0x15c32709, -0x040f7740, 0x753c93a1, 0xd07cc44a, 0x91cbaedf, -0x5eff71ea, 0x92fd9336, 0x1a799220, 0xeda3b0b9, -0xf92e0ad0, 0xe870ca9a, 0x8d594bf6, 0xb73361c5, -0x60c59f72, 0xad9ef497, 0x589013d7, 0x760ccd31, -0x855837f9, 0x82abce31, 0x97fd5ad7, 0x5394b26b, -0xa26a2862, 0xcb26a88e, 0x2c7b5dab, 0x6af48382, -0x8e42eb40, 0x3c5f0c88, 0x6f1f1e19, 0x7e495d8b, -0x213137a9, 0x9876d828, 0xa0c66b87, 0x841e6142, -0x7c74e962, 0xdb0b0592, 0xc5d6e8c1, 0x27dfd48a, -0xd2e74095, 0x43fc1d4f, 0x33620fbb, 0x6b6709d4, -0x512c6d19, 0xa438f824, 0x4349cee7, 0xebfaeec5, -0xcd6820ea, 0x9a0672ca, 0xd2ae7771, 0xd5f5003c, -0xe5f34699, 0x5db3e190, 0xf07f5548, 0x7327b8cc, -0xbb4cfadb, 0xed5ee12f, 0xce8202a8, 0x784c9b43, -0x01d74861, 0xd1615b50, 0xf3248d42, 0xef29845f, -0xa00dc511, 0xe08c9a74, 0xf1f48129, 0x7e27dfd0, -0xf6825199, 0xc343b2fd, 0xbff5e539, 0x8fdb0584, -0x92553ce4, 0x0ef81132, 0x5afe55bd, 0x178b3e49, -0x448cec17, 0x57a83b11, 0x5ec6ba98, 0xed8c111c, -0x47c6f4af, 0x152fb172, 0x81781a4e, 0x0828d0c0, -0x99c8087d, 0xa08b8eed, 0x93682960, 0x768290d6, -0x58f2ffc2, 0xac099648, 0xbe4a13d2, 0xff42a909, -0x841c509b, 0x9c51787d, 0x3f894c6f, 0x5d7e1a8d, -0xe75f3538, 0x6364c0e0, 0xc3d1d1ac, 0x67e070f3, -0x9d973d81, 0xa4fc560c, 0x94875219, 0xe909dc6a, -0x9173aeb5, 0xf165b058, 0xc6c9063f, 0x2bb729f0, -0x91f0f61a, 0x28f89c1c, 0x840acf32, 0x11aa9996, -0x112d28ee, 0xc72d6d72, 0x523ddf29, 0x1858c7f6, -0x0de480bd, 0x4a76a201, 0x5bf89c7d, 0x49828410, -0x5b21f665, 0x06aa3ce1, 0x52809a7a, 0xce91b1fb, -0x2b29572b, 0x8bead63a, 0xac80af8f, 0x18acd8a1, -0xe8a76108, 0xdc57c4c5, 0x84f3d246, 0x90dbc01f, -0xb6ec29c5, 0x7ddaedcb, 0xb6d8e739, 0x7a76806f, -0xaf820198, 0xec3485dc, 0x6061e65e, 0xf7719e55, -0x56c50ee7, 0x229f2e49, 0xbf0ea8a5, 0xebff1402, -0xee1c1da1, 0x6fbfc351, 0x893c99ef, 0xe5d00111, -0x772c6f14, 0x24a361b3, 0x3d16a93d, 0xa6841f4c, -0x283c0a13, 0x22b1f80f, 0xf920a271, 0x2fc563b2, -0xaf0ab355, 0x50f1c520, 0x378f6077, 0xa2ee2099, -0x1f371660, 0xdc50baf9, 0x4802d882, 0x852bf860, -0x5dd1371b, 0xc5a8e850, 0xf522d7ce, 0x30b139e1, -0x9f34739e, 0x12bc8cc7, 0x441ee88c, 0x356874cc, -0x10f8dd8f, 0x0c278679, 0xa239daac, 0x2838b951, -0xd3388084, 0xf882d4f4, 0x24cb5932, 0x420d492f, -0x52c3af03, 0x76a89c0a, 0x77128133, 0x8b868951, -0x53a08411, 0x55abc0d0, 0x4388dd84, 0xbbc7e67c, -0x792ded03, 0x7dfd60c0, 0x4b643e0b, 0xc748082f, -0x5ad760e7, 0xb7289d63, 0x8bac1b49, 0xe08ecf99, -0xca0aa34e, 0xd4cb5709, 0x8ad390fe, 0xa63a99be, -0x0ec8e3ca, 0xc0cca548, 0x6c6db302, 0x222ff202, -0xdd437d25, 0xeb2ef95f, 0x5d5969a3, 0x942f34dd, -0x32177e7b, 0x6e29118d, 0x17ef7b59, 0x2f6544d0, -0x7a9a7717, 0xb4e63681, 0xd2577ed4, 0x6f6c3359, -0x86bd78fa, 0xaad2ae67, 0x0de6398d, 0xb825a772, -0x5d24e0b1, 0x783c4522, 0xd1f65a6c, 0x2fc65f5f, -0x12e1a2e8, 0x0f902638, 0x112af134, 0xaf62ac20, -0x1ab68581, 0x4a4f5186, 0x8511adf7, 0x411fa38d, -0x4947af72, 0xe1a88d14, 0x8a1f3ed1, 0xb48156a5, -0xb128e8dd, 0x45bc7403, 0xe2e81675, 0xc95fc501, -0x524a54e0, 0x6cb35b52, 0x59a94c9f, 0xf6cdb321, -0x786e7c96, 0x23021087, 0x735a91da, 0x19f10d43, -0xc75f9473, 0x81e7dc62, 0xf3b081e6, 0x3ad27eab, -0x703df5ea, 0x0b7b0d5e, 0x4d0e5b59, 0x009e87b1, -0xb7629a50, 0xfda63bac, 0x54498b72, 0xc9d5404a, -0xf99c0c6d, 0xd49ded94, 0xcd5b2058, 0x340810ab, -0x58c1122d, 0x63f7d98f, 0x89dee5db, 0x026555d3, -0x6538d5f4, 0x6ecc2997, 0xc8ce8475, 0xf1a7bb56, -0xef1a77f0, 0x8f2e5426, 0x57b3e7b8, 0x50fd3896, -0xfd091981, 0x2a1534c2, 0x55d98072, 0x63162b57, -0x7bb17260, 0x095a3e11, 0x6e502413, 0x6e6aafce, -0x96f2cd21, 0x89b84c00, 0xf23b84ef, 0xa973c772, -0xee4d301b, 0xd6d7f0e0, 0x16a57339, 0xbfea860d, -0x9bb2ba28, 0x7acc3057, 0x4073c7c7, 0x6f4ce9be, -0x40e112e1, 0xc0aa34b4, 0x04e630e2, 0x075eec01, -0xf544acbd, 0x5e3d7eec, 0x86fea288, 0xcfc550f8, -0xf29141fa, 0x91865e06, 0x3372c6fc, 0xf512123d, -0x30b8af30, 0xd71b9d0c, 0xca8a8946, 0x56687ce6, -0xe1ac13f7, 0x7769d6c2, 0x6a83c6f9, 0x3abd1108, -0x633eebb0, 0xef21ae47, 0xafdb089e, 0x078b97bf, -0x6bc92ce4, 0x84b90540, 0x1300d07a, 0x56751c23, -0xadb3eef7, 0xce9ed354, 0x7594634e, 0x4e1d2b8e, -0x4d29965a, 0x4069f43f, 0x3497e55d, 0x43a661ba, -0xdc6821c6, 0x2ba52b96, 0x99af90df, 0x023d1fc5, -0x5acf16c8, 0x7c24ee42, 0xd9c84b0e, 0xc40ff495, -0x3b3b2225, 0xc21fc09c, 0x8185bb49, 0xd0d53dc0, -0x7556851b, 0x3d9a554e, 0x96c933d9, 0xaa41803f, -0x58f4f4c0, 0xcb28536e, 0x6bb68e7e, 0x9601d174, -0x0d772e1b, 0xbff231e1, 0x81664807, 0xe11fe2cd, -0xc8a6e467, 0xeab8bad0, 0x62062c51, 0x8807b5d7, -0x095be2df, 0x459ad62a, 0xc5d690ca, 0xbce11e91, -0x389239fb, 0x6f9b8958, 0xbaff8885, 0xd2e9848c, -0xdd92a915, 0xf2926b10, 0xe1d3711c, 0x38736a72, -0x89a0d3d3, 0xb37bad91, 0xae8efdc2, 0xcc405275, -0xaf232a54, 0x54c0df1b, 0xce705583, 0x8c3d7558, -0x4ded5319, 0x4ae97a02, 0xd2022787, 0xcfea8758, -0x2ae0b9c2, 0x2b17400f, 0x8b809b27, 0xd27a84c6, -0x78421d7e, 0xc26ed1dd, 0x1627a125, 0xd3fd4686, -0x0a6e779c, 0x3b102092, 0x8e764307, 0xac3b1655, -0x2ca00169, 0x9edbc814, 0xb23c3b6f, 0x8f144164, -0x4272c023, 0x07e96f44, 0x3d3bcba4, 0xe39ad519, -0x69aa2940, 0x1d873298, 0x66e434de, 0x4f53cfc5, -0xae612176, 0xbf27511a, 0xbb9d76d3, 0x30cad9a0, -0xf9059e19, 0x7d1b4bd3, 0x4660ee1e, 0x9baa20a4, -0x44715734, 0x27f84a90, 0x1f637019, 0xcda00548, -0x638b359d, 0x70e6d0eb, 0x9f7a3445, 0x9c58eeb9, -0x4629dd35, 0x7d3dfd6a, 0xb63978c3, 0xc86bd38b, -0x19cfc8b0, 0x7e452b8f, 0x641c7a94, 0x5ea38d97, -0x481f99f2, 0x39759fe3, 0xc5ac883a, 0xf8d54fa1, -0xc6e4a7ab, 0xe0a61ec1, 0xd5f20ca0, 0xcba1299b, -0x6a087622, 0x50742ed1, 0x41eeebe5, 0xf765a1d4, -0x26809efa, 0x69acc7c2, 0xb43bdbfb, 0xff9e0ea2, -0x74190d50, 0x31b12172, 0x39c11437, 0xb2387bad, -0x14dbb387, 0x14fa6f1e, 0xc75a8aad, 0xc5901e5d, -0xe1f39099, 0x79a705b2, 0x7a1bc1d8, 0xb0239742, -0xc4d61f5e, 0x4281755d, 0x6677c59e, 0x1279fe7a, -0x8e600645, 0x742c0dad, 0x44b35ad3, 0x651acbb4, -0x15164cfd, 0xfd639979, 0x15ed042e, 0xb598989b, -0xed1b545b, 0x28b8f80c, 0xe2be1b03, 0x158a667e, -0xd3609acb, 0x939282b4, 0xb077d1ad, 0x621baf5b, -0x69897556, 0x55e35da7, 0xedef719b, 0x44d55422, -0xc16d7193, 0xcb889bef, 0x6811d959, 0xa74e01f0, -0x0345032a, 0x14ba60f1, 0xe9249298, 0x67b36858, -0x0db5dba9, 0x78ed7133, 0x15e8dd54, 0xf291a062, -0x53e5c77c, 0xc4c23721, 0x303a2eb6, 0x36929489, -0x2151048b, 0x3cb6d287, 0xf69c52ac, 0x5387e014, -0x96ff36b4, 0xf3b693ad, 0x7b617543, 0x765add92, -0x9b9a48b3, 0x1d3b2626, 0xdb098502, 0x802c1654, -0x0aa89f92, 0xb9a35605, 0x5ee8ac95, 0x26497fe9, -0x5a415b56, 0x4fb34497, 0xaeabcb8c, 0x1ef526e5, -0xad6a3a7f, 0xd8b5c98f, 0x9a268b0b, 0xb5138c2e, -0x46353834, 0x4d34156d, 0xe67641a8, 0xfd8cc38b, -0xeb341a69, 0xe9368209, 0xef2d9e05, 0x3696c73b, -0x6c2de6d4, 0x3b34627a, 0xd37956b3, 0x4bcafa44, -0x6145bb6f, 0x1ce34259, 0xff952128, 0x102da75a, -0x2db2d136, 0x3f4950ad, 0x5840cdb6, 0xf770f7a8, -0x82601fe9, 0xd99e4e01, 0x8fffda37, 0xb762da16, -0x72de7bc6, 0xf4dd8644, 0x1d47249f, 0x930432b1, -0x48750076, 0x67a8950d, 0x8b3bf536, 0xc0787062, -0xb45d7136, 0x135d9e24, 0x84bfb72c, 0x6f4e458e, -0x7950c6de, 0xbf3d2dd2, 0xd6e70a3b, 0x2b4363c3, -0x43575d37, 0x7cd0492d, 0x23e4ec51, 0xd3a9f7ab, -0x038c67e2, 0xf8212d2a, 0xea8b7874, 0x6e104927, -0x74d00992, 0x14f0ef55, 0x538ffd7b, 0x7de74a3c, -0x38d460a9, 0xa0f57d10, 0x4fbccd20, 0xe4629294, -0xeb46e210, 0x1bcbe9a6, 0x3a7556f4, 0x32e48117, -0x3484900e, 0xa36c2dbd, 0x26d89101, 0x3dee6046, -0x4347a18e, 0x984dd723, 0x35608142, 0xdae1c344, -0xa5c54cb7, 0xcd8f3d1e, 0x488c5bb6, 0x1f496718, -0x483bd314, 0x0552b160, 0x2f6c4ccc, 0x2c445ec9, -0xac0f34c9, 0x6ad5cab9, 0x21ca0c72, 0x4648b778, -0xedcbf4c6, 0x54f254c6, 0x97bd05db, 0x932d5012, -0xb33ed2a8, 0x7812a829, 0x760fa8d1, 0xe72bec38, -0x98537d0a, 0x47d1b9d0, 0xd7a338a8, 0x61722b42, -0x86d3a9ef, 0x7ff308fa, 0xd6748911, 0x5740487d, -0x9aadc786, 0x2038f449, 0x8f5ce2d3, 0xce133a28, -0x88732089, 0x0e7fa13b, 0x1fda4809, 0xdac91f7e, -0x6f57e545, 0xe843ab02, 0xc6642aeb, 0xb906be1c, -0xf1270fb0, 0xf8458464, 0xd9930cf9, 0xaca44c73, -0x2a26b047, 0x4d87c6f9, 0x1ed2e7a4, 0x3b2f974d, -0x5dbd880b, 0x89dc59d9, 0x764533ec, 0x5ce2061e, -0x8624da81, 0xe41647d1, 0xae46402e, 0xb8dc2f94, -0xf7868865, 0x5c2b8f31, 0x65be3883, 0x954cbec0, -0x4175caa2, 0xec4ddefa, 0x2d9fb2bc, 0x6ed39ea1, -0xf3b3db18, 0x5d8356b3, 0xb0dd19e3, 0xd9db0c07, -0x8d7b23f4, 0x02a67a43, 0xed3c93ee, 0xb17fe2de, -0x65a8bcf5, 0xd2dd7224, 0xfc65bd45, 0x17968902, -0xf1037747, 0xe62c1b76, 0x99d7bff7, 0x69f7ac49, -0x59166663, 0xad59efbe, 0xec1cb532, 0x20e8fde9, -0xc62b4428, 0xc62a6531, 0x65a84a2d, 0x4ad6b3c9, -0xdcc00d9e, 0x40e62b1b, 0xe8153099, 0x764b4179, -0x9d0e8cdc, 0x09f4fbc3, 0xb015f775, 0xb1a27b93, -0xf548b696, 0x5c06d72f, 0xfc5478c1, 0xf75a0005, -0x0f695f00, 0x14029bd8, 0x03729143, 0x40a36c7f, -0xb989a5df, 0xe563a5f0, 0xed0c18b9, 0x7fc48224, -0x2c0fb64a, 0x4be8a77e, 0xe97dafdc, 0x86770b89, -0x24522fa3, 0x259e9722, 0xebedb4a6, 0x8adcb9bf, -0x9845352b, 0xaaa58937, 0xe433a033, 0x5f100b9f, -0x2db37194, 0x5af49e8c, 0xdff0304a, 0xb558ce36, -0x8cbb8cbd, 0x1d91e775, 0xfa1b211d, 0x7a5cf3e5, -0x739df627, 0x3c916993, 0xfa9d3e12, 0xb2922286, -0x76db6342, 0x01f11504, 0x65b150ff, 0x054a3238, -0x69adf366, 0xb8b7e381, 0x980473b5, 0x5baa69f2, -0x1a2973b1, 0x11714c6c, 0x9ae3eefe, 0xe08cd922, -0xbbf70110, 0xdaf59e71, 0x97f57ada, 0x2fbf39b2, -0x770fa307, 0x49bba030, 0x157432b4, 0x927d3b50, -0x188368cd, 0x066c03d4, 0x1968917e, 0xf54a7f23, -0x840e23de, 0x1f86e1e8, 0xfbe5423b, 0xd92e728d, -0xf7339cc0, 0x0793bfbf, 0x1345790c, 0x78831c12, -0xd073a632, 0xee46e12e, 0xfc6bbaca, 0x82933016, -0xc1451b06, 0xf0ce900b, 0xecf032e5, 0x815ec68a, -0x375fb2fe, 0x64978673, 0x689fd6ac, 0xec321655, -0x33ca924f, 0x18501c0f, 0x4b432d1f, 0xf487650c, -0xd40b49c6, 0xbbca0436, 0x8baeb737, 0x8c1e28de, -0x3c2df1e9, 0x6e19d6c0, 0xc8d1ed83, 0x6bce874c, -0x68012a7d, 0x479b4183, 0x9ec9490f, 0xa3826382, -0xf7136b0a, 0xdc1a909b, 0x1fd937cc, 0x379da706, -0x74aa7c07, 0x8d71937f, 0x648c7109, 0x77868eae, -0x65112e59, 0x3d567c68, 0x510dc5b6, 0xb5639c87, -0xf0ade679, 0xc99ec812, 0x6adf0eab, 0x8dff085c, -0xd55360e0, 0x2bbb024d, 0x52466acb, 0x47079d06, -0xf66957af, 0xa595a4c7, 0x78d6d666, 0xa7fe3a67, -0xc7f07d7f, 0xeaf9b84e, 0x692764de, 0xca7e4a9d, -0x0295376b, 0x9dfe2751, 0xeb5f886c, 0x0964c441, -0x2bd6bd07, 0x1d6cc3a9, 0xcfc80696, 0x5df9033c, -0x2a36b8c7, 0xc261698b, 0x2297a98e, 0x13eef5ea, -0xc9df5f48, 0x9f667b0e, 0xe4e16bd6, 0xb50b7a21, -0x43817fc4, 0x15ef7923, 0xebeedeb3, 0x2add983e, -0x15a9d1b3, 0x9036490b, 0x31999dd3, 0xcc235217, -0x2e10e5c6, 0xf6775a2e, 0x6cb46269, 0x005dedb8, -0xd8e80e31, 0xe883698b, 0x323d5f9e, 0x9ab9f075, -0xe2483bb0, 0xb5d4802d, 0x93861885, 0xc68f0c94, -0x2e13c223, 0x54420300, 0x337864bf, 0x78548661, -0xe80f4f10, 0x0bba1493, 0xc29365a3, 0x7540f33e, -0x86e30abc, 0xb14c499f, 0x542107e9, 0x8ed29306, -0x13b5b609, 0xc6b90c75, 0x049d1c04, 0x97c84c44, -0x18a4f8a4, 0x55b50066, 0x4c495844, 0xcb6e4279, -0x390f93f3, 0xc6790045, 0x28f5cc56, 0x0f61d205, -0x44d99188, 0xf67e0b42, 0xa6b14e50, 0x1571f7da, -0xd38ff4b0, 0x58f54f59, 0x95646ad2, 0x998040ac, -0x92bc11e6, 0xe8834025, 0x87ea8135, 0x3acc7643, -0x83a34847, 0xeda9c86c, 0x52e47719, 0x3b3842bc, -0x61b2886f, 0x6638adb5, 0xca9c1f2e, 0x2cd92807, -0xd9c4464f, 0xd91b9953, 0x3d1ecfb9, 0xa1516e4d, -0x60b01c2c, 0x08459d5f, 0xe99a102a, 0xdfac4df2, -0x70333609, 0xb1904964, 0x1b6d54af, 0x9968a440, -0x04347224, 0x88dc7467, 0xbcff2ef4, 0xb83d961a, -0x247825fc, 0x8c6f624c, 0xe05ee9ba, 0x94e73cbb, -0xcb6edebe, 0xc9793be8, 0x053280f4, 0xd29418fd, -0xa0512900, 0xabfd8d92, 0x8aba9e8b, 0x33d149ff, -0xd5ed45f4, 0x62a4840a, 0x0bf481f0, 0xbf038c47, -0x82d4965e, 0xb41eebfd, 0x5b287f0b, 0x71d6d69b, -0xf2d06e0d, 0xe1218c89, 0x71720f49, 0x94390240, -0xc4c3f49f, 0xd32d517d, 0xedfe45c6, 0x74b04c58, -0x2372b2be, 0xe5a7de41, 0xb017d5d7, 0xf934a681, -0x0ac56d3b, 0x0be48e98, 0xae47c17b, 0xf8ddbcf8, -0x5682f9a2, 0xf43e9eba, 0x6c0b336b, 0xc40150eb, -0x4aa0ca2b, 0x0d5a305d, 0x56fefed2, 0x99a705aa, -0x6096092a, 0x001f26c2, 0xe364bcf4, 0x0a4f07e7, -0x68633e62, 0x46165fd8, 0x777c8734, 0x7188064a, -0x7728a2dc, 0x0132a4ff, 0x1411da4e, 0xc0d7cae4, -0xb0827a24, 0x1f33ca0d, 0x301b45c3, 0xcfd76566, -0xb3140209, 0x2020d58e, 0x6c7828aa, 0x469e3e1b, -0x53e5cc4b, 0x8c9bb974, 0x9c0be380, 0x00d29a02, -0x5f7e9fd6, 0x45f517a0, 0x1bc394a3, 0x78fe109a, -0x4af25164, 0x5f56c9fd, 0x9d5dab8a, 0x64fa3425, -0x1a365db6, 0x1c586a1f, 0x56e55cf4, 0x2d93358e, -0x448271ba, 0x06e8e093, 0x0042488c, 0x54bd9d23, -0x0a887744, 0xcb551856, 0x27556ed2, 0x2eee49d6, -0x85d12f41, 0xaecc4f26, 0x2a7bec40, 0x8d7ec8b6, -0xb384dc7c, 0x01c21f9a, 0x9876ccea, 0x1924bed5, -0xe0600462, 0xe4f94e3a, 0xcc03b228, 0x24e98fce, -0x26bbd55d, 0x152c96fe, 0x58baf202, 0xb32ea38f, -0x22c554b1, 0x368334f8, 0x45e64e5e, 0x3f9dae32, -0x9c6a0ff1, 0x4665a203, 0x23786040, 0xa21f24fe, -0xa97cb082, 0x6f4a18c2, 0xbc51598c, 0x08309bd8, -0xb62379b4, 0x779bb74e, 0x8870ce16, 0x932d1ebb, -0xf49f6c68, 0x69c4bd4f, 0x08d3cb08, 0xa379bb0d, -0xf0e18560, 0xe10c446b, 0xe60aa1cc, 0x398b54dc, -0x67974d8f, 0x9bd2fe47, 0x01d57215, 0x1f419459, -0x0b94be20, 0x9145f783, 0xab47acb3, 0xbd1d3022, -0x97c64c01, 0xcdb21b65, 0xcc447f47, 0x9835192a, -0x671fc924, 0xc6003828, 0x36625701, 0x76fb155e, -0xcf1babce, 0xa7fd901d, 0x2c6e6f0b, 0x14392642, -0xa4ce369b, 0x6a899816, 0xe52dad41, 0x18ccb12c, -0xa7a3ee18, 0x05c15fc4, 0x0b16e652, 0xce0dbeea, -0x083ac310, 0x48c34502, 0x2c190079, 0x9befd0de, -0xe5095afc, 0x37a6ff3e, 0xa3b75262, 0xef3eb9e9, -0x61a9ea28, 0xb9bac46b, 0xc8f809e9, 0x9580a1b9, -0xf10a2570, 0xa5314534, 0x11045ccb, 0xf575d940, -/* 1469-m9df4406.inc */ -0x00000001, 0x00000006, 0x04212005, 0x00000f44, -0x9f60db18, 0x00000001, 0x0000009d, 0x00000bd0, -0x00000c00, 0x00000000, 0x00000000, 0x00000000, -0xe563140a, 0x7a20a196, 0xeb1d9a96, 0x5defb059, -0x551ef057, 0x018ee1e6, 0xdaacf6e3, 0x14105663, -0xf1e0900a, 0x35e5b615, 0x542b082e, 0x27a12e48, -0x6e3986f8, 0x73be0124, 0xa2d87e91, 0x3a6f0d62, -0x749a41f5, 0x722ce5f3, 0xacf63c0c, 0x1dffb5b9, -0xb1f377a0, 0x258e340d, 0x2826e300, 0x46ff70a4, -0x000c7a3d, 0x5c7d517c, 0xa4ac08c4, 0xf3251d6a, -0x97ee3046, 0x74b66de7, 0x70ddb034, 0xf1cc3728, -0x24646e08, 0x89d1ef84, 0xf2c5d259, 0x5636ef08, -0xbc4b18ab, 0xb77a3bf4, 0x34ed12b6, 0x3904c93e, -0x2aabac33, 0x30a9be4b, 0x3cb32cf3, 0x0c8ec4e1, -0x5dd3de8a, 0x6822723d, 0x1ee4a4a5, 0x76f8dff8, -0xc114ecd8, 0x24e2b997, 0x895778d4, 0xd96893a3, -0xc3f8b3b7, 0x0894e3d6, 0xacf5f40d, 0xb6c4805d, -0x9e702a73, 0xd83e0f61, 0xe57efbec, 0x734287d9, -0xad22e7ba, 0xd43369ff, 0x5c8f9702, 0x10faeede, -0x8f7a2b16, 0x27a2f4b4, 0xb9dae4d7, 0x2e060e6c, -0x0a565ac4, 0x56017827, 0x1d40da17, 0x302f4015, -0x4df69cd6, 0x557f99fe, 0xe05ae859, 0xa4d26771, -0x66668ed3, 0x1b02cbe2, 0x6402e2b9, 0xe2d45956, -0xacdbdf95, 0xcf15e429, 0x1211a69f, 0x6527d512, -0xd454cf93, 0xc8057a6a, 0x462abebf, 0x50f4a562, -0xcc021bd4, 0x12e4dcf5, 0x0f643ac4, 0x64b62a5a, -0xe31293f4, 0x69a4f441, 0xfd7c73a7, 0x3de19d86, -0xacea1763, 0x5452e277, 0xaf998cfa, 0xd0dbd619, -0x437a136f, 0x7d84b255, 0x0badc43d, 0xcfdb5155, -0xe0f18baf, 0xc7e50dec, 0x12f74c21, 0x10839a4b, -0x384c0010, 0xbb64e51b, 0x6b1f8001, 0x3a42ea68, -0x52ba8707, 0x4840e661, 0xea8cb909, 0x71bf8fe9, -0x301e156b, 0x1b28299f, 0xd6f83b79, 0x68b53c17, -0x8ee827d4, 0x4d264534, 0xd831f750, 0xc0897c28, -0x9c27edd1, 0x2c54ffcd, 0xbdd61a3c, 0xbb750d1f, -0x92ba81b5, 0xe8b41b21, 0x92bd9214, 0x2f3bcfe1, -0xfd7e8ee6, 0xbbf21e5b, 0x2d2f042c, 0x6c2f1c00, -0xfa5db9eb, 0x64e9da32, 0x27ccb83a, 0x6ee2c527, -0xe480e71f, 0x74d3726e, 0xef8a1239, 0x795cbd73, -0xd29bc178, 0x34560391, 0x4bb7009f, 0xc150a672, -0x68094238, 0x7b23b1b8, 0x4561db18, 0x9e9e2cde, -0xb4b6defe, 0xe412c6ed, 0x19bdb157, 0x3431b08c, -0x83cbf398, 0xc02744ae, 0x757b3636, 0x70cc9a6a, -0x16644d51, 0x66ff4e2e, 0xa8f9e6c1, 0x2d36259b, -0x54f24515, 0x47f972c0, 0xe5b96f48, 0x2e8f8866, -0xee84deb6, 0x261022b8, 0x25e08920, 0xab692cf4, -0x2899a0e2, 0x4fb247d8, 0x84dad90e, 0xade5b71b, -0xf866993a, 0xdb0e8d9a, 0x855db464, 0x46c73e5b, -0x6c4dc8ee, 0xff498c8e, 0xf5bcf485, 0x2c222e5a, -0xea373f27, 0x4c98a5f1, 0x6d389f50, 0x24181e62, -0x761fd60d, 0x11ff22a2, 0x9be6e06e, 0x5d6349af, -0x743a43a9, 0x6e183bfa, 0xceb18be7, 0x87693e10, -0xc7589a26, 0x147efde0, 0x82bb18e7, 0xe0a9b9ca, -0x81f4f143, 0x814c966f, 0x1ae2043c, 0x2b2f4bc9, -0x9ad21435, 0xe4ec4152, 0xb6f735d9, 0x29c6cf4a, -0x5172795f, 0x7de9a8ce, 0xb11ab201, 0x37cc8504, -0xc4341e1a, 0x32e7b6bd, 0x3ada1f2b, 0x5f8e8670, -0xffd0e48e, 0x7b204a33, 0xbf8ccf79, 0xfd7a0537, -0xbea6017c, 0x13ddc317, 0xa2b49bc1, 0x85535884, -0x2306bc4f, 0xf7fd5f14, 0x2f25e16d, 0x7a05c70e, -0xa734f67e, 0xed9bcbaa, 0xb4b23ae3, 0x743a2302, -0xba46fa60, 0x44b8fcab, 0x53d89eb6, 0x75d3f3d3, -0x3cf9ef83, 0x265b38e9, 0x99f9df3c, 0x2af44ab9, -0x34802ecf, 0x2341609e, 0x04ad291a, 0xc2110545, -0xec4a8447, 0x42d6132f, 0x6a729029, 0xf56a07da, -0x9f51b3e3, 0x81e20e55, 0x48b7f7d1, 0x6ceae8e9, -0xcf28c1cf, 0xb0459807, 0xed8c8daf, 0x572bcbdf, -0x77c5640f, 0x4edc4215, 0x3fff4444, 0x4784c4e2, -0x3ffb9ddf, 0x1af87147, 0x1638fa9d, 0x61771e20, -0x621459b1, 0x021f0a08, 0x0a8336df, 0xd8c8ccc8, -0x88b75e47, 0x18ae2461, 0xc06d45c4, 0xf814ae69, -0x9a368b90, 0xbe063af0, 0xc8e466b1, 0x78993bfc, -0x8d797b93, 0xcb9eeda9, 0xc2320b6c, 0x0043b902, -0x2eccbc54, 0x48a4e5a2, 0xc218b3ba, 0x488183e7, -0x3df27709, 0x45e0daf4, 0x6bfe1329, 0x3c518851, -0xb53c01cd, 0x5b10b2c2, 0xc88f1150, 0x8133965f, -0x8b16773a, 0x65de9860, 0x5cb18ae4, 0xe61105a1, -0x4c3f0d28, 0x9189f726, 0x620106e7, 0x0ae5d1bc, -0x46bbd58f, 0xd7b7b07c, 0x53d82958, 0x2febb95a, -0x4ffcdd8e, 0x57a046df, 0x3b63f580, 0x463fe2c1, -0x209a9440, 0x79882a80, 0x5cdadafe, 0x1c7a31ba, -0x3bf5ca92, 0x76115d65, 0x731a4e07, 0x8f2198d4, -0x19921981, 0x664f4e11, 0xe1e6022d, 0xc55ec9a3, -0x758a56c8, 0xc35d3895, 0x7cd59bab, 0x234a3699, -0x0b5aeeef, 0xfef8ad6f, 0xbd82b866, 0x471a70c1, -0x7de86792, 0x12f88a2f, 0x031beb63, 0x3660e731, -0x919853a7, 0x100a8549, 0x14e6105b, 0x3f332601, -0xf052c2d3, 0x7d8be989, 0x87f54337, 0xbfa644c9, -0x24dde887, 0x3d69f2f6, 0x80026b49, 0x90739ca4, -0x3862381f, 0xbf2d9626, 0xe02bd15e, 0x55a675df, -0xef1839d7, 0x99469915, 0x91cfaf2d, 0x7f94040e, -0x35db5f2e, 0x1d38d47f, 0xebc93baa, 0x193f516a, -0xe0b6a8c3, 0x73c5b0c2, 0xd56da2b9, 0x510d7b46, -0xdab1fc17, 0x1a1c680b, 0xf73644d0, 0xf43258a3, -0xfc729ea1, 0x17593652, 0xdc9a37b5, 0xc53b613b, -0x71a648cb, 0xc28af23f, 0x96cde33f, 0x0acd49b6, -0x2cc90ae2, 0xf2cbef0c, 0x300dbaf1, 0x5110904c, -0xe0da462e, 0x541d3d34, 0x527c9afc, 0x2bcd7311, -0xe0d8dcf3, 0x1974fc1b, 0x552345ab, 0x5ddcc35f, -0x3699800a, 0x47a5f674, 0x7579adb9, 0x8c9ebdb9, -0xedeaa964, 0x07bf6a14, 0x56b5fc09, 0xd6ae4f7f, -0xa4427021, 0xdaeffdb0, 0x928631b6, 0x3d6feb97, -0x592ab6da, 0x943bed47, 0x4e90670f, 0x6eed39af, -0x558a3291, 0x69676209, 0xe26b1251, 0x45e748af, -0xd7db0c17, 0x09d904af, 0x5c23eee4, 0x7dce5a88, -0xaf448358, 0x6d2cc780, 0x94b4e6fa, 0x869a5a07, -0x3f75da4a, 0x4981f4f0, 0xad2c1bd2, 0xd415266b, -0x61d4c2e8, 0x9978181e, 0xa614c894, 0x51bb75b0, -0x697f25bf, 0xbb387310, 0x901fb6bf, 0x7a5775aa, -0xf4e54003, 0x2337ba70, 0x76dae5b2, 0x1bfe4416, -0xbfc66700, 0x635a01e8, 0x230e0a21, 0x0647f1dc, -0xacb82703, 0x233333f1, 0xd089d131, 0xc827d423, -0x7ee72b61, 0x741576ed, 0x9c684f01, 0xe19af7d8, -0x4f58f71c, 0xb717d8d2, 0xc6b831b3, 0x5528044f, -0x96dd56f9, 0xa2a35007, 0xdd261fc4, 0x33397ed2, -0x53d58350, 0x3b901c93, 0xd323a1c4, 0x5a2ff964, -0xf194322e, 0x185b3a7f, 0xe0f25f21, 0x7d4e0d38, -0x00422302, 0x72066cc5, 0x9391be09, 0xd4162cc7, -0x8ad4051f, 0x73556df6, 0x1588929f, 0xf56e27ad, -0x50c0350f, 0xa66ff66a, 0x0a1f67e9, 0x068eafc2, -0x14f5c391, 0x88baa8a3, 0x13170c2a, 0x229a7ea2, -0xca01ec98, 0x4818229c, 0x54e076db, 0x7c17e80a, -0x8580283d, 0x6b59273b, 0x24a34b79, 0x6e25f7ad, -0xccff2b70, 0x53efab29, 0x5d90e63a, 0x9bcd34ef, -0x71f0da42, 0x18ed41ed, 0x695cbc37, 0x9c7f679a, -0xc6088111, 0xd9bc46c2, 0xf5cca3d4, 0x20c04383, -0x791793fa, 0xb7e9e066, 0xfc95fab6, 0x6dd1d554, -0xbe778ba7, 0x7dec91e5, 0x94024a42, 0x64a1eb3a, -0xc81a3114, 0x0babf6d6, 0xaa7d38c4, 0x5115e4a7, -0x9ac88b93, 0x39ae62c4, 0x2acf36c5, 0xb574de96, -0xcdbdb1a4, 0x413d5bc1, 0xae04a74f, 0xc9832330, -0x633c6d74, 0xb1b139e8, 0xac763c36, 0x2360f00b, -0xf30c9ecc, 0xc7ce662d, 0x4f79c584, 0x39edc122, -0x24cc4698, 0x24e10e96, 0x1809b9c0, 0x3a3f8ac9, -0xf2fa2e48, 0x376780b6, 0x8efd4055, 0x324d429b, -0x3f6df8d8, 0x1a0aab7e, 0x9719292b, 0xa8e80f5d, -0xdfd687f1, 0x1ca45455, 0x4582e3fa, 0xdc769c17, -0xe4b4b6a6, 0xb3ef5ffe, 0x77c6080d, 0x2c5e8928, -0xe49b00c9, 0xdb9af793, 0x83882747, 0x5c0bbb97, -0x6d798b75, 0x3c487b6c, 0xc18aad39, 0x2b33b4f1, -0xb77e14c8, 0x7e7f60ec, 0x31a7d15b, 0x54f7a3f5, -0x409be002, 0x4b7d598f, 0x5a55ef80, 0xb0c26a57, -0xd2c0054c, 0x68ec0a7f, 0x094ddebd, 0xf2cf11b5, -0x0cdc898c, 0xae7103b7, 0xf73378e2, 0x1bb441a1, -0xc1d156b0, 0xc3e353e8, 0x51b2d82f, 0x6b86be5e, -0x24ddfe39, 0x7b57c5e9, 0xabacf363, 0x119b7e41, -0xf07018c4, 0x4059c66d, 0xd0a259be, 0x436f1d41, -0x2ad68f7b, 0x06bb476e, 0x8db8294d, 0xc50f5eb3, -0xb71d28b5, 0x381a0df8, 0xf690b6f1, 0xcbc08020, -0xf1e69098, 0xbb424bfa, 0x1b74bfa4, 0x2c51dd1c, -0xb52b4195, 0xad192d71, 0xec1da669, 0x3c93966f, -0xabab81df, 0x6f5b968e, 0xf170fdc9, 0x0755af35, -0xc7bf6bec, 0x760ed225, 0x7b7fdedc, 0x54598081, -0x3e537194, 0x6ecc4255, 0x773d14ba, 0xd2dfe382, -0x34e94cff, 0x22074f61, 0x75ee7965, 0xd220de84, -0x032c6593, 0xe375bccd, 0xdb50c167, 0x31a925cf, -0x4dca17b8, 0xb5f4acc8, 0xb9382557, 0x74de2b3f, -0x77ecccc1, 0x42d84094, 0xb042f4ab, 0x0b0d19d5, -0x1d03283a, 0x1c20b9b6, 0xec2db4db, 0x1e90b7ab, -0x7e6ef7cf, 0x193cbad0, 0x15507944, 0x96a05ff7, -0xfc634fa6, 0x086aa071, 0x543d4a48, 0xeb25d690, -0x1af843d0, 0xc4f62d3e, 0xdb5ae34e, 0x1e98338f, -0xd87d258a, 0xff12601f, 0x48c19218, 0xe4db722e, -0x218e9377, 0x258c91ec, 0x9cbd58dd, 0x93332ac2, -0x8a15361a, 0xae807a30, 0x1875bddc, 0x212f38ad, -0xf60c6c98, 0xce5bdbae, 0x36709283, 0x0e6f5806, -0xe09d1733, 0x49fea86c, 0x21a34c9c, 0x2e97b2f3, -0xfe008eb6, 0x4b18fa60, 0xe9989bfb, 0x400fc607, -0x054d8a62, 0x348c0dd2, 0x85a16292, 0xeb6b16a7, -0x41c698cd, 0x5fc86abd, 0x48ccdbcc, 0xa02e52a2, -0x27e186b2, 0x88404198, 0x10fb0972, 0x1a07931d, -0x53425b21, 0xd8dc8ccd, 0x08a3e7d5, 0xf26a467b, -0xe24f3c9a, 0xf6eff6c4, 0xa3d0802e, 0x8617af99, -0xa68d4981, 0x9005a2ff, 0x0999d184, 0x01369b46, -0xd799a679, 0x64e1fa7a, 0xf0ec5c83, 0x114fd630, -0x13a8d73a, 0x4515c0f4, 0x465abcd0, 0xdc024d64, -0x6cc43301, 0xb497574d, 0xaed546f6, 0xef5ae94b, -0x2fef7571, 0x70defbe0, 0x67847c5f, 0x3fd7e969, -0x2d5b08f7, 0x0167291c, 0x3d8fbb68, 0x44d83e5a, -0xae5ea654, 0x78e36f1c, 0x1056ea08, 0xcc791fdc, -0x72214384, 0xe2037b43, 0xfe2cb96f, 0xaba26e63, -0x5d9800ff, 0x397fd531, 0xaeaf8537, 0x21872429, -0x1fae93bf, 0x3fd7906f, 0x34994338, 0x368726ae, -0x14612ae0, 0x8562d699, 0x688ed9fd, 0x3e0dd4d0, -0x7ea37322, 0x4da5cb8d, 0xd3ebd8fa, 0x1fbc490e, -0xf8474471, 0x92cec355, 0xce5e6265, 0x4f099546, -0xee269914, 0x20232907, 0x2609b2f8, 0x2ade1ead, -0x972fe2e0, 0x5c57e86f, 0x8cb7c577, 0xfeeae944, -0x55ca8166, 0x5980457c, 0xc7da1649, 0x11f671c4, -0xf6fcad24, 0xbb6bedc2, 0x283b6c74, 0x17ec2f39, -0x773013d5, 0x928c2fa9, 0xcf7b1f8c, 0x4a5d66b5, -0x92b7cfa2, 0x90813a5d, 0xc9565359, 0x2c8fbbc7, -/* 1471-mbdf4117.inc */ -0x00000001, 0x00000017, 0x04222005, 0x00000f41, -0x326135c1, 0x00000001, 0x000000bd, 0x000013d0, -0x00001400, 0x00000000, 0x00000000, 0x00000000, -0x23869663, 0x00e8d132, 0xdfe7a33e, 0x20662972, -0x6cd78e27, 0xd40cd9d0, 0x1779cf53, 0xda1410b4, -0x3a7e01d2, 0x2610ad09, 0x466805b1, 0x4f83bde3, -0x0089c4df, 0x414d55d6, 0xc1a55777, 0x15397290, -0xbe73c0c1, 0xcd711d83, 0x9582e3fb, 0x4252d42b, -0x07bc38ee, 0x57e59d01, 0x04340908, 0x0e7ff2de, -0x73799873, 0xeebd252e, 0x26f35c02, 0x17d52208, -0x2894111c, 0x02d6a971, 0x0dc494d1, 0xc5d1d4dd, -0x893e98db, 0x0b2bb463, 0x209dcc8f, 0xe3a0bcb4, -0x3987884b, 0x4e83a501, 0x10c4fccc, 0x33523a90, -0x5e38588e, 0x741f7b18, 0x7bef6e37, 0x977ba083, -0xcc550f6b, 0x3c7b4752, 0x69965735, 0xc2a368ff, -0xeb8a4b75, 0xc28e6d6a, 0xc08bbd99, 0xb3188777, -0x24132a22, 0x9a9f1f71, 0xfeab84ae, 0xc1cdb604, -0x6f92eb4d, 0x3085955a, 0x1a7c51b4, 0x3193aedf, -0xd0fdb9c9, 0x8f858301, 0x048559dd, 0xffebc1ed, -0xdb71cba7, 0xa1df624b, 0x3c62de85, 0x7a086a76, -0xa1472fba, 0xce1e2869, 0x27a2565c, 0x419dc5fc, -0x501d9451, 0x03246b66, 0x210061b1, 0x0348d26b, -0x2a3802bb, 0x351f903b, 0x968b209e, 0x12dbeeaa, -0xdb1205b6, 0x5332993e, 0x280dff0f, 0x9147408e, -0x807cf7cc, 0xd6ed0e2e, 0x4a073f0f, 0x24432e3c, -0xf449f9b9, 0xc1ecf004, 0xa231f7fe, 0x15e6d179, -0x44971caf, 0xdc68da09, 0x0facd5af, 0x80161743, -0x9f675525, 0x30aa65e9, 0x7de3e032, 0x0018a0fc, -0x7236ffda, 0x4f6d6cae, 0x5c9af30d, 0x0552799d, -0xfa729385, 0x71947988, 0xb8aec61f, 0xba7e2e2b, -0x7e65c8e1, 0x6016f7ee, 0xbbbfa2ea, 0x59898d30, -0xcd0ac559, 0x8527d33c, 0xaf9a15e7, 0xae9b044b, -0x4ce02b95, 0xe299e65e, 0xf30b8fb3, 0x4d18b4b7, -0x6783a7d3, 0xa0c9955b, 0x52ad0b6e, 0xb78b3173, -0x24b4b551, 0x9a291645, 0x19d57d22, 0xbae5c7ae, -0xe82e6e2d, 0xe10be39c, 0xc2d26e7b, 0xb26b1e8d, -0x97471f7d, 0x5f405fa3, 0x658987f9, 0x8a90f2aa, -0x5dc6c0b5, 0xfd9b5b1a, 0x3d432314, 0x48ce4ea8, -0x26d0097f, 0xcdcecc97, 0xd0a0eea3, 0x5f0690e5, -0xf40dd231, 0xa3c71707, 0x00059355, 0xcb0badb2, -0x23fb63f1, 0xa10bec29, 0x9fdb03ae, 0x1f85dc9f, -0x3cec03e9, 0x0377e06f, 0xf256e7ad, 0x1a2db020, -0xae97d2f4, 0xb20c0106, 0xdcb02aa6, 0x486feece, -0x29487f07, 0x0c934081, 0x820aae29, 0x05405e2f, -0x34a068da, 0xde1c956d, 0x931b128d, 0xbec61127, -0xb89b8162, 0xf4adcd12, 0xdb3452e5, 0xfaf11e6e, -0x4ef489bb, 0xb9048451, 0xa8d986ab, 0x283aa33e, -0xb8f607d9, 0xcecc2f8f, 0x8b669cd4, 0x5de9d03a, -0xd809a9de, 0xe6ca7747, 0x0b0c9e20, 0x04199433, -0x4e2f4502, 0x1c68f178, 0xbbb8bc13, 0x1390c017, -0x5dd0c688, 0x45211e3b, 0xd20bf653, 0x58e4567d, -0x330f3b7d, 0xf4f1b03c, 0xfbdb0014, 0x95883876, -0xf811c78f, 0x30feceba, 0x6a822ece, 0x0c1f28a6, -0x21e86bf4, 0xa91ca6f1, 0x06a534ef, 0x4fa941d5, -0xa1e22f33, 0xa4438b88, 0xa0313dbc, 0x38ac3733, -0x5e772ea0, 0xb319576d, 0xeeac02b5, 0x590c55ce, -0x963f15e1, 0x77281f33, 0xd59ce20b, 0x5319c529, -0xa5ac445f, 0x084980f5, 0xa6476003, 0x59d085ca, -0x08f98cae, 0x7738f971, 0x01fa8642, 0x91576241, -0xdf826f04, 0x5b0ac434, 0xb05daac7, 0xcc4c8a31, -0x7dffeb94, 0xcbc8da3f, 0x6b27c0bb, 0x429855d4, -0x2fc6593e, 0x0b098e3d, 0x4b356bc8, 0x1e7122c2, -0x0bafd085, 0x9b2e343c, 0x24259ddb, 0x27335804, -0xa4cc06ea, 0xe7e99bb6, 0x093a860d, 0x3bb00ca0, -0xdfbb59d3, 0xc7375b12, 0x3e1afd3d, 0x21e34603, -0x392dabfd, 0x99caf016, 0x9c95d368, 0x117bea69, -0x900c4a4f, 0x8a1b3c5d, 0x7220d03b, 0x1f721f5f, -0xa31174b4, 0x32a2133c, 0xfb6e3be7, 0xe835f4a6, -0x8e09663f, 0x45b64191, 0x852dd810, 0x494e3205, -0xdf51bc7a, 0x35b9e273, 0xad98417b, 0x09fd7867, -0xe2c9824a, 0xe3b21ebf, 0xc99982ac, 0xcbe639d7, -0x7811c1ff, 0xe1db9878, 0x0fe74cfc, 0x94576c2e, -0xb719ca45, 0xe0960f65, 0x4e421a9d, 0x9c6b061c, -0xabde24d7, 0x0fef5a7e, 0x11544d8d, 0xed6f9b35, -0x8a612f0f, 0x3f5bd220, 0xf8bcfcd9, 0xa8b85029, -0x8ce1adc1, 0x8f4f2a35, 0xa4bc2c91, 0x29effaa4, -0xe7ca6c38, 0x89687497, 0xd76c755e, 0x6abacc63, -0x18f95328, 0x084d2732, 0x2b99c8b5, 0xa5cc679c, -0x7b39f528, 0xf6d22d1a, 0xe282cff1, 0x4f84e4a4, -0x44adb6e4, 0xde9b104c, 0x79df1974, 0x9c08a94b, -0x29b676df, 0x42a9c9eb, 0x93d86764, 0xf4db50c6, -0x3b22b62f, 0xabe76510, 0x92fc7279, 0x0e65b57e, -0x53c0ad78, 0x77181939, 0x059de191, 0x0fe04ba5, -0x83407676, 0x2ec98625, 0x7b16e66a, 0xe760fe12, -0x4a5ad3dd, 0x5fe3dfe1, 0x9799dfd6, 0x2453a5d6, -0x2b3c15e0, 0xa00b7248, 0x4caf83aa, 0xd56333f4, -0x3b28e188, 0x5fec6905, 0x5602272c, 0x11a880a3, -0xd863707d, 0xe13d30b9, 0x3fac9971, 0x03974a6d, -0x16a977a8, 0xa29ab4ff, 0xbcbca489, 0xcb80d6e8, -0xaac55951, 0x04df40a2, 0x778f6d2a, 0xfb71f60f, -0x97cf473c, 0x6f11ce3e, 0x81657389, 0xe8393417, -0xe9a71afc, 0x7191f0da, 0x956af1dd, 0x5f354bdf, -0x37e3ad81, 0x633eca08, 0x612c1de6, 0x6e5f888a, -0x42f19871, 0x4d4804d5, 0x4c3c7e51, 0x66f1c539, -0x85917f9f, 0x6f602a12, 0xb762f892, 0xb58fde66, -0x95698716, 0x7bd33b3a, 0x71a0136b, 0x828d78eb, -0x1b364f9d, 0xae6ae3e9, 0xa689ef5d, 0x814c6105, -0xd5bc7ba6, 0x57188df0, 0xe7ee2de3, 0x1070ad06, -0xf19f135c, 0x7a1cf2f7, 0x095d27c8, 0x13adaf91, -0x7310274a, 0x61729379, 0x40c1410e, 0x7a04fc6c, -0x2dc6062d, 0x24454bb5, 0xd70f2135, 0xb132a185, -0xeff2dbe2, 0x343ca212, 0x20089805, 0xbd50064d, -0x9475a4ea, 0xb501a35a, 0x9ed4e634, 0x54e7868b, -0x1452657b, 0xa1d55fe2, 0x5d45664c, 0x1f92f7dd, -0xcd2ee2b2, 0x72810ade, 0xacd6981c, 0x74d97c68, -0xc6197d01, 0xc1d7d1b5, 0x1b889832, 0x00377dc1, -0x35dcb606, 0xbc3a6152, 0x5556fd42, 0x3b396140, -0x069370e1, 0xf97b8f48, 0xd8561936, 0xee9aef0e, -0xec80b07d, 0xc280b8c2, 0xc42f9d65, 0x40c3cd24, -0x7accc51d, 0xf5e22954, 0x5bf9b798, 0x8f5b4d13, -0x74c3977c, 0xa243da07, 0x244dcc57, 0x977fec01, -0x12bf785c, 0x04b643f3, 0xbb211a93, 0xa0764ff7, -0x14101e55, 0x7f3da5e2, 0xb0b46e28, 0xdb616566, -0x70c0e0ed, 0x4565f1e2, 0x1767f652, 0x213f966f, -0x754d4868, 0xea9172e8, 0x8ad24070, 0x9b7737f9, -0xa57de77d, 0x6de0b195, 0x7ffa9709, 0x56255daf, -0x85a3d4c4, 0xdc1ab1d9, 0xfbc7e65c, 0x69ea2ea0, -0xef496f2b, 0xc8f74d6a, 0x0649b66c, 0x28d5eb58, -0xb44d4758, 0x0e6aae11, 0xd400b41f, 0xc7273115, -0x7e0d9a8d, 0xebfb62e1, 0x70ba546f, 0xef81f10e, -0x807f730d, 0x9c73c748, 0x37a1c985, 0xa2b4aa04, -0x2e932351, 0x5cd11c91, 0xc2b6535a, 0x622288f0, -0xd6b63e54, 0x9f6d5906, 0xa4c82f56, 0x8ce3e118, -0x26b47bbf, 0xf936e888, 0x3c4474fa, 0xb4211d0d, -0x5c2ec780, 0x0557c1a0, 0xfb935e8d, 0x08d27a00, -0x962e7dd0, 0x0867960e, 0xdd1e3553, 0x3b9b9682, -0x441a234d, 0xdf94804c, 0xe97e180e, 0xad7ae7b0, -0x4afc08e6, 0x589c6b7b, 0x82ed0c1a, 0xffa3707d, -0xfc2b487f, 0x7a73bfcc, 0xba9f22b6, 0xae7fa5d6, -0x1eb7c8bc, 0x10642385, 0xe8f51462, 0x09b7d40c, -0x40d7818c, 0xe740cf46, 0x55b0c2f3, 0x5b82bfd6, -0x8449a7d9, 0x5a1848db, 0x77c228ec, 0x7d78b419, -0x460e05b6, 0x45077372, 0x1e134121, 0xc37451fc, -0xcd734d9c, 0x2596fced, 0xd00922e1, 0xabaca36d, -0x76ae1209, 0x2be64d6c, 0x2ba81270, 0xd0845d0b, -0xa9297e7d, 0x8842f686, 0x428eb289, 0x56472cdd, -0xe61e1789, 0x26980ff2, 0xf44f3dd6, 0x7efa0c9a, -0x669de28c, 0xef70aa5a, 0xf841c6ec, 0x46c4bc78, -0xf813386c, 0x75043cc9, 0xd1817d6a, 0x4788bcf6, -0x97aee340, 0xc1ffa0ba, 0x4fbda2cd, 0xa937850a, -0x08a6d5b6, 0xa65b0ac8, 0x85647fd1, 0x947e8577, -0x4d348f3e, 0xfedf809f, 0xf997c620, 0xfb02f089, -0xac7f842c, 0x7b149778, 0x119dcb7e, 0xa5906986, -0xc87563c7, 0xa83e6971, 0x02de6124, 0xe070678f, -0x80662c65, 0xb004287f, 0xdb531a75, 0x4b2c5dc1, -0x5b3648e1, 0xfe64276f, 0x909e6930, 0xb3fa82ab, -0xfc336690, 0xac665252, 0x37728038, 0xd96c32ba, -0xa9ac3198, 0xaefbed90, 0x44742af3, 0x32a4b131, -0x357b46bc, 0x2262bdfd, 0x4a9068c6, 0x8aa11f53, -0xa4a86547, 0xb484cc27, 0x34779665, 0xe3655ad9, -0xd0255644, 0xf14cb46a, 0x090b0aa4, 0xd84210ca, -0xe59b6bf7, 0x8a80142c, 0x4df8652f, 0x1ab22298, -0x993cdbc5, 0xd3a43828, 0x980636e6, 0x132d53cf, -0x84477fc4, 0x95e84ad4, 0xa04cb613, 0x5bfd0eb6, -0xd53f46b9, 0xe7b3e64a, 0xeab5fce8, 0xcf4106de, -0x2f0464fe, 0x941887f2, 0xd7ab411d, 0xbcd268b1, -0x6494d150, 0x54eca2b6, 0xdef87a80, 0x7bc5ad6e, -0xde75507e, 0x10f4ee75, 0x295d3e70, 0xb021f568, -0x5b3b7a6a, 0xa18e69c5, 0x8014d58e, 0xa1d847ba, -0x7ea65405, 0x472469c2, 0x1d438800, 0x6a58e959, -0x4a4343d3, 0x9bcfc24a, 0xdb4515d0, 0xc9803b9b, -0xa0c781ba, 0x97425f38, 0x0e9fed84, 0xbddbb90c, -0xf4242ae4, 0x039500ee, 0x99976b17, 0x714d0fb9, -0x85181429, 0x4e22a22f, 0x4165f667, 0xb45a6de5, -0x34967e7a, 0x9bbf9e9e, 0x28b027fd, 0x2780aeff, -0x6ec6c288, 0xcd1d011d, 0x0c88c54f, 0xbd0bfb5c, -0xd40b63f4, 0xb5c783da, 0xa4b39929, 0x6cbb4a21, -0xa2c2c897, 0x86703c38, 0x15408e1c, 0x133ad235, -0xf51d1371, 0x848bcdde, 0x9b7eecb5, 0xba2ca677, -0x39871164, 0x7065d811, 0x5dd770e7, 0x5a732dbe, -0x58e6461b, 0x2a2c51b9, 0x703062a9, 0x545ae881, -0x0860f6f3, 0xc7e29228, 0x9fc59c61, 0x881ebef3, -0xab2a061f, 0x82b3a4d5, 0xe799e152, 0xd618faba, -0x6c2e4d18, 0xe4611bce, 0x5587717e, 0xfcc0cb92, -0xa6207512, 0xf2ff1ffa, 0xba269d1f, 0xc1879edf, -0x38359369, 0xcb684db0, 0xa773b9e0, 0xb57257ed, -0x587b4b47, 0x6e151398, 0x2667424a, 0x261a6a40, -0xffe3291c, 0xea0b7369, 0x70ac567e, 0xb39b49b1, -0x725a77ca, 0x2507206c, 0xc8ea7a60, 0x5dd5ec2d, -0xfb5ce938, 0x987b290e, 0xce6147b6, 0xf34a8acd, -0x125328ac, 0x94866e32, 0x4ad59e55, 0x8a0b7aad, -0x45658446, 0xb4f695f0, 0x189a0160, 0x38b762ce, -0xf643a8a6, 0x657d6d88, 0x2441f0a7, 0x88653b45, -0xa28826fb, 0x975c1e93, 0xb5aabf28, 0x53f9c1ce, -0x36ece683, 0x0f67fbbe, 0xb4ea726c, 0x86e0f6bb, -0xd8f360f1, 0xdb0e2f10, 0x14e46bd8, 0xd0883022, -0x6ab0f8ca, 0xa99711d7, 0x4a9451c9, 0xef26029d, -0x7cd5ecea, 0x593f2587, 0xa39b410f, 0xcc3632f2, -0xd03d3ef3, 0x237eb7c5, 0x3a657ab4, 0xfc573ed6, -0x9dfb6f5f, 0x5b710f01, 0x551566bc, 0x1eccdcfb, -0x3d07c680, 0x438b4075, 0x4bb302d2, 0xa90659bd, -0xe642c00f, 0xdc7e938a, 0xcc399534, 0x52f2e704, -0x4420520c, 0x19f02d49, 0x9e2d5d8a, 0xb4c3fbaf, -0x29ae6509, 0xae021764, 0x832077fa, 0x71d419bb, -0xa746b3b2, 0x76362de8, 0x41bd6436, 0x08056245, -0xc0d11c06, 0x644228e2, 0x205f55f6, 0xc40d4159, -0xb8b2df85, 0x2d734c2c, 0x0ec55443, 0x02d288c1, -0x927d91a0, 0x1e627cd2, 0xca3a1913, 0x8f42cfc1, -0xedf0d71d, 0xea9fc128, 0x0db7f256, 0xf03eba20, -0x176357e1, 0x98163efd, 0xd6031ee2, 0x4b41108e, -0xf99f6036, 0x9ea730af, 0x82a1dd96, 0x1991bd12, -0x1aceee34, 0x63668a06, 0x4c0ad9b4, 0x31386049, -0x931f18d1, 0x0fe7c51e, 0xa4865238, 0xed7c8953, -0xb5718a5c, 0x5092df33, 0x006c9d17, 0x405bf78b, -0x522c1765, 0xd849eb2b, 0x4d50ddfb, 0x90e2514a, -0xd7a1e43f, 0xda6ea0d4, 0xf22b2b11, 0x63b6df32, -0x85e1f6c7, 0xd1365d03, 0x6ac62a81, 0x92693068, -0x56ef2428, 0x49016a53, 0xf752d088, 0x128bc866, -0xf823c05b, 0x6d8ad85a, 0x47f92649, 0x765b66db, -0x7b14fe51, 0x01edf60a, 0x54410699, 0xc9cc530d, -0x275fc862, 0x278f39e1, 0x3fc980a2, 0x475f079e, -0xa53c5026, 0x3fe3b777, 0xc8f92b5c, 0xddfe54d6, -0xdb13146f, 0xde1a74f7, 0x7e2e8043, 0x5fb7ff54, -0xe2cbe801, 0x4c50f3af, 0x0ffaeed1, 0x025b1fce, -0x2273faf1, 0xc8955ff7, 0xe5068c37, 0x42f6c6cc, -0xefed1e37, 0xc4e66e60, 0xc4a6eb63, 0x59078dc6, -0x9529dfe9, 0x81abad48, 0xa2eeee30, 0x718d1194, -0x9023695e, 0xbfcee06c, 0xeccca3f7, 0xa051fdd5, -0xe91f7002, 0xba818c9d, 0x7bda4201, 0x73e5a202, -0xa9042251, 0xe4106c9c, 0x1ff5133e, 0x36d74e84, -0x38063048, 0xa2804700, 0x27c20e05, 0x5e20cd58, -0x1539dfa1, 0xfa08d141, 0xc2215a49, 0x74f30566, -0xb4ff34e5, 0x99873de9, 0x7599b6a8, 0xbbd40d02, -0xd9ab39dc, 0xa7551850, 0x37436dab, 0xed55d20c, -0x3f4f0041, 0xf0ff7466, 0xf7e67c8d, 0xb1406f22, -0x4e43c13d, 0xb52500e5, 0x985ad53f, 0xa4b3825c, -0xde2b9106, 0x365dcbc1, 0x77014217, 0x169c12d3, -0xc7bc869d, 0x922a8043, 0xa6111e23, 0xe74b2290, -0xa3e2410c, 0x33422d46, 0xe1dacff9, 0x3c979ea7, -0x3697c0cf, 0x96c88610, 0x1832e947, 0x7f4d65ce, -0x2cd5ed28, 0x0c1cc240, 0xf61265fd, 0xa64afca8, -0xe4860c99, 0xa43857cc, 0x616e9a5c, 0x9365866a, -0xa5549228, 0x20aa24ab, 0xd7bb6e6f, 0x9dbb3e25, -0xf01b507f, 0xe9b649de, 0xd84e3324, 0x6424df6e, -0x77bbcd8d, 0x45d9deca, 0x281c8229, 0xe603463f, -0xd585f541, 0xbf51f6dd, 0x3e3aa065, 0x12635f25, -0xfe224cfe, 0x0385cf5d, 0x4efe873a, 0x18da5b1d, -0x0bcdeb2b, 0x8a59c122, 0xf2593715, 0xdc22685c, -0x2c38f3ca, 0xc0b46ae2, 0xf5f103ac, 0xd17462a6, -0xb9d9ee2a, 0xb40e6d75, 0x9d355887, 0x0099c8ff, -0x06b6f634, 0xe4dc43d0, 0x2623a7dd, 0x34b9ad51, -0x718107ce, 0x8ad0b008, 0xe69e21da, 0xc1d47860, -0xb444246e, 0x2abb0323, 0x43ea237b, 0x170bf5dd, -0xeba9eead, 0x28d02fd5, 0x7b4f22d0, 0x51d4728a, -0xa9954103, 0x04b9cd77, 0xa72da2bb, 0x74330b0f, -0x56c741c4, 0x039c62f4, 0x3c665ea3, 0x047b5cc8, -0x64a59471, 0xe9281c9d, 0x894b630a, 0x793e34eb, -0x68d7df44, 0xc94404ca, 0x1856ad8b, 0x18f3f6de, -0xdc902798, 0xc3814844, 0xa9e068f3, 0x6769998d, -0xf12a4119, 0x909a97ff, 0x842432ec, 0x08aa7af1, -0x8858e492, 0x4ada49fc, 0x178f173a, 0x5991554a, -0x9c907487, 0x55b1c638, 0x72a1a06a, 0x19980cbc, -0x65ddcaa9, 0x260703b5, 0x8c60404e, 0xdc4402c8, -0x83977bda, 0x1031a065, 0x5d3a24a8, 0x8861eba0, -0xc09e3951, 0xbd631bdc, 0xd7282286, 0xe32380c8, -0x50b2f198, 0x4def47b8, 0xf94a521a, 0x8f9a8a29, -0x1a7e6413, 0xa2302de3, 0x7348be92, 0x3857be1c, -0xf54dd509, 0x61411ab0, 0x35b34232, 0xdac05cb4, -0x5d9b0a8e, 0xde69a9bf, 0xbeea5edf, 0x34040ad9, -0xa115587c, 0xbb18d1c7, 0xd07a996d, 0x80289a3b, -0x0fd58e87, 0x4e6aff16, 0x47ae69c0, 0x87e6328a, -0x87adc8ab, 0xaffde7c4, 0xada1fe8d, 0xf7a299d6, -0xe69bb375, 0x36f49809, 0x66c2f884, 0x4a8aedd4, -0xc7fd1fb9, 0x01c499c7, 0x2faa2ff4, 0xe821423c, -0xcb6bb413, 0x90fde54d, 0xf09ee30c, 0xa72913bd, -0x16b07378, 0xccf225f1, 0xebb20fde, 0xb0524d99, -0x1b9faf3b, 0x10122a9c, 0x2ecdff53, 0x993fd223, -0xe6fbdf1f, 0xaaa23e5b, 0x5629d1c7, 0x134f537a, -0x51323cd1, 0x67f4e421, 0x8d1dd2b8, 0x6be7a601, -0xa658f134, 0x00cb82da, 0xfbb719d2, 0xa9d91f11, -0x3fe4a8e7, 0x71887197, 0xd77f5c3d, 0x53c80ad9, -0x0b6045f4, 0x1d4cac3a, 0xa3c6608d, 0x47be3319, -0x5f3aae36, 0x378b6c69, 0x89d8d004, 0xdbf1a13e, -0xdb25ebe5, 0xa386553a, 0xe5ebc1e7, 0xd8151054, -0xbb0b9127, 0x63685e1b, 0x9356bef2, 0x6c945f61, -0x6cf55ba4, 0x00db0365, 0x15a63c01, 0x787dcafe, -0x43d75560, 0xd86eed95, 0x448bc692, 0xb1d487c1, -0x320edd3b, 0xa3510418, 0x1adee6c4, 0x6ea34c19, -0x0bdfa30f, 0x30c0f341, 0x01ff2f2f, 0xc356cdfb, -0x0e6ff905, 0x9b4d411f, 0xa15429f7, 0xeee0f2cd, -0xfb6b526e, 0xdb6d9e90, 0x10226e12, 0xc5238a39, -0xb40f0884, 0x11a91802, 0x7f1636a0, 0xba658b3a, -0x68a9c80b, 0x3f2316c8, 0xfb8fb0a6, 0xe7c33636, -0xcbc8d632, 0xf058c218, 0x6c2b7525, 0x3ca42916, -0x39099c3a, 0x1321f3e5, 0x9e0e6344, 0xaa75d386, -0xe28b580d, 0x0bdb47fd, 0xd8e31aa9, 0xd8b4b204, -0x388f1bff, 0xb92772a8, 0x2350fe36, 0xd105108e, -0x2d322d69, 0x9661e811, 0x46a855fe, 0xe2507c81, -0x168b0831, 0x6bbe4600, 0xe5ab19c9, 0x6e8cb822, -0xe6ce419a, 0x7b055119, 0xf1c9b63b, 0xca49b674, -0x95932012, 0x3e533453, 0xb0c6cb70, 0x94d7fd13, -0x23635019, 0xdd58d8ac, 0xaa9cf0c3, 0x455bef11, -0xc1ef00cd, 0x7c92a95b, 0x8252da9f, 0xe63bac5c, -0x6761159c, 0xaa67963b, 0x7c25cfd1, 0xebd59104, -0x71967969, 0x32a90da2, 0x37d83045, 0x77041b1a, -0x0e9e3947, 0xab904b5e, 0x6580a40e, 0xe199dd34, -0x7f9bb7fa, 0x39aab849, 0x036ad852, 0xb7d2af89, -0xc5ab8c67, 0xe52885df, 0x9c816e4d, 0xb4a6bb8f, -0x2e4b0685, 0x09eeedca, 0x3d89a745, 0xc49c8e42, -0x470628f0, 0x3845dc7f, 0x0ebbe8b4, 0xb2ca084e, -0xafc2b33b, 0x2b29a5ac, 0x33c2057a, 0xb0aaa36e, -0xdbaaed25, 0xb3f80759, 0x66dd388a, 0x1c05fc93, -0x0707a813, 0xd6d8ae75, 0x86fbdceb, 0x088f91db, -0xb802193c, 0xf983a7d9, 0x9b3b33ed, 0x2d8672e0, -0x3b13e330, 0xe88b879a, 0xb1fcfdc6, 0xa006850e, -0x7a2f3943, 0xff94d1bd, 0x2e41b7b4, 0x5858ff11, -0x62910311, 0xc03124a1, 0x4c9ab497, 0x8b6cf246, -0xc9ac4856, 0x058b1cf0, 0x094146a4, 0x21b34465, -0x3bcb5453, 0x90d6022a, 0x28190001, 0xf18f2280, -0x8fad8551, 0x65113513, 0xe192bd6c, 0xa2cfc9ef, -0x21c4f033, 0xab4f34fb, 0x224eab9e, 0x899edf52, -0xd494af2d, 0x1ce1600f, 0x7bc0e2cb, 0x4f49e6f0, -0xb8fbe79f, 0xc9c91b53, 0x025585c9, 0xd1d81072, -0xcbcde043, 0xc94d077b, 0xb164efee, 0x7156806b, -0x86699184, 0x75f514cf, 0x95bee913, 0x96fbbf85, -0xb37760b1, 0x9665d6fa, 0xb27ec974, 0xffa844d9, -0xc2cd368f, 0xd608dd3c, 0x0144c468, 0xff855bda, -0x38b722ab, 0xe0d03d11, 0x481f7936, 0xe333cebc, -0xab099835, 0x4916bd84, 0x94976044, 0x7d444113, -0xfd7138f3, 0x3aab1781, 0x353ee8c2, 0x3f3b258c, -/* 1729-m206ec54.inc */ -0x00000001, 0x00000054, 0x05012006, 0x000006ec, -0x7066b518, 0x00000001, 0x00000020, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x7eb963a3, 0x81dd6ce0, 0xded19ca6, 0x9c4c547c, -0x4ffe6333, 0x9daea9fc, 0xa99d0e45, 0x40d831fb, -0xc34a48c9, 0xe99943f1, 0x3eb82749, 0xc27adb97, -0xceb7ce90, 0x2b9fd70b, 0xfdd8cd48, 0xf09bfba3, -0x0a802e3f, 0xff791e57, 0xd904a6e1, 0x019baa1b, -0xf06cac6e, 0xc1b92ca8, 0x018a122c, 0xd022163e, -0xf53aee44, 0x1f932932, 0xe02dd579, 0xca667ac9, -0x097489dc, 0xe9a6a13d, 0xd55d5d8a, 0x083e1325, -0xda6c517c, 0xdd28a452, 0x08cf5296, 0xeffe1b21, -0xebb0eddb, 0x10a96bd1, 0xf23ee356, 0xf70db5c0, -0x21794b89, 0xe0780e67, 0xd53c387c, 0x2764b1de, -0xefa8b543, 0xe7c2a535, 0x109bab7f, 0xc3258ea4, -0xf81eb5fb, 0x264b114c, 0xe8cdad74, 0xc9286033, -0x2efca9e9, 0xddaf486c, 0xcb174b77, 0x1247cc43, -0xfc2a5940, 0xd92e965c, 0x298b9cc6, 0xe94519ff, -0xe9a46566, 0x122a2564, 0xe842bae5, 0xca3cecb0, -0x0877d766, 0xfc6c5c03, 0xf3c8e775, 0x23cb6009, -0xdf125f99, 0xf2329969, 0x006cff15, 0xee305a0b, -0xcaf81e1c, 0x25023329, 0xf5dc3edc, 0xf9ef7bd8, -0x3f0ba575, 0xc3436132, 0xceca9997, 0x2752a329, -0xe23a8359, 0xca98871a, 0x18a4219e, 0xdb578317, -0xe712b71c, 0x3f8acb1b, 0xc8e5a45a, 0xd02a30ba, -0x246db19d, 0xf01fb657, 0xc98be2a7, 0x0492afea, -0xd213d7c1, 0xf13b6a40, 0x080a9753, 0xdce3ee84, -0xc6701e00, 0x3d8b83af, 0xfd65eae8, 0xd198b88f, -0x1ea955da, 0xc17869b5, 0xdab97efd, 0x19ee3b16, -0xdae564c1, 0xeb37f38b, 0x07e58300, 0xd1769fd8, -0xd36e6b01, 0x1458ae64, 0xdff50ee2, 0xe7b8a0cc, -0x10e2f1cd, 0xf65cbaec, 0xdce4985c, 0x385f8c59, -0xe6891614, 0xe9671703, 0x13b1ec37, 0xc87574ec, -0xfe6459a6, 0x31d69428, 0xe6be49e9, 0xfcb184d6, -0x3c162b7c, 0xc00e5aed, 0xc7e499e5, 0x137f142d, -0xc2fcf099, 0xd1ebe28e, 0x2b894a14, 0xe065c15c, -0xc2d3fe1b, 0x35b6e732, 0xff0c845b, 0xf0bf2cb9, -0x37949535, 0xfc1ba418, 0xe9c0032d, 0x20979496, -0xeb788c37, 0xccd207ac, 0x19314352, 0xe10c8803, -0xe15cb069, 0x1c4cc4f1, 0xe82520bb, 0xee079d0a, -0x38f8c902, 0xd71f01ca, 0xf96c962f, 0x1d4ceefc, -0xeb6ac91e, 0xd2edee13, 0x2b87dbda, 0xc384d473, -0xf150d06a, 0x2c35b9ea, 0xd748c5fa, 0xf5fca164, -0x1f12ec1c, 0xcaec1b94, 0xee804b73, 0x2473054a, -0xd6c8f0b0, 0xf37be591, 0x03a0286b, 0xe921dcfd, -0xe72d930f, 0x3fe6f577, 0xcf313d6e, 0xe2cd5600, -0x19a40963, 0xe3b8bd53, 0xd12fcbc0, 0x1c524f54, -0xfc962e75, 0xc6bf374d, 0x0d279bd4, 0xd1e9a9dc, -0xee6df719, 0x3c1c00ba, 0xee84e9af, 0xc26bcd8d, -0x39f9e540, 0xe1bb00cd, 0xd6bfe547, 0x39bf3cf0, -0xede94eae, 0xfd35a58d, 0x342980f1, 0xc2f13c69, -0xf3de750f, 0x19d4ce33, 0xe7281dd1, 0xcaa95c41, -0x06009f38, 0xdd0701be, 0xf16eef09, 0x2057029c, -0xfa21d9cd, 0xedef9e92, 0x11613b80, 0xc21b530c, -0xc93e1b91, 0x040c3c7e, 0xe6a5034a, 0xc35698c1, -0x234312bc, 0xeb973380, 0xe49f9be3, 0x30d1c4f1, -0xed6ea0d7, 0xc3e53fe5, 0x3ae32a8a, 0xf28645eb, -0xd25319ce, 0x0727a1e9, 0xf18a0847, 0xde33d5be, -0x14ffc09a, 0xeb576096, 0xcebed8f7, 0x39785123, -0xc6e0f876, 0xcccd1012, 0x083db8e8, 0xf94dfd51, -0xca0148ee, 0x0bcd5dcd, 0xe91a2e5b, 0xe71b0114, -0x339c7fd3, 0xdf613b74, 0xd64ea5f6, 0x00d6e01a, -0xe808f9a8, 0xc0379384, 0x2ce3036c, 0xe2fe6128, -0xe8a18034, 0x18629142, 0xdccee5c7, 0xe09f0032, -0x0e56e9ef, 0xef8175b2, 0xfbbe46e3, 0x32873857, -0xfb0ae3ee, 0xcabf9ed6, 0x263fb334, 0xecc12cd2, -0xe0c8ca53, 0x20931272, 0xfe8cf541, 0xf7fbc330, -0x112dce0f, 0xebaba8be, 0xdb6a70f1, 0x3bb2e1bc, -0x05fe41e3, 0xada99f4f, 0xfeaf9273, 0xcf6d224e, -0x6f74dd5b, 0x8efc5f0b, 0x9e3d81d6, 0x25688996, -0xec1a4b43, 0xb887821a, 0x57dd51ce, 0xcea136d6, -0x922b06ae, 0xe90a2e9e, 0xf0fb5663, 0x14ef903f, -0xb82b2648, 0x473ebf75, 0x5e2881ad, 0x1eb3eb2a, -0x22c908cb, 0x0591b48b, 0x75786d01, 0x7716ce83, -0x6fa0c4e7, 0xeb07296f, 0x26c4cbdf, 0xe87fd440, -0x80b5bc52, 0x3c2bbe8e, 0x88baf3eb, 0xbb75827b, -0x6787c1f4, 0x058a1709, 0xd20fffc2, 0xefadbcb8, -0x4e33d4f7, 0xe2dc63d1, 0x82a16652, 0x48ddd35e, -0x83d68dc5, 0xf283487e, 0x22a4de17, 0xda737420, -0xb511af3c, 0xc8da4db9, 0xaa66d26b, 0x6358d7e8, -0x87edc315, 0xcaf677aa, 0x051173ff, 0xf9af3986, -0xbaecfc1f, 0x50aaa6fe, 0x8218279b, 0xc7ccbf19, -0x1a189bdc, 0xa59d6fe3, 0xbb6ab89a, 0x386b0f33, -0xe65806ee, 0x77350f4e, 0x7b96347d, 0x30f884bb, -0x2a9cf131, 0x5c51bcdf, 0x40591bb5, 0x09b1925e, -0x324110d1, 0x342fb61f, 0x41195e06, 0x4f03e5c0, -0x5f2ec6de, 0x95edab63, 0x3ba1cc1f, 0xaefc968b, -0xdf3aa8cd, 0xb45a1792, 0xdd5b082e, 0x43b93457, -0xc11483c0, 0x1aed0de6, 0x07e160ca, 0x008f124e, -0x698658b5, 0x5fa5fd4b, 0x6519640f, 0x01e19188, -0x3984d06e, 0x4c8f4323, 0x557c2538, 0x367304dc, -0x37c7be20, 0x28d9b35b, 0x41a9fa8f, 0x56f9a901, -0x67302c0d, 0xb2119a44, 0x2690f978, 0x813c38ee, -0xb451b685, 0x275f26ba, 0xa0b50c03, 0xba392957, -0x13b4c8c1, 0xa247af5c, 0xb934e263, 0xeda8c83e, -0x80dbded3, 0x06d66181, 0xe5b9216d, 0x02acab4b, -0x214e8df1, 0xe7c6d81e, 0x3d585f4d, 0x06963299, -0xd774bcc1, 0xaa281c68, 0x396e64dc, 0x4fe01af4, -0x8e8c27f5, 0x7c8214ab, 0x4a5ec6c2, 0xc2c1f708, -0x6c07eabb, 0xcd812189, 0xeb80ab22, 0xdc313d19, -0xd63d6885, 0x4309442f, 0xf1515e27, 0x40d0e43c, -0x5010cbba, 0xd4897cdb, 0x401b053e, 0x40b5a6f4, -0xef56d806, 0x3bdb3fbf, 0x622d59ba, 0xbec9c531, -0x0aca059a, 0x87f11dd0, 0x9f5c1000, 0x1b0f4611, -0xacaf4168, 0x25f158fb, 0x291c3634, 0x12d38a75, -0xea0408b7, 0x6e0cddd2, 0xc607aed2, 0xa268312f, -0xb5380399, 0xfdce1237, 0x43a8ebeb, 0x85ca9736, -0xde7c9fc1, 0xa24cd3be, 0xac9c6745, 0x066bb5c5, -0x8a5dd218, 0x3436564c, 0x2f127a67, 0x21a8b994, -0x3da4b79d, 0x944d2912, 0x0e2bc53f, 0x9873c594, -0xd5867184, 0xc90f4a5a, 0xc94a53fe, 0x2ccd9d5d, -0xc8710f29, 0xe93e21b1, 0x1659b8c3, 0xd86f2578, -0x2cff166b, 0x322dafe9, 0x10e5cd9f, 0x39ea10ab, -0xa808c512, 0x96ac74d6, 0xa55da964, 0x1d309220, -0x6e99a00a, 0xf478b6a3, 0xd66e848c, 0x17455ae4, -0x62a67a2b, 0x8a6da535, 0xb8abd295, 0x37d21266, -0x8f2d2451, 0x022c5322, 0x1c8098a5, 0x100191be, -0xeb28deb8, 0xc3ceb459, 0xeb405728, 0x04a0aecf, -0xff86c0ac, 0x4c5b866d, 0x18c0c2bd, 0x540c27ac, -0x1759e0cb, 0xd839bf89, 0x143e1418, 0xfe4ac2a9, -0x6e55a071, 0x8a553761, 0x4a654b67, 0xf2f3386f, -0x16f533d3, 0x5c54b599, 0x63dbf2de, 0x2c7080bb, -0xbb20bee1, 0x5703f5c6, 0xd469d09e, 0xa30cc96a, -0xa38d2880, 0xf90d58e0, 0x653cfbf7, 0xab427588, -0x49188c32, 0xf54e28c6, 0x2c16642d, 0xe086fe84, -0xaad5c930, 0x15145f09, 0xb35ec83e, 0x9d331ce7, -0x97a1ec14, 0xf84cb770, 0x2d73c086, 0xc742d95a, -0xc6f942bb, 0xa3d11ae8, 0xc3f26cc1, 0x6a1118d8, -0x7395e484, 0x4b3583a2, 0xb2bd4aaa, 0xf6d10bf6, -0x68dae4ba, 0x11dda178, 0xc839b146, 0xdbeb9322, -0xa94a639a, 0xb45b3921, 0x771ee9b3, 0xe59b2b8d, -0x58afbb4b, 0xf1acfc7a, 0x3db7dd82, 0xce6236da, -0x9e7a90ab, 0x8e81dc7b, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -0x2722bfa2, 0x10462123, 0x30080f7d, 0xb346cd81, -0x0049c396, 0x4e24165f, 0xa7c66809, 0x2e60bdcf, -0xaad70a08, 0xa73ea713, 0xe28f97a7, 0x283a9eab, -0xd4366489, 0xe776f963, 0x64ffa8ae, 0xde717b50, -0xbd2ca2b5, 0x3bae5f6d, 0x8d2bbef1, 0x7e9181e6, -0xf06aa121, 0xd06b2d20, 0xa83ea826, 0xef935e4f, -0xdfd27456, 0xa3451468, 0xc6820a63, 0x43463105, -0x787697aa, 0xcba5543d, 0xdf7e1e2d, 0x6998a8af, -0x98ce6c08, 0x89de731a, 0x943a3510, 0xb36ead85, -0xd5258d4b, 0x1cd6df61, 0x82a5c59d, 0xd078e7a4, -0xa33d4317, 0x24dc45f8, 0x3f3daf27, 0x0478bc6f, -0x92dfa16c, 0x952a872e, 0x7a34e03f, 0x0f088084, -0xa40937fe, 0x38fc7749, 0xa157e8a4, 0xbce94344, -0x7045ff7b, 0xf3e1ab66, 0xe62a6058, 0x5564ff10, -0x38198f1e, 0xf326f0f1, 0xe262bc0c, 0x2f0b851a, -0xc7bcbe11, 0xe79f1d1a, 0xc2f93c29, 0x54f3ea9f, -0x8f8f9141, 0x9f45e13c, 0x7a5b86bd, 0xa764efd8, -0x35f04729, 0xdd8c4b54, 0x5fa12e51, 0xa5824af9, -0xad328f71, 0x0f11fbb9, 0x9048e950, 0x04d7a900, -0x02538d1f, 0x99f745b7, 0xe31f63bb, 0x2c4e3d78, -0x7cdb9245, 0xa3966ee7, 0x27c4433a, 0xe1d79f3e, -0xe640fa06, 0x79ce31eb, 0xf25634fa, 0xdd9ce5cb, -0xb7fab8d2, 0x2f1f0ff2, 0x2acb625c, 0xa0494989, -0x206d7f11, 0xf268b8ca, 0x292bbf9f, 0x763bd7d0, -0xea4b14fc, 0x9d3d6aeb, 0x64cca57e, 0x6fc3e29e, -0x3e7bf4bf, 0x90efc7e3, 0x08e39173, 0xd05bee2c, -0x5b3c8f37, 0x0921ec6f, 0x3371b715, 0xb324e114, -0xe3abc53f, 0x576b18f8, 0xc4469024, 0xb2ded6c6, -0xe7783782, 0xc0a1fd5d, 0xcf324bde, 0x97527c8e, -0x19f8f48c, 0x3e806a5d, 0x96cff225, 0xe3b9d04a, -0x0e5856ae, 0x781372f6, 0x9645f2b7, 0x95a743ed, -0xd0c7eded, 0x86ca3cd9, 0xbab94db0, 0x43a1233a, -0x89c55554, 0xee776239, 0x34aa0098, 0x66a6e1d4, -0xae0e233e, 0x717e7b29, 0xb403a4c1, 0x36eb96c5, -0x42140832, 0x04250936, 0xda375dca, 0x524cb2e6, -0x86deaa0c, 0x400dc9d1, 0x12c00364, 0xe3ca7cf5, -0x87f20da7, 0xf57df9ef, 0x580dbdfc, 0x0b3e0369, -0x014d27fd, 0x4afaf6a1, 0xd1f4ca09, 0x77abc831, -0x30e49729, 0xec61cd2c, 0x159c1e92, 0xb61b40b1, -0x17c66fd6, 0xde11c061, 0x79d7f792, 0xc709cbfa, -0x94201c89, 0xbe65137d, 0x18aea1b4, 0xf248bbc3, -0x465f957d, 0xcf4a9672, 0xbf293fd2, 0x2c5e31c9, -0xc2c73011, 0xfb29cbf2, 0x576f7f0b, 0x74de1745, -0xa76e172b, 0x99b96223, 0x14ce1502, 0x231013fb, -0x1d4df40a, 0x951b0c16, 0xab173e66, 0x4ff65f74, -0xc4a87a47, 0x09cc3370, 0x66385490, 0x73e09118, -0x4ee96432, 0x0164d347, 0x205069b5, 0x158dd226, -0xc932c238, 0xe9048fa2, 0x100b626a, 0x86ee08cd, -0xed87cb1c, 0x6353ec37, 0xa36edcc3, 0x8a16dd6b, -0xd28a4198, 0xebea1127, 0xca0b761a, 0x61c31acf, -0xced5ff4f, 0xbf4dbd8f, 0xd969d8a7, 0xb6e4e9e8, -0x8421c402, 0x809d7222, 0xabfd1d2f, 0xc1857ce5, -0x23958fd7, 0x3226f1d3, 0xd822b4cc, 0x2f1cc3aa, -0x501fe01e, 0xe36f8c94, 0x7ad27716, 0x3321308b, -0xa85b957b, 0x38cfdf6e, 0xc7497dd5, 0x2462090c, -0x8f9e42e7, 0xdf97684a, 0xac8af621, 0xd5224866, -0xc5f64e50, 0x9724f297, 0xc386097b, 0x48c6f98a, -0xe1478b1a, 0x2dd23fd8, 0x716b2d85, 0xa5c3789b, -0x53625e80, 0x9b8b312c, 0xce482165, 0x66161e35, -0x64ecb56a, 0x9981c46a, 0xe6cb6bb3, 0xe1983186, -0x75ed470f, 0x4adcbd27, 0x3efeda68, 0x4d193a2a, -0xbfdb3cd4, 0x7c6167b6, 0xdbddea68, 0x4b0d2d62, -0x00ba3860, 0x49ec2544, 0xa68698c9, 0x2ce7be1b, -0xf5afc9fc, 0x1cebf9c3, 0x350f8f5b, 0x893eefb8, -/* 3025-m08106d126.inc */ -0x00000001, 0x00000026, 0x04062009, 0x000106d1, -0xdeac5852, 0x00000001, 0x00000008, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x8a62197b, 0xd41eef98, 0x9d9182ac, 0xce90899b, -0x593b5003, 0xda6b2375, 0xaec0ef83, 0x90372d17, -0xa88d2585, 0xfc178cc7, 0x040e8edf, 0x5f881c70, -0x41c6e5db, 0x0a21d4ce, 0xb93f9d52, 0xdefa0b09, -0x46b47482, 0x89e1216f, 0xa49b269e, 0x85f55632, -0x48faf49f, 0x74d0d770, 0x191ff3d9, 0x415322bf, -0x0e073d70, 0xef71b7ed, 0xbfdcff71, 0x9a7e696b, -0x3ef047c1, 0xdfb0f3a7, 0xc7219105, 0xbdcb77c7, -0x449661c1, 0x1bf3d2b4, 0xb96f62ff, 0xac2bb1dc, -0x2c51c691, 0xa6f6f574, 0xfa216399, 0xb9a9aad7, -0x52f9b3dd, 0xd9a09939, 0x3640ce2f, 0xd96fa8a2, -0xe408e2a2, 0x40302c2d, 0x699c8675, 0x6a4ba9ec, -0x4b87cb54, 0x428dafc9, 0x8ad37629, 0xd92d62c0, -0xe401f3bb, 0x2ae527b2, 0x41b7ef6d, 0xad22d2e2, -0xbf935eba, 0x3447667c, 0xc241ef0c, 0xb2e847d4, -0xd28290b6, 0xd42d0b0e, 0xea8fbc1a, 0xb4b71e8e, -0x6986710d, 0xa4cf0914, 0x235e8974, 0x2d2f4e1b, -0xfe33393a, 0x3588135b, 0x19bb5b36, 0xe8e9e4c0, -0xc97a62fc, 0xe09b1ea8, 0xe9f492ff, 0x92807086, -0x04a93231, 0x6a38d271, 0xd41917a5, 0x3b2c4473, -0x7cddcc24, 0x8b1bd7d1, 0xad9031bb, 0x3aa140da, -0x92d23d8b, 0x8256d88c, 0x2d4f76db, 0x23b7252f, -0x62c89fe4, 0xfeecec9a, 0xbed25f1f, 0xc81727b3, -0xd4230bf5, 0xfd2bff4d, 0xa2d71562, 0x2a7df5e2, -0xd3650f2e, 0x0e3138a2, 0xd6bac0eb, 0x549b1dea, -0xd84e2c98, 0x7172b49c, 0xdb401b67, 0xc3e666ef, -0x1817d0d1, 0xea7322c0, 0x81973c06, 0xad35520e, -0x600844f2, 0x21f93024, 0xeddae77c, 0xdf86947c, -0x6667c0f7, 0xdebc19d7, 0x179967d8, 0x7a0ccfed, -0x0da5fafe, 0xb6b4eeb6, 0x01474e9e, 0x1b4272de, -0x1968eeeb, 0xb9e8e70b, 0x3808867b, 0x12d0fe40, -0xf7144fa3, 0xc9c57a89, 0x1ba4da9f, 0xc5aad9d3, -0x2e934951, 0x9f67d3b1, 0xae6efdcc, 0x3014d885, -0xb82a83de, 0x826af12f, 0x5d7816ff, 0xbea30c27, -0x1f66425b, 0xf65372f9, 0xf92724cd, 0x9b3f9d40, -0xf91bd54a, 0x971ac2a1, 0x55adff9b, 0x2e21e466, -0xadbc1e3a, 0x2b5f4580, 0x9f87147c, 0x81bd5934, -0x4dd32e16, 0x1420ab63, 0xebb98984, 0x44fb6b87, -0x968de4f9, 0x6e3e70a2, 0x332e3769, 0xa62b6e05, -0xc629fde4, 0xfd82ab18, 0x6e4eb7b3, 0xf8993165, -0xef4758f5, 0xb9f5d43d, 0xeae11bb8, 0xfee0b327, -0x821b7908, 0xd9b9eb41, 0x18524a27, 0x528d2060, -0x0586d6db, 0x41ac7e35, 0x0f60a09e, 0x0d19e5f5, -0xd2923f79, 0x951fb42c, 0xd9a4b075, 0x4b2f8115, -0x468d11ab, 0x9e3689e7, 0x7d88e98d, 0xf10f246f, -0x21776219, 0x6c9ea2d1, 0xf62090e5, 0xf4897d50, -0xde5a1c6d, 0x128c8ea8, 0x0925a78c, 0xdb005ffb, -0xb8e1a8ec, 0xd352c429, 0xb9fb3a81, 0x0f70d960, -0x6bb50f30, 0x5332478c, 0x37d0c989, 0x0fea766e, -0x63cf91ea, 0xe9333698, 0x2a9f6fc1, 0x547b4192, -0x3d48dff9, 0xd12afce5, 0x263ea05d, 0x404b02b0, -0x8a68c9c9, 0x5fb7a13d, 0xe8566220, 0x6b981478, -0xdbef8f87, 0xc7045d1c, 0x71dd6f9b, 0x787dde0e, -0xbcd1fdd4, 0x3264ebbd, 0x14586a4a, 0x116af8df, -0x21fb08fa, 0xd5669e48, 0x2afe7082, 0xabc66801, -0x03eb374f, 0xc146532e, 0xc68dcb3d, 0x96e4f659, -0xd6c5816e, 0x4495ddf3, 0xdb658825, 0xa1a6179c, -0x33da2e45, 0xc55817bc, 0x49594ef1, 0xea6f9e2b, -0xcc4c40a6, 0x66c73c38, 0x43d968a5, 0xa6d83662, -0xfabbf3af, 0xfc06278e, 0x468d770e, 0x48e7e8dd, -0xd1952fbc, 0x12e75a2d, 0x03f8fbc4, 0x6e42b676, -0xe9a634d8, 0x78cf814e, 0x8a1886b8, 0xb8fbf111, -0x3b3631dd, 0x758f44d4, 0xb82a3c17, 0x620a3b4f, -0xfbf24991, 0x5a9489d4, 0xbc9b4193, 0x58e7ee5b, -0x11d3b4ea, 0x632f586f, 0x2ce4b827, 0x60f855ee, -0xec28df5f, 0x6d7d298d, 0xb26e9174, 0xa25791b0, -0xeb6a7de9, 0xc8ef78d2, 0x6e88eba1, 0x651ef2f0, -0xeb197e3b, 0x07c9e926, 0x8339033a, 0x3a557e03, -0xe216c7e6, 0x626e1995, 0xa0e4bc2a, 0x4c25388d, -0x0f98489b, 0xeab06afd, 0x0eb99b2c, 0x621bcc53, -0xcb306a0b, 0x3b6b22ab, 0x1059a835, 0xf452e7d5, -0xf2ff8706, 0xf2938036, 0x01c099e6, 0xc362a251, -0xe05443a2, 0x3da9dd70, 0xc6b0bf41, 0x312490ed, -0x3e23d0c6, 0xd99e6d48, 0x4f2703d6, 0xf80933e1, -0xe66f3322, 0x1efdda13, 0x0f26cf39, 0xb4bad0f1, -0x913ef9dd, 0xd433e5a0, 0xfc44169f, 0xcd7c7499, -0x3b6ad376, 0xb0b23611, 0x45dee41b, 0xe2ba9b59, -0x3cb51809, 0x8e86f45c, 0x859a0d33, 0xdaa4d46b, -0x4c063ef0, 0xf9d06d4f, 0x53501ddd, 0xeb487dd9, -0x81d62e1e, 0x2df42871, 0x5cf8aa44, 0xc5e40bdb, -0x7176fecc, 0x5516b195, 0x99f722bd, 0x41976195, -0xb8e84ad3, 0xef3ccec6, 0xe3d86e9d, 0x97941d90, -0x9e962a1b, 0x1c01e460, 0xcf0f85be, 0xab9b1c58, -0x16bf58fe, 0x81771f94, 0xdacda319, 0xb232ad3e, -0xb17437d4, 0xef5b512b, 0x827e8742, 0x7492f401, -0x4f69912a, 0xb9939a88, 0x1dab019a, 0x6b2ed2d8, -0x6df07ab9, 0x39011ad6, 0xc903fbd6, 0x1cec4fbd, -0x5eb20046, 0x3be8c64c, 0x378d680b, 0xf6f464f0, -0xf446fc56, 0x5783494f, 0xcbf7c271, 0xeeda7799, -0xd801328f, 0x6c8dd64e, 0x7029f05c, 0x25b25745, -0xca6d34b6, 0x33ce1bd8, 0xc230e50f, 0x1464b0a4, -0xc4a7f26f, 0x3cfc85ac, 0x8beda431, 0x0817abab, -0xc8de82b1, 0xc8877cd0, 0xa89cab22, 0x7fbce2ab, -0xf3d97379, 0x9d9b19ad, 0x6abc1686, 0xc24926ca, -0xdfca2347, 0xb8449300, 0x8793db9e, 0xafd44bc3, -0x5777c00b, 0x2c8976b4, 0x7c350594, 0x05408ea2, -0xa8e0a8c0, 0x389adf7d, 0xfbb0c0f2, 0xb96f4393, -0xe0dd2830, 0xf439f6ad, 0x0bde70a4, 0x18653b73, -0x1f6555d8, 0xf2dfa847, 0x4de927bf, 0x5f7fc911, -0x866c831a, 0xc55f0438, 0xfa235014, 0x24866364, -0xd3cd198b, 0x8eaad6e9, 0x7d0749b5, 0xd55d6584, -0xffa1e913, 0x6e66632c, 0x99a570c1, 0x478df5ba, -0xd06a5370, 0x5ac8ba42, 0x4c6065d4, 0x137eb693, -0x3a5be8f1, 0xe737046d, 0xb410c4d8, 0xe5488c95, -0x459c79ac, 0x09b95a26, 0xdb999724, 0xe3864e7b, -0xcc3782b5, 0xfdba2842, 0x6bd86d38, 0x76040688, -0xa7f44e6a, 0x4adc35b6, 0x5ded0032, 0xf49eaa48, -0xf30a7330, 0xe4b721bc, 0x7db4a898, 0x6d0e5881, -0xd78f56f6, 0xbcf27f8a, 0xae53768a, 0xbcead007, -0x9bd889f1, 0x280a8799, 0xa79f9433, 0xc4c6580b, -0xd0dc85c4, 0x34920875, 0x2208aa4e, 0x5adae859, -0xcd92c560, 0xb79bd098, 0x246d6d7e, 0x2c51163b, -0x97ab0f6a, 0xd8b63d37, 0xc7e3c538, 0x4b63da86, -0x19d28495, 0xda662f64, 0xec1e1e32, 0x17379978, -0x916543f4, 0xfeff6e10, 0x993010f5, 0x014a477a, -0x55edfee6, 0x836bde93, 0x8150415d, 0xe1ad7f1a, -0x2649babf, 0x3cde67ec, 0x4f225b60, 0xbe8e4c1a, -0x9270bac0, 0x0337ebd7, 0xe1b679db, 0x9fed87f5, -0x10a6f1ae, 0xeb1fb9c2, 0xfe71da61, 0x27ec4cb6, -0x4cc95f15, 0x6ad90b47, 0x411ed72c, 0x7a514182, -0xec451e0c, 0x48ea82a2, 0x682c56b1, 0x4f2cfbc3, -0xb67eb0fc, 0xdc7f7c25, 0x642ee06d, 0x8cfbc122, -0x6d51546b, 0x30c6db5a, 0x0f6f46dd, 0x1229dac1, -0xc65a568c, 0xc3fa072d, 0x7d2d1d21, 0xfce985f5, -0xb6232963, 0xae9b97fc, 0x55cd5726, 0xd948d2ff, -0x1028c41e, 0xe07b79c2, 0x6a5c39b1, 0xb980d663, -0x2660919e, 0x9a4764a1, 0x833eee84, 0xf2578407, -0x415b77ec, 0x1b018267, 0xb1be03dc, 0x75ed845c, -0xf35d6fc2, 0xe2780315, 0x3bb40ce2, 0xdb292934, -0xdb95ee2f, 0x408cba8e, 0xcfe6f423, 0x2dece2a5, -0x1f3b44cb, 0x99498157, 0xd6472d24, 0x8817d846, -0x35b647eb, 0x974dfd9c, 0x434a2336, 0x8913f3ec, -0x4aa531cb, 0x878f596f, 0xd7c38bbc, 0xad8d91a8, -0xdddaca6b, 0xa3fc3f92, 0x195d813d, 0xc710786d, -0x81d6afe3, 0x6f1d1856, 0x22492b69, 0xac284f74, -0x773cbc77, 0x85e341ad, 0xa20dd4e4, 0xc7af888a, -0xf0295bb2, 0xf1d5b9fc, 0x5322500b, 0xb87b6855, -0x3d44f92a, 0x1f2879b6, 0x7a8685e0, 0x0da3e6f3, -0xa364e557, 0xc28edafa, 0x5e0c06e3, 0x19f513f6, -0x94cc4e2c, 0x71a5e1f0, 0xf7400157, 0x17300a53, -0x56b690fb, 0x055a2d76, 0xf06457aa, 0xdebb8747, -0x8ef5052f, 0x319bd715, 0x8a19dc30, 0xb067be8f, -0x7e6ae81b, 0x7e5b6dce, 0x069274c1, 0x4b6d0e74, -0x90362e92, 0xe899d949, 0xc43126d7, 0x0d6b0031, -0xb1f49c44, 0x97b9c961, 0x439757be, 0x8906a5d7, -0xb7a0e97b, 0x46ddd9d6, 0xf60356bd, 0x4087155a, -0x9ac53b24, 0xdc979beb, 0x323fe352, 0x10c64391, -0xb699a0e8, 0x2bd4c295, 0x0bf9dcef, 0x630adaaf, -0xd735e4c1, 0x4417157e, 0x3a69d2a5, 0x9c385c0d, -0x2382c14d, 0x9c33f851, 0xcb4c90ae, 0xa8c557ae, -0xa40b05dc, 0x7e8709e0, 0x7dc96450, 0x8c6db77a, -0x0c1e0b03, 0x203a65c0, 0x79b2d038, 0xa0c6b2d6, -0x0aa3d0b7, 0xd36ec0b4, 0x8012cb10, 0xd99eecc6, -0xc2072906, 0x8acee2d7, 0x50a1a17d, 0xad6f890f, -0x123f3802, 0x73d6ca71, 0x9b531513, 0xd89c8779, -0x2ab5349f, 0x5999084c, 0x2889cdba, 0x3d2cb55f, -0xfb922dc2, 0xd5e64ad5, 0xd2fa69e1, 0xe4cf08e9, -0xdb43cb05, 0xce09d796, 0x7af98dcd, 0xb3e03280, -0x03147f3e, 0xe038a4f4, 0xb701791c, 0x77dbd759, -0x12fcd2f7, 0xbce9c9b9, 0xa2561be6, 0x97d05bd2, -0xda6922a5, 0xa81bae70, 0x0ddd38ea, 0x7ca70ee8, -0x97475a5e, 0x3a68d72f, 0xb5affa34, 0xc44f235f, -0x37ae1c8e, 0x13c055c3, 0xe4629ce2, 0xcf1910d0, -0xb314d24b, 0x78dda8c6, 0x47b5a43c, 0xb1e71bab, -0xfeebcaa6, 0x7761d599, 0xaadabb05, 0x9ed05d71, -0x913cd4ba, 0xc10a5b6a, 0xb84918d0, 0x8117048f, -0x99a56c04, 0x999d552c, 0x2b9e6bcb, 0x26608b43, -0x7942197a, 0xa4830c85, 0x7d673bf2, 0x38ceccb0, -0x1d10610c, 0x456b408b, 0x84a5a85a, 0x954e4282, -0xdbb6c6b6, 0x49469986, 0x2c5cd7f7, 0x5aa92bb7, -0x94c435f3, 0x2e9fd7ed, 0x3e3c19a6, 0x18837c97, -0xcc8473c1, 0xf9c6c1d5, 0x8d7f5df4, 0x26bb14f2, -0xa187704c, 0x2e0c5e63, 0x22d5426a, 0x4ea50d35, -0xbbebd272, 0xeb27ae6d, 0xe94572bc, 0x7d9bedf0, -0xbe9125e7, 0x9d60ef39, 0xb3e26109, 0xa257558b, -0x5997b17a, 0x3a170aa6, 0x6a14caf8, 0xc3bf1cdc, -0xce2f073e, 0xb3fac275, 0x80dd056d, 0xa3934fda, -0xce48329e, 0xb4b60b86, 0x5291d4cc, 0x63fc43ab, -0x0f17b7ec, 0xe6ed7b20, 0x2fdc0954, 0x4d0c284a, -0xcd10a2f4, 0xcd6487f8, 0x80315834, 0x8342a75c, -0xa16b5091, 0x18d7de86, 0x798a6d34, 0x3a9cc59c, -0xcf94ba72, 0x041c411d, 0x694e31ed, 0x8043005b, -0xa392fa03, 0x4b5f22df, 0xdf346533, 0x51eadb14, -0x201b4c59, 0x4f0bdb1f, 0x7a095e77, 0x47c52c02, -0xd7c8f5be, 0x256976f1, 0x461116b2, 0x6b505e95, -0x75e18247, 0x73e6addd, 0x2c28b9c0, 0xd00ccbc3, -0x608422f3, 0xc5dff95a, 0xd6a994c6, 0xa25af71e, -0x32746665, 0xd77a153b, 0x71b165d4, 0x09c3ca4d, -0x58b440c7, 0x914984f8, 0xf4c513e7, 0x23409995, -0x6add5bf6, 0x56370e1b, 0x86d6e143, 0x7cf6ca8d, -0x2f9fdfb1, 0x23e318e3, 0x292eed7a, 0x1867c5a8, -0xdb5ecf88, 0x7d9101e7, 0x7d1d6962, 0xd5e8d91a, -0x1c3f1e95, 0x7fcac975, 0x49f42977, 0x92a4fe3c, -0xfa3017b5, 0x874394ba, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2111-m801066133.inc */ -0x00000001, 0x00000033, 0x03162007, 0x00010661, -0x9e99cc48, 0x00000001, 0x00000080, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x90ad6a7e, 0x152c72d4, 0x0ff6ebb7, 0xb9b54882, -0x17babb3c, 0x0e24725c, 0x0f447da4, 0x09785e65, -0x28e1be4e, 0x3461d75e, 0x29e97bea, 0x23c76a4a, -0xddc3d190, 0x020318c5, 0xdeb8a6c1, 0xf5b73b57, -0x2a712aee, 0xfb4309fe, 0xd3875d41, 0x04afb41d, -0xdc57fed4, 0xf38ae786, 0x201ba0a7, 0xc87b00e4, -0xc6aab395, 0x10aad94d, 0xc91fe860, 0xcf4e74e6, -0x221842e7, 0xe44c7ae5, 0xdf098f72, 0x210eda92, -0xdc8cfa35, 0xdaf80aa2, 0x272a2a06, 0xfcb6407f, -0x542ae3e6, 0x04bfa647, 0x43972432, 0x56e7cfbe, -0x0094ce94, 0x64018038, 0x5df36c50, 0x01e4ec15, -0x83783560, 0x7791d607, 0xda778213, 0x8fdd82fe, -0x505b2e3f, 0xdb260012, 0xbf72c44e, 0x7b1f3717, -0xeaef705c, 0x9df6d9ec, 0x7e516d1f, 0xe06e4c6d, -0xb2dbd4fb, 0x53a6a326, 0xf2ceecef, 0xb7e8cdda, -0x3277bb22, 0xdbd989f4, 0xff63b09d, 0x32d02a05, -0xc0b7a02d, 0xd907f153, 0x17006924, 0xcd118084, -0xf87bd157, 0x374e65a1, 0x8512e958, 0xe14b0737, -0x5c295c73, 0xb5192105, 0xf088eb2f, 0x5d994080, -0x8ac98cb0, 0xd50bf122, 0x5b244766, 0x8379e108, -0xd0f9e345, 0x76e2bc23, 0xb2fde461, 0xd6e7dd40, -0x45453b2b, 0x979706e5, 0xda4bf76b, 0x58ebe864, -0xb14c7577, 0xe0ac578a, 0x71df5320, 0xbdb34d75, -0xa7f9c0e9, 0x55734a03, 0x91963507, 0xafbc3926, -0x331edb37, 0x9db8f4c4, 0xa0485d90, 0x35444571, -0x989b1ea9, 0xa594817b, 0x580aed7a, 0x8091a986, -0xe6220d5d, 0x4e8d3779, 0xa7ed5b92, 0xc1177b53, -0x423af3a6, 0x838dcb15, 0xa344ff5e, 0x5bdddcb0, -0xcd15dfb8, 0xbdd32cf2, 0x70eb5c80, 0xc15a3762, -0xbb8f5cd0, 0x7183110c, 0xe899a48a, 0xaab5c072, -0x7e432dac, 0xf4fe3bfd, 0x8b6b7c9d, 0x5c460b8c, -0xf207554b, 0xae8072f4, 0x11cd7ea5, 0xef2113f5, -0xc28694d3, 0x08d65dc0, 0xc1b75411, 0xe378bb29, -0x0fc9ea96, 0xe19f2428, 0xa8450da9, 0x1a4779e5, -0x81e9245a, 0xbf17dee0, 0x34bbf4b9, 0xa5fb7a6b, -0xba6d33cc, 0x1a5f1948, 0xe6b3f578, 0xac2aca48, -0x7fbed4ef, 0xfdeda2ce, 0x891336ee, 0x5a10f69b, -0xf8e499d8, 0xa3281387, 0x559b7e17, 0xf180a796, -0xa1488b74, 0x52696f53, 0xfaee5bdc, 0x854e9269, -0x506a47a4, 0xd78635c9, 0x861f34d4, 0x5101f844, -0xd46828f9, 0x8c33be78, 0x5830597c, 0xfe80ecf1, -0x808ad780, 0x7c1a8c6c, 0xfead77b0, 0x8e798cf7, -0x7981826c, 0xf67b4565, 0x895bf820, 0x565f8be7, -0xff7848da, 0xad5961c7, 0x5d8f9d05, 0xfdbb17db, -0xa54308e5, 0x57aae95e, 0xf833773d, 0x81d23cf3, -0x599f0561, 0xd8ef6185, 0x87431e1b, 0x5291f114, -0xd56c4247, 0x89fb1636, 0x58c49868, 0xf0a35ac6, -0x83c7579f, 0x72d674d7, 0xfcc710ad, 0x89fbcfc8, -0x7300bef5, 0xf351bccd, 0x80ea186a, 0x5bf99c08, -0xf5497d36, 0xaca91965, 0x56bbcbe7, 0xf70480ff, -0xad7d58cb, 0x57164107, 0xf32f71a7, 0x8b78d376, -0x55c77e35, 0xd77609af, 0x8b9fa59d, 0x5765b06e, -0xdbdbb6bd, 0x8e7284fe, 0x5f6141ab, 0xfb2f5e8f, -0x82dd238b, 0x7cea7457, 0xfbeb2952, 0x834db863, -0x720e93f9, 0xf45c6892, 0x85d202a0, 0x5a24ee39, -0xf237b6cc, 0xab3ea86f, 0x5befde46, 0xf1ca8ba3, -0xa6ddd695, 0x5627b81a, 0xfe41f5ad, 0x893327fe, -0x5d9ba05d, 0xd0e63019, 0x82ce74ac, 0x504961f4, -0xda62fe63, 0x8344c69f, 0x5e0d0f03, 0xf4002b10, -0x8e9b41eb, 0x7210d428, 0xf968469d, 0x8c86ed92, -0x76ef9233, 0xfe5e8851, 0x897b961a, 0x58153abe, -0xfa09eb76, 0xaf517a02, 0x5ec9184e, 0xf10f6c4b, -0xa6a51764, 0x5b6c3f3c, 0xf1034726, 0x89a75974, -0x5d037899, 0xda94e8a1, 0x83f4e6bd, 0x5b9347af, -0xd9a39843, 0x8fc8efd1, 0x505cf34d, 0xf2235e8a, -0xaa7e187e, 0x7091418a, 0x946d6385, 0xad3a4ffe, -0x11b70d50, 0xbcc122d2, 0x9a283ef4, 0x1e36ad20, -0x9ea87c24, 0xb124b8c8, 0x2c6c62fa, 0x9ceec8ae, -0xb79a925c, 0x2f7d8e3c, 0xadba33db, 0x954a9990, -0x3f6f9ae8, 0x8f4e8321, 0xd04525ab, 0x39d67ff1, -0xc8ad9053, 0xfe6e7893, 0x07887339, 0xce17f6ba, -0xda80c4e2, 0x26c001af, 0xbeca4e80, 0xde77bff8, -0x6679538e, 0xb4119250, 0xeecc77b8, 0x4737cd26, -0x8a3da39f, 0xc7112321, 0x69717eb5, 0x823094e5, -0xc482b42f, 0x615af641, 0x8aab5178, 0xedbbf611, -0x699a4244, 0xa3b521bd, 0x8d258d5a, 0x7695600c, -0xd5c989d8, 0x98f6ddd9, 0x417d9ea0, 0xf37aacf6, -0x90db51ca, 0x6e7028b2, 0xfbf1ee0f, 0x85ea06cf, -0x4c55acdc, 0xc3e617dd, 0x919e8f4b, 0x4652501b, -0x6e5981cf, 0xbff00c8a, 0xf95eb320, 0x6bede078, -0xdc453750, 0xd016f074, 0x235a33a2, 0xd414c7f5, -0xd0cb0fae, 0x03fe622a, 0xd184a2eb, 0xd5d564b3, -0x0e20d8b4, 0xfaa9cb0c, 0xe1d369ef, 0x0c9edc66, -0xcc930515, 0xc5b78823, 0x4c3c0123, 0xdebb750d, -0xa53cd5b2, 0x7a1e6ec5, 0xed21264d, 0xaa573b5c, -0x6a27bcc2, 0xc543751f, 0xa6177d70, 0x6de604e7, -0xcc340754, 0x8cf3d915, 0x703ac314, 0xc87978a6, -0xbbcb5952, 0x5791d446, 0xa4c1ddaa, 0xb9fc7c87, -0x785840d3, 0x82934719, 0xde2a0c97, 0x726c0c28, -0x4a9698b7, 0xfc05ae90, 0xb2a7b639, 0x4862af8a, -0xfe32625a, 0x990fc9ec, 0x77b7cf77, 0xf04665c8, -0x99fc1713, 0x5b472577, 0xe26a7b52, 0x9021e7cf, -0x730c6b4a, 0xe7b5a46a, 0x951d7a87, 0x56e040f2, -0x244ec1b2, 0xb9b2f959, 0xdcb37dfe, 0x21155f8b, -0xfab60075, 0xf8ca5f38, 0x2671ff99, 0xfd9bd3cd, -0xeb23d86f, 0x086bab90, 0xf9b5a57c, 0xeb66c45f, -0x146133a2, 0xd055bab8, 0xcbd53416, 0x1753b0e5, -0x3794726a, 0xec2440ad, 0xfa2615b4, 0x3b88f231, -0xcb235180, 0xf098bf48, 0x0961e9e6, 0xe9e1797d, -0xc1be41c1, 0x2cc21baa, 0xe99fab72, 0xce052e33, -0x25591285, 0xe3df2edb, 0xcb364bbe, 0x2d756a27, -0xeb59ea24, 0xc1d1d0f6, 0x6e362988, 0xf9cbf55e, -0xa5b82c94, 0x50f8df4e, 0xc19a8331, 0xa530e1f9, -0x6cb0b110, 0xe5fbb2e8, 0xead47b8c, 0x6795f5e6, -0xe205b3d1, 0xee7a0356, 0x326cfc54, 0xcf37275d, -0xd85fd7de, 0x1350a92f, 0xcc3aef0d, 0xd49db91a, -0x176692ea, 0xea49bb25, 0xc3710747, 0x177197a3, -0xfda669b4, 0xee828a6e, 0x6b4ff614, 0xef7b088f, -0xb8886c25, 0x55218b79, 0xd594d7e5, 0xb4675cee, -0x7b9f50d1, 0xf858829a, 0x85c08321, 0x78894360, -0xd51dcd94, 0xafb928bc, 0x6a53ba7e, 0xd25649dd, -0x92aafc4d, 0x4c43f1e3, 0xd2a7c8a9, 0x93b2d677, -0x4fccab4c, 0xf5dd9c66, 0xa0d7dd4d, 0x44c4b36b, -0xfcdd1c58, 0x8e3d3dc6, 0x7bef8a12, 0xf4b49134, -0xc873b39c, 0x7076dc8d, 0xb4fd61d9, 0xe0f09937, -0x72aae1f5, 0x9d96ac0c, 0xeb9cbbb0, 0x7ed1df44, -0x95a8ed4c, 0xe7f8d850, 0x7ae7feaa, 0xbd2a491f, -0xcd2634f4, 0x5722082b, 0x9d946dc7, 0xc6d85c71, -0x76f5dd1b, 0xbbefd778, 0xde98d4ba, 0x79f47211, -0xa2fd81df, 0xf566c325, 0x590fbc48, 0xa9781f35, -0xf81bf20d, 0x7e9ace93, 0xbc1421ff, 0xf5980d9c, -0x5717090c, 0x9362b228, 0xc047fa7c, 0x577bb947, -0xb41fe491, 0xe9c7ed6d, 0x7e6cf882, 0xb9a819b4, -0x47c32050, 0x591bc9e1, 0x1eeeba2c, 0x420a24c7, -0x62e9d152, 0x17ba6435, 0x5bac2953, 0x013c0ea1, -0x12e2cc6c, 0x3369bd1b, 0x289c1969, 0x1cc42846, -0x7189b3d6, 0x2c8d74aa, 0x6e54e711, 0x5c46e0b2, -0x3a0855a5, 0x5f9e093a, 0x7c928ed7, 0x28fa4c94, -0x63f803f6, 0x7bf7900f, 0x2ebdeb25, 0x452e411f, -0x433b17b4, 0xdb9ef1e2, 0x03898ca6, 0x4fbb0616, -0x38de376f, 0xea90cc1c, 0x38511e4c, 0xd148b708, -0x9d88dd59, 0x41db3efc, 0xa841a2f0, 0xed64f759, -0x0995223a, 0xf78773e6, 0xa0c217e4, 0x588d243c, -0xdeb8a347, 0x01541aac, 0x734c849d, 0x79bd8585, -0x43edc648, 0xe9ec9058, 0x395f15c1, 0xd5b649e0, -0x8ec10807, 0x78c82a85, 0xbf95a887, 0xce983ad7, -0x1d15dede, 0x43e74349, 0xa2cd38c0, 0xe9bbfcb2, -0x4553bed8, 0x2c99e9f8, 0xe424062b, 0xce407a08, -0x0c30681c, 0x3f6a4ab2, 0xefd1a7c8, 0xda291ed6, -0x2613dd9e, 0xb04a9f4c, 0xc7d9577e, 0x7d3f7e70, -0xb983db08, 0xbd3e7f31, 0x783ce96e, 0xc5d1af05, -0x936a945a, 0x532eb328, 0xeb70e177, 0xb2733522, -0x7ee59c7e, 0xe60ab1a9, 0x99f53726, 0x71620b60, -0x921ff574, 0x4d5353d7, 0x0af7ce7f, 0x4e285e88, -0x4e0e3e6a, 0x844dbf41, 0x4205aa45, 0xc02a9018, -0xa8434e93, 0xbcd30fbd, 0xe18623da, 0x5bfd5cd3, -0xcb9fc587, 0x18f149ae, 0x2d649d57, 0x362da034, -0x640fc6db, 0x74531d2b, 0x4761817a, 0x373fb65f, -0x0e22c094, 0x2c121d8b, 0x4bebf5b1, 0x66873d79, -0x5f69b37a, 0xb10d11db, 0x1d9233f4, 0xa64784ff, -0xcdd9ab49, 0x9e24a855, 0xda9467d5, 0x43fa43a9, -0xe5dffbef, 0xd3147f58, 0x342bcd32, 0xeb398ef4, -0xa07624bd, 0x612078b9, 0x99755fcd, 0xf70d7c16, -0x143d6fa4, 0x7de25374, 0x8912b37f, 0xf46c427e, -0x77a37fd1, 0x1fb824c4, 0xf8630036, 0xe756857d, -0x1663cfaf, 0xc7a6efeb, 0xe2873c1f, 0xd9ea1602, -0xc0a398dd, 0x49d778de, 0xdf5983dd, 0x61988838, -0x427ea458, 0xc3d2aa46, 0x6a7c07ef, 0x52713bf3, -0xceebe9eb, 0xf1c12137, 0x5809579d, 0x543b189d, -0xff51c01e, 0xb5837569, 0x5d6125ea, 0x1061cad1, -0xb233b577, 0xb7b9841e, 0x1635734d, 0x6da82921, -0x91fd15c0, 0xc3d89c6f, 0x40fe6593, 0x799bd016, -0xcc57561e, 0x492bb6db, 0x77c8ad4b, 0xcf0420fd, -0x4734e15e, 0x11569799, 0xc9edefcb, 0x2d67edd3, -0x1f31ed10, 0xb4038c08, 0x22d6be2c, 0x0e81af92, -0xd8c83eac, 0x0690805e, 0x61720ca4, 0x9b3834ff, -0x0c697047, 0xa167618e, 0x934bf164, 0xc93cda5c, -0xaba0f413, 0x608eebc8, 0xc28fe564, 0x55ea298c, -0x6c749175, 0xac180e39, 0x58feac63, 0x0c770a08, -0xae1e8681, 0xff829710, 0x0795d59f, 0x071a80bd, -0xf6144e2d, 0xc82b2210, 0x074b6c12, 0x39f88d43, -0xc8164ab4, 0xfc6bfdda, 0x39a971a3, 0xcf680545, -0x722ee5da, 0x8ee9f12b, 0x450593a6, 0xc6e82f4b, -0xbdce0f1f, 0x8bad990d, 0xfdce63e9, 0x70e03f0b, -0x701b77e9, 0x6de3db08, 0x8f1de62b, 0xee7cf37f, -0x4009df1f, 0xe5a934c4, 0xc4ee2353, 0x2c348eaf, -0xdc3e4eda, 0xc0587cf4, 0x109e3678, 0xdc624b06, -0x05699fd1, 0x429909eb, 0x15929d5a, 0x51d42287, -0xf339094d, 0xca1a4c9f, 0xe1ca5a68, 0x22db5b03, -0xe5323a69, 0x358de935, 0x03e3bc2b, 0x308331dd, -0xf1806e62, 0x9bec9496, 0xfd751ed2, 0x6533efd5, -0x2f05dd3e, 0x0f4f2784, 0xd1fb581b, 0xdf145b59, -0xf19b57fc, 0x0c0968ae, 0x27b6a565, 0x2d42b99f, -0x1f29a949, 0xc349a33f, 0x32d80242, 0xf4e25ae3, -0x261ccc25, 0x64b0d5f4, 0x1a3fec73, 0x7a133579, -0x5b480ed6, 0x1106f906, 0x48fb0ad8, 0x5cc98d13, -0x4bc0a84b, 0x473234fe, 0x073698d7, 0x47557d3c, -0xe48e1f44, 0x03e77cfa, 0xe798df74, 0xe158c41d, -0x2a8ea25f, 0x192685f7, 0xcff138bf, 0xde10a3fa, -0x94a9cd98, 0xc15aa272, 0x5c9bc223, 0x98c38649, -0x902c9d11, 0xb947fcd5, 0xc5ab1a43, 0x774d2dbf, -0x33031f2a, 0x45af307f, 0xf8c150b5, 0xb06ae551, -0x8cf8bb3a, 0xc5268cd2, 0x76a1f9ab, 0xbd771767, -0x86eec88f, 0x5dd4e191, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2986-m086fbB8.inc */ -0x00000001, 0x000000b8, 0x04282009, 0x000006fb, -0x7db01441, 0x00000001, 0x00000008, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x000000b8, -0x00000036, 0x2a000000, 0x20090422, 0x00000301, -0x00000001, 0x000006fb, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xebf1742e, 0x487dc67d, 0xd72853f8, 0x1c22d12d, -0x0bc4c0c9, 0x9a9da3fe, 0xa65d386f, 0x6f814020, -0x58d10d9f, 0xb7f2421d, 0xe4d5fcf1, 0x02889a15, -0xad9bed07, 0xa32ab3e6, 0x3491afcc, 0x9c991c37, -0x2a1c2071, 0xf066191a, 0x3bd898e7, 0x2648d958, -0xc05f7908, 0x05864b9b, 0xbe4c1eee, 0x1e6c7ef4, -0x0e7a539e, 0x100b2ab3, 0x1273dceb, 0xfec8847d, -0x8f37946f, 0x634e3b5c, 0x691dbd61, 0xd89e3cb9, -0x094639d4, 0x7d972e1a, 0xd6dbd94d, 0x2001c3ec, -0x34f791f0, 0xeee0d794, 0x88b7459d, 0xc2c73aa3, -0x607a174d, 0x4f0f8304, 0x65790b35, 0x00532bfe, -0x1fd1e0cc, 0x7b91f873, 0x154ed42b, 0x7a7108e9, -0x81637c95, 0x192cb173, 0x28ccd94e, 0xb9bcc372, -0xac05171b, 0x867f47da, 0xf8e8c47d, 0x1edcdb4a, -0xd2ca6c2d, 0xe9ee9169, 0x5a6efedc, 0xb6825038, -0x09277eaa, 0x2a34e580, 0x0f794366, 0x86c99402, -0x211b98bf, 0xdf8eb0e3, 0xda11d7bd, 0xd440363e, -0xa7d49f1a, 0x16dd7395, 0x5b23c2fc, 0xab93ea3c, -0x00000011, 0x2a951fa7, 0x8e2eb625, 0x872727a1, -0x44876f3f, 0x2c0f6158, 0xd45cf5e9, 0x54607168, -0xa0d26aed, 0xa3fd8988, 0x9cd32a0a, 0x34d31b90, -0x2a3d3f9a, 0x13307d43, 0x00f65908, 0xa91f7029, -0x04034196, 0xa86763dd, 0xea93a95d, 0x016c8cf9, -0x4b9de2ff, 0x9deb18f3, 0x1277d44a, 0xe3d81fd8, -0x6474e760, 0x8ad051a6, 0x91b46235, 0x8ad29801, -0x3fe22fa6, 0x1ed3d8c2, 0xe66a0f5c, 0x7351a946, -0xda8f1735, 0xf080278c, 0xd5618cff, 0x6c9a764f, -0x712612ac, 0x3675ee64, 0x681ce4c2, 0x064fe43f, -0x4748bc9a, 0x796f3c47, 0xb1506e5d, 0xa0a4bf1c, -0x399480b3, 0x12d04bdd, 0x1c1ba33c, 0x80636956, -0x09e12327, 0x844ceeec, 0x4f49dfa7, 0x5131a56b, -0xc5f6eab4, 0x829fbcc7, 0x2222d7d1, 0xe31cca72, -0x5f86e2f0, 0xfce2a225, 0x774dafe3, 0x245f6aeb, -0x31efe1a4, 0x32e45fdc, 0x9441a088, 0x0a71e66d, -0x35b665e7, 0xaf0e45d9, 0x724aaed1, 0xe71b28aa, -0x0a85d7eb, 0xc3301564, 0xaa36f371, 0x33828715, -0x3fefd577, 0xbc5077f6, 0xb61ecd52, 0x718463bf, -0x0a0b4863, 0x0230c333, 0xa07b6b06, 0x71fa24cb, -0x23736581, 0x35a24f24, 0x07aa84cc, 0xe0f703b6, -0x2e7a4346, 0x3cfd2d41, 0x0bf1cc46, 0x80618a01, -0x6d2e7af8, 0x87edb675, 0xbe715b2d, 0x9a099f00, -0x7707f4e1, 0x0be26830, 0xf4fea45c, 0x1a1ff50e, -0xac59589a, 0x5302b891, 0xcacee84d, 0x61ccba06, -0xa8fdf364, 0x52b087a4, 0xff8c1d03, 0xb70b23c2, -0x6d8be28e, 0xc5881603, 0xe95a0166, 0xa57da8c5, -0x7e9ce8a7, 0x02793a14, 0x4c3a7060, 0xb9158340, -0x8dccaa98, 0x70fe4f8a, 0xf7110d1d, 0xfe7cea61, -0x09f64a65, 0x02cdb3ac, 0x29a800fc, 0x5b31538d, -0x139172c8, 0x1392fdc9, 0x2b8ef74b, 0x8f814dc1, -0x44c62437, 0xe0ff6a6e, 0x54bcc977, 0x39531e09, -0x0ede2d37, 0x6212b87a, 0x1a4a3497, 0x18ae28e0, -0x3e4a6824, 0x0b9074a1, 0x95cec1f1, 0x42dd89c3, -0x5ec94f97, 0xe3d475e0, 0x53a99eaf, 0x9416d9f3, -0x2e7dbd9c, 0x3479d85f, 0x162108fc, 0x28fea45b, -0x88fddf76, 0xfcd3cb1c, 0xa513e438, 0xda4b54c4, -0x0cd940e6, 0x8116782e, 0x2d099a3d, 0x093defba, -0x66fd715d, 0xe9b1b8cc, 0xb19ea37b, 0x29eb211d, -0x67c4abb3, 0x99c691c9, 0x2556b76e, 0x5a18250e, -0xf83daae5, 0x68e9ea29, 0x515cfb9a, 0xe24375a7, -0x2f3c5d33, 0xc590ef39, 0x59719ae0, 0x0f2eb3e4, -0xd517c978, 0x8d63a3a5, 0x6696273e, 0x52c15c86, -0x4843e160, 0xf25a0b15, 0xefa8bfc7, 0x0fd274be, -0x344fffdf, 0x3d007a81, 0x25a093fe, 0xb6083bae, -0x430195fc, 0x255e8002, 0x0d559ae8, 0x5ae67790, -0x3b4c6ef1, 0xbd0defb8, 0x30e6742d, 0xd91e4f54, -0x23a5720e, 0x9892af37, 0xb66643ac, 0x5784c7f5, -0x5f2157fc, 0xee0bdb53, 0x053b9413, 0x12fabc27, -0xf5159414, 0x68bdd104, 0x26bb17c3, 0x2ad63099, -0xa4718f3b, 0x7d83a491, 0x00e206f1, 0xbbebcc2b, -0x2e0ae307, 0xc8f53a56, 0xcefffe4e, 0x78071689, -0xc7946727, 0x29dfdc9d, 0x5f7cc90e, 0xbd2f5655, -0x559970c4, 0x6ea3e6bb, 0xfef812e1, 0x6893f67d, -0xdaaa4616, 0x0158f920, 0x55e7421b, 0x397b030c, -0xc0e353b4, 0xadbc4870, 0xd2482de1, 0x3322a09c, -0x869852c0, 0xbfa21833, 0x22e1fbcf, 0xfc102376, -0xd38c9b98, 0xa149444a, 0xc4f3fa32, 0x54cb5d80, -0x9114ce21, 0x37b38f84, 0x7513d34e, 0x41d486d6, -0x48e074fa, 0xb61d48f5, 0x334a8555, 0x49b0cd91, -0x8a6b90f9, 0x608d74e2, 0xae96fc66, 0x0401de61, -0x740e5e76, 0x2cae071c, 0x7d30816d, 0xed545e0c, -0x49c19817, 0x2f86c1a3, 0x4777abc7, 0x6b4683ae, -0xa54de530, 0x18b258a0, 0xe3cf869b, 0xbc5cfb48, -0x344244aa, 0x8405a80f, 0xe78ca2bc, 0xc9b5c35a, -0x525a41af, 0xe9b8c09c, 0xcef40290, 0xeec8a2b9, -0x714dbdbc, 0x19fb6a23, 0xda52b6f2, 0x9fdf6728, -0x5da724d3, 0x34b1b1f6, 0xae86bb71, 0xfceec4ae, -0x90ba25c6, 0x2b4be3f8, 0xa2bf99db, 0xee319bb7, -0x65c7cc17, 0x2afd752a, 0x3099c5d0, 0xec90902a, -0x9c38849f, 0xbc784540, 0x497c2f5c, 0x8fe78963, -0xe017b2da, 0x08ab0858, 0xc4e5ebb7, 0x05216c4f, -0x8320b666, 0xe13c2e7e, 0x9ec2d543, 0xdb69f4fb, -0x1a5ab423, 0xb0bfa001, 0x4455e40e, 0xc139f9be, -0xf4a07f53, 0x3aa7b1f4, 0x241aaa2e, 0x32420dd5, -0x11e54221, 0xfd2a208b, 0x33a238b9, 0x98b808ae, -0x3bb81df0, 0xa96eaa27, 0x15733deb, 0x272c04b5, -0x6987452c, 0x95e0b3c5, 0x92ec3d87, 0x3512a49f, -0x99803ab8, 0x2ac63150, 0x9c95baf9, 0x1091624e, -0xc9cb81d9, 0x2d2290c4, 0xc49ecb85, 0xdd68050f, -0xb9168f9f, 0xcc43d1f5, 0x72913c8b, 0x7d1ce13d, -0x19f14484, 0xee9e8372, 0x6d8499c7, 0x25f756c6, -0xc13496c0, 0x2387e65a, 0xe5d1c2dc, 0x158c1673, -0x96cb1178, 0x6f2d86d8, 0xfc7d7da1, 0x7e6c19f2, -0x86667d29, 0x4212c7b1, 0xafdb4b90, 0x395386b2, -0x4e36241f, 0x6d64dcd6, 0x100b1c2c, 0x4acc5f7c, -0x1ca1d043, 0xc7f9e94f, 0x62679150, 0xfb1559aa, -0xec7ba8fb, 0xee09e687, 0x46e2a4cc, 0x83feb933, -0x7b8de254, 0xbe2c880f, 0xe21f6252, 0xad2813fd, -0xa901caec, 0xc17f5842, 0x95ede60c, 0xf03ff028, -0x1c1f5a79, 0x9bf2c0b5, 0xc9318e9b, 0xf89df2fb, -0x980e50ef, 0x883d83f1, 0x05dc5ecc, 0xbecfeb3d, -0x87cb6fd6, 0xf5194a85, 0x1b605e16, 0xa34ca7e5, -0x48b3bbb1, 0x040f6ac7, 0xe1d824b7, 0xa9a5a681, -0x1836da8d, 0x0e2e7fc9, 0x4e0b3365, 0x8f85678b, -0x7ede256d, 0x743baf7f, 0x5dd32df8, 0x3988f6e7, -0xbe5869c0, 0x417f0fbf, 0x73b7bb1b, 0xbc5436ae, -0x7c18d05f, 0xb57c8db8, 0x7ebf5b1c, 0x8f3bb195, -0x74583f19, 0xd394cc34, 0x1ff82349, 0x37543fe5, -0xe4feb4f0, 0x82e16477, 0xd25aeda9, 0x8a9d2802, -0xfb583621, 0x0b610325, 0xd04a8859, 0xb8bb9b80, -0xc1f25ad2, 0x40549e73, 0xbe9d2d28, 0x949a1adc, -0x85974dfa, 0xaa3dce21, 0xf644ee26, 0xf9b05d88, -0x3bc03eef, 0x1f0e66ab, 0xe373aae0, 0x660935cb, -0x10e02a11, 0xfc16dd50, 0xf2aab8f3, 0x0772264b, -0xf9d5a769, 0x5bfbe792, 0x33d313c6, 0xcceddd43, -0xc846fb0e, 0xea507ec1, 0x992c5cd0, 0xb972e66d, -0x6ac06508, 0x5af9e004, 0x978be6cb, 0xaa8f0378, -0xbf4c55b4, 0xd43b75a3, 0xd1633f80, 0xfaa82238, -0xa06a4feb, 0x46cdbd49, 0x235e9f53, 0x6c225389, -0xdddb8e37, 0x99987cbe, 0xc10b1a12, 0xb2b42512, -0x19b00fa7, 0xc972b2aa, 0xf655511d, 0x88b62724, -0xc736a9c4, 0xa6fd2b9f, 0xdccda959, 0xbd87d805, -0xee02ab55, 0xfebcd4c8, 0xa23096ab, 0x94495964, -0xd1c52cf1, 0x0ce33220, 0xbfd64f83, 0x5ab879ba, -0xa81cd2c5, 0x77ae5475, 0x6b1577f0, 0x4dffcabf, -0x55797d78, 0x624176e0, 0x2a675064, 0x11683e1d, -0x1c060580, 0x93bd04c4, 0xffb2591e, 0x66a04b5a, -0xa83447fa, 0xa4978adf, 0x213fe843, 0xb990203a, -0x923754f8, 0xef49f48f, 0xb832edf9, 0x8e43b18d, -0xed250344, 0xdb4838ab, 0xc0697dc7, 0xffed4e47, -0x5de04509, 0xd1f8045f, 0x54cf320a, 0xe688d018, -0x771b1fb8, 0xbc0dcd75, 0xcb9037cb, 0xb9043053, -0x136059d2, 0xd8c7ab40, 0xec859b8f, 0x0a2447c8, -0x101566c0, 0xb4fd42c0, 0x4f49a436, 0xe51071e8, -0x443d843a, 0x32c19b4e, 0xe03631d1, 0x1c4f70bc, -0xe97288a0, 0x5b508b54, 0xec895875, 0x76ee77f5, -0x1831a76d, 0xfbd8b2de, 0xa20f35f4, 0x42f27cd7, -0x89e6fe2e, 0xce560886, 0xd5366f2c, 0xbb7e6720, -0xc8d21d23, 0x9d2635d7, 0xfc916d88, 0xe5712b50, -0x2dd59e1e, 0x29be6f85, 0xdbdab957, 0xf8c3a60b, -0x7bce8080, 0xc1f09449, 0x25b54e7c, 0xa3134f63, -0x270e71c0, 0x986d79eb, 0x61efb79a, 0x41d477f0, -0xa729b9dd, 0x90322e39, 0x8bbc69f3, 0x89e64e81, -0xeeafcc5f, 0x0185dfdc, 0x7ecedfb7, 0x54f8ab4d, -0xc2fd47a3, 0xfe8c9de2, 0x931cf0a8, 0x2c798b8c, -0x278193db, 0xb3ccf34f, 0xdf25c3c3, 0xe2e55cbf, -0x0404032a, 0x5ccfce9e, 0xba950d0d, 0xe19fc144, -0x0450211a, 0x8b3bae1f, 0x99798b1b, 0xf9c2c3d4, -0xaa2a7f53, 0xad7b1a39, 0x650608a7, 0x527e734f, -0x2bf29b1b, 0x240491a9, 0x0cccc47a, 0x01caf144, -0xf112324b, 0xf4e727ee, 0x92306225, 0xcf381fd6, -0x60e74e29, 0x4537e483, 0xdf7afb59, 0x0ef3d2ba, -0xfdcbd567, 0x83bd0826, 0xf262e167, 0x318f7ef4, -0x18f79081, 0x164d96b3, 0xbd17be54, 0xc7020759, -0x4278ce5f, 0x54147d97, 0x4a7abb9b, 0xac607d56, -0x8e28db0e, 0xb7d9f6fd, 0xbfcbbc42, 0xf2a7399a, -0xcf76ee6c, 0xedd0bba7, 0xa7d38835, 0x15d43d3e, -0xd265974b, 0xdc7c8677, 0x1b1e9162, 0x8579928a, -0xba3160bd, 0x161eeb7d, 0xfbef9fd9, 0x5e988fdc, -0x8589563d, 0x929f3159, 0x2f3eb5f8, 0xd4046c81, -0x3781df71, 0xf73d142f, 0x6e09a940, 0xdf11175b, -0x4a6cd750, 0x4bd55651, 0x17ced9d0, 0x99a3ee49, -0xe0c69ec5, 0x31d25e87, 0x274567b0, 0xa9c0efe8, -0x305c7621, 0x8a941ddc, 0x30fe6e03, 0x4567e5e3, -0xecabeada, 0xd2bb30c7, 0x811ee965, 0xb4b42771, -0x60a2ef48, 0xa9d3fe26, 0x0734cbab, 0x10b215aa, -0x16e33def, 0x2b2e745f, 0xe1bd7e00, 0xf4b3c71e, -0x8d6d792f, 0xf0280da8, 0x0f20456f, 0xcf8af0f6, -0x82cbcaf4, 0xab5ff49f, 0x1d42fddf, 0x894d240c, -0x5f1ef48d, 0x8d972d3c, 0x63e94de8, 0x576154c4, -0x82435ace, 0x1b1b0593, 0xf143526f, 0x897b4085, -0x9f84047e, 0x514ca06e, 0x71b49f06, 0x3aee2eb3, -0x4a00c841, 0x619d677d, 0x6e82818f, 0x116a5893, -0x068ddb8a, 0xe0dfa2ff, 0x507a41e4, 0x48d38270, -0x36b346eb, 0x6f41e011, 0x0d1f9dd1, 0xc5ee0692, -0x37dee528, 0x5e79d22d, 0xde96843d, 0x2a53b60d, -0x5d73533d, 0x697ca3f3, 0x6471b3dd, 0x489fa5ca, -0x9e87cf68, 0x4eff4b16, 0x4566617e, 0x07e1c66b, -0x38ee5254, 0xce91ee22, 0x397331ae, 0x1f0380b5, -0x51f995c2, 0xca0a2e5f, 0xe718d724, 0x351a5b11, -0x25de8a24, 0xb97cf8f1, 0x3860a587, 0xcee65fd2, -0x02210416, 0x3b9155ce, 0x143edd29, 0x9607d935, -0x085cbb23, 0xdceb9646, 0x9cfceca6, 0x19c1b99e, -0x79920ada, 0x38e1421f, 0x09d14cd7, 0xf4bd0e9d, -0x18ef46a5, 0x0b4eb9d3, 0x7f418c14, 0x0c93d6bc, -0xf819c494, 0xc8e7f5c3, 0x8b9748ca, 0x5985d13f, -0xc38a9653, 0xd5c2f0c3, 0x32617e88, 0x4f7e056b, -0xd34f9261, 0x0c9e6b68, 0xf658e4c0, 0x0ccfb638, -0xaf95819d, 0x60971797, 0xf25289b6, 0xb0399dde, -0xb54f1ae3, 0xf6c5f00e, 0xd812629e, 0xd4da679d, -0x86be28d8, 0xfc257bf3, 0x9a2202c6, 0x651130ca, -0xd401c8ed, 0x4a937465, 0x730a163d, 0xd9a3d91a, -0x6f809aae, 0x5177a58f, 0xa765df09, 0x4c4172b5, -0x7ad2d716, 0x9d9c5d9e, 0x93542415, 0xee8332ad, -0x1d161da3, 0xd330f455, 0x364d3004, 0x24a9b599, -0xa9f0c156, 0xd4aaa6a4, 0xc69f54a1, 0x3f9b6f74, -0xe88b7075, 0x97f413b9, 0x92c45875, 0xeca74971, -0x273de936, 0x607d6947, 0xfcbb6c51, 0xd4a35a42, -0x39ab4a99, 0xd108aa65, 0xe01773bb, 0x7a477391, -0x64ef8a00, 0xa7030caa, 0xfd4299fa, 0x61afcdf7, -0x77b29125, 0x75c059f6, 0xddd86824, 0x180d192f, -0xecad4a7b, 0xbfa85eab, 0xc78b1e6d, 0x033b40ca, -0x3c22078b, 0x712de3a8, 0xc9f74b30, 0xa640b05e, -0x3a687177, 0x5a75b3d8, 0x33e4392c, 0x1d7a15e9, -0xb5c86386, 0xb60bb3f2, 0xf5a3134a, 0x98b81d09, -0x46a34f9c, 0xcbba1498, 0xecac34aa, 0x0f64d716, -0xa33a4095, 0x4506b782, 0x6c0911fd, 0x9c1860fd, -0x388d24ee, 0xde1b8eea, 0xb2b396aa, 0x18062871, -0x8ed014b6, 0xfc1cc5e0, 0x9c2aa989, 0x66c485cc, -0xed345ea6, 0xf0fc6735, 0x0174efce, 0x02afcf8d, -0x80f3f90e, 0x11e1bc2e, 0x32fdeef4, 0x936d8e85, -0xa4873205, 0xd7f97201, 0x6d1fc249, 0xbfb6c2e4, -0xbe1176da, 0x8061ff07, 0x50a96bb6, 0x3d0a198f, -0x19a51f3f, 0x17bf5db4, 0x2e67bf16, 0xbfc93f71, -0x6224b456, 0x9c58c335, 0x7fa318d0, 0x00abb735, -0xa1506f2f, 0x7b65138b, 0xc8a4c3ad, 0x0a5f0881, -0xf6ef5f3b, 0xe0f25af0, 0x71e68c61, 0x85769554, -0x4c03f549, 0xa6a5baae, 0xb7a4204d, 0x29c76c88, -0x3819f5c5, 0xaeea77f4, 0xf5e6817b, 0xdbe7596f, -0x883b5862, 0xa5a6222d, 0x92694372, 0xd797569b, -0x3ac63239, 0xd0f16da5, 0xd6872613, 0x38386a3e, -0xf39df604, 0x9cf6cfc0, 0x454e1f11, 0xc50aeafc, -0x8cde6c0a, 0x35242370, 0x238b921f, 0x19fcde38, -0x6858e9e3, 0xfca80695, 0x6fa82b16, 0x841ad007, -0x8cca0ec7, 0x571a1bf1, 0xab7440aa, 0x85dd503a, -0x6e30ab20, 0x4a554d0a, 0xe9915c46, 0x30e5df0c, -0x83559afe, 0xf935b5db, 0x77147f64, 0x52a917a3, -0xd2d4947e, 0xda2e96a0, 0x23907b75, 0xecea1cea, -0xb355a45b, 0x13acbf19, 0xd356bf11, 0xfddc1bbb, -0xbc5d2f53, 0xf5063467, 0x5791a0d3, 0x1c6153ef, -0x8bf515f6, 0x81c868f3, 0x28c99de3, 0xe277fea4, -0x23c29ed8, 0x3e1af1fc, 0x1af0fbf4, 0xf7aca48a, -0x6f0947c9, 0x2d118558, 0xa4e272fa, 0x83e87111, -0x732009e0, 0x07312dec, 0x9edab8f1, 0xa598e688, -0x39278bac, 0x2ddb6446, 0xfbd2d018, 0x5d8e5bf6, -0xccf9f835, 0x66e8893f, 0xc6ae5cdc, 0xb631947b, -0x69ee9172, 0x7818ab85, 0x0e32baee, 0x7011a6bf, -0x74f0c212, 0x4c036f87, 0x9ad3568a, 0x3e9d49f0, -/* 1521-m5ff4807.inc */ -0x00000001, 0x00000007, 0x06302005, 0x00000f48, -0xd0938263, 0x00000001, 0x0000005f, 0x00000bd0, -0x00000c00, 0x00000000, 0x00000000, 0x00000000, -0x26d329c9, 0x2a31e166, 0x66c2f9e9, 0x20f1b679, -0x8418e6a9, 0x116f5f00, 0x707d6a41, 0x3e4d0c52, -0xfbf77861, 0x11d27df0, 0xa8781fda, 0x1607aa8c, -0x9065f419, 0x16028cad, 0x0a73e487, 0x82e268e8, -0xb25b4ffd, 0x35e5ce9b, 0xb7076c9e, 0xbc89f562, -0x82500ee7, 0x84bbac26, 0x56a91ac9, 0x3b779797, -0xc366ffba, 0x82c1edf0, 0x2efa4b95, 0x638fe157, -0xf4931de2, 0x1de21ba3, 0x92860c8b, 0x605c4d0b, -0x49c76b47, 0x698c8b80, 0x6725edb9, 0x1be37787, -0x0513890b, 0x69e5aa1c, 0x1c109c96, 0x9276986d, -0x8df3ba1d, 0x091851f2, 0x879b75e2, 0xaaa7fb42, -0x867616cf, 0xbc6dce65, 0x4a6d1dd3, 0x16bed1b1, -0x1d889d22, 0x90f4fe8d, 0x7146fe49, 0x6dc47fc0, -0x2deeea68, 0x106c9c9a, 0x0c3236b6, 0x4ce15a87, -0xf4e86e50, 0x62ed122b, 0x103315d0, 0x045348ad, -0xccadafdf, 0x751df108, 0x7cd8a8f8, 0xf6094c95, -0x6dfa8897, 0x06cb717b, 0x812e7985, 0xe2138280, -0xfbdbbd90, 0xcd78270c, 0xd1136263, 0x1624eca4, -0xac36fd00, 0xc6f92d02, 0x7d7cde6c, 0x7d42f8d8, -0x1debf85c, 0x16f44a7f, 0xb108cefd, 0x6f74f0e7, -0x2cf15966, 0x43b44ecb, 0x0c7acbb5, 0x3f811a1a, -0x7362aad9, 0x60a38395, 0x0bea2c1d, 0xce4c32bf, -0x73ef7173, 0x2c3e8a79, 0x57f45aa4, 0xe936c616, -0x1e2ac943, 0xf7936b29, 0x2bc26fcd, 0x1415abeb, -0x6b2a186e, 0xde918cc0, 0x1c260822, 0x27c38d5e, -0x711e0ba7, 0x3954496b, 0x4a142649, 0x3044ed5c, -0xf64e33b4, 0x1135ab77, 0xf5eb8a21, 0x1b8812ba, -0x9ce2a81b, 0x180a3666, 0xf7ad6aa5, 0x0bcd4265, -0x85412eed, 0x3dd0cd50, 0x47bfa46a, 0x1e1361be, -0xdf1442e8, 0x37d16ec2, 0x9b001437, 0x1d3f0f83, -0xd19cdda9, 0x1842234f, 0xa1816f52, 0xae04e7b0, -0x29785274, 0x33108fa9, 0x0be625c2, 0x99c34506, -0x5a2a3fb2, 0x899c02aa, 0x201a96bd, 0x30f06406, -0x119a16de, 0xa9f8cde4, 0xfd3f05a8, 0x1d32e01f, -0x7d255d7e, 0x1ab06d89, 0x82f8e458, 0x372e977a, -0xbd4383b3, 0x35b339a8, 0xbed83b22, 0x3ca1a8e1, -0x9acb1a79, 0x133015f1, 0xab2de80a, 0x1ffa4635, -0x7b289ca3, 0x27d464a5, 0xbf8513aa, 0x0953f0ef, -0x8c289cd9, 0x29bfd938, 0xb330e038, 0x2e752cbd, -0xef07878f, 0x0abdde48, 0x23bdbeae, 0xacb2961f, -0x256b164e, 0x18cd4b10, 0xb8710450, 0xb3473090, -0xf93076db, 0xb3af056e, 0xd42d7443, 0x058038f3, -0x0cb42251, 0xb59f0cac, 0x4aee1890, 0x3a3dac62, -0x834e2b58, 0x008ce6e8, 0xb54665aa, 0x011af9ea, -0xef75ff6e, 0x28105b21, 0x99e65e67, 0x26b786f8, -0xc54fa94e, 0x2ca1ec0c, 0x97f5cdea, 0xc34c6a73, -0xf84db454, 0x0ca6a53f, 0xd4439423, 0xfce0200b, -0xfcb91cf2, 0xecd91276, 0x8410b378, 0x36d0417a, -0xe5aba0cd, 0xf499e947, 0x5db658f2, 0x59c7b74f, -0xfb5534b5, 0x24962122, 0x6cb4a7cb, 0x751ff89f, -0xcaaf49ec, 0x687e084f, 0x98fb9aee, 0x194bcdc8, -0x4a4ebb51, 0x7a7a5ecd, 0x0608ca23, 0x9c452376, -0x37fe00df, 0x3fbae5e5, 0xa4ac30f4, 0xab34d2f2, -0xa9809c2f, 0xacda54b5, 0x928ff76c, 0x3acd87c4, -0x4e993e24, 0xaddd2bc3, 0xf209c792, 0x7e2da52a, -0xce7b681a, 0x0032afeb, 0x88d3e9e0, 0x498296ba, -0x2f6aad06, 0x55a24b33, 0x9b025513, 0x0381fe99, -0xd55c4f51, 0x57f667a6, 0x993673b4, 0x9c9b87ab, -0xf4f1b67b, 0x31a03ebb, 0x903390b3, 0xaddf67b5, -0x07cd982f, 0x8140dfd2, 0x8d5d0100, 0x0fd5b620, -0x2c77b00d, 0x923866f7, 0xe4ff8e7e, 0x1de67a57, -0xa3bff444, 0x3e73ab15, 0x3815c6dc, 0x347067de, -0xcfd4a9d0, 0x261517ca, 0xe65c41d4, 0x15dd1d33, -0xa3c61112, 0x27186852, 0xd75a74a4, 0xa907a37a, -0x450a1a48, 0x3681379c, 0x14688ef3, 0xb394ca30, -0x6c6a7180, 0x8d92a1c4, 0x54d485ba, 0x12ce5cd8, -0x05abf478, 0x8ab2eb67, 0xb35331ea, 0x7b0eb20e, -0x49875e9b, 0x0f537d80, 0x793d97b5, 0x739c4919, -0x7457e25c, 0x59bb23b8, 0x92f14d7a, 0x3aee7846, -0x94f0d443, 0x72c7840b, 0x3c39f33e, 0xd6249267, -0x04eaecf5, 0x01eff271, 0xff3fc968, 0xd5be480c, -0xe98acc2d, 0xe66a8c10, 0x853553a7, 0x1814dc35, -0x3b0b33f7, 0xff955179, 0x79be003e, 0x2e0922ce, -0x66038e77, 0x35d7d68e, 0xe0472ea0, 0x08adc04f, -0xc9e431f4, 0x20533f0e, 0xb0c1a69c, 0x1bdb8cde, -0x79cd5852, 0x12bc5c95, 0xeb92a5ec, 0x87e4dec2, -0x372a6079, 0x1a0b68b8, 0x0fff60c3, 0x975946d3, -0x7f81f7b8, 0xbbf6f932, 0x72ae43ec, 0x09e15978, -0x1f6c46bd, 0x9c4c535c, 0x6940e513, 0x5d67c5b2, -0xd5d9cf00, 0x06234f8f, 0x49516da5, 0x6dd03aac, -0xc08dfa52, 0x4f2254c3, 0x59626c09, 0x3f0e1970, -0x81dc904d, 0x6f69377a, 0x991daff4, 0x57cff106, -0xf749da77, 0x0c2692ed, 0x3eafef42, 0x6efb757d, -0x873b1130, 0x418474ad, 0x1c4cf7ef, 0x2311e096, -0xb67cf807, 0x6dd18fd1, 0xc4c68d72, 0xfaf3bfc9, -0x89f35dfc, 0x19b07cc5, 0x27209822, 0xe2a9b0dd, -0x2bbe3848, 0xc657b6bc, 0x3f50b3a4, 0x2a801164, -0x11e7992b, 0xef41594f, 0x1dc7afd8, 0x4e86fc9d, -0x3e19d225, 0x04b2fb67, 0x2530bf28, 0x4d5310ed, -0x5e73962a, 0x582755ea, 0xf8d6afb3, 0x0c11d4fb, -0xe1824faf, 0x490811c5, 0x3d78a250, 0xa32786d9, -0xbd626c2a, 0x20c7898c, 0x0a740d2b, 0x95d42069, -0x3c54f3d2, 0x802294a6, 0x91734eda, 0x360edb8d, -0x91c193e3, 0x9c102c40, 0x6d0f3116, 0x34de39f4, -0x98ef4001, 0x1afa00b0, 0xab57cd3e, 0x071de60b, -0x58b9bc66, 0x12878ac8, 0xf09db7f4, 0x2d24a91f, -0xa2146992, 0x015ca3b7, 0x851284a7, 0xf222f9c9, -0xe170191d, 0x3a665e9d, 0x45851684, 0xe397777d, -0x4747ae71, 0xcc99dd99, 0xc546154b, 0x189d7ca5, -0x2c7bf0b5, 0xdf8ccd5e, 0x3f203b3e, 0x662b2c60, -0xe734fb1b, 0x21393f9e, 0xadb29511, 0x67c90049, -0xd5bb8b21, 0x4e69c8bd, 0x65db40f7, 0x2a69a9bd, -0xb56edbb4, 0x6fae3038, 0x03219228, 0xdbc4af3d, -0xa59d7a3a, 0x362d2168, 0x0d9c7c27, 0xe62be3d4, -0xb63a6b13, 0xef7860d3, 0xa4d117f9, 0x369be422, -0x8d27cc00, 0xc7a1bb67, 0x7836549c, 0x20ed758a, -0x90ad7500, 0x38b929a0, 0x3229d9af, 0x154b028f, -0x97232dda, 0x15cb4f42, 0xa58077ec, 0x276ccbbe, -0xb0de78fb, 0x3264115f, 0x0f4b174f, 0xbe2a65a6, -0xda506ff5, 0x0d4d559d, 0x79948872, 0x8a95fd4c, -0x12d6335c, 0x844f497a, 0x9bb45150, 0x28bd620c, -0x80b40b4c, 0xb4051d5e, 0x455eae91, 0xd28e3e52, -0xac4d592d, 0x3ad6a991, 0xf074cb5f, 0xc6973256, -0xaa71e4c3, 0xd6eb7c57, 0x581a55e7, 0x00e1b63b, -0x255aeb5c, 0xf027ba58, 0xd9bfa4cd, 0x6d03b145, -0x663eea00, 0x29233db7, 0x4437557b, 0x5a7c23ee, -0x365580a1, 0x411f866d, 0x8c9bdcd3, 0x2b4a96a1, -0xc8bf36ea, 0x51236715, 0x7132a778, 0xc73c07ca, -0x8d289809, 0x3c974992, 0x5d770492, 0xc2908798, -0x00a24042, 0xf4bc0a54, 0x40c0ba8d, 0x07b1258e, -0xbc51f7c4, 0xd9ee4929, 0xbe0bfc9c, 0x334421b2, -0x889eebe8, 0x3c03fcbc, 0xbf22d714, 0x3587a446, -0x37ca6e3d, 0x01e338d4, 0x31bf68ff, 0x00fabf85, -0x57494c1e, 0x17020886, 0xbc0572eb, 0xdc9600ab, -0xeb710c7b, 0x0eddd9b2, 0x1193ed40, 0xc69f5e7a, -0x62040a15, 0xd0e3e898, 0x0b18d0af, 0x366af56d, -0x5b8536d6, 0xe4a65046, 0x965930f4, 0x263cb67e, -0x09c9d4f9, 0x3bfb7a4d, 0x95bad066, 0x30133fd6, -0x3e15f9bc, 0x0e194da9, 0xa5b2b20d, 0x2a2936dc, -0x336f26f0, 0x3f344e86, 0xd9488143, 0x8b64dd28, -0xbd4b145b, 0x200a19bb, 0xd21537be, 0x908c8c9f, -0xa8221796, 0xbbb73fff, 0x07e356db, 0x38bec8d1, -0xfa6ff6c0, 0x86835c79, 0x76428063, 0x5ee63b8c, -0x05498359, 0x394944ec, 0x2cc16b7a, 0x40e36aec, -0xdf71f61d, 0x5d2c7324, 0x08efba21, 0x37ac71ea, -0xa2b2b251, 0x4b986748, 0xc28aaa7f, 0xcf84e31a, -0xeb2fa943, 0x057e302a, 0xa2530048, 0xefe24dd4, -0xa8fb035d, 0xfc417d87, 0x4629a3b9, 0x21775352, -0x1a5a64b8, 0xe59b2055, 0x8e257fcd, 0x24261511, -0xb2be3f5f, 0x1b4ef82d, 0xe131fe18, 0x337b53c9, -0x55c11b19, 0x229e3819, 0x11a8923a, 0x0dd5168f, -0x507dafa6, 0x1dc50a76, 0xb4aa3257, 0x8ddfca38, -0x1c987a61, 0x20735b89, 0xa73455c1, 0x8f459b40, -0x05007320, 0xb65bd8d8, 0x938a9956, 0x3913cd4b, -0x37cac3a3, 0xb14cc5e4, 0x5b0372df, 0x2777e6c1, -0x6a6259dd, 0x05f27545, 0xba159c25, 0x3adfb42f, -0x77016837, 0x09fc1014, 0xbfe6dc10, 0x154f77ea, -0xb6f1ce8e, 0x2aa99bab, 0x230d5ff2, 0xa3bef6f8, -0x6db613a1, 0x39e0167d, 0x9d057421, 0x9cd0aed8, -0x4c722d24, 0xaebe325e, 0x259dfcc5, 0x39b4b6e4, -0xcec2edb0, 0xaeda631f, 0x646977ed, 0x41e40c9c, -0xff8ecfd8, 0x0892af92, 0xe7d50c3b, 0x6fb106e2, -0x63206315, 0x78070c93, 0x9d03b462, 0x163a4202, -0x92ef3da6, 0x5f249006, 0xde090c17, 0xea9f368b, -0xb67f6e31, 0x22c1870a, 0x23541006, 0xdcf6fab1, -0x55150fe3, 0xc0dbd69f, 0x3d3f88e7, 0x1da20749, -0xdb4c7249, 0xfd1e1242, 0xd15db994, 0x71104f58, -0x078ee22e, 0x2ac24674, 0x28c84427, 0x460e4859, -0x520980fc, 0x6222abd4, 0x362bb52e, 0x183b64f0, -0x75d5c416, 0x7ccae489, 0xf7083301, 0x83b210d7, -0xf391a201, 0x2c0e136d, 0x51b6872b, 0x9db440dd, -0xa59d7875, 0xa976f5cf, 0xc705bdc2, 0x0b7fa6be, -0x1f4c0df4, 0xa63395cd, 0x926a78a6, 0x3a3fb625, -0x276ebcef, 0x0f1595dc, 0x1bcab7f7, 0x065744f9, -0xb7679ba0, 0x24606525, 0xaaa30b45, 0x341f5ea4, -0xd155c561, 0x1b4b0a65, 0x63a36a4b, 0x097d9eea, -0x2a07c905, 0x1e2fc01c, 0x8860a3b0, 0x25eabc20, -0xa4c20b4a, 0x353eb5d1, 0x31964504, 0x0e224464, -0xb6cfca44, 0x32bb77ac, 0xf3e37914, 0xed46cd81, -0xe57acbe7, 0x1d6922ea, 0x7251aac0, 0xdfc9cc46, -0x6fa6b37d, 0xd3a99cbd, 0xad81ff1f, 0x36b291c0, -0x91ff7f94, 0xee28fb63, 0xe5a52bb6, 0x5f1037db, -0x88587ff9, 0x3df7d637, 0xb0b61834, 0x7884cdfa, -0xb1732935, 0x00d0306b, 0x824c92d2, 0xd09640b8, -0x35d5aa27, 0x1e6aef33, 0x75e5850d, 0x18ba7cab, -0x735c8ad5, 0xd79045f3, 0x9b86ccba, 0xd5448883, -0x68784740, 0x9dede6a6, 0x37540723, 0xdc8dfde7, -0xbb3fce7d, 0xa8de647c, 0x5d414a14, 0x2dbc3e19, -0x06fee8a2, 0xf9df2b49, 0xa66607bf, 0xa6793f17, -0xace3fb23, 0xb30c40ea, 0xff798ce1, 0x8c87c2a9, -0xcab87256, 0x730ff551, 0x9c8addc0, 0xcb52ac8b, -0x60b47338, 0x8ff343fa, 0x18a69cac, 0x2866c9db, -0x6c0665c6, 0xbb9d9b29, 0x3dda21c4, 0x773f8916, -0x77c4ae2b, 0x6e1b6c6f, 0x85b98de2, 0x9fd1b7be, -0x33917c11, 0x2be25fb1, 0x1ae146dc, 0xba0d2703, -0x0c8310d1, 0x801d6100, 0xb7dfde3f, 0xccc72ddc, -0x7b09d6d5, 0x921e54ae, 0xb72ee68e, 0x11e69284, -0x0efff061, 0x07983fe0, 0x6cf3bd9a, 0x0eedd36b, -0x1444744e, 0x37c5b1ee, 0x8f6c17c9, 0x75dbd656, -/* 2389-m16f25a.inc */ -0x00000001, 0x0000005a, 0x09262007, 0x000006f2, -0x594ddba0, 0x00000001, 0x00000001, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x152fb7fd, 0x850cbe5b, 0xe75e2947, 0xf788eb54, -0xabca24f1, 0x16fc1a71, 0x7f21cab8, 0x3d73c05c, -0x755d87e6, 0x13a4319f, 0x557caa79, 0x18cae86c, -0x73f505c1, 0xeae87978, 0x935e984e, 0x21e586a9, -0x6f8dd7cf, 0xb13522c2, 0x8ac3f259, 0x22fec739, -0x9fa75b90, 0x3a73fcc9, 0x1f3de62b, 0x9118414f, -0x788f3e85, 0x02dd4ff6, 0x9d1ca368, 0x58bbb255, -0xf60514cf, 0x0740be5a, 0x91c73633, 0xc9d2a381, -0x32d6d9c8, 0x5f6763f3, 0xefbdaf07, 0x5520aff2, -0x4ecf52bf, 0x417700ed, 0x61628b47, 0xbba700d5, -0x65492543, 0x77d372ed, 0xcc6f7445, 0xe8e1f1fc, -0x4f168aa8, 0xbda26bae, 0xaf4d8926, 0xb9dd2c84, -0x2f7bf0e8, 0x01086c71, 0x673ba5a1, 0x1a4502ef, -0xf6e77b29, 0xc2a5a476, 0xf2269ba8, 0x63d33a8e, -0xb7e9fb2c, 0x543b2915, 0x1b457be2, 0xa1c59632, -0x2c84e2e7, 0x9cf6439f, 0x65ed7d8f, 0x95b4267d, -0xd7bce79c, 0x4797f834, 0x68cdd196, 0xd5f0e2ea, -0xa3ae3170, 0x7cfe8168, 0x7afd2fdb, 0x012486da, -0x35f1667b, 0x0973298f, 0x00091763, 0xeee07b37, -0x90e4a608, 0xe76e89f7, 0xab4c198e, 0x49572f69, -0xd023feb1, 0xf058f820, 0x5c07ccda, 0x606dac10, -0x20b87c7a, 0xb527d8c9, 0xfe2c66c2, 0xcd8aae4b, -0x4b238f67, 0x3432b883, 0xcc779cf3, 0xc79b4662, -0xdbf4f9f6, 0x4eb4c769, 0x48c093f8, 0x601f6666, -0x5ddd73cd, 0x6559ed49, 0x252b9fe0, 0x7fdf6ba7, -0xd976c227, 0xb848e27a, 0x769d43bb, 0xd76c31b7, -0x8a5fd658, 0x95a5c6b3, 0x9f1393a2, 0x25e918d1, -0xe96a36b2, 0x1aaecb55, 0x068c18cc, 0xe6614d61, -0xa232c14b, 0x13d513d2, 0xd9ccd4d9, 0xca99a988, -0xd44b42cd, 0xb6abb17a, 0x07031920, 0x886f8fe1, -0xc7756a52, 0x82ee4f9a, 0x2f356d42, 0x2044dcb7, -0xea2da2ab, 0x7726fd32, 0xcf979e08, 0x5e0e0354, -0x1ba120b3, 0xcc21b547, 0xbf98e8ff, 0x114a1bfe, -0x3e41fece, 0x07b5f920, 0x88cf832b, 0xf5e98deb, -0x34747f7a, 0x03a39064, 0x5da11460, 0xbfb41656, -0x95a111fa, 0x1df7e7d2, 0xf0680ade, 0x071d3c53, -0x79ba893f, 0x7791507e, 0x5a098130, 0x9a7752ab, -0xa6a4a0a6, 0x4f45a65b, 0x3614be25, 0xd65ae806, -0x82fafbf9, 0xcf9a932a, 0x16e39c33, 0x0eb56b4c, -0x08c6d8d2, 0xdc73c409, 0xa0153cc0, 0x88a68745, -0xfdd65375, 0xfaa74f1a, 0xf6e6877f, 0x1a0c85d2, -0x479f5a10, 0x78f67d26, 0x88c910c6, 0xf36fffad, -0x4082b994, 0xd266ac62, 0x4d739545, 0x1fc2f70b, -0x1b7e1ac0, 0x67777d41, 0xecda77ef, 0xf32afc1d, -0x15dee9c4, 0x60e531c8, 0xa5c54184, 0x8f22a836, -0xaee5e044, 0xe1c0617d, 0xc00d440c, 0xc93395a2, -0x86e7c3b7, 0x318382f8, 0xe53c45dd, 0x18b57b37, -0x6000e01d, 0x22cc6cc4, 0xe265c1f3, 0x98012e13, -0x038eec0a, 0xb2f6cf92, 0x89ce1fe5, 0x43de926c, -0x5a0b8ae3, 0xb6cfc1e3, 0xa7e8a621, 0xc6bfca93, -0x9e1b77d1, 0xb8fc54e7, 0x7560bd2f, 0x4cabd94f, -0xc6831724, 0x178bc5e6, 0x1f9c59a0, 0x269e95c2, -0x03c270c2, 0x8db34d1e, 0xbe92f0c1, 0xdd0445b1, -0xd3113a3c, 0x876339a2, 0x810f39fb, 0xbebe992a, -0x780c4d20, 0x8407ca95, 0x9ab841f0, 0x36cdd022, -0x863f1c26, 0x4c40d415, 0x94fce6ce, 0x8388f1b0, -0xe63d30b3, 0x8267aa21, 0xaa68b68b, 0x191bbe3e, -0x7ea62abb, 0xb0d0c35d, 0x790d80de, 0x5dd613b8, -0x42fde2b1, 0xddafeb79, 0xf5b58ec2, 0x3a972e04, -0x1dfd433d, 0xc5c3c230, 0xf09997e2, 0x30e1411c, -0xf05fcbcf, 0x6b5be86b, 0x48e480cd, 0xad260caf, -0xb279f8d6, 0xa883729e, 0x3a143f6e, 0xe8c59008, -0x5f5a1a05, 0xc576e1f5, 0xb22bbd82, 0xef74f199, -0xf4d8b068, 0x7106e506, 0x8182a8cc, 0x9d794773, -0xb1d603be, 0x3478f207, 0x85026e92, 0xe91ecc16, -0x73294d00, 0xfe797696, 0x75c8310f, 0xe9964758, -0xaf769bd0, 0xde532e94, 0xb7578b7c, 0x5916f8ac, -0x6fba254b, 0x5739e288, 0xec6800c2, 0x507f69be, -0xf442a1ea, 0x871e84f0, 0x7116a0ef, 0x576648be, -0x4dee7717, 0xe099452d, 0xa0ade876, 0xde18e59c, -0xaa0fb31d, 0x4e92256f, 0x5d44ca1c, 0x251b2dae, -0x476cb2ba, 0x85237506, 0xef2b6aee, 0xd0936e7b, -0x30f8ba52, 0xb923acda, 0xe0d0c993, 0xd3de81a4, -0xf6cdece1, 0x27ed29b3, 0x21dabde0, 0x935ff7f5, -0x9d855b92, 0xa52cb2f2, 0x498fa9b3, 0x49bf08bb, -0xa36266a9, 0xde341a10, 0x885675fb, 0xd8264d75, -0x6c2a8e9f, 0x48d4875d, 0x9aaf73e3, 0x422aa96b, -0x15a58d18, 0x1449a939, 0x93cf44b6, 0x501896fb, -0xd59a46eb, 0x90ddacad, 0x84fde9ad, 0xa3295550, -0x3704c2a4, 0xb9e6c49e, 0x088237b7, 0x1772a5ab, -0x32d7f004, 0x54c680f4, 0xcd5c7635, 0x945ec9cf, -0x66893f71, 0x36c50881, 0xc51ea31c, 0xacbcfffb, -0xcddc5d97, 0x56a70a0a, 0x9e64a05c, 0x50d632ee, -0x4c2517b7, 0xe781d33b, 0x83da0d2b, 0x17cdb806, -0x15aca814, 0x82db0921, 0x40d2c497, 0xf28459b8, -0xaf62cfa2, 0xb6657c05, 0x96f8c0b6, 0xd3b1305e, -0xc3dd0d08, 0x04b7e05d, 0xe95854d3, 0xefee27b9, -0xaf33db1d, 0x920a7626, 0x66680468, 0x32348218, -0xb627a0e2, 0xa794b5fe, 0x2cde0b39, 0xaeb66413, -0xfec7e465, 0x1a8038ce, 0xd2b94d31, 0xd63ffead, -0xbb03b14b, 0x1fb7384c, 0x16c47560, 0xd4920900, -0x027470d9, 0xe4f22b45, 0x9c5d987c, 0x029e447b, -0x7d67d952, 0xade3cd07, 0x37b7814a, 0x9db82614, -0x4bf56cd2, 0x8d711f84, 0x9cff31fa, 0xfbfa8289, -0x8fd9bf51, 0x8f354bcd, 0xf81e7c6e, 0x3464e90b, -0xb7360bba, 0x050ea5d0, 0x30ab2959, 0x4d83c638, -0x3baafa77, 0xd7b5c348, 0xde518699, 0x073dbbfc, -0x84bf5141, 0x4f0b446f, 0x8e19fc4b, 0xca72ab4a, -0xfef52d7a, 0x67308c55, 0xd11a79c0, 0x1cd51780, -0xf03aceb9, 0x62a55ded, 0xa3e00544, 0xc71845c1, -0xc2bf8165, 0x12e69ba8, 0xfcb4cd01, 0x6cb4cf9a, -0xea6d586d, 0x7fe13e82, 0x9d54a259, 0x97ac9459, -0x80a49396, 0xc85d02c6, 0xf0fbf19a, 0xc0860ae5, -0x3ff44232, 0x76602448, 0x0a706a10, 0x141dd13c, -0xe61b8b64, 0x6e4be14a, 0x4e6d87a9, 0x478d98ea, -0x730a2273, 0xb7007acc, 0x692ec7b3, 0x1d389f7d, -0xb793f67e, 0xd8d66265, 0xd8b993b4, 0xfc6d88bc, -0xa9d3add0, 0x9e59435a, 0x9e7969f1, 0xd243fd73, -0x6effdde5, 0x1dbf31a2, 0x320ca346, 0x1b73bfd8, -0xda401aa8, 0x13cdf71d, 0xfe20d240, 0x3bdfecdb, -0x0b123e41, 0x752ee304, 0xd9c5da00, 0xe3c01c7e, -0x9ce03107, 0x89d8a300, 0xbede9c6d, 0x438d0958, -0x2841ebbd, 0x7c7dfc6f, 0x1849ab1c, 0x1178a256, -0xca4abbae, 0x2e0bb313, 0x888e8346, 0x595130bc, -0xb21f1bf2, 0x4cb7ad8c, 0x96749830, 0x0c3516ba, -0x2302f8c1, 0xb111f506, 0x8395f1ea, 0xfde48a3a, -0xf3735f71, 0xc9659b54, 0x88992529, 0xeb887aca, -0x6c0e87f6, 0xd6362d67, 0x968fd0ac, 0xcff7ea9a, -0x7988fd1f, 0xd00271db, 0x38c22f93, 0x34badb85, -0x9f8f2283, 0x577c6448, 0xb1bd60e1, 0xd2796580, -0x50c829e4, 0x0605fdee, 0x748ddfc7, 0x36bd94f8, -0x264749ba, 0x8a54e5f6, 0x3a19a84b, 0x6f584bd0, -0x64fc0ef3, 0xe7e98d57, 0xcc4d8e0c, 0x041a0079, -0xf5084b9d, 0x4c3b3927, 0xfa1d2e98, 0x71dcd1bc, -0xf74491ea, 0xfd97d9f7, 0x768912d6, 0xb1d674b4, -0x52f0716e, 0x8387ed44, 0x7a3406cc, 0xd9b25c3b, -0x3c2856c7, 0x99f4bd12, 0x44d2e06e, 0x4056feaa, -0xe731e402, 0x490774b3, 0xa6377412, 0x5b57bc0e, -0xe37ee94b, 0x1aef05a3, 0x3729ca7b, 0x7f804ba9, -0x589b5805, 0x60354265, 0x2cf4d695, 0xadb62dce, -0x853cfcbd, 0x31cb5ebb, 0x00c80ca8, 0x51cdb21b, -0xad6be78e, 0xa8e9ffeb, 0xb656155d, 0xafea149a, -0x9fbcb3bc, 0xc89f6b72, 0x6d03f3bc, 0x3381da15, -0x8a267f92, 0xdcf5bf30, 0x38496dbf, 0xc5bd6b9e, -0xa9918af0, 0xc8fad63c, 0xe218d792, 0x83eacea6, -0x418c76a1, 0x749d613e, 0xbe36f88c, 0xb84cd7d6, -0xb4e7308e, 0xce6e4143, 0xd39fa6a0, 0xbe7bb3b1, -0x9eece758, 0x8d490022, 0x9c5b92cc, 0xc57b244d, -0x6b442bb1, 0xb19d0c26, 0x1e3e1fe4, 0xfd9e384c, -0x642a3233, 0x4b7a4358, 0xe4b4a9b0, 0x920a89bc, -0x67bdce9c, 0x7d96b2ac, 0x5cbe3c13, 0x4af3f4b5, -0xa4e701d3, 0x80b4efe1, 0x841613f3, 0x64a49885, -0x45d821ff, 0x1a7a2117, 0x93147289, 0x8ebbe7e9, -0xcd3f04c4, 0xdb888d97, 0x0c55b583, 0x80ace4e3, -0x11ab298e, 0x8fc499d4, 0x98ec32fe, 0x086b0642, -0x290732f1, 0x562bb750, 0xac9b7a2c, 0x1f1b85e5, -0x04ac16e9, 0xc9e86674, 0x5eecf0cc, 0xc276c820, -0x5584fc0a, 0x947af43e, 0xc391c579, 0x59f0f0f3, -0x33d729c8, 0x9250c732, 0x3b364a2b, 0xcc028b92, -0xf6339e57, 0x67bdb10b, 0x8adc8905, 0x808475e0, -0xfb69fcd1, 0xf7088f7e, 0xafcd6732, 0x0ffcbbfd, -0x64058baa, 0xbaa6996f, 0x04221519, 0xe64e5801, -0x3d1b3c28, 0xc5ab8d20, 0x5291ed0e, 0x52e8939a, -0x79ebe0a2, 0x5e548b49, 0xf069bbc5, 0xd102a0ec, -0xe5a7b49c, 0x0a9f6417, 0x67493489, 0xe386752a, -0x59755c62, 0xe95ea052, 0x4d4f6403, 0xa6636625, -0x93cf3e3d, 0xe2894a74, 0xf7f55522, 0xfeddb51e, -0xfb5be65a, 0x8e5ef093, 0x52bce66f, 0x56937c52, -0xb0bbc6c2, 0x03574feb, 0x0d0c94c0, 0xd160828b, -0xccb2f851, 0xabcb3b49, 0xc3eabce5, 0x7930acd8, -0x0076ca0e, 0x85cc9159, 0x2545f934, 0x6968716b, -0xa01609c2, 0x592322f9, 0xac8ca99c, 0xf97b4b52, -0x398fbd8a, 0x403d0e0b, 0xa38b4549, 0xcd89c55e, -0xc6cfbce5, 0xb932e3dc, 0xa5242c59, 0xe391ceb8, -0xa1efb4eb, 0x06ee07eb, 0xb4d5ddd1, 0xae38b88c, -0x0bb94dfe, 0xf02b0125, 0x910bb8be, 0x80f9d20c, -0xf017bc44, 0x18342c66, 0xc4495bfe, 0x14e9b1d8, -0xd61a63f0, 0x1283c3dc, 0xb8663c79, 0x591f1fc9, -0x0f52cab0, 0x530e9c52, 0x327f0380, 0x932c89a0, -0xe7895303, 0xedeb046d, 0x400219af, 0x08eabb3c, -0x824199ce, 0xbc188572, 0xe35e844a, 0x409b6afa, -0x9d80ae8d, 0x98be78c2, 0x49049ab1, 0xfb921fed, -0xf47c6b1c, 0x54ce9a0a, 0x9c81b083, 0x31694911, -0xc5adaa93, 0x51f4d362, 0x45949957, 0xa1bc132d, -0xdbc037b8, 0x510f859d, 0x4a3e70d0, 0xea91f20b, -0xbaa64855, 0x32acc401, 0xc689dcc3, 0xac71af82, -0x47a2c479, 0x617b1df3, 0x98968c18, 0x3f342afc, -0x921cdd37, 0x9c515004, 0xdea8d3e3, 0x576fa5ff, -0x719a6fae, 0x98635ce2, 0x4eae86fc, 0xc77aedff, -0xe3076a45, 0xf672338b, 0x3e930234, 0x43301a6b, -0xad2fe508, 0x4d307dde, 0x2e9a599d, 0xad7e4242, -0xa62b3239, 0x14b02e24, 0x43d3fb7c, 0x31fb39c0, -0xc1c4de0d, 0x44984242, 0x1d35462a, 0xcdb6205d, -0xe138a574, 0x33cd0479, 0x2bf3fa56, 0xb25de4ce, -0x99a25cc9, 0xa7859b8c, 0xc4dc3178, 0x898d8b27, -0x47778970, 0xf4b3a46a, 0xbbba9097, 0x18824623, -0x3941733d, 0x5028d200, 0xb4c6c63e, 0xe552da5f, -0xd0af35d9, 0x70d99fd0, 0x5e483b30, 0x6826811d, -0xd6f56267, 0xccbd900e, 0xbfe8e78a, 0x34f53ae9, -0x28b554a4, 0xd0c8b157, 0x91e55d6d, 0xdec21006, -0x74a135df, 0xd5d3d4fc, 0x24011884, 0xb2946e4f, -0xa643a55a, 0xe2d20347, 0x67a2100a, 0x96efd06e, -0xa870a665, 0x662e084f, 0x5ecd5092, 0x03c658c3, -0xcb363766, 0x676bef19, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 1869-m806ec59.inc */ -0x00000001, 0x00000059, 0x09122006, 0x000006ec, -0x75996a3e, 0x00000001, 0x00000080, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x53b182f4, 0x30d6de9c, 0xfb30545c, 0x58852265, -0xbf1878d3, 0xaadee666, 0x646fc5fb, 0xa45c8461, -0xc01f708d, 0x2bcc9025, 0xe7b2edeb, 0xd18292c6, -0x39069d18, 0xf6e3dd30, 0xfde656b6, 0x3c56e0ed, -0xcbf70ef8, 0xc1d4f29c, 0x2b66a751, 0xf013e497, -0xd0cdfa75, 0x36c365d9, 0xd737cae8, 0xd6a746ff, -0x16c6ccc4, 0xec2b401a, 0xc552a1a8, 0x215f8505, -0xe6827da1, 0xd0253fa0, 0x0715e1a2, 0xfdef30ba, -0xe3b1193d, 0x33ed65b0, 0xff7e819e, 0xd3482ae7, -0x20b90501, 0xe3b17981, 0xf77e9d12, 0x32d5d57b, -0xdf45911e, 0xdf2b8f2b, 0x2efc8e9b, 0xfd783cd3, -0xd9150e59, 0x30a56b13, 0xdc573a08, 0xc069a725, -0x034fbd66, 0xe937436b, 0xc76367b7, 0x35742135, -0xf4b24300, 0xd4e01c3d, 0x19e3551a, 0xe659ccc7, -0xebfbf38d, 0x21b42a07, 0xfeaf08fa, 0xd2718636, -0x3d9d185f, 0xee3bbebf, 0xe9f2c003, 0x3e0c4760, -0xdc6780eb, 0xd146d676, 0x21aef1ee, 0xea35087d, -0xc4ad71d3, 0x34637655, 0xc3bc5cab, 0xc47f955c, -0x1fd13f04, 0xef726be5, 0xcde0dff3, 0x36793a45, -0xe10f282e, 0xde86914b, 0x10c1bc4b, 0xecfcb0d3, -0xeebb4405, 0x2316a5b3, 0xf56a4411, 0xc70ab977, -0x2cd8da1e, 0xfd832a8d, 0xebc57968, 0x38eb999b, -0xc17bfa75, 0xdd50368c, 0x204d06f7, 0xeb3f056a, -0xc7222baf, 0x3ce3e58a, 0xca7f225d, 0xc8c07ad1, -0x1928df0c, 0xf162e92d, 0xc535493c, 0x3087e49a, -0xed9764f7, 0xd2c87b27, 0x17321630, 0xe1f18656, -0xec707d61, 0x3aa898cf, 0xfd64ce5a, 0xdb428482, -0x3a3a4fd7, 0xecc61449, 0xe66c8176, 0x3eddfc7a, -0xded2b59e, 0xd83bfcd1, 0x2c00e600, 0xef20fe5f, -0xdd362f16, 0x2979f8d1, 0xcd1a810e, 0xc9dd70e1, -0x15f81b04, 0xe2320a17, 0xc18c97d9, 0x207ac4f6, -0xf3bf84eb, 0xd44cf732, 0x010d6975, 0xfdf1e58a, -0xf0cd3683, 0x21cfbe8b, 0xe4cc6eeb, 0xd3a7995a, -0x3fe96a01, 0xfde77c17, 0xe28b808e, 0x250aafb0, -0xcfd0fa1d, 0xc7eef408, 0x3e6961be, 0xeb771a95, -0xdb0b8a71, 0x2b1af779, 0xd375fe0f, 0xcb1912e2, -0x0790c573, 0xe39e4519, 0xdc961130, 0x35268a88, -0xf25c4053, 0xd00d6d63, 0x1e50b357, 0xf849bed1, -0xf3dfbf1f, 0x24664d59, 0xfbdf925a, 0xd03079ef, -0x38bbbfd3, 0xffabbf4f, 0xf333775f, 0x32370fa2, -0xc740822e, 0xc275d779, 0x3f1faa89, 0xf626cdd5, -0xdc78f618, 0x3209ceb9, 0xc9d6cb0f, 0xddecaa34, -0x185c45e9, 0xff33258d, 0xdefae69c, 0x29ca332a, -0xf2b65db4, 0xc9df2ff5, 0x1d3ea2fe, 0xe954e244, -0xf6287a9d, 0x38933c35, 0xfb4c27dd, 0xc43c1789, -0x3e915738, 0xfb61d55a, 0xfd02c397, 0x3c0a8693, -0xd0ee1d5c, 0xcc137695, 0x32e23d26, 0xf25f4c83, -0xddee1226, 0x312f01d6, 0xd4eee429, 0xda24778a, -0x1c95aade, 0xe175700b, 0xdb9faf2b, 0x3116bd4d, -0xec6668b9, 0xdb9716aa, 0x03933541, 0xf69a7c1d, -0xf4f66d3c, 0x23094b2a, 0xe22f9eac, 0xd6665e91, -0x35d1ecfc, 0xf779ab44, 0xeaa7e8f8, 0x3de35c5f, -0xc7812e85, 0xc548e73e, 0x2c9d0b09, 0xeea4f540, -0xcbc4ea7a, 0x2e16a22e, 0xd655d8fe, 0xc3808b59, -0x00fa68bd, 0xf0abeed4, 0xc14b4b22, 0x2db8a36b, -0xfa0948e5, 0xd1b0c247, 0x08bbc94d, 0xe060fc59, -0xf4231a34, 0x3b09fb37, 0xf31d2c2a, 0xc06d708d, -0x3be350a6, 0xf895140b, 0xef3cf537, 0x3daafbfd, -0xd2719d8a, 0xd060bd17, 0x316aaa0c, 0xe0c8fa47, -0xdd0564cf, 0x2d41fc43, 0xdf854062, 0xdaafc6c7, -0x0185d1d4, 0xf366135f, 0xcf7a191f, 0x32fe5d9a, -0xe50a2534, 0xcba071dd, 0x07cbdb8f, 0xf9d80145, -0xf149ac35, 0x3024ac21, 0xea13d0f1, 0xc977237c, -0x21ba3409, 0xe6d96f93, 0xf47dc585, 0x25884a15, -0xc82ac51f, 0xc1e5a5fb, 0x35dd4faa, 0xf76e9556, -0x7ee314b8, 0x5778adf7, 0x290b8438, 0x4b936098, -0x1ca31624, 0x3fcc4f34, 0x2ef19518, 0x1f318a4b, -0x441a2edb, 0xdf2ea7f0, 0x75dd83bf, 0xa0d9970a, -0xe1671909, 0x3a5efc43, 0x881bc862, 0xbe0d4a66, -0x3c2bbcd2, 0x9f364688, 0xb42dc4c0, 0x3dcaedc6, -0xfabddd74, 0x9a5dc61e, 0x58a9ae97, 0xc60ad1f0, -0xfa32d453, 0x1f197242, 0xaaf4d475, 0xb7ed5053, -0x7f7a7533, 0xcbc475b3, 0xc1d6847c, 0x0da87a63, -0xaf002841, 0x9ef5bc45, 0x76287bd3, 0xf7cf9f90, -0xf0b780c3, 0x9c081385, 0x8e362c7e, 0x0a195cce, -0xfba79ca8, 0x816adf24, 0x754f3692, 0xe376805f, -0xf204e0b6, 0x046cb3d1, 0x99555d03, 0x878f7728, -0x63f11f4e, 0xa963d82e, 0xe6a3b6d5, 0x5e0c9cd7, -0xd1f46a14, 0xb3a12623, 0x2977d7b3, 0x95c4065d, -0xda581bf2, 0x5b8b87e4, 0xeaf439b5, 0xb3437cc7, -0x3d70dcda, 0xe10247eb, 0xc4379e5d, 0x33898528, -0x88b5b061, 0xf7e87209, 0x5b17ae11, 0xaa90ffb2, -0x80d8dc2c, 0x409ddf2c, 0xdf1fbca2, 0x9558b6a7, -0x25249090, 0xd9fec80b, 0xead71a49, 0x2d0732e4, -0xbc742d06, 0xdb89f2c1, 0x423a13bd, 0x9184fa2a, -0xa97d9ac7, 0x024a76bf, 0xf045cdad, 0xf6fe6992, -0x6aae0f46, 0xe6fc887e, 0x859fd956, 0x73d2b957, -0x9dca69ad, 0x6ae10a7c, 0x10462a8d, 0x6828acb6, -0x1cbf5062, 0x1e0c6370, 0x1e3400c3, 0x1b72216d, -0x7f851809, 0xa86037ec, 0x6d4e8a25, 0xd994c4b3, -0xa422b7a4, 0xb7f4746a, 0xdec5c5e3, 0x76f65170, -0xac7b3bee, 0x652d4055, 0x612c500b, 0xfb495fa2, -0x68b608ba, 0xfc2b9032, 0xe88ce6bc, 0xd3b383e1, -0xc3e1cbca, 0x77f8e4de, 0xfaf83a5e, 0x7a410d85, -0x7822b5d2, 0x24d1e840, 0x7585a8b5, 0x8a8c683c, -0x06cdc81b, 0x7dd4ad7c, 0xbc5f49e5, 0x3382c5cc, -0x7747d721, 0x9643fb77, 0x3cd1a82f, 0x5c0af967, -0x9a692973, 0x73249cba, 0x5dcee244, 0xd75a5f8c, -0x64480f09, 0x36935849, 0xdfbfbfd9, 0x1d29c3bc, -0x3eac276d, 0xe49df3ee, 0x0fe5695f, 0x0d7cb047, -0xf48676b2, 0xe9df9817, 0x15122e1d, 0xfaff532c, -0x1fdd56bd, 0x16653852, 0x15d2d1a1, 0x04da9a1f, -0x54c10acc, 0xb08b55e3, 0x59389450, 0xed7bc040, -0x27c807fc, 0x4b5b7ac3, 0x64c977bb, 0x3c41bf5c, -0x7ebadc62, 0x01256f20, 0x100e5b6c, 0x0a3b947d, -0x041fc183, 0x02043810, 0x0d446df7, 0x1578b1a1, -0x140c585c, 0x5c9d28f1, 0x11cbd4bc, 0x417433ce, -0x15559892, 0x143f8382, 0x1dcf3db7, 0x194eb843, -0x728fec93, 0x13652ece, 0x727dd07c, 0x7b837548, -0x76ed3ac9, 0x64ecff47, 0x12ab949e, 0x75f21c1a, -0x136a64b3, 0xcd7f5a4e, 0x13b5472c, 0xc176b2e6, -0xc3e087ea, 0x8ff78c20, 0xc6ec8424, 0x43a6a233, -0x42fc6170, 0xb1d5fcda, 0x89c83548, 0x37cd3055, -0x83afc495, 0x106831f3, 0x0cd1f4fe, 0x1543f6ff, -0x3c97141e, 0x2d96e82d, 0x28220d54, 0x0e903138, -0xc4ca1b2c, 0x3261cb0d, 0xe02fb5b7, 0xce18a517, -0x7092e17e, 0xf3a96e18, 0x94a50092, 0x762d4b36, -0x6b4b5243, 0xa2222363, 0xf0277678, 0x5303afe6, -0x63c5a228, 0xf13ee85d, 0x8fa59f6d, 0x7c610767, -0x5f034eed, 0xe12c923f, 0xcb4f5fbe, 0x30413e0e, -0xb8e44469, 0x7e5cf715, 0x69f0d6d4, 0x07efe897, -0x2d30c3f4, 0x6a1a7afd, 0x5ec25d03, 0x2dadd94c, -0xd885ab27, 0x93118d7a, 0x8f1f5ab7, 0x1aed77cb, -0x7fb524e5, 0xd983dad4, 0xe89096b1, 0x3dd93136, -0xc368222f, 0xba5e6656, 0x380eddfc, 0x8434327a, -0x7e1e8274, 0x4cf89dfa, 0x5da9e9c1, 0x0ae01923, -0x7d23bcec, 0x85cbb64b, 0x2e8669f2, 0xa9614623, -0x12da3003, 0x9ac927ae, 0x38d4c9df, 0xbb27f3fc, -0x2f95b864, 0x73c04583, 0x1737cfa8, 0x6d5e5af8, -0xee7f0c27, 0x0771affa, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -0x2722bfa2, 0x10462123, 0x30080f7d, 0xb346cd81, -0x0049c396, 0x4e24165f, 0xa7c66809, 0x2e60bdcf, -0xaad70a08, 0xa73ea713, 0xe28f97a7, 0x283a9eab, -0xd4366489, 0xe776f963, 0x64ffa8ae, 0xde717b50, -0xbd2ca2b5, 0x3bae5f6d, 0x8d2bbef1, 0x7e9181e6, -0xf06aa121, 0xd06b2d20, 0xa83ea826, 0xef935e4f, -0xdfd27456, 0xa3451468, 0xc6820a63, 0x43463105, -0x787697aa, 0xcba5543d, 0xdf7e1e2d, 0x6998a8af, -0x98ce6c08, 0x89de731a, 0x943a3510, 0xb36ead85, -0xd5258d4b, 0x1cd6df61, 0x82a5c59d, 0xd078e7a4, -0xa33d4317, 0x24dc45f8, 0x3f3daf27, 0x0478bc6f, -0x92dfa16c, 0x952a872e, 0x7a34e03f, 0x0f088084, -0xa40937fe, 0x38fc7749, 0xa157e8a4, 0xbce94344, -0x7045ff7b, 0xf3e1ab66, 0xe62a6058, 0x5564ff10, -0x38198f1e, 0xf326f0f1, 0xe262bc0c, 0x2f0b851a, -0xc7bcbe11, 0xe79f1d1a, 0xc2f93c29, 0x54f3ea9f, -0x8f8f9141, 0x9f45e13c, 0x7a5b86bd, 0xa764efd8, -0x35f04729, 0xdd8c4b54, 0x5fa12e51, 0xa5824af9, -0xad328f71, 0x0f11fbb9, 0x9048e950, 0x04d7a900, -0x02538d1f, 0x99f745b7, 0xe31f63bb, 0x2c4e3d78, -0x7cdb9245, 0xa3966ee7, 0x27c4433a, 0xe1d79f3e, -0xe640fa06, 0x79ce31eb, 0xf25634fa, 0xdd9ce5cb, -0xb7fab8d2, 0x2f1f0ff2, 0x2acb625c, 0xa0494989, -0x206d7f11, 0xf268b8ca, 0x292bbf9f, 0x763bd7d0, -0xea4b14fc, 0x9d3d6aeb, 0x64cca57e, 0x6fc3e29e, -0x3e7bf4bf, 0x90efc7e3, 0x08e39173, 0xd05bee2c, -0x5b3c8f37, 0x0921ec6f, 0x3371b715, 0xb324e114, -0xe3abc53f, 0x576b18f8, 0xc4469024, 0xb2ded6c6, -0xe7783782, 0xc0a1fd5d, 0xcf324bde, 0x97527c8e, -0x19f8f48c, 0x3e806a5d, 0x96cff225, 0xe3b9d04a, -0x0e5856ae, 0x781372f6, 0x9645f2b7, 0x95a743ed, -0xd0c7eded, 0x86ca3cd9, 0xbab94db0, 0x43a1233a, -0x89c55554, 0xee776239, 0x34aa0098, 0x66a6e1d4, -0xae0e233e, 0x717e7b29, 0xb403a4c1, 0x36eb96c5, -0x42140832, 0x04250936, 0xda375dca, 0x524cb2e6, -0x86deaa0c, 0x400dc9d1, 0x12c00364, 0xe3ca7cf5, -0x87f20da7, 0xf57df9ef, 0x580dbdfc, 0x0b3e0369, -0x014d27fd, 0x4afaf6a1, 0xd1f4ca09, 0x77abc831, -0x30e49729, 0xec61cd2c, 0x159c1e92, 0xb61b40b1, -0x17c66fd6, 0xde11c061, 0x79d7f792, 0xc709cbfa, -0x94201c89, 0xbe65137d, 0x18aea1b4, 0xf248bbc3, -0x465f957d, 0xcf4a9672, 0xbf293fd2, 0x2c5e31c9, -0xc2c73011, 0xfb29cbf2, 0x576f7f0b, 0x74de1745, -0xa76e172b, 0x99b96223, 0x14ce1502, 0x231013fb, -0x1d4df40a, 0x951b0c16, 0xab173e66, 0x4ff65f74, -0xc4a87a47, 0x09cc3370, 0x66385490, 0x73e09118, -0x4ee96432, 0x0164d347, 0x205069b5, 0x158dd226, -0xc932c238, 0xe9048fa2, 0x100b626a, 0x86ee08cd, -0xed87cb1c, 0x6353ec37, 0xa36edcc3, 0x8a16dd6b, -0xd28a4198, 0xebea1127, 0xca0b761a, 0x61c31acf, -0xced5ff4f, 0xbf4dbd8f, 0xd969d8a7, 0xb6e4e9e8, -0x8421c402, 0x809d7222, 0xabfd1d2f, 0xc1857ce5, -0x23958fd7, 0x3226f1d3, 0xd822b4cc, 0x2f1cc3aa, -0x501fe01e, 0xe36f8c94, 0x7ad27716, 0x3321308b, -0xa85b957b, 0x38cfdf6e, 0xc7497dd5, 0x2462090c, -0x8f9e42e7, 0xdf97684a, 0xac8af621, 0xd5224866, -0xc5f64e50, 0x9724f297, 0xc386097b, 0x48c6f98a, -0xe1478b1a, 0x2dd23fd8, 0x716b2d85, 0xa5c3789b, -0x53625e80, 0x9b8b312c, 0xce482165, 0x66161e35, -0x64ecb56a, 0x9981c46a, 0xe6cb6bb3, 0xe1983186, -0x75ed470f, 0x4adcbd27, 0x3efeda68, 0x4d193a2a, -0xbfdb3cd4, 0x7c6167b6, 0xdbddea68, 0x4b0d2d62, -0x00ba3860, 0x49ec2544, 0xa68698c9, 0x2ce7be1b, -0xf5afc9fc, 0x1cebf9c3, 0x350f8f5b, 0x893eefb8, -/* 2109-m021066131.inc */ -0x00000001, 0x00000031, 0x03162007, 0x00010661, -0x891e5cc8, 0x00000001, 0x00000002, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0xf7686225, 0x4ef86bbf, 0xb8d5004c, 0x937ac335, -0xc9dc84ae, 0x1b346788, 0x4a6552eb, 0xee81afd4, -0x2e2f5d20, 0x2ffa5e48, 0x2fbb2e62, 0xa940bc71, -0xe5fe42ea, 0xd601240f, 0x3e24e7d6, 0xeba0d8ea, -0x383161e7, 0x6c9e0cbc, 0xe7a99df9, 0x8ddd5157, -0xe5499852, 0xc281b6d6, 0xed7260f2, 0xdf249a80, -0x0782690b, 0x816a0fb0, 0x2db70d3d, 0x63af97bf, -0xe872a8c6, 0xa94f62d0, 0x20d68039, 0xe256ab93, -0x4d0905d9, 0x470165da, 0x76ccfe9e, 0x005c156a, -0xa3c59adf, 0x82008a6c, 0x0851556b, 0xbde274f7, -0x501c7009, 0xca8e7af7, 0xf1fdb812, 0xc3b36a79, -0xb9494c00, 0x24125036, 0x4c24535f, 0xba9dda5f, -0x2fd19617, 0xe58fd06b, 0x07d751c7, 0x2ba1ca0f, -0x29cfeebf, 0xe818380f, 0x33d7efcc, 0x1882e27f, -0x94eef22c, 0x5a5c251e, 0x2c20c402, 0xf6c166e8, -0xa0f1824c, 0x93279f1c, 0xe00110b3, 0xf0dd9c91, -0xc3ce27dd, 0x2b39da76, 0xc99d2d41, 0x5a88944e, -0xaa56d562, 0x588d637e, 0xd59ced8d, 0xbee49abb, -0x0ca6fcd1, 0x1bb514d2, 0xf6cd7762, 0x27f971ca, -0x6d887ef3, 0x3a813f22, 0x3b3cf42f, 0xc0687806, -0x05f4735e, 0xdccc2468, 0xcd527ddf, 0xd49be6fb, -0xd3987654, 0x8ac9cf1c, 0x1bc2772c, 0x80066cb7, -0xa619f56b, 0xecffc798, 0x392ce98e, 0x5f4f1d40, -0x03d9a596, 0x01dc88cb, 0x2230b4f2, 0x08021966, -0x335dfb1c, 0x8b6540f5, 0x3191e9ba, 0x88b56281, -0xd9be97ad, 0x6f4c4741, 0xc8dbf087, 0xc92f88d2, -0x2e9e3a03, 0x040d7039, 0x0b3fed04, 0x2664ef58, -0x09e6f783, 0x6e2243b3, 0x01caaa6c, 0x90da36eb, -0x4a60630f, 0x041d8871, 0xc5deeda9, 0x511029fb, -0xd3fe3692, 0x702290de, 0xb65d7559, 0x5cbc0be0, -0x9c16a723, 0xfaec18c6, 0xa380fc1f, 0x764549ad, -0x16de8ace, 0x1b6c49ff, 0xab58919c, 0xcf342ba0, -0x1a8649a3, 0xaf73e902, 0xf3a5cf81, 0xfc69d766, -0xca088b88, 0xa03430de, 0xac0333dc, 0x3bb2213f, -0x175e826a, 0xba0ccccc, 0x64402ad5, 0x8be20ad1, -0x63c79695, 0x07c6c798, 0x22742137, 0x14085f11, -0xe9420a12, 0x73284057, 0x8e434c09, 0xba0d69bd, -0x917782c0, 0xef31b647, 0xbeced97a, 0x4fc96f21, -0x61a0d256, 0xb968388b, 0xe50854bf, 0xb9200ee3, -0x004021d7, 0x244681b1, 0x7f96dfc1, 0x7086f893, -0x57ca8cb0, 0x17f58c56, 0xd732ca6d, 0x40f9b31b, -0x209ede64, 0x541019f9, 0x0e992dd4, 0xb98788aa, -0x57a85562, 0xfceb96f1, 0xca68f9df, 0x0c8a1283, -0x90f70e9b, 0x2dea2e8d, 0x91ad91a5, 0x4b7664f2, -0x594a5bd5, 0x01ae6e99, 0x1edefb6b, 0x6afa213c, -0x371fad96, 0xd4cd1c1a, 0x0b72658e, 0xd2e148dc, -0x08c1234d, 0xd7bccb6b, 0x7c6584cd, 0xecb0661b, -0xa7c71897, 0x00f43041, 0x62617348, 0xf22b602d, -0x334b08a5, 0x0ec9440c, 0xdf302f24, 0xba968b20, -0xab1283b9, 0xbf8fa58a, 0x0e101d1a, 0xadf6cb1c, -0xf5ae6b43, 0x027308c3, 0x7c594b25, 0x6b28e2fb, -0x7076d5f6, 0xa941e49d, 0xa2404185, 0x6de0b678, -0x72f43ce2, 0x665bb3e5, 0xab9042df, 0xacb1866e, -0xdabfa640, 0xddcdedfa, 0x6f0cfd7b, 0x162ef758, -0x994e436c, 0xd907a714, 0xf24e5788, 0x5ee0f29b, -0x199b0796, 0x2a35ecf8, 0x241edc05, 0x7aa71aaa, -0x58790326, 0x7ae33c8a, 0xd1ccb8ac, 0xb18c2c36, -0x9d1e230b, 0x057fea5d, 0x01e49aed, 0x8883f770, -0xfee63499, 0x9d8156ff, 0x0204c154, 0x5244680c, -0x33692fb4, 0xe08a42a2, 0xf0e53457, 0x46348cf6, -0xe6903bbc, 0x82d74e02, 0xe0fa12bc, 0xe6d03c3f, -0x65383df2, 0x268bc988, 0xc7690ca3, 0x050c3724, -0x32e3d584, 0x9dffc7a7, 0x360b877f, 0xb248dbd1, -0x5e154b49, 0x2baba816, 0x7cda3d56, 0xd1d37f4f, -0x514ee6b3, 0x491129e0, 0xb3447b54, 0x14ec6daf, -0x3a522988, 0xef339e51, 0x2237b08a, 0xcd3ceb66, -0x6b0a51b3, 0xd9f5648b, 0xe69d2694, 0xe543690c, -0x89b65c85, 0x16fc9d01, 0x4103cc5a, 0x7955f351, -0xa24082e3, 0xd9534951, 0x1c2c8ef5, 0xb683917e, -0xbbd0416e, 0x9f52a739, 0x77392ea6, 0xb2d43e71, -0x954db293, 0x5cf5b436, 0xb891130a, 0x0c8496f5, -0xdd64eea3, 0x70be1972, 0x985b6a54, 0x5ccb1431, -0xedd8d183, 0xf55e689b, 0x933dca7c, 0x9542f67f, -0x86517d1e, 0x83db24dc, 0x6b9a0936, 0x20518976, -0xb6413205, 0x37931beb, 0x265236cb, 0xfcb77aa8, -0xa5fbbaa6, 0x9a5d80b9, 0x3ccd47bd, 0xe7cdf306, -0x66449996, 0x471d1255, 0xf756ef4c, 0x0e9c7351, -0xe3de1193, 0x63a02e41, 0x8f71941b, 0x06b2d8b2, -0x99751d97, 0xc084ec30, 0x812fcd01, 0x5552559d, -0xb79f086c, 0x7748f548, 0x56a3184a, 0x93243935, -0xd93a819a, 0x3ab65649, 0xbf7ca9b2, 0xf2b7a1ef, -0xea009f2d, 0x7fe804f8, 0xde6624b6, 0xec8fd349, -0x124e297a, 0xaed271d8, 0x8abbcc3e, 0x2f112fa5, -0x4b3af8ed, 0xc21a7522, 0x376877b3, 0xf19300b9, -0x7a42e481, 0xd74c1d68, 0x97f853f4, 0xd2ba157d, -0xec23322a, 0x133b093e, 0xec641e08, 0x3ba704c6, -0xd7241dd9, 0xe16ff159, 0x538e1518, 0xca13be54, -0xb8f4c435, 0x5b88dbf0, 0x535df391, 0x9d627ffb, -0x27e148bc, 0x4f679502, 0x7b3525a2, 0xe4d0efc5, -0xd10bbbd9, 0xbb0c3bed, 0xc733ef7d, 0x1cfc08af, -0x2972537e, 0x33b5e4d8, 0xd0c6ca80, 0x2de1071c, -0x3dbd527a, 0xaaaddeea, 0xe7330c4a, 0x43e48a03, -0xb55ef2b2, 0x773d0e42, 0x8372fd8f, 0x73d1dfa1, -0x1acf91c4, 0x412b14e0, 0x7a52050b, 0x7f57c573, -0xe902de0a, 0x62ab1c8f, 0xd066190e, 0xa93e3945, -0x22c34d1a, 0x6c360951, 0x57f65baa, 0x78cbb2b8, -0x38a14718, 0xc05ee3d8, 0x1fc1b139, 0x26e68e3f, -0xd10d0a3b, 0xf1953462, 0xd948b500, 0xd9570403, -0x8cb71f35, 0xa705a242, 0x7b564cf6, 0xdc02a115, -0x7c7735a1, 0xd6a2e6f4, 0xfe15bc15, 0x1d3b919b, -0x45a0f640, 0x4595ca34, 0xf0e08177, 0x2b82d1d6, -0x4c7c879d, 0x091ed8ac, 0x3fb383f6, 0x8dd729b9, -0x2e906401, 0x03eb95d1, 0x566f5bd8, 0x7b60eea6, -0x5325a7e4, 0x7b6eafe0, 0xe7b2f0fc, 0x0e7dd584, -0xfc645285, 0x89c630d8, 0xcfb797fb, 0x2c2644f9, -0xdd5586c7, 0x869d11f6, 0x13d1e37d, 0x1298d062, -0x8a6b9e4c, 0x4333ba7a, 0x1e5ab3de, 0x7cfe5c85, -0xf67ce235, 0xc78548c9, 0x9c56b769, 0x2a1ec829, -0x9ecf067e, 0x628df873, 0x3b5aaf47, 0x87b66077, -0x81646301, 0x01f01947, 0x0573b517, 0xf3f1520a, -0xc98286f9, 0x059f2667, 0x8751a5af, 0xaa60fd06, -0x52923f67, 0xb68b8207, 0x8ea56f41, 0x072e190e, -0xd0e2f5e8, 0xba8ab301, 0xf6368a58, 0x60f0b1da, -0x732d9037, 0xca6a78f0, 0x4b57f7f0, 0x510dcbaa, -0x78a73ff6, 0xa4a091f4, 0x082ba3b8, 0xa3cd1758, -0x483fe06b, 0xf9f395c2, 0x5aeb2af6, 0x4ce063e6, -0x7daa69d2, 0x5db3b33a, 0xe7f20b65, 0x680619bc, -0xbcb076df, 0x6935da52, 0x92607aaa, 0x4463efdc, -0xe97f95e6, 0x6851f083, 0x0d9f15de, 0xfc91225d, -0xc47bebaf, 0x32be1ae3, 0x29b47478, 0x9bb22174, -0x71148599, 0xe7383074, 0x61e63293, 0xdd5c5960, -0x77a2c7c1, 0x964f7326, 0x23e00af7, 0xfde072af, -0xf11c684f, 0x68cf5efb, 0x60946a05, 0x1cfb35c2, -0xaa77d38d, 0xb8f129cc, 0xcee0fdb9, 0xc1e98ceb, -0x9ff7dfcb, 0x6f62c724, 0xbc47a77d, 0xe6b869ca, -0x21f5e658, 0xd7ab5ddb, 0xfada483c, 0x738cd51b, -0xedf10917, 0x2b3dc577, 0x8d72bba5, 0x2b0daafb, -0x7570beba, 0xea6469d0, 0x9774e49e, 0x556de1a4, -0x87bf5a00, 0x5ff7b62f, 0x49c3cdb5, 0xc7950334, -0x77f38227, 0x0fbf40a1, 0xf4c2666f, 0x150a0777, -0x246de555, 0x2dcadc6d, 0xe0914f96, 0x27cbd925, -0x103e3cae, 0xaae83504, 0xf22b6cf1, 0x67eafaa0, -0x3e1772d6, 0xc31685dc, 0xc518a07a, 0xb75afaad, -0x88042921, 0xf718d779, 0xeba4dd1c, 0xc5be44d7, -0x60feb8fb, 0x852f12fa, 0xe88debdc, 0x0f6d2b14, -0x87ff700e, 0xc1d2859d, 0x26c4a0cf, 0x22f946c1, -0x46132611, 0x47516d3e, 0x83048232, 0x8e6a1885, -0x00e6c5e7, 0x98321d95, 0x6afa8e70, 0x5c004e07, -0x5129ba0f, 0x32e69037, 0x23ef3349, 0xb9e76036, -0xe4560af4, 0xc3eedad8, 0x7b113c89, 0x1faddd61, -0x2924b80e, 0xd761c51c, 0xbc74ff8b, 0xecbd623e, -0xef016e07, 0xbf69956d, 0xa7d70940, 0x1a6c9504, -0x8c309d76, 0xbd8d6107, 0x455da83f, 0xfbd1f764, -0x52c0173a, 0x0e809302, 0x82521cc3, 0x385172a9, -0x071642ae, 0x423abcf5, 0x8d662467, 0x9d1e56cc, -0x0c9931c9, 0x089a3403, 0x15485415, 0x37d14e7d, -0xa217733b, 0x6c602a25, 0xe3fc6bbd, 0x17a8e941, -0xf8077fd5, 0x8cb99b51, 0xaa8499d4, 0xcc20e05a, -0xb16f4c15, 0x2ec6000b, 0x00c7c607, 0x4bde4790, -0xe4ca6ade, 0xc748fefd, 0xaa2fc8b8, 0x78c4c1de, -0x354b1771, 0x1eef7bbd, 0xc4091812, 0x403da3c2, -0x7abc8a09, 0x4defe6cb, 0xfecfa44a, 0x1a4f0573, -0x35941961, 0x63381c63, 0xd7f124f9, 0x58095d19, -0x48bf009f, 0x9a5b8c36, 0x58517a30, 0x2292c779, -0xfc73b3ef, 0x351ae98f, 0x370c320c, 0xe55e9d8c, -0x1ab46ac4, 0x9a52c283, 0x4522e321, 0xbf0dbe57, -0x7072ef53, 0x748184cf, 0xb4db3ed2, 0xbf891079, -0xd3f42c4b, 0x17d78aa4, 0x0b80f840, 0x34084fd4, -0xed951bea, 0xd2755ead, 0x73ff222d, 0xbd929cd4, -0x363d1e00, 0x366a998e, 0xc0efcb38, 0x3a2680b3, -0x67cadd34, 0x51d996e7, 0x1b7cd5b9, 0x2282a8dc, -0xde33eb1e, 0xdd0f6699, 0xf080298e, 0x2bd236c9, -0xfa7095d2, 0xb67c1193, 0x545974ad, 0x56a60b18, -0x25b4ac52, 0xc64e9eef, 0x2678551e, 0x7aca1a7a, -0xdceb7d31, 0x02408a48, 0x7e8f3c18, 0x74b41b32, -0x707251c8, 0x939a601d, 0x0e8bcc10, 0x79f776f5, -0x35543ab4, 0xb059b25a, 0xbc763815, 0xa9da6f93, -0x5eb1b293, 0x2c1ba3ed, 0xbd779d8a, 0x8b96f417, -0x4a52d310, 0x742ada5e, 0x4a3140e9, 0x69c9cd00, -0x7c9a08aa, 0x9c41602b, 0xd37b3b56, 0x854a51cc, -0xdaf009b0, 0xb292a496, 0x914e4323, 0xa28c15b9, -0xf96bb247, 0x90460c31, 0x809603e4, 0x8e3e2901, -0x207d814a, 0x7697ae44, 0x6aa47365, 0x732644f3, -0x7044ba73, 0x8a8b54bf, 0xc2526ee0, 0x00a95261, -0xb4467081, 0xf7ac1535, 0x0bdc46d4, 0x7a8f6e6f, -0x020d6ec4, 0xd3c80697, 0x01160365, 0xbb67971d, -0x0b3c1125, 0xc4f455ae, 0x20d99f8e, 0x2861ef06, -0x0b69e237, 0x68be6d8e, 0x3c4cb68f, 0xed36339e, -0xc5a12abb, 0x0e00ba16, 0xaa5c53de, 0x956be826, -0x4c4e91c1, 0xea1bb00b, 0x2f5065d5, 0x05482460, -0xe3b6c164, 0x680c3c05, 0x519cefe4, 0xe0f31fc3, -0x95e4de55, 0xcd23c19d, 0xdf8f816b, 0xd32162a4, -0x386fba01, 0xcccc981a, 0x45931e66, 0x43ac5399, -0xe60126cc, 0x50df2232, 0x603a9242, 0x1efd0ab1, -0x5efd57c9, 0x53065d3f, 0xb0ae9072, 0xbb25e18c, -0xcf20ecb7, 0x90ac0b0e, 0xebe657a1, 0x86fb4948, -0xc14563b0, 0x8531a293, 0xfa95fc95, 0xac859ebe, -0x83917592, 0xff654f62, 0x7c6c66ca, 0xb31bd8ff, -0xc1ae2096, 0xf3d6cc0d, 0xde7add56, 0xd445fbd3, -0x2630dea3, 0x81ed5ea9, 0x648a07b6, 0xef260840, -0xc590a8b8, 0x25d3d5e8, 0x2405cccc, 0xfc22c9dd, -0x4ce86fa0, 0xaf6b8f1f, 0x1986e0c2, 0x2a57db87, -0x358f388d, 0xc5a3aa33, 0x47cf13e4, 0x9ee4d133, -0x3d7af56c, 0xd221f74e, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2360-m011066138.inc */ -0x00000001, 0x00000038, 0x09192007, 0x00010661, -0x8a2d6f19, 0x00000001, 0x00000001, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x04edab0c, 0x753dc28a, 0x2d998811, 0x7c34d933, -0x0c7db493, 0x03969ead, 0x456105d8, 0x39c6aa8b, -0xef28e0a2, 0x323ed4f4, 0xdf30a352, 0xae0fe98c, -0x89462aff, 0x391e4fba, 0xbc4c4e34, 0x6af2de19, -0xa52cfe25, 0x291ce41a, 0x18d3cf9d, 0x1507515d, -0x6dbc0ef8, 0xc87eacb1, 0xe10e8d33, 0x8ccb615c, -0x067b3412, 0xe9b8150f, 0x509d573c, 0x7da63711, -0x48e07875, 0x2247478c, 0x239efc7d, 0x81e5940e, -0x3dfe3729, 0xf551c52d, 0xed1b5e8b, 0xfeb15f10, -0x99d9e2b3, 0x28b7dd4b, 0x01be41ea, 0x1c38d731, -0xebd76aea, 0xf897168f, 0x5fc0ea48, 0xf80c9f21, -0x99d10486, 0x692e9355, 0x28aeca24, 0x2f449adb, -0x2f2dab6a, 0xdb99e720, 0x357c7d1a, 0xf393b5a9, -0xbf013ce6, 0x80ff1faf, 0xd119e2fe, 0xe5e3e086, -0x74972a90, 0x89e66251, 0xf473f261, 0x11a19e0b, -0xad9948af, 0xb7a25e24, 0x10bd14d2, 0x4abbe586, -0x462b658c, 0x5b659fe9, 0xc02bd04b, 0x0ce6bd03, -0x1468bed1, 0xa7727077, 0xf03ecf36, 0x0e0ccccf, -0x1867b524, 0xfc6e4dcb, 0xf9e807b1, 0x08d29b7a, -0xbd9f1444, 0x124e857e, 0xbd8cdfa4, 0x153f648a, -0xf5248986, 0xbbd3146f, 0x4e7c90ab, 0x9d5512a4, -0xcfcb97be, 0x5e983b61, 0x56f3bcce, 0x8ab0b172, -0x9759b343, 0xfa054335, 0x506ef847, 0x2683074b, -0xa2859a9c, 0x315f4abe, 0x9b7b644d, 0x20db051b, -0x9a316866, 0xf2ae2cad, 0x8289ff80, 0x6fba3aab, -0xe6871f00, 0x44d188df, 0x5946ec70, 0xb984b93f, -0x579ba307, 0x242cbd55, 0x3de52ee1, 0x7868d3e9, -0x04c41aa5, 0xcfa6e738, 0x14b8f07f, 0xd6b58632, -0xf085f5c9, 0xfd962b21, 0xc28144ab, 0x685ba162, -0x32aaf683, 0xdb66dfa6, 0x091054de, 0x6a1dd372, -0xe34da67d, 0xef62f799, 0x54dc33e2, 0xd1456e79, -0xb59b81a8, 0xc889db76, 0xd65d2d17, 0x6037e59b, -0x0220f082, 0xfd95b479, 0x85a042e7, 0x6ca93f38, -0xec0bc5d9, 0x86f8b17c, 0xd780bc26, 0xd87742dd, -0x76933609, 0x1af3252d, 0xa44f362e, 0xf6acb349, -0xc11c7449, 0x2914efe8, 0x0d1e342b, 0xa354633c, -0xb53cbbdb, 0x6e6fc594, 0x085b9f48, 0xbd1508bb, -0x6a3a41d6, 0xd4ac2a45, 0x0c3e31dd, 0xb2f2be03, -0xa92727a4, 0xa412a387, 0x28a69d62, 0x56280bcc, -0x87fc5d7c, 0x2c224b74, 0x7e42dc1c, 0x3db48525, -0x553de822, 0xad7747f8, 0xbd32113c, 0x6051cc78, -0x02390e95, 0x8fe89849, 0x4abb954d, 0x2a374ad5, -0x926f1d10, 0x3b06647a, 0x905a2adc, 0xab4995cf, -0xcd63cf14, 0x8e4ccae6, 0x5db08150, 0x18608e51, -0xd9c963c5, 0xfb73357e, 0x75c881bf, 0x4c7931d1, -0x652389be, 0x243c0e67, 0x837601bf, 0xb3f54082, -0x1f55331e, 0x3bfc7edf, 0xf5ad3c39, 0x21965865, -0xe923c885, 0xcf512590, 0xcc4af4d1, 0xa718e1d5, -0x78c38809, 0xcb41cb14, 0x2b8ba17e, 0x06bdada9, -0x76d6e67a, 0x94f5cf9e, 0x2136f028, 0xcb2212c8, -0xc19af1a6, 0xe35f0dbb, 0x0f0c986c, 0x43b9ae5c, -0x479402bd, 0x9e80402f, 0x4012c2d1, 0x6cc5cbdc, -0xaa95ba9b, 0x22a845af, 0x365f27e0, 0xfb76d28a, -0x333ee35c, 0x4783a0a7, 0x8206a50c, 0x8e5d5196, -0x66e9b2d3, 0xc106d483, 0x83f43616, 0x3a64b1b7, -0x10d85809, 0x33ef60d5, 0x1c859470, 0x359bc105, -0x7c9e705b, 0x9f52d7ae, 0xe7ccb42f, 0xbacfba02, -0x5c0f093f, 0xfa49f315, 0x5f4d63c6, 0x21dc29d2, -0x03f0f8ce, 0xb19a8160, 0xe3ecd54e, 0x33c86edf, -0x1978b1d0, 0x7dce052f, 0x051c0f91, 0x8f7ee8a8, -0x89b05a2b, 0x9aa2c144, 0xb1b8532c, 0xaacb3ea8, -0xe52d2a9a, 0x1f329b23, 0x3985e0de, 0x1e81f62d, -0xbdd09ea5, 0x59b94ddf, 0x17bb0f1f, 0xe49302e8, -0x913f58f9, 0x2726a744, 0xefb2756f, 0x84044c90, -0xfdd05bf7, 0x5d43b466, 0x2e241659, 0x53d22b40, -0x99cc2e81, 0xdb6b9811, 0x16bd9d0a, 0xb1884040, -0xcd339383, 0x1a1f54ba, 0x55f0c3ed, 0x2f8fed41, -0xc79777ee, 0x981b30a4, 0x3b034b3e, 0xc2f5ec72, -0x50eefdbc, 0xabee8706, 0xbae469ea, 0x7fb1fe93, -0x954d760a, 0x861d0d25, 0xf2a050b2, 0x19ebc945, -0xe8f7a8c7, 0x98cebb9f, 0xb20f95a2, 0x9e22835b, -0x936d23a5, 0x3c713b9d, 0x2879cedc, 0x239d143f, -0x88003fa7, 0x9092398e, 0x964b37a1, 0xf3af29c2, -0x8e0fd87b, 0x9ad949de, 0x2aefc296, 0x50c23c9b, -0x5a7b0489, 0x99d28b3f, 0xbc026f52, 0x2eb7b49d, -0x5654e67a, 0x55176822, 0x74c16f48, 0x1a6edb16, -0x34351ff2, 0x5c265627, 0xf5073ae3, 0xcbb8698f, -0xe01e91cc, 0x7e3ae3e2, 0x36515144, 0x0cf6473b, -0x1190d969, 0x724ad5fc, 0xef2bbcc4, 0x501597af, -0x098db900, 0x56bbbc56, 0x03b76131, 0xa5a954ad, -0x441bc454, 0x4f6e2070, 0xd0714447, 0x76f0c462, -0x61999ecc, 0xd41ef37d, 0xbbc05d69, 0xb727af0d, -0xda1e49f8, 0xc697ff57, 0x255352af, 0x1bad7abc, -0xaafb3e57, 0xe6379086, 0x35b1fe5b, 0x8b3bad48, -0xcd37384d, 0xea88bd36, 0xbfac317b, 0x7ee67abd, -0xb02507c3, 0x8785cc15, 0xef76c808, 0xc4e8f064, -0x3fb7f5f9, 0xdda44518, 0xdf46ea58, 0x9e2ab1c8, -0x68caf7cf, 0xb3f4bf3e, 0x55522102, 0x7918189a, -0x475f6644, 0x1a6e7ca5, 0x2cd86d9c, 0xb0e1fac2, -0xc958329a, 0x3119bae7, 0xb32d013f, 0x5f056b98, -0x4b6b5798, 0xce258bf3, 0xd43f34a8, 0x7e8647f3, -0x9742cb47, 0x12bed136, 0xc0d35976, 0xe6519490, -0x5a575d9e, 0xcb276d20, 0x58e19613, 0x6a1215fd, -0xf7959e92, 0x93acb922, 0x68c17024, 0x33a3ddc1, -0xf642d20a, 0x4a427216, 0x94d498e2, 0x148eee3b, -0x7560ee24, 0xf7a779c5, 0xaa989d30, 0x1abddbea, -0x86b614ff, 0x9778d0bf, 0x3aecd988, 0xb728a0c6, -0x593de7d9, 0x10149838, 0xc1b14ec8, 0x4ec993b8, -0xc2196a63, 0xd1f3f5e7, 0x045aca36, 0x5754b6c1, -0x7dfac21c, 0x254501be, 0x29a6f9cb, 0x33d00f90, -0xdae4ec5a, 0xa7ab019e, 0xaf882059, 0x7a3b9d6b, -0x45e0325b, 0xb039d766, 0x9b2c1f0e, 0x3f448929, -0xc8454a40, 0xf8c10efd, 0x94b41a37, 0x9a838b71, -0x60ddbf3b, 0x1c15295e, 0xf994b7d3, 0xa3dfdd5d, -0x8032e518, 0x123701be, 0x5dcebc6f, 0x80d6f4a9, -0x6aa26e9e, 0xdcd4c88e, 0x841e83c4, 0x1851915b, -0xfb6d1d92, 0xcc0b91e2, 0xbb541922, 0xd06b042d, -0xaf2ec85b, 0x35d99c76, 0xc9af68ea, 0x740dbdd2, -0xd537367f, 0xdd29ee8b, 0x286aeaa9, 0x16449221, -0xea08c306, 0xf6902906, 0x78ba7774, 0xc77e6d58, -0x80d6dcad, 0x7e174318, 0xa71aa539, 0x463dd61d, -0x76fc0ed1, 0xdbf9135b, 0x7eb26556, 0x172c043c, -0xffdbf51f, 0x03557f90, 0xaf867d85, 0x2a1f339a, -0x12cb27e1, 0xae260f9e, 0xd201bf29, 0x8dcb3c2d, -0x45a5771e, 0x64eeae5b, 0x9ac90e3f, 0x143fe9d0, -0x28676f5a, 0x5b1396ae, 0xb48d6c16, 0x2445584b, -0x8478894a, 0xe5455e63, 0x740c044e, 0x45171247, -0x4b2a3dae, 0xd288a203, 0xaa52655e, 0x45023c06, -0x84215eb5, 0x1991884d, 0xca6803a4, 0x96c23c34, -0x711143bf, 0x4e5f1f02, 0xe6be3205, 0x12a4e5a8, -0x1e54535a, 0x9874712d, 0xa8ed6aab, 0xf8e9dd8e, -0x4ba41834, 0x938f32b6, 0x6eb45808, 0x5b7f5f24, -0xdf5068ad, 0x2b0d6ba1, 0xc1f9618c, 0x92a831f5, -0xeb0cd324, 0x9a784752, 0xd19a30c2, 0xe6b3e9d1, -0x0f604748, 0xead250cd, 0x1483fd3c, 0x8dabb1f1, -0xdd98a78f, 0x07831a92, 0xfda45704, 0x4cf3a89b, -0x295917e6, 0xbdb8e65a, 0x050068a7, 0xdae26311, -0x33ec1ac3, 0x5984753d, 0x65628b48, 0x82dcbdb6, -0x542a70b6, 0x8768acd7, 0x1829de29, 0xb19f0db8, -0xea0ca24f, 0x71b22805, 0x44fe50eb, 0x76ecca1f, -0x50a69a79, 0xc325ee2e, 0x20dbe76d, 0x7296ba19, -0x46e242c4, 0x1ecb1e3f, 0x1be14a8f, 0xc55ea513, -0x7e14ce2a, 0xce50fc02, 0x1d3f95cc, 0x20bb0510, -0x2bafed47, 0x0adf25c0, 0xb0788b94, 0x54d64296, -0xdd4ca8f7, 0x304bc9db, 0x2fad5b53, 0x79d34c4d, -0x9cb63708, 0x063a61fc, 0x4cb5c1bc, 0x61865d4f, -0x05bb9c68, 0x8506ae0f, 0xef4a2e30, 0xcbd3fe9d, -0x54b23597, 0x30ef6bb1, 0xc496c4df, 0x00f52245, -0x32212ea0, 0x6c01394a, 0x7a0ddd84, 0x751454c0, -0xc6976a80, 0x7181ea76, 0x437ac15e, 0x3bc420b5, -0x49ffa13f, 0x4f994e99, 0x9b667956, 0xd83735d9, -0x31812cb7, 0xbdb69ea6, 0xa1ba6d07, 0x06d1f20b, -0xb22d62bf, 0x0cdcb7c9, 0xa9c74431, 0xf4f1d1e4, -0x79d765b0, 0xab9ce36d, 0x2e984802, 0x3ed48b45, -0x78c5d70d, 0x64637b73, 0x91e44d92, 0x2f00650e, -0x7e7270e6, 0xb0b0e6b0, 0x09bb8565, 0xb0ded3b3, -0x2db61a97, 0x487aeb77, 0x5db35bc0, 0x727756c2, -0xfc716dc6, 0xfc5df1f0, 0xad6fb560, 0x09339656, -0x7f2f74af, 0xacff607d, 0x0aafee01, 0xa3e4cf62, -0x9899ca6f, 0x33787a19, 0x510a7d77, 0x58829e4f, -0x2e4c3a30, 0xeaa3b201, 0x4c706de3, 0x1620fcc9, -0x56741cf4, 0x21371491, 0xa5b6c083, 0xec88fb63, -0xbb0399ff, 0xcf0451c0, 0xe9671bae, 0xb4191904, -0x3b4f7775, 0x7bffb243, 0xe9d766ab, 0xeeffedca, -0x3e8f4784, 0xa515c160, 0xc6fc2c82, 0xdf9b7ef2, -0xb706740e, 0x712fc333, 0x3996fa72, 0x2bf509a1, -0x74821349, 0xe136de3c, 0x871629b5, 0x0bd538a7, -0x7d423a9d, 0x48ee44b4, 0x14b96b88, 0x6b819ca0, -0x77674c91, 0xa2c6e96c, 0x5331e28c, 0x0f62402b, -0x5ad65199, 0x0c3128ef, 0x6733a286, 0x7f34342d, -0x188dcfa6, 0x28552add, 0x78d76095, 0xcf1e718f, -0x1a30b39b, 0x2d7954cd, 0xc1b5b92d, 0x2f14c4e0, -0x67d82644, 0x99d65979, 0xc6411fcb, 0xd99c5ff5, -0x6c7790e4, 0xae250294, 0x1cc063af, 0x16c3a84f, -0x74cb781a, 0x693b9281, 0x848cf3f7, 0xb7c00c17, -0x360a695a, 0xa4366d9d, 0x9cdb154e, 0xe077ff83, -0x4ad4dd5e, 0x7a10cf6e, 0xd35fcedb, 0x3258d838, -0x380c9555, 0xff9397fa, 0x32c0aeaa, 0x9c48f057, -0x8f0e1a9b, 0x15dd32e1, 0xb6f21fa3, 0x74c3be72, -0x18a8dbf6, 0x1fccc9b9, 0x94409113, 0xa1978134, -0xd094008e, 0x4ce19486, 0x0bb5172e, 0x7065f6cc, -0xbd457d8a, 0xa37e2ec5, 0xeee97672, 0xca0ae634, -0xbc8b44d1, 0xb97b7056, 0x578fee89, 0xd0222b9f, -0xadb8b3e1, 0xa7bd9525, 0xf6aef00a, 0x3282ac4d, -0xf97076ff, 0x7726bbba, 0x46ce9db7, 0x7016f83f, -0xfac41994, 0x025804de, 0xb4977511, 0x2b2aaf86, -0x732debc6, 0x072360af, 0x0b25ec36, 0x45e8a251, -0x9cd9e5c2, 0x6367b497, 0xd5923296, 0xd574a3af, -0xbc3dba83, 0x5eea9967, 0xa80f8577, 0x77f803ef, -0x43fd50c0, 0x525368d2, 0xce61f844, 0x1b652c56, -0xe9cdf56f, 0x38deafbe, 0x288043d8, 0x61c38fd1, -0x54f519b1, 0xcdf3911f, 0x2651eeee, 0x7b097fe5, -0xba02d544, 0xca1c8f42, 0x9e645f92, 0x50170562, -0xdce41094, 0xa8a7ed0b, 0xd6f2f4fe, 0xcb098894, -0x14b9861e, 0x13786769, 0x26c1dc22, 0x330e3ce1, -0xad187ebf, 0xc8c8c267, 0xe8a6f620, 0x1cdeec54, -0xa6e1ac03, 0x5d029ec5, 0xb1de4091, 0x2ca530ab, -0x950969bf, 0x0721a6f7, 0x445ba622, 0x60766f96, -0x86e0245d, 0x94866c85, 0xb4d01674, 0x67f9976f, -0xbf220f92, 0x8585e70b, 0x4d78cd26, 0x93f369ed, -0x0ac2a550, 0xde5114f9, 0xe7c8436f, 0x47ee726c, -0x981c6a7c, 0xf0192ffb, 0xc1b2c383, 0xbea801a5, -0xd3e5db10, 0x032a7acc, 0x18af5ed7, 0x88a17d27, -0x7d3b9e5b, 0x94f1fbc6, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2380-m106f768.inc */ -0x00000001, 0x00000068, 0x09162007, 0x000006f7, -0x18729a7e, 0x00000001, 0x00000010, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x67615a02, 0xc5c97f5f, 0x67c6cc07, 0xc2b8af48, -0xe6144a74, 0xeb752f3c, 0xcc641d37, 0xc85dbcbf, -0x8aaade67, 0xc12d84d2, 0x42d1e9fc, 0x648e9b8b, -0x7ba8726a, 0x10730fd5, 0x559ec216, 0x6ce0304e, -0x6262dcef, 0x9bcfb566, 0xde72b180, 0xfff5e1bb, -0x357fc3fa, 0xb433b4d0, 0xe0a5c2c4, 0x77d08032, -0x058d1ae6, 0x501f62b9, 0xd536ee5d, 0xc42cda2e, -0xb32833da, 0x79b0e085, 0xdd4c876b, 0x7ce16476, -0x21a34fee, 0x4a7c9a43, 0x55fa4e5d, 0x58c491b5, -0x9812db2e, 0xaf55d9d1, 0x6d179bf4, 0xb550b764, -0x0eea6215, 0xb46f1eec, 0x2007d397, 0xa819e1f0, -0x7ea88495, 0xc40cae2c, 0xc16b49ad, 0xb92c71bf, -0x5b3fd03a, 0xa7d20283, 0x2b144d56, 0x47c6b4e0, -0xc02c37d6, 0x07f461c4, 0x943c86f1, 0x1bf5de9f, -0xb204aaf0, 0xa24bd8e6, 0x6a48faea, 0x3058ba2c, -0xa8e86950, 0xb5b4379c, 0x990fe958, 0x55171689, -0x9ff43ba5, 0xf8bf0b99, 0xca5b9d3a, 0x6293d6a1, -0x0b7d8354, 0xdf95b72e, 0x7f2e9e77, 0xc505ee34, -0x2edec94c, 0x188473ce, 0x26c7362c, 0x3dd5cf5d, -0x05ad2dcf, 0x66c59f30, 0xdf1debed, 0xc93fff73, -0x2642be44, 0x17442c17, 0x10671a4d, 0x02c54398, -0x33f14adc, 0x020cf5f4, 0x3597dc28, 0x42e987b7, -0xc40f9739, 0x625e6650, 0x3b60315f, 0x940e136f, -0x3dca1103, 0x4159b10a, 0xf42a3027, 0x900c7980, -0x61106101, 0x5aaa4c16, 0xdd95902e, 0x507c3c70, -0x3ee2d404, 0x40498827, 0xe2a4b67a, 0x767e8e7b, -0xa9560205, 0xf194ec13, 0x5fafff8f, 0xd53d6edd, -0x59c614c0, 0x6a0f4494, 0x30bb87be, 0xaf1ada6b, -0x514d7c35, 0xced06aa0, 0x3f2cd210, 0xd47ebb24, -0x89d317da, 0xd8eb25b7, 0x418bd5b5, 0x71b8a88f, -0x8ba4d56f, 0x6f6a2a92, 0xb5bb0923, 0x269679ee, -0x1022ba01, 0x5961ee04, 0xffecb06a, 0xf78cf0c8, -0x22011938, 0xf6e0027b, 0xb59d29c2, 0x3c64808f, -0xafcb0d9e, 0x8477f881, 0x6e3aa0b6, 0x097dfc20, -0x2fd6504b, 0x64346735, 0x13903009, 0x1dc3f335, -0xd1c7c3ab, 0x1be49d10, 0xf31d50de, 0xa67b35b3, -0x2aa9fbc8, 0x39d0b34b, 0x533f165f, 0xf8ec6056, -0xdf03fcd9, 0x261527cc, 0xbc386be2, 0x89272956, -0xca340c54, 0xa87b2959, 0x9dd445fa, 0x476a6320, -0x5ec91ee6, 0xccd6f647, 0x4b5f2b38, 0x1c12bc75, -0x88f20dc6, 0xb363d3eb, 0xa883466a, 0x01271996, -0xd547f1fa, 0xcfc9637b, 0xbf3ab2d0, 0xa2c34aa6, -0x5f1b4642, 0xa10030a2, 0x2ec1fdd9, 0xcad61c34, -0x70243eb4, 0x8b94c510, 0x37c25834, 0x70e2558e, -0x520ed333, 0x8aff0b4e, 0x77d86d46, 0x7b1b8bf9, -0xdfd41082, 0xdcf4e512, 0x6fb04eb1, 0x91f536db, -0x4ad991b1, 0x737cf5e9, 0xfe5cfa24, 0x18a20bfd, -0x8471e184, 0x39026c6c, 0x4a2f658a, 0xcc95ea19, -0x7f6b63e8, 0x6898846b, 0x6313970d, 0x8c05f8b5, -0x45f5e6a3, 0xe808d5ab, 0xe427b730, 0xa67d845b, -0x572583a5, 0x04e8e1c9, 0xe0b51899, 0xb22508a1, -0xcfc9b3e4, 0x6af3bb0d, 0x5ddc0027, 0xd45a5bcd, -0x72d64b56, 0x9cba2941, 0xb165f22d, 0x6f848282, -0x0b5b94f4, 0x18eb6bcc, 0xc8ff69ca, 0x5b1aac44, -0xbd38547a, 0xc3f5fe80, 0x8e71900e, 0xf765e42a, -0x1be04368, 0xba6b77d1, 0x027853a1, 0x4d76fe05, -0x30b44278, 0xca1efae7, 0x36fc3696, 0x2feb3958, -0x560acd1e, 0x71bcdb1e, 0xff0c0f48, 0xa7ebdcc1, -0xe874123f, 0x050e72e9, 0xaa51e4fc, 0x14e60100, -0x42116c64, 0x58a87c0a, 0x3cc6816f, 0x6ef8022e, -0x822b9e42, 0x76699062, 0x87c1d73a, 0xd71d85f6, -0x2c048669, 0xe53a0f9b, 0xedefa244, 0x3112ba9f, -0x0ddf05fb, 0x43d2a8bc, 0x8a912f27, 0x120b57d1, -0x12d0a08c, 0x3055610a, 0x0611c5e9, 0x62ff32a1, -0x96b856a1, 0x13c9a0cc, 0x81bdc683, 0x8d1e4af5, -0x5dddefc9, 0x2167f11f, 0x080de923, 0xf93d81b1, -0x89aa8364, 0x14a9218c, 0xc65494d3, 0xc955648a, -0x9d532e77, 0xc9bafa7f, 0x30099ca5, 0x71ce1593, -0x52b08e34, 0x2ecc93c4, 0xd2b00f8b, 0x2265551d, -0x4b5f1fec, 0x75bcafc0, 0xb032813d, 0x60c83e46, -0x88fc0a32, 0xc24685ee, 0x1552dd77, 0xd4d8beea, -0xf6101d37, 0x5067e008, 0x03c0ce59, 0x49d8df07, -0xf0f3b2a1, 0xae6a1194, 0x1b1c9a5e, 0xc0c5087b, -0xcde2ddb0, 0x9a52499e, 0x6cc44420, 0x0a9fe620, -0x6cb2ea9e, 0xc1c5dd9e, 0xb5c21092, 0x5d6b62a0, -0x54420a2e, 0xa55fe6c6, 0x5be036e2, 0x00ad1a1c, -0x49fe30d8, 0x13db6cd5, 0x1d367882, 0xfa4a08fb, -0xb037e9cd, 0x243c4e45, 0xccf4509a, 0x6db26901, -0x0075ab9c, 0x6ee273b3, 0x46e953bf, 0x55625aaa, -0xfb4c043f, 0xf986c5bd, 0xc2262652, 0x28bb1b7b, -0xcf429e66, 0xde10a292, 0x70de0224, 0xb34d3b44, -0xba0468ac, 0xbd06f79b, 0xbcdce47a, 0xaffaaa80, -0xb093dbec, 0x4e250f0c, 0x73639683, 0x021fe836, -0x49439a22, 0x2e4fb04f, 0xe0b3f943, 0x3c6ee400, -0x23316a70, 0x80235474, 0x30b98b5d, 0x94a03c53, -0x1a314d5b, 0xa630ff3f, 0x4e19d90e, 0xfb9c77d9, -0x98c95421, 0x065ec7c9, 0x1065516f, 0x47c897a4, -0x704e3cef, 0xe011a1a3, 0x3a5ad35c, 0x68526d7b, -0xb480bb26, 0x0669ccc1, 0x047cc38c, 0xd5574b18, -0xa64909a5, 0xb5e73a87, 0x5ea071f1, 0x76df8d93, -0x53e57d5e, 0xb2a62d6c, 0xc506e3da, 0x69385811, -0x09d25d90, 0x54e79cc5, 0xd68a620d, 0x4c4974bd, -0x98b55474, 0xe4b700dd, 0x3f70e16c, 0xc07ef531, -0x9c11b7aa, 0x8bbeacce, 0x21391b4f, 0x73624bc3, -0x5706b45e, 0x92a200d4, 0x80f2f6d0, 0xb933d8c3, -0x179e5a40, 0xae89a6c8, 0x153eaa99, 0x10bb4e91, -0xb50a198f, 0xe0abdcb9, 0x035f44ac, 0xf0f2998e, -0x18cadd3a, 0x23050c59, 0xb58a65fb, 0x6c999ccc, -0x8763005f, 0x1703af79, 0xda1d75cc, 0xa3a2f063, -0xdde69386, 0x43039b8c, 0x25e1b4bc, 0x162f930c, -0x70e335de, 0x59fdc4e7, 0x88c864d4, 0x77db0614, -0x8d0d0fdb, 0x56862726, 0x83eaa90d, 0xe509b226, -0xa4ada038, 0xe84a085c, 0xa648287b, 0x2e23bbe7, -0x449180b2, 0x5dcc1bfe, 0xd4fa7aa3, 0x2cbe4a49, -0xc519cdba, 0xd82cdff1, 0x2c8e00d2, 0xcfa395d7, -0x680c8e2a, 0xb0105431, 0x49c98d09, 0xf0bc411b, -0xdb36b018, 0xb8bf0c6b, 0x3d4793c4, 0xc2c8b854, -0xbf759b5f, 0x69713fd2, 0xecef764c, 0x170dd67d, -0x8ea058f7, 0x9b9f2c7e, 0xe2e50483, 0xbf377736, -0x67a40d09, 0xdb97b029, 0x18fca161, 0xbea0cd76, -0xa3380607, 0xb40553ad, 0xaa2ba855, 0xcfdbe241, -0x07f78103, 0x16269f13, 0xf947b3d0, 0x7542caae, -0x840573e7, 0x7bb4b73c, 0x18fb5bce, 0x6510a043, -0x09816599, 0x35a3b7ab, 0xd5aa1265, 0x4ff654a0, -0xaf919aac, 0xa45d4d56, 0xad1d53c6, 0xf8e4a825, -0x58aadc02, 0xf925c5b2, 0x2e1f1137, 0x3bde5e6f, -0x29237bdb, 0x93a29f52, 0x4618d46e, 0x055078ee, -0x4672eb9b, 0x1d84e114, 0xcd3e8620, 0x5e9c11e9, -0x3473a677, 0xa0c59414, 0xdba554a4, 0x7d570d61, -0x7fc49885, 0x6d967357, 0x8e2c95b3, 0x599b0a3e, -0xdeeb825b, 0xa26e7a46, 0xfa6344be, 0xe360cb75, -0x598d3b1f, 0xa1de27d5, 0x6d582656, 0x7460caf2, -0x9a9b0a1f, 0x6b03e47f, 0xcb773bfc, 0x8b4dbf7e, -0xb2346a85, 0x7524eb59, 0xad850431, 0x1b7f3435, -0xaa872445, 0x5383f435, 0x277db9e8, 0xd0885463, -0xcd9c190c, 0x59b067ee, 0xe2a649d8, 0x0de635f8, -0xb971eab5, 0x5251d886, 0x0fbee652, 0x20a69173, -0xac648bc8, 0xf527bbd3, 0x5991e44a, 0xc354d183, -0x533ebb92, 0x4e213450, 0x32da96d7, 0x1bc6eba8, -0x9a982769, 0xc63f6a40, 0x5362ff6e, 0x31603fef, -0x4326f4bd, 0xc69df862, 0x67015fd3, 0x2cc17450, -0x751adb02, 0x5a959871, 0xd4744b5c, 0x02c05fe0, -0x301d3565, 0x9a7df8bd, 0x5ea285ef, 0xd6cd559f, -0x20ed318d, 0xcd4c0972, 0xf6fd10c6, 0x51dcbcf8, -0x343bc9f5, 0xa7b1e1ca, 0x7072ef25, 0x25050f84, -0x4cc19863, 0x247562bd, 0x960e87f7, 0xea2a401f, -0x58e2451f, 0x4e59f93e, 0x9ebd55b0, 0x6c4bf8ab, -0x6d8de270, 0xbaf9e338, 0x64a6f36a, 0xc61817a9, -0x0cff6e4d, 0xe9d6facd, 0x9f679b31, 0xfb4e0df3, -0x5d3601d5, 0xdb557456, 0xee907bd0, 0x97f55ad4, -0x9be94661, 0x37d20c4d, 0x61c2e4f8, 0x1410ad12, -0xc70e847a, 0xe7aefa4f, 0xbfedf651, 0x6d82c2b5, -0xe72ee260, 0x7614a850, 0x810fa301, 0x24382684, -0x8cbf769a, 0x6d200632, 0x3e5fac0d, 0xb3f721e5, -0x191a57a0, 0x938ef2e8, 0xb9577657, 0x8c48778b, -0xa64f1049, 0x553062a9, 0x4f0a17e4, 0xe4a7949a, -0x6fa14161, 0x67ceae86, 0x22cc55ca, 0x8f49bdcd, -0x8636d5c7, 0xf6db1b31, 0x5ddb0ce8, 0xfa84e29a, -0x3b465c6e, 0x40438b22, 0x54c77f5c, 0x11260af3, -0xfa9c31a5, 0x62574201, 0xb47b260e, 0x49bcda40, -0x9ca8ff1d, 0x7ef6a279, 0x4b9b3701, 0xd514317d, -0x1397305a, 0x60e37da0, 0xe883c100, 0xaeed8582, -0xc4c984fe, 0x5b8fde0f, 0x3a1ff9ef, 0x66077a5c, -0xe7779cbf, 0x1bec9cc4, 0x1ae72ef1, 0x13479f70, -0x3c180bf8, 0xd948cf8c, 0xaa7de543, 0xab853b9e, -0x5fe0a2df, 0xc91f811a, 0x08ee75ef, 0xdf912c97, -0xc357c8f5, 0x64049a04, 0x382a1d20, 0xa34de556, -0x8443f669, 0x85589500, 0x5bff7e15, 0xfba9d7d7, -0x5ee9511c, 0xef6c7809, 0x32e2b93a, 0x01dc227f, -0x42af4cbb, 0xbf89eebe, 0xee70ccc7, 0xdc8edfa2, -0xe9fb5422, 0xe682d011, 0x2015a8a8, 0x9290e8a0, -0x45e84ab2, 0x09e54944, 0x6498df04, 0xe1cbd37b, -0xf0ef571a, 0x11126396, 0x194bb903, 0xe4b9a1c9, -0xa31ea519, 0xde38d30f, 0x71bd64fb, 0x19548c4c, -0x99f19c88, 0x2c368d17, 0x23370946, 0xc927bbee, -0xc6b7ab96, 0x233427ea, 0xf4ba633c, 0xb05f583d, -0x42407188, 0xf3937760, 0xb72c9a9b, 0xfe855280, -0x076b9424, 0x13b7f5e8, 0x96223666, 0xd9e45123, -0xbf342078, 0xd6fd02f4, 0x1d731bae, 0xec80d22c, -0xb29df9e4, 0x667b78a2, 0x7f5642f3, 0x99e9bcbf, -0x4f336820, 0x4b8fde3e, 0x93b01d0e, 0x7ccb245b, -0x0014f1b4, 0xe1b1c1ca, 0xaa7ca490, 0x85d838ae, -0xf134027a, 0xc64a16c1, 0x8b94368d, 0x85202ad5, -0xcfaf0f31, 0x9d81d9de, 0x09e374eb, 0x7d905160, -0xf8409a09, 0x670b3696, 0xa584a070, 0x84342454, -0x95253da1, 0x229f2918, 0x1a702051, 0x22e81f48, -0x766bf7fe, 0x07384f51, 0x82487bbf, 0x10c9307d, -0x2b572e64, 0x139cef4d, 0x6ac5e564, 0x6fcbc0a3, -0xba1bf522, 0x85eacbc3, 0x28530abf, 0x7322f6b6, -0xbdbde559, 0x100f0c60, 0x26b64329, 0x93ea0651, -0x52573484, 0x63f48bab, 0xa0d5ecb6, 0x23bd3d48, -0x706634ec, 0xc52537cc, 0x2784e92e, 0xd095c0b6, -0xf5c6a0d2, 0x1d5f041b, 0x6f86c937, 0x5403a4c6, -0x1f354de2, 0x6f074fa7, 0x9465e5cd, 0x0b8c87fe, -0xd4057cdf, 0xb3a60164, 0x627f39a1, 0x33020fd7, -0x51e197ea, 0x40cb35b6, 0xdf2327b0, 0xff6aa5b5, -0x48e196aa, 0x37077b50, 0xabc7535d, 0x089fad31, -0xba46bca6, 0x57730eb6, 0xc039f71e, 0xa19963fa, -0xda9c5d12, 0x7360c4b8, 0xa2fd2347, 0x3a58da4a, -0x8ba6803c, 0x781cf017, 0xffdbfbc2, 0xe3f7cbc9, -0x343900aa, 0x432e4ea1, 0xb9e0eb2a, 0x11ec2e64, -0x5b205aea, 0x65cf92d1, 0x4fe48dd0, 0x72558b78, -0xb0d9b571, 0x6ada41a3, 0x4e8180af, 0x222054ca, -0x98556eeb, 0x145b8d08, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2990-m046fbB9.inc */ -0x00000001, 0x000000b9, 0x05112009, 0x000006fb, -0xb6a7f0c9, 0x00000001, 0x00000004, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x000000b9, -0x0000003f, 0x2a000000, 0x20090510, 0x00000341, -0x00000001, 0x000006fb, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x15341951, 0xd9f92c58, 0xd61aff76, 0xe96873ee, -0xdec6dd45, 0x3dfa2e4e, 0x61661b88, 0xcf5c5841, -0x58d10d9f, 0xb7f2421d, 0xe4d5fcf1, 0x02889a15, -0xad9bed07, 0xa32ab3e6, 0x3491afcc, 0x9c991c37, -0x2a1c2071, 0xf066191a, 0x3bd898e7, 0x2648d958, -0xc05f7908, 0x05864b9b, 0xbe4c1eee, 0x1e6c7ef4, -0x0e7a539e, 0x100b2ab3, 0x1273dceb, 0xfec8847d, -0x8f37946f, 0x634e3b5c, 0x691dbd61, 0xd89e3cb9, -0x094639d4, 0x7d972e1a, 0xd6dbd94d, 0x2001c3ec, -0x34f791f0, 0xeee0d794, 0x88b7459d, 0xc2c73aa3, -0x607a174d, 0x4f0f8304, 0x65790b35, 0x00532bfe, -0x1fd1e0cc, 0x7b91f873, 0x154ed42b, 0x7a7108e9, -0x81637c95, 0x192cb173, 0x28ccd94e, 0xb9bcc372, -0xac05171b, 0x867f47da, 0xf8e8c47d, 0x1edcdb4a, -0xd2ca6c2d, 0xe9ee9169, 0x5a6efedc, 0xb6825038, -0x09277eaa, 0x2a34e580, 0x0f794366, 0x86c99402, -0x211b98bf, 0xdf8eb0e3, 0xda11d7bd, 0xd440363e, -0xa7d49f1a, 0x16dd7395, 0x5b23c2fc, 0xab93ea3c, -0x00000011, 0x0741cbc1, 0xcb879f12, 0xb53a6cbd, -0x8d26a6ca, 0x2aca7c7a, 0x1e952ea5, 0x07da17e7, -0x52d164d9, 0x62c68a73, 0x2d489e03, 0x45a07f1b, -0x0f0cc8cf, 0x4fa8fa70, 0x2315d683, 0x33e36418, -0xdda877f3, 0x8e1bfc6c, 0x7f636e46, 0xbb114fab, -0x69c0e244, 0xf261040f, 0xeeeea4a8, 0xc88fbfac, -0x507ac028, 0x4932bf5f, 0xb40db20e, 0x8d18c03e, -0x44b1f658, 0x2f0527f9, 0xe6d65979, 0xfd881db7, -0x770be7a8, 0x459b7a4b, 0xfc00c5d2, 0x1bdee510, -0x94bf752f, 0x68a06b2c, 0x4fdf4668, 0xdd08536a, -0x19438a29, 0xdfa14148, 0x266ccbb8, 0xd7ab60f2, -0xceaf893a, 0xb00858da, 0xd204d03b, 0xea8d3784, -0x4f3a4d8b, 0x323f53e4, 0x3180af2e, 0xd06428fc, -0x932bfc3d, 0x8d701652, 0xacd6f494, 0xebd48f9e, -0x2b1248b0, 0x63f4d854, 0xbedc0412, 0x505e1f49, -0xad20cee5, 0xc95a2a56, 0x49b90a51, 0xb3de9036, -0x1f4c88df, 0xb7460c4f, 0xad3a53b4, 0x3d3e83cd, -0xde1ea2d5, 0x5d3b0237, 0xda3c8637, 0x0aeeeead, -0xae2b5959, 0x35624290, 0xbabab8d5, 0xa4899633, -0x7d6e607d, 0x410383ae, 0x10916b70, 0xb2adf0c0, -0x52d8faac, 0xe6937b79, 0xb959bc66, 0x14d8d06b, -0x0ec3c602, 0xb6c71f26, 0xbbd8c4dd, 0x63d23706, -0x6bee321d, 0xc8a1ec7d, 0x8de3941e, 0xd549d1c4, -0xe33588e8, 0x681cff2d, 0x66dddada, 0x807040e6, -0x006c83b0, 0xba10f7c8, 0x38eafe62, 0x0777e74d, -0xfa39a198, 0x05720466, 0xec377dbb, 0x23d46da7, -0x3a387dc8, 0xe005ab95, 0x5d92190b, 0xb811b9d9, -0x9b09dddc, 0x62a64be5, 0x0c9014bb, 0xcc871ef9, -0x4846edba, 0xc60305e2, 0x91b831aa, 0x8f7d5aa7, -0x6712012e, 0xbae578bd, 0xc5bb2872, 0xb635139f, -0x41444279, 0xc51f819a, 0x92fe6768, 0x96c480e6, -0x6a958394, 0xb4b7a6e5, 0x007c0429, 0x43af55b5, -0x33697de5, 0xcb6b363e, 0xf527556a, 0xd4a79f83, -0x9c628ccb, 0xef72182a, 0x8406cbce, 0x6035ff55, -0xd6325e79, 0x111ea438, 0x962b7e5c, 0xecc816e1, -0x39a8f348, 0x8f5bb065, 0xa2419dd2, 0xc036db13, -0x5360daa6, 0x82d2ffb8, 0x15681502, 0x6d5497d6, -0xe9028ce5, 0x2e05c16a, 0xee8711ae, 0xac5b11e4, -0xabba0581, 0x1ef11c35, 0x54ecf615, 0xcf45b599, -0xd8ee7594, 0xecda2c12, 0xa6b2b120, 0x32edc139, -0x7734c724, 0xbb88978b, 0x12092d6b, 0x133fb4f4, -0xa6fa233d, 0xa059395e, 0xb86920df, 0x60b25bff, -0x1fe831ef, 0x2b5cb3aa, 0x27ef4afe, 0x02f3ad21, -0xea597773, 0x2caaf33c, 0x03b30480, 0x7d8e32e5, -0xad9a917e, 0x1bd0695c, 0x68d8ca07, 0xeef84400, -0x928ff8b4, 0xecea6a3c, 0x9bbedbd8, 0x5c2654bf, -0x2d1644d5, 0x961ddc1e, 0xcb216e0c, 0x55fcff3b, -0x6054f145, 0xad2d4159, 0xdcbe8ed7, 0x3b2e7495, -0x7a33fdb5, 0xa92fdfde, 0x65ad1aa7, 0xf6866ab0, -0x53388681, 0x0a369d17, 0xf087441f, 0x44007109, -0xd1d8b88d, 0xdc94549b, 0xa11f14d2, 0x72864a34, -0xd7f71dd9, 0x6f948c77, 0xd3e89fc0, 0x11b097a8, -0xfd2cd3fc, 0x774f951d, 0xe1170076, 0x2bde8936, -0xa3ea656e, 0xabbe230e, 0x2fe6e1d2, 0x53b331e2, -0x7b392823, 0x48c2aa80, 0xb7824981, 0x275bac51, -0xd3b3eb48, 0xa3541a00, 0x4375b1fe, 0x086302fb, -0xd744a440, 0x0323a890, 0xcebc28fc, 0x9921427c, -0x7a4b5465, 0xf4db5f26, 0x6461f88c, 0x2dbe6ea3, -0xeb6dd03c, 0x8257fcce, 0xf44dadd6, 0x7d367355, -0xda56024d, 0x750430f5, 0x5e4151d9, 0xd90a0db6, -0xdc29eff5, 0x6acb146c, 0x97ef9139, 0x4992e11e, -0x87833d75, 0x897f9beb, 0x33aa151c, 0x28a717fa, -0x5c5bb59f, 0x45617198, 0xfc791809, 0xef17a7b2, -0x10931956, 0xdd697c3a, 0xd8a2f728, 0xd4171ff8, -0xd507ad63, 0x40c2a2b8, 0x519fe54e, 0x6ddbf5e2, -0x215f916e, 0x99694eca, 0xeb87cf67, 0x69691e42, -0x76d17fa0, 0x0edb5d25, 0x82303164, 0xa6ff4797, -0x8a19ce37, 0x71005b4d, 0x41930843, 0x0251a3cc, -0x594886d3, 0xe2e463e0, 0x812ab47f, 0x477b2ba6, -0x17c544a2, 0x802b8757, 0x1692cc60, 0xb86bf34f, -0x1f8a5fc2, 0x0693dda6, 0x5da932c7, 0xfd216376, -0x25002074, 0xad6987f9, 0x93bde120, 0x2ae45842, -0x092941c2, 0x0bc4878d, 0x30507588, 0xe9351bb4, -0x81dda9a2, 0x6b89e825, 0x948482ef, 0xaeb22085, -0xace5a27e, 0xa20c3f4a, 0xd768a0da, 0x919d2d26, -0xded8effd, 0x01812972, 0x9ba923be, 0xb69023a5, -0xe7defcfe, 0x865e123e, 0x02107238, 0x92c688cf, -0x30b0a462, 0xb56e62e5, 0x009e60fb, 0x02db37ca, -0x19a5c9d0, 0x9b879be1, 0x16ec478f, 0xa983dd56, -0x2776b4bd, 0xb858a7c4, 0xdf340c19, 0x137d7e01, -0x4467564d, 0x855bcac8, 0x9cf1cd0e, 0x54a19437, -0x2e4ed636, 0x7b693cfa, 0xddba25a3, 0xef65d915, -0xaccd377f, 0xcdc2f092, 0x74704385, 0xda63baf4, -0x1ac4bc8a, 0xb4ea4309, 0xa73ad61f, 0x6293ce83, -0xdde1e829, 0xf88514aa, 0xcc488bcc, 0x6e4c9d36, -0x78b7e22e, 0x5a7d29e2, 0x42f40246, 0xdf4a9afb, -0x82ca32e0, 0xc7118b4e, 0x25165db0, 0x7770aecf, -0xdf7582f0, 0x35b55887, 0x33a47c37, 0x08c158f6, -0x7a21b06c, 0xcb6a9bbb, 0xdabcfc6f, 0x486b55b8, -0x6187d764, 0xe5c70327, 0x492a7da7, 0x24264c3e, -0x8e5c09d7, 0x3836c445, 0x9fa2d9cb, 0x6bc2b196, -0x1ef155ed, 0xb949f5e8, 0x00846e44, 0x2b79a60a, -0x9e40d440, 0xe8b97836, 0x90a14cef, 0x786cae97, -0xe39447a6, 0xccf6d399, 0x0accbac1, 0x54250900, -0xc0351c81, 0x00b88195, 0x5beb4553, 0x682e6920, -0x9379d47f, 0x69cd76f7, 0x097b55db, 0xa9ead305, -0xbcbf9b4e, 0x8d627c2a, 0x380a2367, 0x14790660, -0x9c95ebed, 0x76e551eb, 0x645370f3, 0x497634cf, -0xeffa7029, 0xf66aa141, 0xfe718fc6, 0x094c6914, -0xbd00207c, 0x77e3154e, 0xabc1749e, 0xb8c40c07, -0xaac4f806, 0x89d5f6eb, 0x2d89377c, 0x65caeecc, -0x1c21568c, 0x901ddb9d, 0x915df7d7, 0x4f9cb664, -0xf62c432c, 0xeeecadaf, 0x0ccb4f75, 0x14186099, -0x68245f8f, 0xd981ff3b, 0x722de32c, 0x2b55e9ef, -0xb918ac26, 0x94fdb9bc, 0x02b7ad08, 0x7592dd6d, -0x470f9624, 0x9d403aeb, 0x5e7b4f3d, 0xb5e11056, -0xa97be649, 0xe9826083, 0xeec24fba, 0xe731ac9b, -0x5b339d05, 0x97af9713, 0x86390c44, 0xed541028, -0xeaf9969b, 0x3c72446f, 0x0b654ab2, 0x281b99a0, -0xa31e8b79, 0x86175d4a, 0x96fa99f3, 0xabd90de1, -0x642bc82c, 0xdcc81442, 0x16719e3c, 0x0cc60e15, -0xc276faaf, 0x9d0e7759, 0xe8594cd3, 0xbfa376e0, -0x4daabe5f, 0xcbe3009e, 0xd1812e8c, 0x744b1fc0, -0xcf3728a2, 0x34442fb9, 0x1c28619a, 0x35844d65, -0x115306a6, 0xa3c936d2, 0xf781af3e, 0xef7bb760, -0x0264321d, 0xf52bb605, 0x3a83684d, 0xdd21a5ff, -0x777115f2, 0x69b8e872, 0x64517548, 0x70267f4f, -0xbe3b1dcd, 0x5a2bc602, 0x222c7241, 0x424864ae, -0xa735c475, 0xcc44d6f0, 0x27d8d5db, 0x67bc23f8, -0x3391d751, 0x197aa11b, 0xf16a2a9c, 0xe4d58566, -0x9dae5211, 0x1601c94b, 0x491bd296, 0x48dac3f6, -0x8c6ddb0c, 0x734bc4ed, 0x83d4015c, 0x29ff784b, -0x3707b6dc, 0x6c14e801, 0xc76aa725, 0x70740fc1, -0x6aba6f3e, 0xf122dfd2, 0xffddda9d, 0x516c60ff, -0x396bf3b6, 0x2d3406b4, 0x4355cfb9, 0x126d6dbf, -0xd0d55fcb, 0x6f23a648, 0xe2f286dc, 0x8af42ef8, -0x497f9446, 0x7285afdf, 0x3ff58008, 0x583df7d2, -0x3aa49b76, 0x9281e837, 0x6196b8d5, 0x5ee4428a, -0xf4f92c37, 0x6c6376d2, 0x6afb2760, 0x3f355e4a, -0x1ea450bb, 0x5e9da7c6, 0x2b4b1e72, 0x74d5e29e, -0x07de0aea, 0x77544e2c, 0x66c19ac3, 0xbe86aaa4, -0xe5233e14, 0x7d4e763e, 0x31ca0aef, 0x0527e563, -0x149b4d2a, 0x5f5ad61f, 0x65f1161b, 0x86c7633b, -0x2877e065, 0xf5592a41, 0x60e67df5, 0x555aafdd, -0xe3caffab, 0x501e6b00, 0x11ac37c4, 0xf84c8688, -0xbad031ee, 0x6c10e5f9, 0xc7087e4b, 0x86d0bcf2, -0xdcec3d4a, 0x999fb6a6, 0x7de512a3, 0x25a4304b, -0x775003fe, 0xc3da9a99, 0xdb02be9c, 0x8c8bae98, -0xd95e979d, 0x6094a6f2, 0xf69c4d09, 0x51fa8ab0, -0x9e31adf5, 0xed2c1ddf, 0x0bdc379d, 0xe0c24b81, -0x021511d9, 0x6aab3cd8, 0xbdb35278, 0x5e253639, -0xdc51e798, 0xb7969a75, 0xb448b42a, 0x4db2c7bd, -0x92ab4fd1, 0x99a0c92c, 0x5b59394e, 0x5e06cd33, -0x76d0636b, 0x01c826fb, 0x66d62ad4, 0x2177e49d, -0xbfdf80c4, 0x0687e341, 0x2cb66974, 0x0765697e, -0x33a9d5c8, 0x790deacd, 0xb528b72a, 0xad4f0332, -0x9efb2065, 0xa1621eda, 0x6da51c10, 0x891eb234, -0x66015c9d, 0x8551be17, 0x34ddbe4a, 0xafc5de23, -0x9ee441d8, 0x92153585, 0xd4ee376d, 0x7f267079, -0xdffe357f, 0x0e0cd672, 0x8d914a79, 0x55c6242b, -0xba984937, 0x6d4e5c6e, 0xdbbf9de8, 0x7b07ffb1, -0x4c60f396, 0x81780d39, 0x1158e09f, 0xa7b04aa5, -0x29e4e907, 0x321756e8, 0x938df05f, 0x3d2e2a2f, -0xa0218157, 0x3b43bb2b, 0x90aed14c, 0x99e51a0f, -0x94ed8b33, 0x230c8dc4, 0x49a1aaca, 0x38552316, -0xd2b4d683, 0x402572f2, 0x6b35d2ab, 0x8f54d64e, -0xbf6713fd, 0xb1baab41, 0xea513b9d, 0xee1fabdb, -0x96965270, 0xb9c73510, 0x307504f6, 0x66e6efb6, -0xe5edf87e, 0x0dfc0dda, 0xce9b9f4b, 0xc495c0dc, -0x8eb4ae2e, 0x15d4ffaa, 0x3f72c117, 0x9066433b, -0x1e326a9a, 0x87e472b4, 0xe8e9924e, 0x2d34ddd6, -0x9f045dc5, 0x4e517bf9, 0xd4215701, 0x997945f2, -0xda577384, 0xc26b9a43, 0x72cc0d2c, 0x1a6f0feb, -0xb0deaa5f, 0x085e3c1c, 0xe84cd89d, 0x0c0b72ea, -0xb6ba866b, 0x5495bf3c, 0x322cead1, 0xc15fa497, -0x90813acd, 0xabdc90af, 0x25f8bca2, 0xef81a57d, -0xa3f95491, 0x257d3c3d, 0x2ac7aa7b, 0xd713ee46, -0x11a2cb99, 0x516713f4, 0x3c2e6d1f, 0x8dfc69e6, -0xb2aa11c3, 0x4735befc, 0xccc1c2e9, 0xedd47dc8, -0xfea0a020, 0x7477af3e, 0x59c5a8c3, 0x22546f44, -0xfed2ffc9, 0x3b1dc4f3, 0x6d4fd900, 0x0df8a070, -0x1bdbd385, 0x1b028b64, 0xd2c7b639, 0xaf26374b, -0x48a6a1bf, 0x4f7896de, 0x0356256a, 0xb0bf4df2, -0x3d0f3382, 0x28f1a73f, 0xadf4ed6b, 0xced36065, -0x1c807f0b, 0xcd33028c, 0x62da94be, 0x79a2b539, -0x3b81dc8b, 0xda9094c2, 0xdf52d610, 0x47d10d38, -0xed9cd5c0, 0x482e26a0, 0x1459e4f0, 0x6cf0b6cb, -0x4e29d1ef, 0xe67e1cb9, 0xd2ddca3f, 0x6e67ef3d, -0x299c296c, 0x1e39f62d, 0xe77ee72f, 0xfc3c6f35, -0x1317aa16, 0x5b9b266f, 0x292eca31, 0x39a8d234, -0xd667205f, 0x4a2d3bf6, 0x70ed41af, 0x4e5d9985, -0xa7ed1e30, 0x4a5ef783, 0xa9b51db1, 0x6fa70d0f, -0xe7414e10, 0xc310129c, 0x2a486151, 0x2a0c9bee, -0xa45f38f7, 0x0be89a12, 0xcb4ba82c, 0xb80cc7ee, -0xb59b6377, 0xa02c239d, 0x3d823ee9, 0x77e3ffc7, -0x17af5213, 0xb303a743, 0x38f96fb1, 0x14d3bdbc, -0xc5ca7945, 0x5dc85885, 0xe4504922, 0xe7c4733e, -0xf0fc251d, 0x9fbb0793, 0x5ce74c74, 0xb3e89185, -0x84c07f55, 0x250d23e7, 0x87991bc4, 0x756003de, -0x25bd29de, 0xa4a4890a, 0x6221bc7f, 0x0e2152ef, -0xbfa74e3c, 0xe05707d9, 0xe6173655, 0xb5f18ec8, -0x77a9d945, 0x950a28ae, 0x9e8a89e4, 0x63f0ec5f, -0x9d076f5d, 0xe58dc77c, 0x25ee33f9, 0xc3e7f8fb, -0x83527683, 0xaa61f768, 0x2205c8d0, 0x0d6168cb, -0x246cf5d2, 0x85a4ae73, 0xb5d3ebc3, 0xe19687a0, -0x9142d39f, 0x020feac5, 0xbf936a88, 0x531966c3, -0xeefde76e, 0x813b650c, 0x9395f9a3, 0x60977944, -0xadb0e013, 0xfc5ca32e, 0xc37bbb0a, 0xb163bff7, -0xf7747ca4, 0xf26bdd07, 0x729fabaa, 0xdac72d73, -0x4aa514fc, 0x33afdcd4, 0x42d8ef5f, 0x66d3596f, -0xbf7171da, 0x46c3f239, 0x2d341c89, 0x69f0dba9, -0xb254dc2e, 0xaa9ba584, 0x700a8ad5, 0x5dba481a, -0x9307d3eb, 0x14c96fe5, 0x242a89d0, 0x0989fee6, -0xcc68b593, 0x79061e54, 0xc4031f53, 0x41197bc4, -0xc7e93644, 0xd67bfcb1, 0x2f38d97f, 0xd0024f6c, -0xa6b95737, 0x575f4cec, 0xd69d5a72, 0x7e43e98c, -0x0540ba2c, 0x6f4cadfc, 0x829ef6ce, 0x9837e2cd, -0xb60f889f, 0x5e4a515a, 0xf11878eb, 0xfd873925, -0x27413b1f, 0xae1f0200, 0x14700e37, 0x3807ca50, -0xf8bf4663, 0xd1ed4780, 0x4480ac46, 0x3902cf3d, -0xe33e8a81, 0x732aaa74, 0x21262a1e, 0xb4e62db6, -0x1ca18e6a, 0x51495ab4, 0xb2934c32, 0xc6bcb687, -0x22d4c9b6, 0x304d9bf8, 0xf2fd09f9, 0xf26d3d60, -0xf7bb7d89, 0xbb19f13c, 0x148cb5f2, 0x85fd9045, -0x9c6d3db5, 0x5da8c1c9, 0x048ac803, 0x94c91a96, -0x25bf6e95, 0x2ee75dc4, 0x34e50927, 0xb2264221, -0x6a7fccd9, 0x8efcaad3, 0x4ac94464, 0x493a2738, -0x45c46d1b, 0x7ec0ebc2, 0xf870d8f1, 0x521b6386, -0xfde5b6c7, 0x52717e80, 0xc25214d5, 0x239dd53a, -0xcd4e0e62, 0xc0623e3b, 0x4827474f, 0x59ebea6f, -0x54fe5e77, 0x1023eb02, 0x6a527d7a, 0xe24b64ce, -0x5db22ab3, 0x0a680da7, 0x65cacc9d, 0xeb021a50, -0x0c469683, 0x66220235, 0x24b031ea, 0xb6a92ecb, -0xdc420a74, 0xf43057db, 0xe994ed65, 0xd70f65f2, -0x3705d791, 0xde59eebc, 0x40916333, 0x516f3fa5, -0x21b2a41f, 0xf466918e, 0xb859be7e, 0xeb2df428, -0x1cde44b5, 0x93380060, 0xdb0dcdd3, 0x338cb6ef, -0xc0ec9c37, 0xdbba2a12, 0x75da511b, 0xe915d57d, -0x99fde0ff, 0x4e377dbc, 0x881617ca, 0x78d1d21d, -/* 3107-M10106CA107.inc */ -0x00000001, 0x00000107, 0x08252009, 0x000106ca, -0x482cae0e, 0x00000001, 0x00000010, 0x000013d0, -0x00001400, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000107, -0x00000010, 0x000500b0, 0x20090820, 0x00000401, -0x00000001, 0x000106ca, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x2beaa92c, 0xfc3395b7, 0x10be81a0, 0xb318e067, -0x723923f0, 0xb297dc63, 0x7d52bc4b, 0xc6ef362f, -0x0882023d, 0x953684cb, 0x0abe06ee, 0xa7ef1798, -0x160d6cb8, 0x930cf745, 0xafc3fd79, 0xa70df3d5, -0xb0620f46, 0x70048a23, 0xbf95ecf0, 0x76c1b997, -0x5128616d, 0xb6b4b969, 0xcc69f71d, 0xdf7416e1, -0xdf9a571b, 0x50c0bcc8, 0x85e2b3cd, 0xc1927532, -0x7a04b6be, 0xe56b7f97, 0x524085c4, 0x668bf327, -0xb3eaa54c, 0xccde06f8, 0x09b4e42b, 0x033b0a46, -0x0f6e2fde, 0xb308ce53, 0x93eff03e, 0x8830014e, -0x5c8a6f22, 0x91d2f757, 0xf70b648d, 0x0789998a, -0xd84d4640, 0xe5f34e80, 0xf3357e64, 0xd1e2beea, -0xc7e95c3a, 0x30e57e4d, 0xec214356, 0x7e10859e, -0x1d5895d5, 0xdeeff6cb, 0xed1030ed, 0x827e603d, -0x6b4b2de3, 0x83ec6fd0, 0xa64092f3, 0x8d9887e4, -0xbefcbedd, 0x2111afef, 0xcb9abf96, 0x5c79ceac, -0x9bf8a57f, 0x5d0e44be, 0xdca3d3b6, 0x9072d1ca, -0x48e73a50, 0x8d0bc804, 0x6aea94d3, 0xc372403e, -0x00000011, 0x3b994153, 0x23faa5e1, 0xc3feae68, -0x76d5e67d, 0xbd696479, 0x138a05ef, 0xf2b5de22, -0x4ccba0ed, 0x333cc95c, 0x8d98a2ae, 0x0bf1fa24, -0x239f1fbf, 0x44701d3b, 0xb176783f, 0x20eff2cc, -0x0cf93bf9, 0x4e6ace41, 0xe346d231, 0x11d560af, -0xae8874a2, 0xe344fa92, 0x0056d268, 0xd8068d91, -0xf336cf97, 0x45c54f6d, 0xc0650992, 0xa3f86cb2, -0xc73d3aac, 0xc7654f1f, 0x385777ad, 0x20928850, -0x47509cab, 0xf40f9ba6, 0x34efbe6c, 0x1fe3b873, -0xfb39bd58, 0xa50b6367, 0x66c20e63, 0x49a4e1ee, -0xe490ed5a, 0x98c340fa, 0x30bfe19d, 0x4c17d142, -0xea54c4e2, 0x8c00e086, 0x219dee1b, 0x739a2fc1, -0x1e07b80f, 0xea6f4799, 0xb4684fc2, 0x42fc725a, -0x1d3c7413, 0x188b6f3c, 0x2c0e440f, 0xc6ad011d, -0x2048625b, 0x3be9d940, 0x0a932622, 0x1fafce30, -0x1cfa4c90, 0xd0e9f989, 0x31c0c399, 0xad0c597d, -0x48a94bb5, 0x109da683, 0xcdc197aa, 0x7bf7ef14, -0xebf3afa0, 0xde4ff7d3, 0x02a79e3f, 0x4d77f0e5, -0xd0c1fd98, 0xdb342a5b, 0x7f753eca, 0xb710c135, -0xacb3b9c0, 0x5e89ece7, 0x2ca4fe84, 0x4f22e461, -0xa6a633fb, 0x508fb453, 0xfe1f342d, 0x79bcff1f, -0x0c776771, 0xd6c5db47, 0xfe4d8cc5, 0x68b9f655, -0x447b7366, 0xddde31ad, 0x8e3496df, 0xe091f8dd, -0x78eb0fe2, 0x9e08c72d, 0x6909c46b, 0x92ca6b4a, -0xfb7a0efb, 0x55f65148, 0x9fcc90e1, 0x254f5f40, -0x0690dcd5, 0xc6a67013, 0xda2e35a9, 0x9171cb50, -0xe477a087, 0xc0f89e14, 0xc1221ebf, 0xf032e99f, -0xc8883a7e, 0xba4b17c9, 0xb0ef0962, 0x6ea751f6, -0xfc8c336c, 0xd1966bf1, 0x26d57e1d, 0x952e847d, -0xccdaf0c9, 0xd0aaee65, 0xb2f22a59, 0xc74bc035, -0x900ef42a, 0xeb1e7bfe, 0xfc465b3a, 0x0cd002ce, -0x560f5d4b, 0xecbc2658, 0x9f38856a, 0xa3f77ba1, -0x3ee18273, 0x7ab97b2c, 0x0f5843cc, 0xdb648b0a, -0x8e450381, 0x80176891, 0x05e3e6d2, 0x36593afe, -0xebe78fce, 0x53d7f64c, 0x2dde1104, 0x293cd7e2, -0x4f430fa6, 0xf3a8cdb0, 0xd28f6535, 0x9159d53b, -0xac66a916, 0x8f77be38, 0xa16b9dad, 0x1a4699d0, -0xe278df12, 0x2c336789, 0xb668fe15, 0x099fa98c, -0x4fe5ef10, 0xf4692cda, 0xb86d4040, 0xb6dce0eb, -0x6c5ef896, 0xdef35c52, 0xc02a04a4, 0xed99c619, -0xd91721b2, 0xa2fac92a, 0x5ab9c724, 0x0ee25329, -0xc2029fce, 0xc847bfbd, 0x3b97ddcb, 0x4aaaa55a, -0xa16e313a, 0x06e4b6cc, 0xc0e56598, 0x60ebfadb, -0x88841f3a, 0x7c6b65ef, 0x15542ce1, 0x70b88b78, -0x382d1155, 0xe73c900c, 0xd8b6409e, 0xf1cc5406, -0x64fc3223, 0x43cb616c, 0x17e3a1ac, 0xa9aba529, -0x8dd83b32, 0xb625cd1d, 0xbcb4b0ed, 0x685cc4b2, -0x803e35f8, 0x4e679481, 0xc7dd7591, 0xf8676b62, -0xac25b6c8, 0xb0211931, 0x5c5df337, 0x3bde6fb6, -0xbc433992, 0xf7315d49, 0x028e112f, 0xe3d59076, -0x7757e95b, 0xe5c5a193, 0x59b243a0, 0x341f33d2, -0x7c0d591d, 0x5f96d138, 0x5116c490, 0x747caf2f, -0x6da223f1, 0xcbe30d11, 0xe10b6b28, 0xa09328e1, -0xdf1b94ee, 0x163b48b9, 0x72e7a36a, 0x78eda572, -0x393f0ad2, 0xf85561ea, 0x6e7ca7c8, 0x352cb3b4, -0xb75bf9f3, 0x97ebcf76, 0x932b8b91, 0x937f1fab, -0x6ef1e868, 0xce84fc3a, 0x9dd09a21, 0xa8f3be36, -0x244834e9, 0xd871f223, 0xdef842f3, 0x787eaf73, -0xf2326bca, 0xd2c3ae20, 0x48dc7621, 0x91419afe, -0x23a44b12, 0xce0443d7, 0x4a6f1d9f, 0x1ea8cf7a, -0xb6b7694d, 0xf29e3e25, 0x51665303, 0x33581b86, -0xc762d72f, 0xaa658158, 0xcddb7354, 0xdacfd75f, -0x9ec31b1c, 0xf8aa3154, 0xfdeeb2e0, 0x9cb52f84, -0x16ce9fa4, 0x25050178, 0x2ef25d50, 0xcf4b4d41, -0xf27d5684, 0x7bae3f36, 0x05b50e59, 0x91d23add, -0xdbdee4ac, 0xe16994b5, 0x0a5481c3, 0x3deb8a17, -0xb8844d77, 0xcbce6140, 0xbd748572, 0x6531627f, -0x2137be68, 0xf46f8aa9, 0x6d2526a0, 0xe72aa307, -0xb361a2c8, 0xed9c2987, 0x75ddeb95, 0x637d3cad, -0x2c4dfd37, 0x01f0e2bd, 0xa521a1a4, 0x1194ab8a, -0x96d7b9c2, 0x94cee6e5, 0x454cc836, 0xa5c0fac3, -0xf6e9fe9b, 0x3107c251, 0x14c8c6a6, 0xd727c1e1, -0x339f2742, 0xb0a033de, 0x56fc9280, 0x36a907cd, -0xb74acdde, 0xe8122571, 0xd0116007, 0x238b3d4f, -0x34532ebe, 0x1c534370, 0xd1eb258d, 0x354b2289, -0x6007a18c, 0x58dcee7f, 0xa033ee94, 0xa5e1145f, -0xe345c315, 0x58510592, 0x33d9db2b, 0x7ea86edf, -0xce60a8ad, 0x2d9a8919, 0xb5e2840e, 0x020e6e15, -0xaff8660e, 0x402c12da, 0xfaea95a5, 0x6ffb0748, -0xc4c730a4, 0x1f57ead7, 0x2cc6d295, 0x0ef4bdb6, -0x01a7368a, 0x52e88f43, 0xf1b14c65, 0x38018686, -0x0c70ee45, 0x271b1fe2, 0x0eea950e, 0x61a6f56a, -0x842497a5, 0xfbcf0f4a, 0x35132cbb, 0x4f2eb1ce, -0x24fb1bc7, 0x343ec960, 0xda94e0a2, 0xf1206e0b, -0x80bf8007, 0x7e09d8d8, 0xba6bc1ff, 0x892c956c, -0x4ceaa5e8, 0x871f3358, 0xe802a1a4, 0x7fa29ced, -0xea8616cb, 0xc1999088, 0xc5baf089, 0xd1490754, -0x091f6f21, 0x9a3e3c4f, 0x1eb11650, 0x13fd05fc, -0x5e9d5b0e, 0xd1485d34, 0x474feaae, 0xc211a60f, -0xa609643e, 0x07052bb2, 0xa7bfb285, 0x30bbc170, -0x9ebe8d27, 0x5207a9ee, 0xfc12bd0e, 0x7fa428af, -0x2d1c8a2d, 0x6f15c0d6, 0xdaf0ee75, 0xd32bb1d1, -0x694463f5, 0xa1ebdae4, 0xeaa3d0b2, 0x954077de, -0x181da0bb, 0x4556808d, 0x46e80a64, 0x0c017172, -0xd8ef8702, 0xa0e6d100, 0x90b0a9f0, 0x4a13a407, -0xf1675dde, 0x5110d8c8, 0x1c028526, 0x7774581f, -0x9d3d8c23, 0xcaf8b632, 0xf401a52f, 0xa5d14a5c, -0xebed6c1b, 0x2ec618ad, 0x5b63935e, 0x89508732, -0x43a48b2e, 0x87535b2b, 0x0ffb28c2, 0x1fd1becd, -0xd2b2a18d, 0x45dccb4c, 0xad41a54b, 0x7ffa2fed, -0xddd18aa1, 0x1db06a98, 0x860d6b58, 0x2997109e, -0x80a2300e, 0x0cc52e7a, 0x15b24c31, 0x8f717016, -0xa425cac3, 0x8153e1bf, 0x5e91fd89, 0x04b17f35, -0x150fd30c, 0xc7309d31, 0x63dce1b0, 0x162eb854, -0x8093904e, 0xf7b4399d, 0xb23fa735, 0x67509c6c, -0x5380dec9, 0xb79172a8, 0xb6c249d1, 0xcd040b42, -0x4efe12f8, 0x63ce3363, 0x406d1666, 0xf8e9bc95, -0x99cbff2c, 0xaf0cac38, 0xe6556ddf, 0x9bb2a399, -0x43387c9e, 0x4951f5ac, 0xfa4ddb69, 0x562ec852, -0xa2e3e441, 0x32a80b75, 0xd88361c5, 0xf04b7ac9, -0xb0ea18bb, 0xf5035c94, 0x520c9c12, 0xb4c7e15c, -0x6f72c4bc, 0x80f2112a, 0x4e4bbb87, 0x7bb5ee1f, -0x54eb313e, 0x18cb6cb9, 0xca5ff580, 0x2538d798, -0x2b813681, 0x58c11a6c, 0x68ae4070, 0x40799341, -0xa740f86a, 0x722ca7ef, 0x815c71c7, 0xe663c6f7, -0x5e249b96, 0xe97e3b71, 0xb7ee5a12, 0xd5f065bd, -0xaa642191, 0x9864e095, 0x0c087780, 0x0fc0d969, -0xf6b82791, 0x04aa55f8, 0x872c7cd1, 0x43bc93b0, -0x12fe4c05, 0x16f15229, 0x06161603, 0x6e76239d, -0x90ea9c62, 0xecf642df, 0xb52a8db6, 0x2e0c5d58, -0x10f09bbc, 0x1bb1b2a3, 0x7132167b, 0x291d5f16, -0xd7814a9e, 0x79e52dbf, 0xef6b61e8, 0x585b920a, -0x18ea4e61, 0x72ce62fc, 0x59ed8e9f, 0x610564d3, -0x40f4f145, 0x0a2f60c1, 0xec64ebc3, 0x8ad5b251, -0xb471e120, 0xb899cffd, 0x2b81118a, 0xa3b591a8, -0xdeced3ab, 0xcb9aacb8, 0xba53fbdd, 0x6e49e298, -0x75fa6c19, 0xd11cfe98, 0xd29ce7fc, 0x7471df09, -0xb59b2474, 0xdff0b07d, 0xae92c4b7, 0x6414ee6b, -0x6acba1a5, 0xed9c0b5b, 0x728f7644, 0xf6d20c7a, -0xf03ad03e, 0x6612b0c3, 0xe156c417, 0x9aec4a8d, -0x02be86ff, 0xe11d1660, 0xefeba14a, 0x7d275f33, -0x16acabb2, 0x7ac99cd7, 0xd18566e4, 0x3bce4ca1, -0xb0312f16, 0x5700f72c, 0x345864bd, 0x917a4db2, -0xaa22b7f0, 0xc66eb69c, 0x62f8a99e, 0x6364a44f, -0x956d2cd2, 0xfa64b7df, 0x47238b18, 0xddebaeff, -0x39c9d16b, 0xaa1487cb, 0xc6f91d13, 0x8191316d, -0xbf5d7ddd, 0xc907cbb1, 0x7a283ba3, 0x0365e6a3, -0x2fbb3185, 0x159d0436, 0xb55b6990, 0xf0935005, -0x441e4fc8, 0xd1dfdc91, 0xdd9ff8bc, 0x95c88203, -0xa8029310, 0x62501ff4, 0xf838a813, 0xfb66d5ce, -0xe6bb8354, 0xe2afb832, 0x55dcf796, 0x315f28cf, -0x400de577, 0x3ad89b1b, 0xeee943aa, 0xbd5d9001, -0x8dd4771b, 0x21ad481c, 0x504d6222, 0xfc0e6728, -0x7abe5d62, 0x332f8309, 0x50d8c688, 0x4b686808, -0xbe6395ec, 0x5153b67c, 0x04144a35, 0xa85077ca, -0xa3775cda, 0x838556dc, 0x973c2222, 0xf5037c9f, -0xd02b0c87, 0xa3e69f8f, 0xdf68cce7, 0x9490d31f, -0x3d9c5cf2, 0x939e7823, 0xc51b9a2d, 0x2e802e27, -0x65079a36, 0x3b6e3d79, 0x5fafbac6, 0x9973bc64, -0xfc4e7124, 0x56e1fad3, 0x10ec049f, 0xefa79c0b, -0xcde48353, 0x3fa7f449, 0x07cb1a31, 0xf6ba0053, -0xe5af7b10, 0x9e2dc089, 0x290f3fa4, 0x116da472, -0x7a006f5b, 0x727205bf, 0x7c59870d, 0x968c6000, -0x3ed4fd57, 0xe423effe, 0xc352ef7a, 0xd23d00e5, -0xbded3a50, 0xedcdc3d0, 0x3a517a74, 0xbdfc58cc, -0x24b2371f, 0xf967f533, 0x26069547, 0x2114e85e, -0xa1953f56, 0xf0c52ebf, 0x235320ae, 0x35600f33, -0x5c1ca2b7, 0xe89db0da, 0x08ce35aa, 0xc66cef79, -0xacd41ce4, 0x865f4c69, 0x15a3376b, 0xdee5d7a1, -0x6fdd6362, 0xa4125977, 0xcb61bae2, 0x5e3da819, -0xc6d2e56a, 0xde1807f2, 0xb30c3473, 0x1c4038c5, -0xbf8afac6, 0x37423d2d, 0x72d9da33, 0x39e95bf5, -0xd6a91cc8, 0xbbf4c2d8, 0x7c9d4b21, 0x13c514d5, -0xcae41aac, 0x07b97f18, 0x0cdfbdee, 0xe7a9020b, -0x1839f082, 0x7c414530, 0x43ba1070, 0x95945971, -0x82e31721, 0x2fb159e5, 0x225c2158, 0xfadf74f6, -0x788387d6, 0xb40c98fe, 0x0c75ba9d, 0x0487eb2f, -0x7e9a1b0e, 0x5c442185, 0xcf1dffde, 0x39f9bc44, -0x46b961d3, 0x9a14b19a, 0xe284d2ac, 0x52151caa, -0x67f34f5e, 0xf4042d4f, 0xa28a223d, 0x3deb23f1, -0x12d14b6f, 0x18901f31, 0xb3c7950a, 0xfb7d3557, -0xb83e457f, 0xb6e13f07, 0xd26f5435, 0x83f05e15, -0xf549a030, 0x6d1122d0, 0x540b3ef9, 0x8ecdac22, -0xdabe1b2d, 0xf4913cc0, 0x579f9d77, 0xd4725d33, -0x76b7abb0, 0x03452691, 0x4d52fff6, 0x12e95a96, -0x42131074, 0xbb3eaa95, 0xb775618e, 0x6325764e, -0xeb847c5a, 0xeb7b9c6d, 0xd01dd328, 0x547269e1, -0x2cebecd3, 0xcbb0ed0f, 0xcc87e62c, 0x8e6b0ce0, -0x8a8f9f06, 0x689e0c4f, 0xb3a1fe5a, 0xed84a0a2, -0x66187741, 0x62a4475b, 0x5c4c31bb, 0xea000d76, -0x8676c757, 0xd59cc6bd, 0x52f107ff, 0x1f4a0c66, -0x7af566ef, 0x4af3586c, 0x11d5cd6f, 0x6b8bc81a, -0x480eed48, 0x2ec7c65e, 0x6c0f3253, 0x100f2794, -0x18d6c62a, 0x338f59f6, 0x8e6e2f9e, 0x75fccfd7, -0xbc80ea7a, 0xa90f1473, 0xfa9d22c4, 0x3ccdaa53, -0xe568fef6, 0x6a761fd4, 0x61c26b23, 0xabc31163, -0x3b840e9e, 0xee864319, 0x84f93208, 0x743a780e, -0x1507a3bf, 0x147dad13, 0x8952177f, 0xbeb40da7, -0x699af39e, 0x6d22bdfb, 0x5fe8112c, 0xdb3f8dbb, -0x026f8ff2, 0x6bf9658d, 0x9faabf0d, 0x6a2f3989, -0x5be4a617, 0x9e55f0c3, 0x70510d75, 0x0fd92413, -0x63d1d3c7, 0x68cf84bd, 0xbbff5901, 0xb0434b77, -0x8564b88f, 0x06eddac5, 0xde2a66b6, 0xc1835355, -0x5566bb1e, 0xbaa890cd, 0x108c6f70, 0x7e80dfcc, -0xb8c03bb3, 0x14bdcbe0, 0x5037daf9, 0xee02697a, -0x3326280f, 0x4f04c814, 0x4f640444, 0xbfa9229e, -0x131c7ba0, 0x5fbcf1ba, 0xebe01998, 0x2a813a9b, -0x3f27c028, 0xf77a6d00, 0xac0ddee5, 0x1b6e52d9, -0xdac4bb99, 0x54a32f86, 0x26bfd80f, 0xf5debd9c, -0x06536e13, 0x9498a87e, 0x3f9e8812, 0x53e0fdee, -0xc08c3c8a, 0x2148b33c, 0x3932e37b, 0xad084cc7, -0xe77a0048, 0x89addf10, 0xb2542186, 0xc4c0be6c, -0xfbc626ce, 0x20a28446, 0x0f29f8f1, 0xbbef5d50, -0x288b8070, 0x31aa2900, 0x4a538fbe, 0xcd344ca3, -0x05170c9d, 0x06c51082, 0xc414194a, 0x6689a2cb, -0x7618c884, 0x412ac324, 0xb0d952d0, 0xfb88757c, -0xaacbb987, 0x92218ac5, 0x032a3895, 0x2e3a7dfd, -0x4bb37e4e, 0x52342695, 0xa699f5b9, 0x45748066, -0x7822f59e, 0x68a55092, 0xf049444b, 0xf274d694, -0x0524ed76, 0x884c3732, 0x22fa43bb, 0x3b97d921, -0x210b8c99, 0xc4ffdf26, 0x17ba16ed, 0xfcdfc437, -0x0b8e2d8a, 0x7b019bb2, 0xd525e662, 0x03346249, -0x7af3c1cd, 0xbf42dbac, 0xb6197a31, 0xebff8e32, -0x84f9980c, 0xa225a4b0, 0xa9f3d94d, 0x8a3da052, -0xc17241e7, 0xf133ce7f, 0x4d4542f0, 0xd884f2f8, -0xa1633ebe, 0xd5c5e6e5, 0x7fce2fca, 0x8ad84a55, -0xfdd96c9f, 0xa60d6f4f, 0xe025d2f2, 0x8be1b787, -0x87a036a7, 0x23819cb9, 0x5967650e, 0x5d549108, -0x57167175, 0x2f94c450, 0xbb536b04, 0xfb381d15, -0x405bd359, 0x3ef9491b, 0xa9834cb1, 0x2cc5151c, -0x148cd3cd, 0x0565ecb0, 0x8e596741, 0xf6d7f089, -0x9e3524fe, 0xf4224e20, 0x583302fa, 0xebe46409, -0x7bfe793a, 0x7d511902, 0x1e4a80dd, 0x53a280cb, -0xa2d81d96, 0xe29b8f4e, 0x877789e5, 0x838ee539, -0x35f9feb5, 0xa5bb1d43, 0xb24d7510, 0x67cd14d7, -0x7cfac97e, 0xf6c72b9b, 0x302f9115, 0x1932060c, -0x0a786f90, 0x85a88dd1, 0x322ef274, 0xb0f8af47, -0xbb5e6bfb, 0x3f1505c5, 0x33b28086, 0x18025326, -0x73293fb1, 0xbd813762, 0xad751414, 0xd533bccc, -0x393b81fe, 0x5b3b79e3, 0x2221dc65, 0x4bf8124d, -0x26df557e, 0xcb9320a3, 0x9e6e762f, 0x2a800bbf, -0xbd30558c, 0xc6b2ebe7, 0x204b2c78, 0x3e55767c, -0xe8dca1c3, 0x446eb4c6, 0xef6f4340, 0x5cbff9c3, -0x37b0e9b2, 0xfb10c3d7, 0xed36aaa5, 0x11615dc6, -0xad7d716d, 0xc1d500c4, 0x5a54754c, 0x0bd36bec, -0x7d297712, 0xb1ae2dce, 0x2a2cb835, 0x89acaba0, -0x936cff34, 0x8f04dc53, 0xfe5f02a8, 0x4b83f193, -0x123c3f6d, 0x25dcdb3a, 0xeba9fe98, 0xe4b73b30, -0x2c768429, 0x4029f674, 0x74815612, 0xb43e7b02, -0x9eb984cc, 0x4c5de913, 0x80ff07f5, 0xc20ed71a, -0x3b7bbbd5, 0xcf4c1a66, 0xc2e66533, 0xd60d0142, -0xdbd557b4, 0x29fe5598, 0x43cbdeb8, 0x1e875827, -0x09b83824, 0x1114224b, 0xd29b9b51, 0xa5a2673f, -0xe3542aa0, 0x50c3bb9f, 0xa5257bb5, 0xa6542299, -0x0b0f37d1, 0x1da0da31, 0xc959c1e8, 0x8abbe257, -0xf234527d, 0x3fac9c67, 0xf1580042, 0xfef8a8f9, -0x704d17e3, 0xda6dcfa4, 0xbc8f4334, 0x0cdba65a, -0x63c9900f, 0x7201b3d0, 0xdf71982b, 0xa604304c, -0x0c5cfc01, 0x125b0999, 0x729d22a3, 0x5b5090f6, -0xea4abe44, 0x2b41d30b, 0x416adfb2, 0x41aa11b5, -0x317049c4, 0xc8aea4d1, 0x273f074a, 0x2d9790a1, -0x49d9c17f, 0x4c98bdb2, 0x6a17a963, 0x8027b597, -0x6b1f92f2, 0xb44b50b2, 0x8831b439, 0xb90b82da, -0x1af3d3c7, 0xc0f28557, 0x1dc0fff2, 0xe3048416, -0x3a778ab0, 0x0fdea888, 0x5f0b4ac4, 0xb8f045f6, -0x596249f4, 0x4ca0df7c, 0x22753ff4, 0x13220710, -0x3900a19c, 0x2c316538, 0x9d3fb2c0, 0xc5c8ba47, -0xc497edbf, 0xcd8bf202, 0xc50b2595, 0x9a9c7984, -0x47b9e4dc, 0x718e6363, 0xbf6384a8, 0x79086ec1, -0x568708ca, 0x39081202, 0xe7ddaa3b, 0x218c006d, -0xaf01bc1c, 0xbd3479fd, 0xbc9cd1bf, 0x1a15b508, -0x55e13c96, 0xe429f11b, 0x70358e12, 0x8a86c907, -0x547d227c, 0x47de1d53, 0xf74a260d, 0xd19ed8ed, -0xc8db4368, 0xe3c6b52f, 0x27686993, 0x8c0b4888, -0x6be7f66c, 0x8261ca74, 0xe3dc2066, 0xa04b3762, -0x4d59b620, 0x90f37689, 0x64ae22f5, 0xa3b0d945, -0x47dffc7c, 0x9566371e, 0x5ae2fc4e, 0x95aff0da, -0x9b8ef2fe, 0x7f22a07e, 0x14aea38b, 0x802ff150, -0x2fa43117, 0x71244211, 0xcb5169ce, 0x04acf312, -0x381c4155, 0x70d3b079, 0xf3b2a91b, 0x3f422e76, -0x5ec10535, 0x9a409fd0, 0xc1f50f47, 0xb209165a, -0x1a934e37, 0x17dacf73, 0x0fa18f20, 0x1c4d73c0, -0x93bd21f5, 0x20be3fd6, 0x7b201124, 0x3a7b0a3e, -0x4d7d1e04, 0xae32c1e0, 0xe699ebee, 0x6cee5458, -0xd2ab4f2d, 0x6df96639, 0x7381fb8a, 0x2ce7cdaa, -0xccc88ef4, 0xb46daa0e, 0xb750ddee, 0x084f07df, -0x40bd18e5, 0xd6c275bf, 0x2d4269ec, 0x96136e73, -0x27b4888f, 0x62b318ed, 0xd81ae496, 0x76542431, -0x3dc0cfc7, 0x1e896661, 0x9e41c898, 0xfa8fcc61, -0xab27f408, 0x9951e94a, 0x29b12179, 0x839b58ab, -0x2097807d, 0x5892e43f, 0xfc958c32, 0xfc0b1b97, -0x198699a2, 0x5de96181, 0xfa9bdd34, 0x175666bf, -0x3b9f7dff, 0xd4541302, 0xde363b1b, 0x26eae277, -0x34ecfee8, 0x32271791, 0xf0682c51, 0x67e9941d, -0x0e131acb, 0x01d3f1b5, 0xe0e2a4c9, 0xa5422eea, -0xa0ee61eb, 0xd11413aa, 0xcb789019, 0xeb72d232, -0xc7532d1d, 0x7b225aff, 0x4f33a319, 0xd419bf2c, -0xe0bced66, 0x1ffaad31, 0x1a9b6f56, 0xa116d71f, -0x8136fa06, 0x9fea9de5, 0x77e8c17d, 0xf804d9f2, -0x76ca41d3, 0x5fdb9e1b, 0x334b4302, 0x90236425, -0xd6392379, 0x7015aadd, 0xac662630, 0x8e16920f, -0x6ad76f6f, 0xec7bc8da, 0x03af52ec, 0x9a09f57b, -0xb8b2354b, 0x9278d172, 0x1b66194c, 0xf61f317f, -/* 1624-m206e839.inc */ -0x00000001, 0x00000039, 0x11152005, 0x000006e8, -0x00e9d6a3, 0x00000001, 0x00000020, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0xc9226026, 0x31d04cc5, 0xeb5e9216, 0x81b9b739, -0xb8187c4d, 0xdb2db5c8, 0xac304dd3, 0x56259185, -0x5cee9dfc, 0xc4c708fc, 0xfbfebb15, 0x4657a346, -0xd5fdfc56, 0x49ccc684, 0xfe2f1980, 0x23e44e95, -0xaf7e0890, 0x0a306ae9, 0x0533035c, 0xf747f6c4, -0xbb7a6356, 0x07415037, 0xb9cd0d46, 0x4dc69422, -0x19ed8dba, 0x61955793, 0x2c69260d, 0x0e23b80f, -0xce2c111e, 0x94c5acb3, 0xf2050f28, 0xc4348718, -0x4496d9b0, 0xec1eb627, 0x8f6d3916, 0xa67909c6, -0x37bdb9ce, 0x4d7393bc, 0x9b7027a4, 0xc1bfa4b4, -0x671fb655, 0x447f72ea, 0xf96b0311, 0xbfa5989d, -0xffa59b41, 0x4af95bb9, 0xeebc0d4e, 0xce0d8017, -0xad35c182, 0x9fa068f0, 0xcdafa471, 0x5459e6da, -0x9bb88256, 0xc593800c, 0x327a1e3f, 0x714bfb6f, -0x8b02e7cd, 0x16020ebb, 0xb0598f84, 0xd021f373, -0x07d55d88, 0x90774676, 0x6cd1f7ca, 0x99e1bfa7, -0x3c67877c, 0xdbd380ab, 0x5eb38db2, 0xe0edbfd0, -0xc5534984, 0x411b21df, 0x16771220, 0x4a8a60f1, -0xd80ab95f, 0x93090a73, 0x12135fa7, 0xbf0fde89, -0x50cb4bc6, 0x508ea81f, 0x8f567bbc, 0xecd02b7f, -0x2b0ceb7b, 0x6fe0367e, 0xce928c01, 0x69589c6f, -0x0c28f0f7, 0xd9ac3fa8, 0xd6a23e1d, 0x19613ebb, -0xe455b950, 0xa58b7cf7, 0xeeab2947, 0x1e588aa8, -0xbb634862, 0x5b6421b2, 0x6297ae0b, 0xbf63b1e9, -0x530e7f14, 0x5c2c0f79, 0x9cdeebc4, 0xf6d7037e, -0xbd4ed6d2, 0xd15f0af2, 0xace5591e, 0xa028a00d, -0x48032c56, 0x67f890ea, 0xbb51ac52, 0x5827bad0, -0x4b402353, 0xba6c615e, 0xfd5cec66, 0xcfb3d0f8, -0x57c54520, 0xcfd5fc18, 0x10d35922, 0xcfd3e6c3, -0xfe68e046, 0x3dc77d26, 0xe9f78a74, 0xa140eb55, -0x08dd3509, 0xc6defaaa, 0x73febfe9, 0x0b79e780, -0x73f35b7a, 0x7e9701ec, 0xeeb571a8, 0xed545d8a, -0x1ecab16f, 0x4d2cdf06, 0x0f8d5bdd, 0xc8d515bd, -0x2b240de4, 0xda882958, 0x6612e8e7, 0x9bea8737, -0xf8c88eae, 0x7f6d9fa1, 0xdd249b1a, 0x07541510, -0xaac8a29b, 0x25d07e85, 0xe9f0f581, 0x3f3c089a, -0x90d4b3fe, 0x529d1042, 0x1e0bc5d3, 0xacbc4634, -0xacdf6376, 0x759f6e7a, 0x614eb519, 0xf97894f9, -0x69e18e24, 0x445adfa4, 0x6fc71d78, 0xb2bd1312, -0x270e3a49, 0xdf22e530, 0x96d6bfab, 0x2d8153c4, -0xe487add3, 0x0461fbe4, 0x6179e23b, 0x22bf0ad7, -0xa527347c, 0xee772c22, 0x94c1c04b, 0x9cff8528, -0x52f17360, 0x1a381a4f, 0xde59c8b1, 0x5ad6ddd1, -0x01440596, 0xfb7ca9db, 0xf1b1c83b, 0xe4983438, -0xdb246883, 0x1044db5d, 0x5e4a560e, 0x8312d13a, -0x5db5e546, 0xfcf1485e, 0x6a95f22e, 0xebdf4063, -0xa9e47fe7, 0xff203e14, 0x3e8c08fa, 0xbfdedef2, -0x380c9a4b, 0xaf19c9c6, 0x75005e66, 0xff492ec9, -0x28b8e6d0, 0x9cd69fe5, 0x839353d7, 0x8d4df3f1, -0x38a4f7a0, 0xd5af72ad, 0x7e7ba9b6, 0x9a2c2f5a, -0xe141e11c, 0x54101bf0, 0x6bd34fba, 0x2aeebd40, -0xf3c6a02a, 0xfb45a6ea, 0x5f6cc3f9, 0x7d19ace6, -0xc4e50923, 0xb77d6c3b, 0x28d21508, 0xa68dbda2, -0x53519ded, 0x7d38215b, 0x6554c1d0, 0xceade8a5, -0x861dbd69, 0x327694d4, 0x2284cab7, 0x79b7a4a9, -0x2cb4e91d, 0xe91b5ee1, 0xa886aceb, 0x586f2b2d, -0x586384c3, 0xed4a41fb, 0xe95f483c, 0x2bc37c1e, -0xed66debc, 0xc081cc22, 0x13b62693, 0x1f739d44, -0xb5c64b95, 0x8a6c382b, 0xe372637e, 0x4024aa2b, -0x6d0cff83, 0x8b23bd82, 0x13251589, 0x9243024c, -0x452e1d68, 0x22ee9797, 0xc02673e4, 0x8b9a7d37, -0xa76d6538, 0xa92d6786, 0xa7cfc9a0, 0xa44beca4, -0x31eb7699, 0xeb54ddc7, 0xa2fe7da1, 0x0ee15251, -0x614235df, 0xe9cfedbe, 0x892a4e69, 0x9da98557, -0x335b3fdf, 0x8ea201e5, 0x0946feb6, 0xb5a786df, -0x022cc831, 0xab624815, 0xbc424527, 0x735f92de, -0x9936cecb, 0x0e761edf, 0x0090693e, 0xc4a0499a, -0x6b23228b, 0x1eb11bb0, 0xfa0e532f, 0xf3908bd4, -0x6d12934f, 0xb0af2c23, 0x8ee4af5c, 0xdc901aa7, -0x0354b0bf, 0xd130aaa9, 0xcdd548cf, 0x63c30fa9, -0x2ce21b9d, 0xd28af5fd, 0xd0dd7223, 0xf8037eb4, -0x475e5121, 0x4da06882, 0x5b5f6d0f, 0x2010ee60, -0x6b70b26e, 0x34046d99, 0x60d17b52, 0x0ceb5995, -0xfe843bb5, 0x32bd202f, 0xd253d64e, 0xafbbc103, -0xfe550a5c, 0xadc17fca, 0xd50e62ac, 0x04aac0c1, -0xfdc53287, 0x2ca779e0, 0x50d3509c, 0xc6642217, -0x15a4a216, 0x792dc831, 0x28aaeb0e, 0xd90a51b1, -0x4aafd019, 0x7120d967, 0x600cc53d, 0xcce4712a, -0xa51c84bc, 0xa446aea8, 0x2d0434df, 0x7cc7e1bb, -0xc58d985e, 0x975fd3b5, 0xeabd457e, 0x63019a78, -0x07dd4acb, 0xf5d1b481, 0x271b33e9, 0x74e6b893, -0xe1660e8d, 0x3b3857c1, 0xae2228b4, 0xe8971978, -0xa5e9d620, 0xc42ce628, 0x8a723c90, 0xe1cbd643, -0xd6b31dd6, 0x10ac4693, 0x30d07574, 0x2ceb736c, -0xc4534cfb, 0xb1576d35, 0xb7452467, 0x83d90ec1, -0x136647f4, 0xee1225f9, 0xb018b3ab, 0xe40e1466, -0x6c39168a, 0x209e1e98, 0x467a80da, 0x39895b4d, -0x9830701a, 0x08bb3694, 0x944d4ca5, 0x1b345056, -0xfcd65853, 0x02dd7e3e, 0x8c3fe8ad, 0x4a250b9f, -0x88f396e9, 0x1c7e6763, 0x8d63d571, 0x46bc5836, -0x3495194f, 0x612a5504, 0xa3c960aa, 0x206508d5, -0x0e742fa5, 0x962dc01a, 0xd7c6ae91, 0x7c60637a, -0x4dd751b0, 0xe9ec6585, 0x7a6a9d8e, 0x97cc23b2, -0x17c7cd98, 0x6bd0197e, 0x825caffd, 0x1b682617, -0xb7a146df, 0x6cd43071, 0x46a325ef, 0x606c23cd, -0xf391543b, 0x0c1273e7, 0xb14311ad, 0xa56c20d6, -0x4f2b1f6b, 0x027fdd15, 0x153e5b84, 0x230ef754, -0xddc5231c, 0x27009a47, 0x6a1af01f, 0x3eb1712f, -0xdd5b0538, 0x1bdd1a17, 0x94a692ee, 0x6569ea36, -0xbbed3e8c, 0x44be3a3a, 0x322e23fc, 0xb620d922, -0xb0e4364b, 0xa6e9a5c9, 0x74ade8ba, 0xb619ba36, -0x1ab260b7, 0x49d93617, 0xf34f51e0, 0x86c922f8, -0x8b62ae4c, 0x4c5d191b, 0x8af345d3, 0x7dabf68a, -0x50630f7d, 0x9367968d, 0x9dd2ec02, 0xcbbc9de9, -0x96ff6002, 0x22557f00, 0xdcb11cef, 0x9a433696, -0xdafd17fe, 0x4a4f2367, 0xcf03a80a, 0x07f1af6a, -0xd17f5c02, 0x69d50343, 0x64e5f0ee, 0x1e8f8795, -0xacb3be79, 0xec758d66, 0x972b429b, 0x70847a5e, -0x26917ebb, 0x120198ea, 0x9fbc891b, 0x6024a8b3, -0x21f187be, 0x5fc97d12, 0x8f40dd2b, 0xed5099af, -0xba1c30f8, 0x42856fe4, 0x4ff70143, 0x3381128d, -0x68074f27, 0xda4e4f40, 0x92355570, 0x87d9fc1b, -0x79ba00f8, 0x80188b0a, 0x54d6c99e, 0x0c291886, -0xae1ba6d8, 0xe1db6d71, 0x812eb8d5, 0xfe443861, -0x4697dfe3, 0x07e2c123, 0xef211237, 0xe39cf56d, -0x0dfe17fa, 0xea6030a6, 0xbaf85b2f, 0xb1fb1e75, -0xb78b8e9d, 0x93d9d1bd, 0x6865386a, 0x85797883, -0xa4136a38, 0x4c0ab699, 0x0647103e, 0x678defd1, -0xf54ffe6f, 0x38042e86, 0xc936e167, 0x7e8be786, -0x37a7a21e, 0x47af9dbd, 0xe223ff47, 0x67a5b932, -0x8b5ec113, 0x4409c381, 0x17f02fc9, 0x4a2fc757, -0x076c4f09, 0xafaad84b, 0x280e8dc1, 0x739ed578, -0x49303f92, 0xe3ad06ce, 0xd6f2cc2b, 0x8c6178a7, -0x7dd611bc, 0x3ef0622a, 0x7b5624c2, 0xc0d3ab3d, -0x0886901c, 0xd50b755b, 0x9e5fff5b, 0x6defbd36, -0x6eb81d52, 0xa83ed60b, 0x5a592ac7, 0xc7106e42, -0x26c4d503, 0x01e85a02, 0xe5794f2a, 0xe59d8e11, -0x642424e0, 0xeb729831, 0x2f7c579b, 0x9420638f, -0x8b262c13, 0x5cbbc0a0, 0x1acd3e84, 0xf4fce699, -0x5d87578c, 0x7e050318, 0x780e3acb, 0x8285e06a, -0xbe10054d, 0xd1123dbf, 0x0d19268f, 0x9abdf2da, -0xb8d42fec, 0xe7cd5df7, 0xd42255a4, 0x21cdd93d, -0xf4613998, 0xc1f0cbb9, 0x21dac2e1, 0x8e14ad43, -0xa89284ca, 0xf78bc18f, 0x94b84631, 0x2efa70c7, -0xd95e5cc3, 0x6c5c9d37, 0x4955d2e5, 0x1986c823, -0x250ad64e, 0xda87a2c3, 0x872d29e3, 0x43cc29f6, -0xe667e664, 0xbf46632a, 0x14119b51, 0x2746bed7, -0x37158545, 0x1e846c85, 0x1b95a555, 0xb7199a1e, -0xa15c019c, 0xa3387c3d, 0x65ce357c, 0x4262836d, -0x0cfe418c, 0x24ecb61e, 0x21bae0f7, 0xae0f7d05, -0x21cb819c, 0x7c6f341c, 0xd40399ff, 0x340603e4, -0x0c99c59f, 0xf2bfe2c8, 0x3fa6ab62, 0xfd523ff3, -0x6729a50d, 0x748b60db, 0xd12ce998, 0xab74bee0, -0xabd8562e, 0x486b62d0, 0xdf54ea64, 0x05706018, -0xad5f0651, 0x03925450, 0x953c9690, 0xf671def9, -0x12f2bc25, 0x489088ed, 0xe0821dfe, 0x86fc2ee9, -0x5337050a, 0x73fe5693, 0xfdb68668, 0x6e3aaf10, -0x1ff17349, 0xe0ed3f06, 0xf04c6a24, 0xc2ca002d, -0x4413be0e, 0xf936745e, 0x2ecba010, 0x12d5d285, -0xac3fbf57, 0x64a4bc04, 0xc8487824, 0xa98ffbcd, -0xd09f47ed, 0xd55c8fca, 0x48f6b1ba, 0x7c91efae, -0x996cceee, 0xe4eba045, 0x93231e6b, 0xeec78b5b, -0x36b57bcb, 0x117e4338, 0x372b2355, 0x858d9058, -0xcfd6a2ad, 0x0dfcf7ff, 0xb2175d06, 0xc30c0b18, -0x082676e6, 0xa72aef65, 0x7fe69e25, 0x89e017fc, -0x0c02475b, 0xfb6db944, 0xa22a7f67, 0x5109be81, -0x49be8288, 0xe5912a66, 0x3e7f9c57, 0x196a17f2, -0xc8f6d41d, 0x4a4ed74c, 0xf7068058, 0x530f85f5, -0x5a62affb, 0x607e69cd, 0x187b3d35, 0xc0ba9105, -0x09242e0d, 0xb9ed74d1, 0x89ee52f9, 0x304e629f, -0xff1c5f7a, 0x541468fc, 0x889f2877, 0x009f0823, -0x1554c91e, 0x4ede3cc6, 0xe8055158, 0x1f875bd4, -0x7f319b05, 0xfd3b3605, 0xeede9e36, 0xfb91c6a8, -0x13a4a1f0, 0xcfe5ea7b, 0x72e4742d, 0xfec9bfad, -0x423111bf, 0xfc123877, 0x9d8a1696, 0xde722ee1, -0x58581af4, 0xe6d333e3, 0x96480fd1, 0x1ec04bc8, -0x89cd9328, 0x184a2e72, 0x61250a9a, 0x02a60896, -0x68c4dc7f, 0x33bc2435, 0xef7ec8e4, 0xc184d4f0, -0x2cc1046f, 0x022ddcbe, 0x44c1bdaf, 0x7a12cd23, -0x5b378349, 0xc304a9b6, 0x3bdb987a, 0xbc33e5e1, -0xb24473fd, 0x3e91a25e, 0xafadce24, 0x69738f5e, -0x64410ade, 0x74dd6439, 0xe05174a6, 0xfc407a51, -0x6330fbf3, 0xcb7c8c5a, 0x2ddded66, 0xd3165da8, -0x023ed9e6, 0x3f2798d0, 0xe58c407c, 0x12f6c6fe, -0x3d4e93d9, 0x1f44033b, 0x7415ece6, 0x797e18d0, -0x1960eb38, 0x6d8802e8, 0x9aad531f, 0xacd1bea3, -0xa437ffb9, 0xa512277d, 0x9ede1f43, 0x30b7894b, -0x12116f70, 0xe238aa2f, 0x0bb75ff4, 0x1c5d91df, -0x3636f6c0, 0xe0dfcfeb, 0x5389b29b, 0xa33a7562, -0x85e4eab9, 0x09fefce5, 0x985ad1c9, 0xd93ff9ea, -0x4c719a78, 0x4f47e619, 0x1dd726df, 0x4d6ac303, -0x624e6340, 0x66986a42, 0xe56fa716, 0x055a5b10, -0x2aaba4ae, 0x247363fe, 0x86dfbbca, 0xb9a66781, -0x98e93037, 0x5d4e8c15, 0x9cc60f0f, 0x09ce687e, -0x7948f82e, 0x329ed957, 0x413c9131, 0xd15a62c2, -0xe19cc4d4, 0xb6435a71, 0xc891e0cb, 0x64067d28, -0x71b59db7, 0xcd65e65b, 0x127354ee, 0x91b9d9e5, -0x7159f111, 0x408dde9b, 0x9b50d36e, 0x93eda2f4, -0x55429b2e, 0xa8b97a22, 0x5b625128, 0x7000e78e, -0xbe0ffa92, 0xa3473045, 0x0990e748, 0x9f02bfd1, -0xb4a4b632, 0xacc6e8ef, 0x83f1e4ed, 0x8c539784, -0xedd466a9, 0x77e6ca09, 0xa453dcb5, 0x247db83a, -0x4cd641c0, 0x4de6a12e, 0xf8599e34, 0xc825fc73, -0x48c4ccaf, 0xfc5bba30, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2346-m16fda3.inc */ -0x00000001, 0x000000a3, 0x08132007, 0x000006fd, -0x89c0d09e, 0x00000001, 0x00000001, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x72cbc5d0, 0xa24e89bc, 0x074028ef, 0x2ad07a06, -0xdeb7acf5, 0x98912a6d, 0x295d17a5, 0xa3b8708f, -0x95c69839, 0xb2f655e2, 0xdce0fc75, 0xf92f04fd, -0x51b6b38e, 0xe7884365, 0x69dcc34e, 0xcfe67a6b, -0x5e421f0e, 0x51527923, 0xb63fceab, 0xae39d6c2, -0x5dc6865a, 0x5819082a, 0xcfcfc6eb, 0xc4ed71a8, -0x06e83b7b, 0x7cc5025b, 0x5fefb2c9, 0x3c02abbe, -0x42dba8cc, 0xfc966b64, 0x2acaa07e, 0x61d32476, -0x72fed3f8, 0x7ef26af7, 0x8086deb1, 0xd11fe511, -0x3dcc3e92, 0x202bf190, 0x17fbf18b, 0x4cd17950, -0x81299fb5, 0xac3d96a2, 0x389ff313, 0x85dd4b22, -0x4eaef9da, 0x623b133b, 0xe3d02b2c, 0x2290a31d, -0xc6f8c543, 0xf6c18f11, 0x8070c5d4, 0xc756e5c4, -0xf4a40060, 0xbf169c70, 0x62dd14d4, 0x729fefe0, -0x6594d275, 0xa5abc2e8, 0x720904e3, 0x5a5b42ad, -0x5e970808, 0x5a6ec767, 0x502a6d38, 0x88d24740, -0xb4739506, 0xe3f497a2, 0x2618e78d, 0xfb602c6c, -0x323fc08b, 0xf9cb3dfa, 0xc90130e6, 0xe373da35, -0xde024249, 0x490b1796, 0x93f157ee, 0x10f73761, -0x6dd5c0e4, 0x4a9fb1fd, 0xadc2ead7, 0xd13e442c, -0xbfbd007d, 0xc8de8a68, 0x09c630bc, 0x69e78a87, -0x4d64bab9, 0x81c58c9b, 0x0b693158, 0x2a40ee8f, -0x47153744, 0x2a32e243, 0xdde6b849, 0xa2c35ddb, -0xf8c10a60, 0xaf5796f6, 0x8a95da67, 0x013f80a1, -0x7f332110, 0x345e3e0f, 0xba8ca1f8, 0x373a3380, -0x97f10a50, 0x3e1e78a8, 0x097496d4, 0x60ef2ffb, -0x9421fb84, 0x03131ba9, 0x535e0247, 0xeda34f42, -0x7f34ebb7, 0xbcfd1c2d, 0x19b2c696, 0x7107aed5, -0xd5877fe2, 0x404186ae, 0xbc41a831, 0x1cd49fd3, -0x92ff4c85, 0x3f65b35e, 0x701ce1cd, 0xe3839c91, -0xab53cf2d, 0xdb124ec0, 0x7c012c6c, 0x432b628b, -0xac351ee6, 0x9da287ad, 0x0adc2580, 0x66f945ca, -0x36bd8108, 0xbce986ee, 0x8fc2d524, 0x06dbf665, -0xb4124dd5, 0xf15c2853, 0x4aaa9b46, 0x753c207d, -0xd7805517, 0xaa6f6dfe, 0xf6eb1ced, 0xe6a4f89c, -0x5cbf2b1f, 0x6889832b, 0xf121bc8e, 0x2d7e02e9, -0xedbc10d5, 0xf3974ab6, 0xf977d65d, 0x40ef2640, -0x9c5f3410, 0x7ce2bca8, 0xac2d2c23, 0x204d560f, -0x2dffb3b3, 0xb051fdc4, 0x76ef18ad, 0x1b13190f, -0xa08cd1d4, 0x1aa202b8, 0x1a5040f4, 0x23a24420, -0x22622bd2, 0x6e543121, 0xfe68651f, 0x4e0d3fd6, -0xda661e0b, 0xfb41bbdc, 0x5a6e0df0, 0x8c27383a, -0x91e24f94, 0xa5db6d2d, 0xc7684280, 0xfddaf106, -0x0ada8514, 0x5cb76df8, 0xea1242ce, 0xc5aca25f, -0x0821a5f3, 0x71e4de37, 0x89c9a2a8, 0x4d2231b4, -0xc3edc81c, 0x56f516f9, 0x7e95a590, 0xe00ea616, -0x827fd358, 0x4511b62d, 0x6cac7958, 0x8259e262, -0x9ee67b13, 0xe73bdab2, 0x811f51d7, 0x88e6196f, -0x642a4db5, 0x1ca77047, 0x5a095f6c, 0xa42ddb9a, -0x66321e3c, 0xeeed0f13, 0x72e48195, 0x988f23df, -0x3d058cd3, 0x45fed77a, 0xa20f4f80, 0xca873db9, -0xcfd4a890, 0xcb406f47, 0x56bd45eb, 0x8ca14876, -0x411da96d, 0xaabe66e1, 0x26ce3950, 0x40ceb4ab, -0xbbb2b914, 0xfd90126b, 0x74c60165, 0xcd2e00ff, -0xe0607bd7, 0x3dc3818d, 0x4102205b, 0x72cca471, -0x0864151a, 0x65c92538, 0x5bc44cfc, 0x406a9b62, -0x10e5aab2, 0x751f6321, 0x533ca54a, 0x335961a9, -0xa386abb2, 0x24f90a2b, 0x3d13ff7c, 0x35d454ef, -0xc236b524, 0x8cf68189, 0x6ba29c87, 0x3925aaae, -0xa12de178, 0x4610a2d1, 0xfe330eca, 0x8d657af3, -0x7f2f81f3, 0x46cd664c, 0x676003c0, 0xdf786970, -0xb240a066, 0x41f852f2, 0xb85e5eac, 0x8ba83def, -0xc12c498e, 0x02c5d742, 0x4b9df557, 0xd9f2ed28, -0x5f7cec4f, 0xf9ff3a0c, 0x457ac549, 0x133f5bd1, -0x951b6947, 0xf835f2df, 0xee51efd0, 0xe90b1bdc, -0xb76c1a80, 0xc3f209a0, 0xb175f774, 0xd8963aff, -0x3d458f2a, 0x9ba9ca53, 0x91561069, 0x444ac140, -0x87f53cb5, 0xc835bec0, 0x2b6906e1, 0x1f2201e6, -0x443bfce4, 0xd0e25486, 0x71ba244a, 0xa85e4fad, -0xb0a9df78, 0xbef803cb, 0x710cbd53, 0xd7ce50b3, -0x38f69e53, 0x5175759f, 0x987de9f5, 0xfc5f9332, -0x090ba2ef, 0xa059c8e0, 0x9efc20ca, 0xaead8853, -0x22cd4804, 0xb30dca16, 0xadbbdf33, 0x246cb36c, -0xec99405d, 0xfef7e46e, 0x454bf0a3, 0xa75d4072, -0x6859ad38, 0x3c6a15e8, 0x37bb8ecb, 0x05747a82, -0x97edcb0b, 0x5bff5a7d, 0x20cd1e91, 0x1e37277b, -0x4c0149e1, 0xc7d5e490, 0x253bcac9, 0xdffe64ac, -0xf7ce2179, 0xada80d94, 0x3653f166, 0x7271d8a4, -0x994f269f, 0x0841e81a, 0x709401cc, 0x0c9fefbb, -0x30fa89fd, 0x1fea8b70, 0xffc68c98, 0x2030e064, -0x8e28b2c7, 0x2750f01e, 0xceb4d955, 0xb86ee560, -0x7ca55701, 0x3a942ffe, 0xd6ad0e17, 0xe8cec9d1, -0x5a6954e8, 0xb14fe7c6, 0x6e7d5c90, 0x8481626b, -0x7c798699, 0xdb0b344a, 0xa721cdc5, 0x861db07a, -0x1844fca7, 0xde861a71, 0x770735c1, 0x3ab64f3e, -0xb352aeb8, 0x046529cf, 0x2fd753f9, 0xbb3cad72, -0x27b44c84, 0x58e77f53, 0x08840b3c, 0x75ceaa6a, -0xcfb8ec2f, 0x8877c4a8, 0xee6bf89f, 0xc6256203, -0x0bb3f6bc, 0x696fa2f3, 0xf04e8efb, 0x3fd0099b, -0x27a473cf, 0x87fe81c8, 0x35cface5, 0x8afad818, -0xb47534e9, 0x90b406aa, 0x7d7c2d15, 0xc9caf1ad, -0x9692ac7f, 0xa3bc5fc9, 0xfd41d0f4, 0xc47f86df, -0x60cbdd17, 0xc1fc9bb1, 0x518ec6f8, 0x45c7e024, -0x7db1e277, 0xd4d30cd3, 0x35bc1c5a, 0x60b61287, -0xfcecbc8b, 0xc6cb70e9, 0xc6280061, 0x9d0ac8ce, -0xfaf12df8, 0x9b3f092c, 0x979a43f8, 0xbbdbe0cc, -0x6274f1d9, 0x7322b577, 0x50589a1b, 0xbd0dca66, -0x2160d66b, 0x4ea6b9f3, 0xd942aa7a, 0x0c8e1c82, -0xc0a07833, 0x0fdb7b24, 0x012a56a1, 0x9d2b019b, -0xba7c66ee, 0xe6af3a73, 0x823e0207, 0xd9913462, -0x8896001b, 0x142af0f2, 0x52539dd9, 0x864a53f0, -0x6e85c62b, 0x66139be6, 0xadd260aa, 0x2a7a579a, -0xd0fe929c, 0x67052a99, 0x1bcb98e0, 0x8c58f5fa, -0xb32d4733, 0xb4e4e4c8, 0xb536ab23, 0xd00ef025, -0x05c4cb84, 0xbbc9b7d8, 0x175d6254, 0x5d8ebdb4, -0xe3f3e65a, 0x52177f95, 0xe85d812b, 0x87fb19ac, -0x88b80b16, 0xc570083b, 0x124da09f, 0xc8522543, -0x5f73aab0, 0x6c25b49f, 0xc8a03cb2, 0xd857bb2b, -0x16378b5d, 0x242f0e79, 0x02d5d491, 0x7fc8b85f, -0x48177825, 0xc70d4bce, 0xa23f5d56, 0xc7ebcb58, -0xaf3b143a, 0xc33e9d65, 0xc043e61d, 0xf05a3d2a, -0xd162c7d0, 0xdad944f7, 0x3226cdeb, 0xd0d044e3, -0x8012c5e8, 0x18524401, 0x2a4d751d, 0x95592574, -0x8e03592e, 0x68a72ded, 0x7d65ba50, 0xfa66bb37, -0x81250634, 0xe92c784a, 0xb585ae7c, 0xc6e350f1, -0x8d40d62d, 0x5b2ad4bc, 0xc87b65d1, 0x700191fb, -0x06015556, 0xaf94c477, 0xa63b5aa1, 0x28a7ab7a, -0x7cdb448e, 0x3819d9d0, 0xcb0dfe9b, 0x715dc992, -0x88f5e070, 0xa1f5ecb5, 0x8c9876ad, 0x44be717b, -0xda7487fe, 0xecc57fab, 0xfb6cd21e, 0x6de34108, -0xa98b84ed, 0xd755144c, 0xb24c242b, 0xa29eab2d, -0xb909c928, 0x077da28d, 0x549454df, 0x173b4e96, -0x5353fdfd, 0xcf06a087, 0x33acdb4a, 0x166b41a1, -0x45219876, 0x96eb46b1, 0xee5f18ad, 0x6a962b7a, -0x9914a217, 0xca72359c, 0x28f5a8f8, 0x9d0b43ac, -0x5fb6964f, 0x0b2685e0, 0xbda83a60, 0x464fbf9c, -0xfd8f4ec5, 0x9d16acdf, 0x1192191f, 0x119c43e0, -0xd0a2df66, 0x8c2cf306, 0x3da0f9f4, 0xf409a043, -0xcfc563b0, 0xf0be102c, 0x3252b4b7, 0x07076cbb, -0x355888f0, 0x4e4bc8d0, 0x1fd64ff5, 0x245147db, -0x9d757b6f, 0xfbaeee9f, 0x43d68df0, 0x2709be60, -0xd333fd6b, 0x79af3f65, 0xb52de3ea, 0x04d94eb8, -0x43865e4f, 0xc736c027, 0xfd180b96, 0x78caa82a, -0xd0021810, 0x9e514f99, 0x72f5067b, 0x7de6487f, -0x6cb34382, 0x0e01763a, 0x89976ae4, 0x7a8bbfa2, -0xa50291f9, 0x6407b33f, 0xf7ce016c, 0x2d586dd3, -0xac0a7612, 0x32fa7be1, 0x3ee474d4, 0xc795f431, -0xd6d0a977, 0xdc859d13, 0x446f01b1, 0xafc13014, -0x67bad636, 0xda3c5946, 0xe169c32f, 0xfe5c93b7, -0xac1b3104, 0x42a5c9ab, 0xc906dad0, 0xe4b213db, -0x6fefea5a, 0x35528fb5, 0x59cadba2, 0x5cbb0ea0, -0x2b01c14c, 0xaa438c3b, 0x6bbad300, 0x3d6d3409, -0xcc87ec95, 0x6f167576, 0x623c3b26, 0xab438ac1, -0x469b5486, 0xb7992347, 0x0418dd1e, 0x54e6ad5f, -0x44bff273, 0xbc97e1d7, 0x7c5c88da, 0xf7bbb29a, -0x48d01e8c, 0xaa4d4376, 0x9a99c998, 0x24d09e2f, -0x24480693, 0x84b6b905, 0xd0ff443b, 0x76605be6, -0x5c6af5bd, 0x5dd0c084, 0x4d162432, 0xed939cf2, -0x2d333e06, 0xd2144645, 0xb06a3583, 0xc1d6e232, -0x03883c1c, 0x6a3a1491, 0xe6b619d9, 0xfee3f413, -0x5e59c26c, 0x28684bc1, 0xca68c55b, 0xca395734, -0x95d8afd7, 0x8a94d5ce, 0x6d780b0d, 0x6ab50934, -0xf5121314, 0xb9ec2632, 0x1beb9a14, 0xcd950304, -0x6fd91394, 0x33f84e25, 0x546d4a4b, 0xc303eb86, -0xcfb7b409, 0xf852adeb, 0x65c4960a, 0x01878815, -0x4a6501d8, 0x5bb3a40f, 0x9414a799, 0xbbae4dea, -0xae9d7b0e, 0x761dcb06, 0x9581c2ff, 0x06edcb74, -0x0c06177d, 0xdc36931a, 0x751d52ea, 0x699dd531, -0x5285df50, 0x81990800, 0xa81d52e4, 0xf305b98e, -0x260f304c, 0xa9f5a19d, 0x702bf4d9, 0xc4e322c4, -0x05e38fbd, 0xf6997433, 0x938443b8, 0x33fe4ff4, -0xc0da5ba1, 0x1701d20f, 0x4f631fda, 0xd966d058, -0x847b08a0, 0x7719b2ac, 0xea7e817e, 0x3cc266f9, -0x39b94930, 0xd5a7c643, 0x831d614c, 0x486c87ea, -0xeb32ec07, 0x27ccfb31, 0x3618615c, 0x01c5284f, -0x138ba020, 0x7f316b7d, 0xf7049fff, 0x2acb57be, -0x156b6bb0, 0x03df196b, 0x72bfb285, 0x0d1fd58d, -0xcb86fb0c, 0x938e1a8d, 0xd387a3ab, 0x5fa1b627, -0x2c4d3f80, 0x0b4a7121, 0xbab5d24c, 0x4e14e39c, -0x19d839a3, 0x0b730800, 0xaabb2b8a, 0xa58aa531, -0xa82260bc, 0x21be659d, 0x714b34d8, 0xa89d111d, -0x02828552, 0xae10e3c9, 0xdd9ecd12, 0xe13beb47, -0x96818a52, 0xb5fcd9b2, 0xa8d0964f, 0xfcc0e896, -0x7ab323da, 0xb1bf60de, 0xdb70c0ac, 0x83373de9, -0x3513e4d5, 0x0634af3e, 0xc3052a5f, 0x3acb8ac9, -0xcf03743f, 0x15555b96, 0x929b04ff, 0xdb2a9428, -0xdce90ae4, 0xe414e73b, 0x5b6b19ff, 0x1a708067, -0x61329d15, 0xc4eb8336, 0x2d861d5e, 0xca108403, -0x0e9ab2d4, 0x04d3b3c4, 0x36ef280d, 0xfea6cee9, -0x80c30cad, 0x399d1c6d, 0x2b654d22, 0x204032fc, -0xee60e1c1, 0xb20fd9db, 0x087a91fd, 0x6a4e368b, -0xad3ca7e5, 0x5355a689, 0xd220e928, 0x925cb754, -0x677991e5, 0xb3941d98, 0xa3eb379a, 0xf0237d52, -0xe96b9e08, 0xb7ae3c7f, 0x7a84124d, 0x9cc15b58, -0x2ddafebf, 0x93a8990b, 0x1555212e, 0x7fe44a1c, -0x90851979, 0x62a143a7, 0x5ba95724, 0x4d8762c9, -0xee3a6f84, 0x0af45b74, 0xcfabce5c, 0x73ff8f3e, -0xa872ef47, 0xe97e60bb, 0x805c1800, 0x8d3b978f, -0xaf71cdb9, 0x4d8da1ec, 0xae5f2f19, 0xe57566f8, -0xa2003cdd, 0xe65293ce, 0x6970388a, 0x979c68dc, -0x2fcf8d5c, 0x61a603d3, 0x92158c18, 0xd2f53c34, -0x842dc4b1, 0x32f3df78, 0xc696ab26, 0x2be86b54, -0xd98bca91, 0x0415fca1, 0x5afc9076, 0x796a5ef4, -0x87a225b1, 0x6b5784b3, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2498-m101067660C.inc */ -0x00000001, 0x0000060c, 0x01192008, 0x00010676, -0xfbac0f5d, 0x00000001, 0x00000010, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x0000060c, -0x00000035, 0x2e000000, 0x20080119, 0x00000301, -0x00000001, 0x00010676, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc8f5cd92, 0x30bd1beb, 0x77c4fb8b, 0xe899c960, -0xc729b4cd, 0x1d9b8923, 0xfcdfc554, 0x580d39f9, -0x170ce7c7, 0xd727c705, 0x019b1ba5, 0xe0414a29, -0x57d45458, 0x26a8a411, 0x9faad966, 0x095ec8b0, -0x083a7c2a, 0x17cfc70f, 0x3c8e78a8, 0xce18c419, -0x5f2ddeb7, 0xc9c95d71, 0x437a5116, 0xe0253ad0, -0xec78db42, 0x681e436f, 0x7fd028bb, 0x1149a501, -0x0bdf0d05, 0xc2321514, 0xd6866cd8, 0x64942685, -0x21e0276b, 0x0817a288, 0x09138669, 0x792985dc, -0xbd60d6aa, 0xfbf902ec, 0x43fee69d, 0x5c5823c0, -0x9dca1fe6, 0xb528b0c5, 0x22fd29ab, 0xac4fe251, -0x77207813, 0x0637a1f9, 0x16bfcf73, 0x80497f6b, -0xe5bca939, 0x1539fa1a, 0x66607fea, 0x2276c06f, -0xd003229e, 0x3622fda7, 0x18d0b8af, 0x9f399760, -0x3ac6387b, 0x6c7148fa, 0xfaf4df9f, 0x965db840, -0x7c142542, 0x7b805f4c, 0x3f2002a3, 0x061399ce, -0x2f1a03c4, 0x7f1c7616, 0xb2f9ab42, 0x4e6a92a2, -0xb44b96d6, 0xe1167017, 0xec4b2fb3, 0xa15376be, -0x00000011, 0x4872f26c, 0x88971c10, 0x66db1385, -0x1e532ab2, 0x7ccd2d72, 0x38dd766c, 0x131f4505, -0x7d5e1e0a, 0x1932938b, 0x79c1db9a, 0x9fe5b8bd, -0x07037c1a, 0x698cd351, 0xbadb5300, 0x063f17d9, -0x8558ada3, 0x224c2288, 0x26fa35b3, 0xe64efb19, -0x0e1b52db, 0x696d5461, 0x3a0f765c, 0x4b853dfe, -0x05147b28, 0xbe146518, 0xb61e1de2, 0xc342998e, -0x083d5f41, 0x737fdbb5, 0xdd812ce1, 0xa7b9549c, -0x164b5fbf, 0xaffd6139, 0x44154437, 0x23d44899, -0xbe41eae1, 0xeecc8d45, 0x31fc971a, 0x44475238, -0x5d4ab69c, 0x67f342a0, 0x118cb268, 0x513fb847, -0x0a86fce3, 0x23f22535, 0x5fa15360, 0x929aa833, -0x3cbd4138, 0xc1dead1e, 0x3efa210b, 0x9781a61d, -0x00b53f73, 0x07df4d30, 0xffe97322, 0xf7b12998, -0xba4d7316, 0x4b746898, 0x45ece500, 0x78cf31d5, -0x0208c1c6, 0xc3999e15, 0xce2f90f4, 0x7e130a0b, -0x3c74ce12, 0x37612fd2, 0x7ce3ae15, 0x99a26321, -0x52ac391f, 0xcb32f7e1, 0x0e50140d, 0x3a6bfc41, -0x497f7f9f, 0x334b7e17, 0xbcf4e41d, 0x3311b0db, -0x0dc65367, 0x44847807, 0x991c439a, 0xd2965df2, -0xfd72e4fd, 0x44b01f14, 0x5a0cf5c5, 0x70029e37, -0x92af3f34, 0x47949bdf, 0x771a3c07, 0x0874f372, -0x7a54670b, 0x7430b00b, 0x356234f3, 0x74edf1e6, -0xaaf60a4c, 0x2bb5eee4, 0xc2c1d43f, 0xc4ee788b, -0x4198fd90, 0x0aba19a3, 0xc251f028, 0xe42404df, -0xccbd25f2, 0xdb13eb69, 0x888f89a5, 0x5a6c8cd3, -0x1e3b469b, 0xe07e48c6, 0x87f25228, 0x64324c03, -0xe0426f9f, 0x148f828b, 0x4a3c82ab, 0x7d46539d, -0x0b5079ea, 0x2c675b3e, 0x83134717, 0xbe775c77, -0x74841ec3, 0x4470addb, 0xfabfa06d, 0x548757fb, -0x184ea712, 0x502765b5, 0xd7067ce2, 0x15afee11, -0x8a95590d, 0x3a1734cd, 0x212c7f7d, 0xe5aa3e5b, -0x9c7e75c3, 0x07486966, 0x5827bbea, 0x391e46fe, -0xc6acbc9e, 0x9761b6a9, 0x37bef8c4, 0x733eb81f, -0x7ac9a87a, 0xceacd157, 0xd931072a, 0x9383c10d, -0x5eae74ef, 0x5f82f6a0, 0xcf89077d, 0xbc641bd8, -0x1b7d1213, 0x980a4ed3, 0x410fa7e8, 0xaaa1a011, -0xa5e94ef2, 0x74937d5f, 0x3c109f67, 0x8e58bdcc, -0x2b43ad95, 0xaa516349, 0x6fa9cca2, 0x48a18062, -0x663c7fd7, 0xf3822d87, 0xbaaf1f97, 0x8da372b2, -0xa416831b, 0x6a645364, 0x9c7ac6fb, 0x3f5a9cab, -0x8cf6f4b4, 0x514fd1dc, 0x7e9d0918, 0x2075f774, -0xfda8677b, 0x3b5c16ac, 0xe887694b, 0x7d622e9f, -0x5427472d, 0x540e5c99, 0x2196e138, 0x5d5e9c58, -0x84a5fc17, 0xb17d6d41, 0x63273bdf, 0xfbb912b5, -0xaf16b7c1, 0xeb1914d7, 0x5d654b8f, 0xf4a594f6, -0x554a6311, 0xb391f519, 0xa5ad4acf, 0x9c052bb7, -0xea68faa7, 0x37399a25, 0x8f6f6d36, 0x47c20f2b, -0xf241ab98, 0x66da024d, 0xee90a06a, 0x33718b17, -0xaa89087e, 0x6dcca7f5, 0x43a59f0e, 0xcb2e3ab8, -0xb19126bb, 0xc56bccb3, 0x04f6fd9a, 0x0f63850e, -0xa2b6c85e, 0x309f9817, 0x7252b154, 0xcba20ff3, -0x143156b8, 0xcfcdc8ae, 0x13c2a75b, 0xea4bf1b8, -0x6e474959, 0xa9c376f5, 0x40d252b8, 0xb6209e70, -0x993efa22, 0x3d7e8007, 0x1857ba0d, 0x72f25310, -0x233a8f68, 0xeb4ca923, 0xb17917d1, 0x9ca3f4f6, -0xdecf1498, 0x99f5ddae, 0x8b6ba2b7, 0x54f41fb0, -0x1ec9ffa2, 0x74ad3bd6, 0x84fee3e6, 0x5294820d, -0x147e8b14, 0xd2dc15f4, 0x152fc744, 0x306bc043, -0xfdbb74d8, 0xf4ea207c, 0x53edfac5, 0x1b609795, -0xe990ee73, 0x749dbed4, 0xd1cefc95, 0x5c7b37f6, -0xc6b39045, 0x7281e3f7, 0xed0e6aa4, 0x590a246a, -0xe6e6a81d, 0x604491ac, 0x6cd14e8a, 0x7a19f5da, -0xf7c7326a, 0x0ef8029e, 0x0e741b48, 0xc962a062, -0x6f4ad86e, 0xa2729726, 0x93bcaf1f, 0x1bb56970, -0x12495cdc, 0x180512e7, 0xa1d68081, 0xb924c24b, -0x5a1461ca, 0x21438ca9, 0x5449ae48, 0x0f564503, -0xcec8df3c, 0x789f9b80, 0x5a708df1, 0x28735bfc, -0xcf11d2fc, 0xa5d01625, 0x80b0b533, 0xa09f026d, -0x1d22fdf2, 0x01928228, 0x8b6779ed, 0x04f7cc95, -0x581fe0b2, 0xcc9a66a4, 0x55b3f130, 0x0f22abed, -0x05b7e95d, 0xd8cc9c30, 0x0850ca8a, 0x34d729dd, -0x973300a7, 0x80ffedb1, 0xbf5b28e7, 0x135c8cc6, -0x4337b017, 0x31d8dd09, 0x35ed75a1, 0xb8f990b9, -0x4384dc18, 0x29d72b56, 0x021aa2b2, 0xa3248b3f, -0x5f4e7301, 0x29991927, 0x1cc50c18, 0x79fcc545, -0x56e2e683, 0xe5127777, 0x4b727957, 0x94d1bc22, -0xacd0da9e, 0xd24771fd, 0x5997ff0a, 0xb9947cb8, -0x8cb9bb5c, 0x16a4c5e0, 0x00d6995f, 0x1e05edff, -0x3a7f1af3, 0x445fd70d, 0x24a602c7, 0x6b50001a, -0x6c99f5e5, 0xad2c00c5, 0xbd16a90d, 0x3b7b6032, -0xa8dd4f8b, 0x437145f1, 0x5a593d5f, 0x749ee409, -0x9c6d8223, 0x40c1dad0, 0x578e7e1f, 0x89072e7b, -0x0ccf47c1, 0x427606d8, 0x4a7bb48c, 0xf85cc4e9, -0xca5ca3b6, 0x9b989f23, 0x6496403f, 0xdf8ef891, -0xf4458e90, 0x28eed125, 0xef91afe9, 0x97a8d65b, -0xe022b3dd, 0xc93c2adf, 0x520cbe7c, 0x58995018, -0x719a724a, 0x9258733f, 0x8df05767, 0x879b9ba1, -0x84684054, 0x71a62082, 0x5be959cd, 0x12c937ec, -0xc21fb3b8, 0x6738aa89, 0xb01d872b, 0x0ff6ec3c, -0x50fc63ea, 0x715b7c5d, 0x4e5d50c3, 0x086c862e, -0x34ec9201, 0xd41176ef, 0xd0238088, 0x53518100, -0x8e1500dd, 0xc6ea9594, 0x0359517e, 0x58d81a35, -0x48c40983, 0x2d562dc6, 0xecf5be9e, 0x4cd82ead, -0x45faeb2b, 0x1a66ec1c, 0x6b692a76, 0x6cb326b0, -0x3a6c362c, 0xf0174da3, 0x5e4549d9, 0xc12c5972, -0x73716059, 0xdd54591d, 0x32ee704b, 0x5a55c22d, -0x56bd1e7e, 0x2bd34024, 0xa42c85d2, 0xb1ce248a, -0x604a7570, 0xbbf4b3fb, 0xe0eeb866, 0x130b7dd4, -0xdb39dc1d, 0xd873b0c4, 0x3aedb6ef, 0x5efb2481, -0xbfaff9bc, 0xb94930d6, 0xa3fe71cc, 0x75867e01, -0x7c8ee191, 0xf38f4963, 0x8d077957, 0x658e7c2b, -0xc1bd58ed, 0xb86a20b2, 0xc624489c, 0x4624732d, -0xc11f1ee3, 0xf1874ed7, 0x173684cf, 0x0e5851d4, -0xc2662118, 0x13dbb926, 0x1668df5e, 0x00749d03, -0xab9530d2, 0x5758e602, 0x6db90ff1, 0x87270f9d, -0x774a52f5, 0xcd1b4b5a, 0xd706025e, 0xe3a51fc4, -0x31c5d55b, 0xbd0278a1, 0x16dce1bf, 0x75a3446f, -0xe030c121, 0xa6f6b3c8, 0x504e3b3b, 0x4c1428b1, -0x74229a60, 0x25d5b7b7, 0xea284c21, 0xf5f1c7cd, -0x0025e9fc, 0xa7db9e56, 0x4e3aeb90, 0x8bad0f3b, -0xc19e88eb, 0x8ea86b83, 0x25cf5d26, 0xca78504e, -0x94109c06, 0x60ad3975, 0x138b8038, 0x4c9d8fdd, -0x28a91526, 0x5d3d6c3a, 0xf81ab861, 0x8db34426, -0x35a3b398, 0xf3b40170, 0xb7e6994b, 0xea72c1f5, -0x63201cd4, 0x1c5749dc, 0x420ada27, 0x419f4847, -0x49244543, 0xb915645f, 0x3a00b3e2, 0x0122000b, -0x296b6bad, 0x7b45d76b, 0x5be8f025, 0x2a04919f, -0x8291fea4, 0xaae644f9, 0x7af3fb96, 0x77d9878c, -0xa8996848, 0xa9a0c1c3, 0xb47ae6d2, 0xc5b6cf90, -0xb04b4863, 0x43fa113b, 0x66ef4993, 0x03a5b4e9, -0x94b661dd, 0x145a5909, 0xd42f70cc, 0x6b816775, -0xfbc0cb04, 0x5e890eb1, 0xb6900305, 0xcd19304b, -0x85c67d21, 0x19e91907, 0x27b3898c, 0xe0ce6ba2, -0x4110d80d, 0x85953740, 0xba7a4225, 0x51db6dd9, -0x04c21ffe, 0xd34ef7cd, 0xeb13f075, 0xc1f8eb04, -0x19a1227a, 0x3e99efae, 0x318346e2, 0x3d4c73bb, -0x402dacc7, 0x5a9e892d, 0x01304401, 0xb3950c6f, -0x9254bea1, 0x5cc8f025, 0x53cb9416, 0x52d716c5, -0x3ff575a5, 0xede2046b, 0x2cbd6b85, 0x7e8feb25, -0xc2d35482, 0xa49b8495, 0x214fed4b, 0xc93ae54f, -0xde3d8a18, 0xe4456b47, 0x505555c1, 0x6418926d, -0x4b6ac1e7, 0x7ac213ea, 0xc081eea5, 0x467ff1c3, -0x1ed5d79d, 0x746dbb24, 0x38b1dbde, 0x4d495fc0, -0x7ddabfe1, 0xfbac0ba1, 0xd17cfc3b, 0x32c819f3, -0x1f4c39cd, 0x6fa5c3ed, 0x0d2e7f50, 0x1f5cb318, -0x1e1770d1, 0xef12c293, 0xb149ace5, 0x93df9bdf, -0x14a98319, 0x3374906f, 0x746d603f, 0x5a368e6d, -0x8dbaef76, 0xb7923f42, 0x607655cc, 0xd144703c, -0xa01fa0f6, 0xa83f4e65, 0x224bba03, 0x6e082d15, -0x11ef27eb, 0xad91427e, 0xd8f0e3bd, 0xba7bc3df, -0xdb031557, 0xf33052d0, 0x2bc3df37, 0xf55d25c2, -0x99af998a, 0x5819eb07, 0xe4b9ebc5, 0xbc3da46e, -0xde1abe71, 0xb8c66434, 0xe811e29d, 0xa48ee5e6, -0x7f961c60, 0x5500769f, 0x9c8e0d00, 0x94680cea, -0x2f7a0c5f, 0x9a058310, 0xd3ddca08, 0x74276c4c, -0x855ebef2, 0x61979f79, 0x09684303, 0x3ea777dd, -0xf700db1f, 0xdf7bcae0, 0x0fa7db2b, 0xd0115231, -0xc0015882, 0xe4af6f72, 0xb4388c7d, 0xfb5656bc, -0xbe1d38b3, 0xf59ae9d3, 0xddc692bf, 0x3aaef998, -0x561f993f, 0x4d191a40, 0x4492df05, 0x7eb17670, -0x0770001b, 0x9b320a87, 0xbc8a559a, 0x19781e02, -0x13c995b1, 0xcb8c1e47, 0x462019e3, 0x7ee6bcc1, -0x9da2afce, 0xee1dbf76, 0x3a72ad3f, 0x711f786a, -0x0c72d639, 0xa3455dc9, 0xef155308, 0x82f3e1c9, -0xc9540414, 0xcec2cde1, 0x748005bb, 0x24197d5d, -0x4b8b7f7b, 0x3dde3129, 0x9ac952c9, 0x6f7932a7, -0xa99005e4, 0x4261280d, 0xfad329af, 0x90bcacb3, -0xe1c4a202, 0x9200d928, 0xffe55142, 0xf69b2a40, -0x227783a3, 0xe4b0c9c4, 0xeca97ce9, 0x9245597d, -0xa922db08, 0x94bff912, 0xdbebd937, 0x5c658f30, -0xb3f4a726, 0x24e2ca27, 0x9ca037d7, 0x745d3d5e, -0x3e8c437e, 0xb807af86, 0xee5fa977, 0xfe335297, -0x5c0a6707, 0x8ab801af, 0x05d02766, 0xcd0906b4, -0x791b47d3, 0xff5a0291, 0x09465b16, 0xa7fff3a1, -0xe2e6d825, 0x7f4f2b9a, 0xc1f2e668, 0xa5cfe1d6, -0x95fd7bde, 0x38681314, 0xc3c7dce1, 0x7b82e044, -0x2c883c77, 0xe8aa72be, 0xd53867d7, 0x7022fdc3, -0x3b697ccd, 0xd71618ac, 0xc87934bd, 0xe96101d1, -0x55d1976c, 0x471c8505, 0x7a36d839, 0x5d62a9ee, -0xf3c54a8a, 0xa2be15d9, 0x244087c9, 0x042c8037, -0x23224689, 0x281c5d73, 0x2139ecfc, 0xffb8bc8a, -0x834fdd11, 0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, -0x4ae2dbda, 0x86d90089, 0x6675dfce, 0x48876262, -0xcec72538, 0x11dc5c80, 0x86a730f9, 0x313565c9, -0xe3e5be11, 0x106d7cce, 0x752b8be2, 0x3d00a5bc, -0xe6f70e95, 0x44447ac8, 0x600df30c, 0x8335ac3b, -0x8816ddee, 0x700982fe, 0xee495741, 0x48c7e81c, -0xa3d55da2, 0xb0172982, 0x70ab2158, 0xd4460621, -0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, 0xa8454763, -0x70877bb6, 0x66005c97, 0xaf292c06, 0x7b843db1, -0xf343b59b, 0x25cdc7b5, 0xa41da617, 0x9e9d895e, -0xc936f475, 0x7270925a, 0x30024230, 0x8e72f53d, -0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, -0xaf377cc1, 0xbff09a78, 0x4b4e0814, 0x95a0b2c1, -0x270398de, 0x201fca94, 0x2a032a4f, 0x131542b4, -0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, -0xa3b3a991, 0x17ee60c2, 0x852c0b8d, 0x11e5853a, -0x762002a7, 0x92c5311d, 0x0d4bf7e1, 0xfffec870, -0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, 0x0111a772, -0x9808e780, 0x29c336e8, 0xe9bc05df, 0x5bedde11, -0x945565af, 0xaff808fe, 0x87e3423d, 0x4de6f98f, -0x93b4adef, 0xbf704fa4, 0x09120e91, 0xd54f3692, -0xdf8eab1e, 0xfabbf59c, 0xe74318be, 0xaab87ffc, -0x29fa791c, 0xe3915552, 0xa652cb9b, 0xa1252e74, -0xb35b723b, 0x542aa28b, 0x12fcc5b0, 0x3941f962, -0x82bcc6cc, 0x47b11974, 0xb821611f, 0x78b34250, -0xf1be5659, 0x561b9e61, 0x6f3bd501, 0x584e6f5c, -0xd54ed547, 0xacebcd21, 0x7b5ff816, 0xb64ad233, -0x9f2f330d, 0x69fb1ece, 0xac8710dd, 0x58dc6c60, -0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, -0xa733274f, 0x884d9b55, 0x42b08b63, 0xafa54a74, -0x1c7ccf64, 0x93a20191, 0xaaa3132e, 0xc69831d1, -0x54634889, 0xfbfe3efc, 0xd3cf68d4, 0x302e3117, -0xf5693131, 0xc3ce8c6c, 0x1f03cd89, 0x6243334c, -0xf16bc80f, 0xdca5f130, 0xcb2cd956, 0x4c1bb421, -0xe8de533c, 0x7f86703a, 0x29aa897e, 0xdd54acad, -0x76b2f2ae, 0x7ef82b71, 0x2e30970b, 0xba402597, -0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, -0x2363d147, 0x5327289a, 0xe89229f3, 0xd63a535c, -0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, -0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, 0x6d65db4c, -0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, -0x8488a45f, 0x8ebc2932, 0xd4767316, 0x3e8c4b8a, -0xbab7402c, 0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, -0xc88528e9, 0x4b2e4e8f, 0xdd938b86, 0x0c964f98, -0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, -0x4d40b3b3, 0xcf203155, 0x0d2fa621, 0x752d2c58, -0xb12bac12, 0x1e7e8c23, 0x94215d54, 0x9854a71c, -0x4de63c64, 0x7a012529, 0x9c171f8d, 0x9e71def7, -0x3bd17d50, 0x11f175d9, 0xec78abf3, 0x7b529eee, -0xd3a69fc3, 0x5b718676, 0x58214d29, 0xa8bd2c34, -0x41ea00ab, 0xa03f64d6, 0x4ee342b0, 0x32b1e444, -0x1c1801a4, 0xc8424702, 0x334a7e35, 0x50cf1543, -0x3b22b495, 0x88683776, 0x8e2e0154, 0x6155c033, -0x4e2fa6ac, 0x42ace700, 0x8d64f97c, 0xaf9ced17, -0xb2a5cb92, 0xa558582d, 0x88705de7, 0x9e528d59, -0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, -0x10462123, 0x30080f7d, 0xb346cd81, 0x0049c396, -/* 1719-m01f6508.inc */ -0x00000001, 0x00000008, 0x04262006, 0x00000f65, -0x5c58f575, 0x00000001, 0x00000001, 0x000007d0, -0x00000800, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000008, -0x0000000b, 0x00020050, 0x20060424, 0x00000121, -0x00000001, 0x00000f65, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x7b8b2c33, 0xa45a8391, 0xbfcfae7e, 0x13c73806, -0x3e6fb5e7, 0x9fa2e0b7, 0xa751399f, 0x9cfd3041, -0x1e777355, 0xd28b9f9a, 0x52366431, 0x98d07e44, -0x4d3e73b8, 0x2451251c, 0xdb49bf93, 0xfcf022b4, -0x71ff9e49, 0x3e2c0df6, 0x83189796, 0x5d85ff06, -0x4b7d4925, 0xb8cff5bc, 0x2b0c003e, 0x7bff93b0, -0xda473756, 0x603a2a5e, 0xb79b1b3f, 0x97fa09a6, -0x58db4102, 0xf4a77bae, 0xa691c022, 0x40c80906, -0xb6151ff7, 0xd8a81a50, 0xe696c918, 0x6fb1bcd4, -0x91928d2a, 0x6f8481c0, 0xc146a3b0, 0xb702c6e6, -0x01dfbe87, 0x255947e5, 0x1ee51d98, 0x5fa7bf0e, -0xa0fc72c7, 0x90d22f4e, 0x85476060, 0xe4438e6a, -0x68370d89, 0x998ac0dc, 0x777b9881, 0x122a7e21, -0x7d04e408, 0xccae7942, 0x1c527cff, 0x382f75fe, -0xd5ae8790, 0xb8ca0d48, 0x87521e7e, 0x98b8c307, -0xb009b5ae, 0x73e60c9a, 0x32fadfd6, 0x1ec078c4, -0x7c6c5dad, 0xf8a0d91b, 0xa84b7259, 0x9ec09997, -0x718eb876, 0x2bc43de6, 0x24bb9540, 0xb6edbc06, -0x00000011, 0xca79465a, 0xd4dc2f88, 0x691a8c02, -0xdf2e397b, 0xdceea993, 0xea5f7fa4, 0xcd1d7859, -0x521cb95d, 0x696d5112, 0x8d7e985d, 0x7729265e, -0x5e5c94ad, 0x90bbec2d, 0xb4a392c2, 0x73e1ddd0, -0xe3f66bd4, 0x3f3de2f4, 0x8c02ed34, 0xbda0d86d, -0xa4bce0e1, 0x4eeccb0c, 0x004e51df, 0xe54f2b84, -0xad7c9bbc, 0x89829a05, 0x33abad36, 0xdbba0850, -0x419287ce, 0x943af8ba, 0xa998b1e0, 0xf29e752e, -0x88c32d51, 0x1e001731, 0xf092cbcf, 0xb9959591, -0x4afe8764, 0xc29db19a, 0xe614c853, 0xf6bcb656, -0xa0f4fe52, 0x1deea1d8, 0xc695468c, 0x02bfc809, -0xc05e99ee, 0x3fb6cee8, 0x5923c806, 0xbe280047, -0x0d62c948, 0x38e216b7, 0x0b00b0b1, 0x9f629916, -0xd99764b5, 0x599948fa, 0x9b76d9b9, 0x2d5b4df7, -0xd28b355d, 0x9f928338, 0x17e6f849, 0xa98f505e, -0x9bd2c80d, 0x1600f39b, 0xcedaa24c, 0x1448822b, -0x8e6994bc, 0x57efb9c2, 0x7bd1cc4c, 0xb5da19bb, -0x31525691, 0x83f4c148, 0xf639ae5f, 0x95f9dd11, -0x26f41f38, 0x99c34dda, 0x0070eb19, 0xf634ef25, -0xdf3a2889, 0x075fa4c5, 0x5020d60c, 0xd9bac756, -0x06c4dd71, 0x5672914c, 0xf7b572ae, 0xc9c50c89, -0xe407d6d2, 0xaf85e015, 0x2db1d604, 0xc2accaed, -0x0c227173, 0x42c58997, 0x376a4040, 0x27f407b4, -0x2c9ebf47, 0x1ebf8cab, 0xdf63df33, 0x5a05ad2e, -0xd0e5c94d, 0x1151c004, 0xfd63ea17, 0xa795fa72, -0x654c6a4f, 0x9461b5e2, 0x8843a2c5, 0xe5d4d329, -0xa786980a, 0x366e2e56, 0xdbec833b, 0x7f78182a, -0xadf23947, 0x49fc56ff, 0xa3028792, 0xb5edb092, -0x050f6df0, 0x592cf58c, 0x0a80abbd, 0x2e70c8c9, -0x88ecf1e8, 0x88c3f6ec, 0x2813b53e, 0x533bb90c, -0x6844c504, 0x4b556b78, 0x97b7ab63, 0x46ee7d95, -0x1ec79555, 0xca34db5f, 0x436b1731, 0x47289b73, -0x4883537e, 0x57477cd1, 0xe02a04a4, 0xa8853711, -0x62e71e2d, 0x1afa5156, 0x6c4f79b1, 0x2ee10ffa, -0xb01f72dd, 0x9c61c63e, 0x653854d9, 0x2212a16a, -0x097d5672, 0x05a585c6, 0x11d4ec5c, 0xfbd542cf, -0xd0ef0830, 0xe3838f0e, 0x524cb241, 0xe7237bc8, -0x52ff505a, 0xaa46c7f1, 0x325b0d29, 0x0696cd2e, -0x7ed85c43, 0xb83d52e7, 0x40e9c2a0, 0xd9147b32, -0x8c5d9d02, 0xceef05f2, 0x604792da, 0x9223967a, -0x27eb5bcd, 0x7f78559c, 0x0d20a3b2, 0x5952cbbc, -0xe35fe328, 0xa49cdfb3, 0x406d3e3a, 0x093d3044, -0x3e7b8c5c, 0x530ed7a7, 0x47c449ee, 0x5fef5f55, -0x777ce977, 0xc67b61bb, 0xaa5fb96e, 0xd73be015, -0x6008d026, 0xe98d90b6, 0x8ef2fdff, 0xa4d0de38, -0x9cc31aee, 0x351b5d5f, 0xdc83fa9b, 0x45b007bb, -0x94941e0a, 0xc842cc1a, 0x13ab92fa, 0x95caa979, -0x51ea69b3, 0xe4fefccd, 0xe21fc4f1, 0x1634548f, -0x756b84c6, 0x9fe76b9f, 0x4e28ee1a, 0x8c8f5ceb, -0x08e3b998, 0xc6dfa5dd, 0x948c7621, 0xbe66d285, -0x7e050ad4, 0xf48e2561, 0xbc00201b, 0x2325ff60, -0x161423d2, 0x2a96eb38, 0x8dad885d, 0x8a4f546d, -0xbd640d83, 0x6aa6b616, 0x086de9b6, 0x80cc15f7, -0x30558280, 0x383eeefa, 0x477b44a0, 0x9fdbed83, -0xa83c7649, 0xc1c48473, 0xfec1fac3, 0xa223b679, -0x1a8a27a8, 0x762b32fa, 0xf4759b79, 0xc356a6d1, -0x16129e9a, 0x429e8994, 0x4fe603be, 0x1ef65832, -0x097e2f72, 0xe47279e1, 0xdd5d2ab7, 0x87833a47, -0xd9009f43, 0x995d4ad3, 0xaaa939a7, 0xef14c315, -0xc3f4360d, 0x3856c208, 0x79641784, 0x81584391, -0xa2fd781d, 0x81d2013b, 0x0224598a, 0xd352fa9d, -0xba10f035, 0x499f9e2a, 0x732ee824, 0x624d6680, -0x0b64229e, 0x71f0e2e8, 0x04711cfa, 0x25ee4a48, -0xe81c15e1, 0xf8e6b875, 0xe944f119, 0xfe2eb47b, -0x3b85420a, 0x392af4d8, 0x1d250cae, 0x4503717e, -0x1d9d6eba, 0xfa823767, 0xcc86abc5, 0xf69e0dfd, -0x93df823b, 0x772fe56e, 0xe5b2d115, 0x57d3b84a, -0xaf86a775, 0x5f16e89a, 0xd92bfbdb, 0x52841f94, -0xe0e8e9d5, 0xdb505567, 0x25d71a34, 0x9af9da0b, -0x24eff392, 0x99060257, 0xfd47408d, 0x30541632, -0x0af6e540, 0x01b85d88, 0x5642607a, 0xf312fb21, -0xfa9f15fd, 0x3f875194, 0xf141af9d, 0x3624580a, -0x78b2466c, 0x0e66bc4c, 0x7b27c988, 0x964fb527, -0x08e8f3b4, 0x47ae754e, 0x8cedc325, 0x9cc875f1, -0xbede5abb, 0x72a0943c, 0xf49c2e3b, 0x6e650234, -0xd1b77cd7, 0xcdc82a19, 0xc0e921c7, 0xb2a066ad, -0xa9187f81, 0xe6c03bfb, 0x4d9a40bc, 0xce087313, -0x7fc63e54, 0x4ae1814a, 0xfe5c8945, 0x8abd2393, -0x4c99ded2, 0x549ee9c0, 0x7dd01eb6, 0x4738f4d2, -0x94263b53, 0x6f11ce54, 0x7d5d4cdc, 0x0cd881c2, -0x7d788aa2, 0xf8851663, 0xa32836e9, 0x86617e55, -0x40338bb2, 0x3015fa10, 0x2329f448, 0xff11e66d, -0xa2b68e4d, 0x17c62286, 0x6d76e8a2, 0x746e0b26, -0xe58e4c9f, 0x2e600a6c, 0x270e71d4, 0x8ea6cc21, -0x15204668, 0x74a8b290, 0x5caf3f36, 0x94e684bd, -0xbf8a33d9, 0x5b0bc87e, 0x1fa3a852, 0x0c2412ae, -0xafaab23d, 0x9d73c709, 0x535d0780, 0x43d0ed94, -0x0c85955e, 0xd0ba545b, 0x50a96f56, 0x89fe1fff, -0xc93f6abf, 0xf3d1a63f, 0x105f9e58, 0x0972f672, -0x23e7a050, 0x338992a0, 0x0884dce0, 0xc69e2e9d, -0x4b4fb526, 0x75fbc584, 0x3b0c39c4, 0x30de01c6, -0xa45bcfef, 0x621aab9a, 0xbf84cde7, 0xb97c1657, -0xd6c35e29, 0x1c340d20, 0x4e629b16, 0x964d9205, -0x773fd59e, 0x6e06436a, 0xa271a4b3, 0x26ea87dc, -0x0b7a0a74, 0xf5ceac33, 0x6abb7570, 0x17ff9fd2, -0xc689008f, 0xbb64e4c5, 0xa1fdbfd3, 0x8fc86b4f, -0xaf368b05, 0xb25d5e2b, 0x993b61c1, 0xd31e2b57, -0xe5e6f0cb, 0xa1c03ea1, 0x99bc59f5, 0x3136a5f4, -0x17bc0426, 0xd4c893bb, 0x6214a7ba, 0xbc17d415, -0x36e33f56, 0x219975a4, 0x7593ea70, 0x0da69d80, -0x3dcd82c4, 0xc3f68585, 0xa3f42f85, 0xb50d5861, -/* 2375-m206f6cc.inc */ -0x00000001, 0x000000cc, 0x09162007, 0x000006f6, -0xb5503da1, 0x00000001, 0x00000020, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x4ca2453a, 0x0c60f81c, 0xf9fb6ac3, 0x446f4eb9, -0x68956ae9, 0x281c27ef, 0x9b6e0e89, 0xce631b52, -0xd8c1a34d, 0x9a174e3d, 0xfd97d9e9, 0x07b641e7, -0x3f50d275, 0x5561d772, 0xa65af9fd, 0x557870d2, -0x12dc035c, 0x15ffbb39, 0x70fc0682, 0xae5c00ab, -0xb597e595, 0xd64f9b42, 0xea014df7, 0x201b6bbd, -0x5b402e36, 0xdc08dd6e, 0x045591f8, 0x63e18c03, -0x810de70d, 0xadb08199, 0x27582ae7, 0xb674dfb0, -0x722836d1, 0x1d64bd8f, 0x5f099a2b, 0xc9c9fc54, -0xb4e16551, 0xf3f6d238, 0xca2a4eff, 0xe4fe8258, -0xebb303a4, 0xaaeca96c, 0x8054b75c, 0xb3c7fdda, -0x4cd15f13, 0xd763420b, 0xd44ada70, 0x44e676e5, -0x6a9acad8, 0x3ce16ecb, 0xf236af13, 0xd19b31cb, -0xa7f53497, 0x811df556, 0x8f4e3f29, 0xc89a1439, -0x8e1585d0, 0xff71d747, 0x7565b24b, 0x284d09d4, -0xd51f0453, 0x7451da9b, 0xf9de2227, 0xd190a59a, -0x37c33c70, 0x22fda711, 0x5c870aab, 0x1e26fb7a, -0x131d1b8f, 0xa1d6bde8, 0x10df2eb5, 0xa2f5413c, -0xd42eb4dc, 0x385b5303, 0xcc7a035e, 0xcb1e1418, -0x571574c8, 0x68ee29f8, 0x9c73546f, 0x75ed27e6, -0x5fb8c3f8, 0xefbd3fe1, 0x232658a4, 0x44d58d4f, -0x50ed3828, 0xcf347f31, 0xef6783a8, 0x36815423, -0x2a86e288, 0x85d9b16e, 0x8499426e, 0x4893d524, -0x31d97028, 0xbeb62dc4, 0xca41aeea, 0x6c006bd0, -0x5fb3b5af, 0x00a99a87, 0x9d3403df, 0x9a636eee, -0xbf42b42e, 0xf1bb04d1, 0x6b3f2a95, 0x8940dd97, -0x6bf9b59e, 0xcb8a0527, 0xebee515c, 0xce1471cf, -0x355dd1ef, 0x680bbb16, 0x64b16e4b, 0xbd88d2e8, -0x4accba0b, 0x645782de, 0xb4e80b30, 0x8dbaff4c, -0x69a316dd, 0xdb385e92, 0xa9d7e2c3, 0x9d528ac9, -0x84cf62b8, 0x6fe4b05b, 0xfd9c1de2, 0x637c77e5, -0x8246a322, 0xd8c0bb8b, 0x1630ca78, 0x02782a7c, -0xfc98e84f, 0x189d1ad6, 0xd49b6da3, 0x38f57c03, -0xd2184b1a, 0x29839a53, 0xb0d59c88, 0xcbb66409, -0x86e1daa8, 0x0962c75b, 0xb2136ab6, 0x8ad8d88a, -0xa34b2d1f, 0x187a4791, 0xd90b7191, 0x43d51a45, -0x207d9dfc, 0xa14631df, 0x10b160be, 0x4979a4df, -0x60b0eb14, 0x926481a3, 0xcee25829, 0xd001b43a, -0x5a0b8d25, 0x6d4da2ef, 0x379cf299, 0x1ece08c5, -0x585b7f60, 0xe21f15ee, 0xef64a654, 0x315f1dbf, -0xc7b0bf4a, 0x8630be84, 0x1e2c6ac1, 0x351deaad, -0x21e70db4, 0x9be6e520, 0x20efd8c8, 0x4fd7838d, -0x7398c60f, 0x31450450, 0xf5bcbcb2, 0xa251b3ab, -0x4802b7c0, 0x6ef397f7, 0x6918667d, 0x41364657, -0x93749c16, 0x68ccc8c3, 0xa7828ada, 0xafe49351, -0x8950e98b, 0xadd263f7, 0x03743b10, 0xe1303390, -0x67c09f32, 0x34a53ad9, 0xea6de14c, 0x73982b98, -0x5cc5189a, 0xc3c717e0, 0xd7482ae3, 0x528c71b4, -0x2f1b0b0a, 0x79658ece, 0xe6939197, 0x46dc279b, -0xd7db9210, 0x93da407d, 0x5eebeea8, 0xa3cd09e5, -0x3861991d, 0xda6a49ee, 0xfada1c83, 0x6873706c, -0x472a42a7, 0x25b0a0a6, 0x10533fb9, 0xfd81f855, -0xffdcb426, 0x44fb83e2, 0x61ff93c9, 0x21c08ec8, -0x7dede282, 0xabe78a53, 0xac7e1c5e, 0x2778c339, -0x3a72dc6b, 0x4d8b1827, 0x097356ed, 0x95aebc13, -0x53e90714, 0xb4449bfe, 0x7a53c105, 0xbca902af, -0x7efa00aa, 0x3aa20bff, 0xc424389e, 0x33015d04, -0x370474f0, 0xa7e9db06, 0x31ef08f7, 0xfffd987e, -0xc188f973, 0xdb5e1be9, 0xc5bd9be7, 0x714c08f2, -0xb5bc782d, 0x7c485554, 0x93f384e1, 0xdb13e1e9, -0xf804524c, 0xd72d2135, 0x59f4b95d, 0xa42ce4ab, -0xe949dbdb, 0xff708a44, 0x191ff0a5, 0xd5dcf1c4, -0x5ed779d7, 0xf84a04c2, 0xb312bb9a, 0x72296289, -0x818ac787, 0x29d3f1b0, 0xe5247de5, 0x204841a7, -0xe343d836, 0x3455f1a5, 0x1ea06a2a, 0x6dd13104, -0xcfcab06a, 0x59b40efc, 0x1aeda2f4, 0x228c613b, -0x3a4aea04, 0x4ff8672a, 0xe1c2a5c0, 0x929b61de, -0xfe04b30c, 0xeb86409f, 0x123cd80b, 0x285b55c1, -0x9fbc657c, 0x96f08d1b, 0x811c3005, 0xf46a3a15, -0x35ce682e, 0x7d0f00a8, 0x8f20ab16, 0xdbf70d95, -0xf3f1fa22, 0xbd490a21, 0x5c1cb186, 0xe70d8e0a, -0xe276e3de, 0xc44e4fd6, 0x95cb1709, 0xd637f3f3, -0x22fccdd3, 0x73638415, 0x09cb4c2f, 0x5edd1810, -0x7cddfcb7, 0x10504f7a, 0x052d2cdd, 0x60d7fc41, -0xd537c338, 0x9df0ae8e, 0x998fd20c, 0xbca60e45, -0x660df350, 0xc358e102, 0xb6a7463f, 0xf915e9d0, -0x9dc3ddbf, 0xa3391de9, 0x821687f5, 0xc97749d6, -0xd7142369, 0x619d3c38, 0xc145a05d, 0x08bdd065, -0x2d07e770, 0x85b742fb, 0x868647ec, 0x42260c63, -0x57f0f08a, 0xbe6c102a, 0x08d5bc29, 0x04ff5ecf, -0x7064a5ec, 0x3c938764, 0x13daf31f, 0x66a431af, -0xd7ffe591, 0x725e90bb, 0x8c7c9c89, 0xdb09effb, -0x49a69245, 0xd86bb8e0, 0x05ccbbd3, 0x1888abaf, -0x379bb483, 0x0da8c7ee, 0xa5f33b28, 0x17090bed, -0xf257cf2e, 0xbca95053, 0xad55a14d, 0x7ee27bb3, -0x86c679a8, 0xae835aa8, 0x20a21939, 0x8b373484, -0xf3a240ee, 0x4b62413d, 0x105429b3, 0x3fc3934a, -0x772a80c1, 0x97dafbbe, 0x6b3f45ef, 0xbc31d8bb, -0xc406f325, 0x7ef9a44f, 0xe8de1d36, 0x89a26f22, -0x112ff57f, 0x5c76e11f, 0x05c737ad, 0xcc2fabb8, -0xa3922153, 0x498c6eee, 0x0f7aa81c, 0x4577417a, -0xc494fcf8, 0xca0ea350, 0x164e10b3, 0x46d2cae9, -0x533bc875, 0xe66514e8, 0xf3b87661, 0x9404fdce, -0x0bb478c5, 0x731e58bc, 0x2b64c504, 0x537b200f, -0x689f08c9, 0xf0579ddd, 0x2ba0d681, 0x2fb46df7, -0xf68eadd9, 0x06ef245e, 0xd16df38a, 0x1bde6557, -0x858936df, 0xe3a8b9b2, 0x71e52cc8, 0x1b1cdddd, -0x5a7a4ddc, 0xb53d291c, 0x509b164a, 0x5d6ce1ed, -0xe07f4d72, 0xa4056fce, 0xb1bd2265, 0x13b908cb, -0x554e5ec2, 0x59d6c0a4, 0xf624fd6d, 0x50f7b809, -0x9ad9d586, 0x021298af, 0xb7fdd41b, 0x636fa09f, -0x0b476a97, 0x02161594, 0x8a441916, 0x1fbe6b3a, -0xf4a5ba89, 0x553410d9, 0x8e878475, 0xaf97da55, -0xcce07fbb, 0x2f6e97fd, 0x7a6bec65, 0xd741edd8, -0x46762670, 0x23a62dd0, 0x1800a0ad, 0x8a833135, -0xf173ed16, 0x8cfd7af3, 0x21b1fbf6, 0x008d081a, -0x86f40203, 0x6d2ae0be, 0xd60f7b40, 0xaefbc0d4, -0x179ee7ad, 0xfa7ecf66, 0xe3b54cd2, 0x5a935135, -0x784eb5db, 0xadafa9b7, 0x02a61651, 0xf61ca1ee, -0xd3034edf, 0x5d0747b2, 0x0249cb51, 0x87ac0e5f, -0x2fbd72fe, 0x11d19421, 0x826aa7f0, 0xbecad816, -0xea303a33, 0xe09e396b, 0xd8f4a26e, 0x83f8bee9, -0xe17d5b57, 0x90d8aacc, 0x148bb70d, 0x70f230d5, -0x8b9d152b, 0xb890c3e3, 0x2975fe1c, 0xfaa78f08, -0x5d3f2402, 0x83e43665, 0xd4baddc1, 0x32fe6e2e, -0xcec77de2, 0x8157232e, 0xc24d91fe, 0xe0c16891, -0xc36d6afa, 0xf613aaf8, 0x6b388fc0, 0x2c4dc07f, -0x379fb3a5, 0x6731c635, 0x6fd4eb18, 0xda60e96a, -0xa1188bcf, 0x4221d7e0, 0x42fe4796, 0xfa9bf912, -0x90281e11, 0xd22e3be9, 0x10133ea2, 0x1a19022e, -0xf5bd3b53, 0x8d3b9eec, 0xa4223edb, 0x8821311a, -0x999601ce, 0x0b016cef, 0x0eb791e3, 0x6c2d7b16, -0x2bcc9cb4, 0x9b8ad717, 0xaf78a2dd, 0xd19cbd5e, -0x83ccc754, 0x44ec7bb8, 0xe1564239, 0x6524d3d6, -0x219e4912, 0xac90962a, 0x6af7074d, 0xb4de29e4, -0x2ade0d62, 0x002975f9, 0x875add41, 0x3af7eb04, -0x5184074d, 0xa799da86, 0x745e9870, 0x8f9b977b, -0xa4fc2d1e, 0xfba1a758, 0xd4acd4bd, 0x46231ad0, -0x19c96255, 0x46a28a49, 0x2747f84f, 0x92c5414a, -0xe9ba4d71, 0xa46c972f, 0x34d99223, 0x1c511c62, -0x90a31554, 0xd313b802, 0x51e31fd3, 0x1b7abc55, -0x6ea77c57, 0x40f67d62, 0x85cfb2fc, 0x5d74f2c1, -0x4102e522, 0x399d75a2, 0x37df2ef4, 0x0885218c, -0x9b7f6495, 0x6546d3e2, 0x6ab35c52, 0x3535b3c8, -0x3fd580c7, 0x3ec9b525, 0x7f0ceaee, 0xd29811ea, -0x88fdd8ce, 0x16d9dc25, 0x257b4177, 0x0689554b, -0xf1bc6a1c, 0xe25e84aa, 0x3fab190e, 0xe53b5591, -0xf92ccba1, 0x72e849df, 0xa54bebb9, 0x7f9cfa4e, -0x9024afff, 0x44d0bb1b, 0x6769020e, 0x75714288, -0x5e6946fc, 0x7eb5a4db, 0xfe724b97, 0x03da7f95, -0x86332888, 0x652baeae, 0x4ff95966, 0x8b59b653, -0x490d78a0, 0x82db6e30, 0x57397510, 0xcbe89257, -0xfb8e7cc6, 0xd8dc344c, 0xa3b65aec, 0xb5476370, -0xe39f95e1, 0x7a17ef35, 0xef747c9b, 0x908a64c2, -0x4b019837, 0xb90c56f3, 0x1427e024, 0x60c697c9, -0x52e8c5eb, 0xe372c9b8, 0x6447ded3, 0xc50e8f41, -0x37e037fb, 0x87ee5ccd, 0x8b120174, 0xbd7474c8, -0x5b140ba0, 0xa753443b, 0x92fe8be8, 0x26020154, -0x6356b4ec, 0x426f3a76, 0x7ce0259b, 0x4ba92062, -0xad5c00c4, 0xcaf50518, 0x34fbbc39, 0xd74b9f0b, -0xa3ba98a1, 0x078b3e78, 0x7ff3ed5b, 0x307739e7, -0x593d4e92, 0x33d8f843, 0x9301bcd2, 0xaf289a42, -0x5609f0b1, 0xf39134a9, 0x2f904b53, 0x62e6b3ee, -0x6a0da57d, 0x36991211, 0xe7a6917e, 0xec3f6b43, -0x26fd7e86, 0x846737b6, 0xa376952a, 0xf7961df8, -0xf48f8664, 0x7d55f182, 0xa2fc9f07, 0xc7207d3e, -0x2a0b2f92, 0xfbed2635, 0x3ecead48, 0x90f91aa1, -0x4dd167bb, 0xe3ab46ca, 0xd4c5586f, 0xe287d92f, -0x86497212, 0xc12bff4e, 0x2e378968, 0x19abfc38, -0x721893d6, 0x7c0302a3, 0xa7dc2a88, 0x58e8df52, -0xd6ae8df5, 0xb2e61807, 0x7f1446f7, 0xa6631a76, -0x9c840dd6, 0x219a8534, 0x69798862, 0x13ecf7e3, -0x593732f2, 0x3fab5b81, 0x9a7003e3, 0x354ecd44, -0xfbf4c175, 0x585696f2, 0xc9bb6d06, 0x75a2d533, -0x5eb5fb61, 0x28a2d130, 0xa3a8dbfc, 0x71fb7be8, -0x3a2584a0, 0xba7d014c, 0x182e3105, 0xcf992d21, -0x2b5c9202, 0xf4565d91, 0x05938b8a, 0xea1eaf79, -0x0b738314, 0xf178f3a0, 0x9ee13d7b, 0x55d7c1e4, -0xbf19a735, 0xe8ea533f, 0x0b915fac, 0x846af3fd, -0x2ea919d3, 0x654cc505, 0xd4e7d3b6, 0x04f535a0, -0x16fcd173, 0x90464576, 0xe5751104, 0x563f4d11, -0x95b28b19, 0x2ff9fc80, 0x575864dc, 0x59b480f1, -0xee59fddd, 0x2ad7b105, 0x92fac0fe, 0xb4d6fd14, -0xe94415c3, 0xa23bdce5, 0xb4cddc6e, 0xf040325e, -0xf607d4c5, 0x7e98e90b, 0x2f52bdde, 0x783eb8f8, -0x0d735e4c, 0x435b4d46, 0x47865cfd, 0xcba84b9f, -0x7680df71, 0x9c89e0b7, 0x52e8765b, 0xca4a4a2a, -0xf5d6bf74, 0xffeb8da9, 0x6b22e6d9, 0x9317d0d2, -0xd3417c8e, 0x257138ea, 0x9f6c650c, 0x2f65c281, -0x186f88f9, 0x8a630a1f, 0xf36a3c4f, 0x3faac09e, -0x18cc37ce, 0x5187d240, 0xadb95d8e, 0x96ef7f07, -0x22098da0, 0xedd3b452, 0x6e827fcb, 0x4ed59ed0, -0x984fc42e, 0xdaa3f5eb, 0xa6fcd30d, 0x150f6253, -0x3ff37e60, 0x1dc93c3d, 0x87e89306, 0x101ab853, -0x81579d33, 0x1d68dc7d, 0xc2dffad3, 0xcf913d2f, -0x96c2f5ca, 0x0751685d, 0x68150a94, 0x8c4c6f94, -0x7f8df250, 0x3868ec54, 0xa348cbf3, 0xc21d3309, -0x508faf0b, 0x28c79e4b, 0x58b8fc81, 0xcb48bb6f, -0xc6cd8902, 0x1d2cf518, 0xec6aaa16, 0xf1316d7c, -0x4273eeb2, 0x5a462ecd, 0x07ebf2d3, 0xc9f5c520, -0x19bef211, 0x53565c26, 0xd9ca82c1, 0x9ccc7fc8, -0xed95ba5a, 0xf8d230f7, 0x252ab660, 0xd989b511, -0xc21ad1a4, 0xf84355df, 0x36254582, 0x339144ba, -0xc04208c8, 0x20372e18, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 2963-M01106C2217.inc */ -0x00000001, 0x00000217, 0x04102009, 0x000106c2, -0xd987bc76, 0x00000001, 0x00000001, 0x000013d0, -0x00001400, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000217, -0x00000035, 0x000b01c0, 0x20090410, 0x00000401, -0x00000001, 0x000106c2, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x09f89a9c, 0xce7faed5, 0x3c508f50, 0x462d2e35, -0xdc20f762, 0x55ff2ae4, 0x88a57956, 0x06ff4465, -0x0882023d, 0x953684cb, 0x0abe06ee, 0xa7ef1798, -0x160d6cb8, 0x930cf745, 0xafc3fd79, 0xa70df3d5, -0xb0620f46, 0x70048a23, 0xbf95ecf0, 0x76c1b997, -0x5128616d, 0xb6b4b969, 0xcc69f71d, 0xdf7416e1, -0xdf9a571b, 0x50c0bcc8, 0x85e2b3cd, 0xc1927532, -0x7a04b6be, 0xe56b7f97, 0x524085c4, 0x668bf327, -0xb3eaa54c, 0xccde06f8, 0x09b4e42b, 0x033b0a46, -0x0f6e2fde, 0xb308ce53, 0x93eff03e, 0x8830014e, -0x5c8a6f22, 0x91d2f757, 0xf70b648d, 0x0789998a, -0xd84d4640, 0xe5f34e80, 0xf3357e64, 0xd1e2beea, -0xc7e95c3a, 0x30e57e4d, 0xec214356, 0x7e10859e, -0x1d5895d5, 0xdeeff6cb, 0xed1030ed, 0x827e603d, -0x6b4b2de3, 0x83ec6fd0, 0xa64092f3, 0x8d9887e4, -0xbefcbedd, 0x2111afef, 0xcb9abf96, 0x5c79ceac, -0x9bf8a57f, 0x5d0e44be, 0xdca3d3b6, 0x9072d1ca, -0x48e73a50, 0x8d0bc804, 0x6aea94d3, 0xc372403e, -0x00000011, 0x14980dd1, 0xff2ade29, 0x768a5b1f, -0x18ac6d5c, 0x455e0e87, 0x46ae1737, 0xce517cb9, -0x020473ae, 0xa299d2a8, 0x69756da6, 0xfed24465, -0x7e627d60, 0xd6c18c2d, 0x8409165c, 0x67d65a36, -0x0a898865, 0x79035444, 0x8fac97be, 0xfbced0a1, -0x5562edf6, 0xd683c850, 0x54cb0839, 0x47929e06, -0x4d6bd42c, 0xd2cc07ef, 0xe1869b9d, 0xae55ba8a, -0x02b186cc, 0x801d2a57, 0x23162402, 0x1c7cde17, -0x497bb85e, 0x090606ad, 0x8d7775eb, 0x1bc5e744, -0x11371ceb, 0x4f5a7aeb, 0x382daf5f, 0x1a3970c0, -0x172f30b0, 0xc5ed2811, 0x603ef865, 0x1a4ff210, -0x81287299, 0xbdf9d9ce, 0x03577eba, 0x75fa0e3a, -0xc7778697, 0x4664ef64, 0xb30891ab, 0x27409db5, -0xa2feff2f, 0xf7638682, 0x901e1696, 0x61625662, -0xa9f71db5, 0x8475fef8, 0x957a55b0, 0x0507639c, -0x3521a161, 0x57bc69ac, 0x93abc8df, 0xc7df8cff, -0x776dc361, 0x4934e712, 0xd4581201, 0xf4b337a5, -0x99cf4723, 0x8b2715a8, 0x487247bf, 0x6dfdb286, -0x453a53fd, 0x88e17774, 0xe6f61002, 0xfe891e3b, -0x0620cfee, 0x6bcc8052, 0x11207184, 0x125a5356, -0x646c1884, 0x2601a0f1, 0x3a84e550, 0xb813fff6, -0x2e66a034, 0xb5f968cc, 0xbf2b77bd, 0x65cb3af5, -0x289a52ef, 0x1aff1abd, 0x503b9072, 0xc07e41ff, -0x78087713, 0xa77e5425, 0x92e4f600, 0xf424b361, -0x562bb01f, 0x78208ba1, 0xc0118f85, 0xb9620c7f, -0x88aeee9d, 0x237c6911, 0x2038db7c, 0x35957f1d, -0x451ba202, 0x4acfd66a, 0xe04da877, 0xefd37108, -0xdbb01e2b, 0xe3ff9aa8, 0xca7860f0, 0xd95d9fa3, -0xe8a0f1e8, 0xba2e7831, 0x9a1aa2a2, 0x5535a65d, -0x27879bd9, 0xaa9d8570, 0x262ae91d, 0x476739cb, -0x3b1f8d94, 0x2ce39fcd, 0xe1f64118, 0x5cc602e6, -0x8a3c6e50, 0xe733c2e5, 0x58cf0ed4, 0x23842b39, -0xcba6e922, 0xa88779eb, 0x5f45a57f, 0x3398ff7d, -0x1c30ac9a, 0xb0d4a170, 0x1ba9b1ac, 0x4123dec5, -0xe43463a2, 0xf13e7515, 0x6d8fce05, 0xcd499819, -0xd91c60c2, 0x68086ab9, 0xdd3a01ad, 0x91336c64, -0x3bf42ed6, 0xdef60794, 0x3506f8ad, 0x4099cac8, -0xc4ad9796, 0x3347943f, 0x7b03e9b9, 0xcdb458e8, -0xf50997ea, 0xddd26aee, 0x0c8434b7, 0xfa0126ad, -0xc7902e08, 0xd6df491f, 0x168a82f3, 0xd4bcd3de, -0x23dee535, 0x1eae8e13, 0x088fe4e1, 0x661b94c5, -0x3551d689, 0x3d913667, 0xa2cd75bb, 0xcea61a1c, -0xb987bdb6, 0xea1b1df2, 0x2754a729, 0xc487f029, -0x58ba9638, 0x467f332a, 0x11336475, 0xb9b26485, -0xdc4fd47d, 0x8c265433, 0xb862dbce, 0x6c3eac27, -0xa7be9cd1, 0x9f0b9d29, 0x1f16f518, 0x71234b1b, -0x728fe49a, 0x8e31bfc0, 0x4e0beeed, 0xe69e32e6, -0xdda0bde8, 0x045910b6, 0xde786f8c, 0x496cda76, -0x95476c8a, 0x8ada681a, 0xb94cccc9, 0xf9dffcd1, -0x442004a4, 0xfd5d9ae4, 0xd1bb286e, 0x35471fb7, -0xcc4aa935, 0xefa0a0e1, 0x870e142c, 0x8b836771, -0x065a0efe, 0xc41adbe9, 0xc0d2a66f, 0x7c4a0b23, -0xf86ca243, 0x045dc285, 0xce19da1c, 0xf6142343, -0xb8d5f1ef, 0x038bfa44, 0x17591c11, 0x98002db2, -0xe15409c2, 0xb4044cae, 0x4da885ce, 0xeaeb5810, -0x62e54ee5, 0x41879946, 0x721cbd0f, 0x6edff1ad, -0x721ae394, 0x90f7b14e, 0xe1b6ed04, 0x96460c22, -0xc3249764, 0xb1ed84d7, 0x9d4267a4, 0x98dadb19, -0x3671dde2, 0x33bb9671, 0x3f5de8b7, 0x5d486e43, -0x19b2c92d, 0x5118290c, 0x18e6fd5d, 0x11e859c8, -0x7f26e5a7, 0xacae907a, 0x157d46ad, 0xdd7e80d5, -0xad7c15ec, 0x416c0e4e, 0xd7c8fa0f, 0xb3e61dc5, -0xc957ecc8, 0x3ce4ce22, 0xa1716ca1, 0x32293474, -0x71464f7c, 0xcf87342b, 0x9b991153, 0xb4cfd21a, -0xfe1f2848, 0x25727966, 0x72b48d58, 0xe80e38f6, -0x3a8eb709, 0xe93983d0, 0x39a98bd2, 0x955afc9b, -0xbb4d95a2, 0x5ea1c16c, 0x2dca4b6c, 0xe1841464, -0xf29b6834, 0x0898d1b1, 0x3cbf6824, 0x332036a9, -0xd2045fce, 0xceb43c07, 0x7ddd72e7, 0xd8495f8e, -0xd62595df, 0x1f48a356, 0x3c810c08, 0xa8b18be3, -0x40aa0d34, 0xe1c6da7b, 0xa0c63ca0, 0xa3978b77, -0x08346409, 0xc7c879d5, 0xe4533936, 0x6e469855, -0xb5e92af7, 0xab14fcf6, 0xbb9d581e, 0x1ade2f8d, -0xd87bafa7, 0x4f23ff92, 0x0c7b1083, 0xfdb31cd0, -0x8668005a, 0x4a3b5d19, 0xa2615960, 0x7c1fcf3c, -0xbc751468, 0xd959dace, 0x3ec35d36, 0x39a2254b, -0xaa59fc84, 0xa848bcc2, 0x4573f9bb, 0xbdb60b61, -0xe3fdaa82, 0x2b33ca86, 0x761b49e9, 0x7794b324, -0xc000cc24, 0x1e8fb5bc, 0x103b6e35, 0x2a38365e, -0xe0c618a0, 0x6a073c0b, 0x7e8f601e, 0x5a09e07b, -0x7d40e359, 0xa21e6187, 0x2e78217c, 0x41a9872a, -0x8b77e812, 0x6d5b951e, 0xa3b9e595, 0x74a50d79, -0x316461a2, 0x62f97340, 0x3e3d072c, 0xb6254c73, -0xdd88bcc6, 0x7037a3be, 0xd456b2d3, 0xa721fe50, -0x43a33949, 0x3645fa38, 0x9dc6dcd3, 0x377c04b2, -0x9b89649f, 0xdab2ca19, 0x9b4ef5bb, 0x2e2ca48f, -0x4feb859d, 0x2c6b42fe, 0x087f84a2, 0xf17ba799, -0xb37b0a19, 0x8ed04361, 0x188a1f73, 0x5185d421, -0x3129ac67, 0x94116de3, 0x607820ba, 0x76a1a9ff, -0x6808755e, 0xf2e508da, 0x6bca967b, 0xbc3a7b70, -0x769b9d11, 0xe925e390, 0xe26e3039, 0x220a75c6, -0x334eff5f, 0x55624cbd, 0x5c2e9f3b, 0x64cab7cf, -0x84c65fb7, 0x5ad7a323, 0x6f3c9efd, 0xee96b7cb, -0x6bb73a9c, 0x4604624e, 0x0e2473ae, 0x2aea52e0, -0xf3b8abea, 0xc5aed750, 0xb7763e2e, 0x4a766d95, -0x1d52e854, 0x22b32f4b, 0xe17119cc, 0x0608ecb3, -0x23f3cf11, 0x12259854, 0xaf57c24c, 0x36a3eb84, -0x9f5919a6, 0x1136d736, 0x547c8a00, 0x9915aab7, -0x0682f3f5, 0x3cb9a6d9, 0x5696fe64, 0x7a01e206, -0xdad7dfd5, 0x4b8478cc, 0xfffbef84, 0xafab5584, -0x754ac2fe, 0x110f52e8, 0x1cf6a7e8, 0x80266a8b, -0x0711c4d9, 0x66086a99, 0x42a9e502, 0x149355a8, -0x00b487d5, 0xf7321320, 0x87b56421, 0x5f7873bb, -0x00536403, 0xfc3d0487, 0x5d8dba88, 0x6d5dfedc, -0xfa65f000, 0x0a5b14b8, 0x2df04874, 0x13183539, -0x4737d8b1, 0xf4172265, 0x844ee0ad, 0xc9b413b0, -0x9316b83c, 0xbb018c85, 0xc078bab6, 0x24fb2bf7, -0x733611d7, 0x66a4d719, 0xb8f0426a, 0x638ac2d0, -0xf907257c, 0x292bd026, 0xc9bd1b1e, 0x0a3934a2, -0x0069eb7a, 0xe5fd66f6, 0x63469a35, 0x4ad4eb60, -0x4abe9ffd, 0x1b286736, 0x113f8874, 0x3f9c821e, -0xbce34a08, 0x1400b4e7, 0x578df00f, 0xcb530a93, -0xe442bc4b, 0xbd819631, 0x6ebd2f56, 0xfa3948f1, -0x75065d40, 0x755d1058, 0xa27d9259, 0x861db21f, -0xd6d28943, 0x77522729, 0x63fa2986, 0xa509bc80, -0x8ab9d121, 0xbec0ec56, 0x66a591aa, 0xf26a6e0f, -0x2bcd477f, 0xd3fe7ba0, 0x5988067a, 0xcddf746f, -0x0a4a29e9, 0xcd933731, 0x59cf2422, 0x025781b4, -0x421cb3ab, 0x1799b8c5, 0x21e32df9, 0x4c8dc991, -0xf198b552, 0xc8f23b9d, 0x71d1f473, 0xc8cc0d68, -0xcfe13358, 0xf0544e3b, 0x76c15708, 0xf6373299, -0x9c77318c, 0x500e4421, 0x17299f4f, 0x71165140, -0x4d1e1550, 0xcfcbd28d, 0xa70f96e2, 0x6b8af010, -0x409e14b1, 0x02269fee, 0xb0a3dd80, 0xe6c939fe, -0x8e5b0076, 0xc40ba65d, 0x01f0b8f3, 0x3370e39c, -0x300d639e, 0x0896c55b, 0x5a0f41a7, 0x4d0ddc60, -0x3fa3f82d, 0xbc582569, 0x102f2e2d, 0x3c2a016d, -0x8bb0a47f, 0x7a751edd, 0x458a7b8d, 0x6c3b70da, -0x15900727, 0xcb97fafd, 0xdeb5d4cf, 0xa5659a09, -0x455d6a86, 0x9ec18406, 0xcd6a72af, 0x9831993e, -0x2f18a892, 0xdbc415aa, 0x4b8d3261, 0x57739a68, -0x2cf8702e, 0x70977ca1, 0x80b3caab, 0x806a09e5, -0x1d445591, 0x2ff0092d, 0x8d8fade8, 0x6e1f8806, -0x4a9fcce4, 0x0d73397b, 0xb5b86afb, 0xc8816f25, -0x191b7360, 0x4ac340f9, 0x82e6d123, 0x0f470975, -0x7c304147, 0x7bbb635b, 0x28f8cab6, 0xc109b6c2, -0xb06bbcc3, 0x4ca536ae, 0x3ae30e66, 0x483f6ab2, -0x560ab845, 0xf5289929, 0x45843435, 0x342f826e, -0x172c2cdc, 0x17ec9571, 0x947a4b57, 0x2b1de023, -0xf10ac853, 0x9ffa7c2d, 0xde2ff682, 0x426caa39, -0xcb482471, 0xc36c15ce, 0x04af08bf, 0xb80b1e08, -0x0d01a541, 0x942354c0, 0x4251c668, 0x50ffdf5c, -0xf19096d7, 0x5813c93c, 0x5c6b1107, 0xff86f985, -0x71092390, 0x15aa7c73, 0xcab0715d, 0xc8d9e6cd, -0x828aadef, 0x8fb2db36, 0x2e3d2375, 0x8eb6f9ee, -0x52006fe7, 0x503cc554, 0x41d9c3ee, 0x34f41d9c, -0x6d1d6d0e, 0x0ce78057, 0x091f714e, 0xa49309b0, -0xaa1b9f14, 0x572c2871, 0x974b185c, 0x8e5b5595, -0x61dbb6f8, 0x5ecd681c, 0x2f6d7a0d, 0xd892944e, -0xb6927173, 0x0c0ef47e, 0x70b7396a, 0x8cbc3353, -0x2af3e2b7, 0x53e9688c, 0xdf68696b, 0xc86dc91c, -0x00311bf2, 0xa1760482, 0x72232938, 0x38ee8f77, -0xd53fba4d, 0xabd9ad0a, 0x66168574, 0x017f3e34, -0xdf327344, 0xd6eae249, 0x7b22f8c1, 0xa5b2bc42, -0x969f4cd6, 0x95f5fc6d, 0xfdb7c7fa, 0x112d3ee6, -0xeaf67b74, 0x0a5a6e73, 0x18df20e0, 0x38236a5a, -0x8130a173, 0xcb3b5b7e, 0x35206d1d, 0x5e050e33, -0x8deb6f0d, 0x60ce0dff, 0x07728a31, 0x6f3a04ae, -0x7831b5d6, 0xa4fbd66e, 0x6bd2e736, 0x5c3443fb, -0x7432fdf7, 0x692a74d3, 0x5dce3459, 0xb93de5d1, -0xba81594f, 0x39a8a15b, 0x48e26bf0, 0xcb41f36d, -0x09ddea57, 0x352b3d01, 0x0a12ff41, 0xa86206ac, -0x478e88d2, 0xf0ee2844, 0xe206e58c, 0xbacd48a2, -0x5260a7d0, 0x1dc5fa78, 0xec9fbc75, 0x37ef6350, -0x94f946af, 0x64a06436, 0x5c02f667, 0x14c38a00, -0x26c482ef, 0xef0317fc, 0x5d19eaf9, 0xff738f59, -0x70db8622, 0x6ea24943, 0x00f30923, 0x2e348bfe, -0x2fd943f2, 0x192450d3, 0x6aada8e6, 0xc2d84796, -0x50c96742, 0xb7c47e4d, 0x6b7e869f, 0xffdc3ef5, -0xe6ee5077, 0xff3704f1, 0x985c9e46, 0x1adcd42c, -0x63331397, 0xd12eac83, 0x7795ac6e, 0x30ae7325, -0x1caf85ed, 0x37c2cc82, 0x4f9f0c36, 0xec6ce943, -0x1ba39119, 0x50c55c47, 0xe4ef5731, 0xc0a76ec7, -0x8c85871e, 0xe15213ca, 0x2b1b738e, 0x0e424959, -0xb0573335, 0x040cd859, 0x49776ee0, 0x0b2612f5, -0xfebb32c2, 0xe8be8760, 0xa0138cb1, 0x889e9ca8, -0x2e48ccf1, 0xb45bf39b, 0xe5412271, 0x1b6ef4d5, -0xc282196b, 0xdd0639fa, 0x521c55ae, 0x58b95195, -0x6857a9b9, 0x9f2bbfb9, 0x7c225192, 0x28acb34f, -0x3d3a6f5a, 0x91abfb0c, 0xed76cf8c, 0xd323d447, -0x65d8fe44, 0x876b3183, 0x0334168c, 0x8711195e, -0x1aa1db76, 0xdea97171, 0x89e188d0, 0xd1425753, -0xbdbebe5e, 0xd0fdd27b, 0xde9ba2d5, 0xf25f0953, -0x6f7a5334, 0x239f2b0d, 0xc3249498, 0x0d97b723, -0xef18c9a1, 0xbbc19fde, 0x628b7257, 0x5ea12b66, -0x2bfeedf6, 0x072d6f46, 0x219421c6, 0x8904644d, -0xa06c8bf1, 0x0c15f545, 0xfded658e, 0x7a2f4106, -0x498a95f8, 0x53d6c015, 0x553268be, 0x31069c90, -0xc304dcd3, 0x9c404feb, 0xe77d8958, 0x0f80a1d7, -0xf6c38319, 0xe30bd224, 0x3a1d6495, 0x9878e6a8, -0x4a873482, 0x038ac7d5, 0x198a11c8, 0x40e7dc31, -0x93aba328, 0x7641c2f3, 0xe6086e71, 0xb3897f90, -0x68639089, 0xa6c9d34f, 0x0ebd25e9, 0x8f024790, -0xf33312cd, 0x317fe8c5, 0xf0488ef8, 0x1c5dd332, -0x6c92abfe, 0xd62338bb, 0x74cf66b1, 0xdd56bdbe, -0x7947870d, 0xec8d9f29, 0x06e28ec2, 0x316b1f94, -0x766a4502, 0xd1825c99, 0xaaf9234f, 0x2ea72492, -0xbf4749e6, 0x4e3baa89, 0xa31b81e3, 0x9de5cdf1, -0xc032f0f7, 0xd56bc9cc, 0x52d82ac7, 0xf7138aac, -0x9941380b, 0x8224d67f, 0x2ac8e885, 0x83edb999, -0x58fcf382, 0xd3c8bce4, 0x53886d55, 0xadbe82fe, -0xb21b6a4e, 0x836838aa, 0x71f632fa, 0x3e621403, -0xb9c81a6d, 0xf4e3cfe2, 0xc3032aee, 0x2ffb4713, -0x7ddcc17a, 0xc0349cab, 0xea36e040, 0xa5167672, -0x0cb7499e, 0xc55eb59d, 0xb3a2333a, 0x37edbbe6, -0x7abe8507, 0xf99505e7, 0x09b0aedf, 0xfb1e1387, -0xc118cef6, 0xf109555e, 0xc2b9ac82, 0xe52ef3bf, -0x2be6f4fc, 0x9f6b3390, 0x3e59aec6, 0xc6c8666e, -0x2e016135, 0x695d5c12, 0x405afd84, 0x3f90d859, -0xb0d11081, 0x60e0ecb8, 0x089ea644, 0x28c2c21d, -0xc5c1b3b7, 0xfb14119b, 0x9ad20b9f, 0xae32664c, -0xbca23d54, 0x1a47db36, 0xeec84a67, 0x515536ff, -0x38c245f4, 0x83e0a08a, 0x2229a519, 0xe60d7871, -0xe8ee5179, 0x341602e5, 0x453a15ff, 0x83a55bd3, -0x5513acbb, 0x1657e8a2, 0x8284f814, 0x706684ef, -0x13deb278, 0xbd3c9921, 0xff6a3dc7, 0xa04994a4, -0x19f6d089, 0x7f505d1d, 0xb8b075cd, 0xeb0f3be4, -0x6fc2d4f5, 0x37f5840d, 0x17fad37f, 0x4fe71d23, -0x424fe1f2, 0xad86001b, 0x5645b172, 0x9aaa2d0b, -0x28058255, 0xbe3140e4, 0x97d1e959, 0xdad9a815, -0x2ca7014e, 0xae8a3947, 0xc07ab273, 0x9c215b25, -0xfc9b4f63, 0x649a14a6, 0x40f20730, 0x148387f8, -0x7706de96, 0x6c44784c, 0xdd76ce12, 0xbb421926, -0x62e18378, 0xbfa9e559, 0xd76763fc, 0x3e24de93, -0x20d75b75, 0xf19f0788, 0xc6f7b50e, 0x7d7a3f62, -0x656f60f7, 0xb1068519, 0xe17d0728, 0xb56fcea6, -0x75beee44, 0x7998c910, 0x266d3508, 0xf0a977c7, -0x02866510, 0x21ca1fad, 0x471d3c70, 0x204ba687, -0x9680a3d9, 0x02b818df, 0xac0374c4, 0xe6a48910, -0x0e33d542, 0x677abf13, 0x8d83c3a1, 0x7a2eda35, -0xd40fdebe, 0x6b0b5fbc, 0xecce7918, 0xcd68eae5, -0xdd6a3e0a, 0x05be5f69, 0x5c3990d7, 0x60d3dbc4, -0x3cb5923a, 0x9a8d643e, 0x1711f7b4, 0x9bab6d65, -0x8393d3f0, 0xaadb08f2, 0x075ed3a5, 0x29c34152, -0x935f10a6, 0xef7279a4, 0x63532e9d, 0x26afe572, -0x6dc112e6, 0x47c97684, 0x6eccb9e1, 0x90da8c44, -0x6e04bda3, 0x80f19b22, 0x2196273b, 0x1ee245cb, -0xd55dcf1a, 0xc7cd14d8, 0xf244515b, 0x055aa301, -0x0c9fce9c, 0x755faa4b, 0x96d5a956, 0x259f4a45, -0x430868ac, 0x4b55f57d, 0x829f134a, 0xe139fdbb, -0xe05dcf2a, 0x3bf268ee, 0x904d6baa, 0xe6d8bb7d, -0x1bbeb22b, 0x45db4f3c, 0x960bdd27, 0x4ebba6cc, -0x0bc84549, 0xc17d6bba, 0x9911fe90, 0x462f4ff0, -0xb0108424, 0xbb0e397d, 0xf5285eda, 0x5a7db808, -0xc70b87c5, 0x994cfd51, 0x13eab491, 0x2d4c1489, -0xbec93d95, 0x5e99f60f, 0x3ed154c7, 0xfd6edd85, -0xb2422fb4, 0x4709edce, 0xae51e4f6, 0xf89d18a7, -0x30094d52, 0x63744563, 0x379b69cb, 0xbb8c19d9, -0x7aa2c0cd, 0x16bc4ab3, 0xe1b2e442, 0xbf5e198f, -0x0dd3e057, 0x07c5413a, 0x3a0e9d35, 0xb47307b8, -0x77aa24b9, 0x2fd8fb55, 0x77d80e99, 0xf3f6e93f, -0xff13d117, 0x2a6739bc, 0x5c8908a6, 0x42ced515, -0x253d954f, 0xd06c3da7, 0x4788401a, 0x19b04ccc, -0xca15f3ad, 0x76f1110d, 0x21e1e1de, 0x879233a2, -0x9fb391c3, 0xdd50ff87, 0x9e661729, 0x8cb80e15, -0xa36ddafd, 0xf55f913d, 0xc9b19482, 0x7e097acd, -0x86e47ac3, 0x347f1069, 0x0cf15cac, 0x997cfd01, -0x4e5c32d2, 0x0a4a38c0, 0x955dcfd1, 0x75be3729, -0xed177186, 0x6e6a277e, 0x89caee2c, 0x605f9c12, -0x539bcadc, 0x34abf93d, 0x96c9643f, 0x0f34633d, -0x36fb15c7, 0xfb7bba4b, 0x212585fd, 0x42b1347c, -0xd3ac6ead, 0x164c64e3, 0xddcacd07, 0x186d85d7, -0x117cbeb6, 0xca9c9fab, 0xa568bd38, 0xd60e0da0, -0xb98fa69c, 0x93a6c623, 0x194441b5, 0xe654f1ba, -0xe2a3cad3, 0xe5cf7b3f, 0x1614a3c2, 0x9b078402, -0x52f37d97, 0x187e9dda, 0x00fa2b8d, 0x07ee62d1, -0x5a5ea2bd, 0xb1e6ed54, 0xb1c24a2a, 0xf41fbba1, -0x92d967ec, 0x4df103ed, 0x1d1ddaf4, 0x705c34b7, -0x08330af3, 0xbe45833b, 0xe874998d, 0x1a22a9ce, -0x83ab6702, 0xcf2a6656, 0xc08758bf, 0x74c56ecd, -0x1afd607a, 0x51bf6406, 0xa302d55c, 0x0ac43266, -0xadc985f9, 0xa9ac229d, 0x4aa82f77, 0x3afce1ac, -0xaf8d5c80, 0x217fb5c1, 0x94c92311, 0xaea31486, -0x7788cb41, 0xb61c75c8, 0x062a0888, 0x7609920c, -0x5344faec, 0xdf10b710, 0x8c8673e1, 0xb39462ab, -0xc3a2bb23, 0x16b93eb6, 0x394ff960, 0x8d81ad20, -0x9f9e1fd6, 0x8a70894b, 0xf96c2c50, 0xd8474239, -0x53228736, 0x68540ee3, 0x3cfa5c8c, 0x8cb74254, -0x13b497fa, 0xb537a6fa, 0x1967e5bd, 0xa638ae8a, -0xafbc06bd, 0x72e905b0, 0xaf6b12ad, 0x76b3fe92, -0x90b6100f, 0x23db02cc, 0x859aa5d8, 0xd702fb4d, -0xa39e940a, 0x66c4f206, 0x17bd0770, 0xdc1224e1, -0x1e4e9f1d, 0x79f7cafd, 0x1209e815, 0xe1f6d276, -0x83b1eabb, 0xf3403674, 0x8f01d66f, 0xcfa6007e, -0xdbff7fb5, 0xdec0cd24, 0x357ed4f9, 0x6f17697f, -0xd15622f0, 0xc410ebbe, 0x442c6c05, 0x96f90c65, -0x447b9422, 0xc675767d, 0x6e9f036f, 0xac53aa34, -0xf889e572, 0x322bbdd4, 0xef947e08, 0xb39a0c48, -0x27e05184, 0x4dec6c99, 0x5b351ffe, 0xc22e0ad9, -0x2f89f4cc, 0x353dff3f, 0x8b45b885, 0x224452f9, -0x01f9addd, 0xd535ba80, 0x76b2d5ee, 0xe4a5d1d0, -0xbce3274b, 0xe2b86efe, 0xe4ec7a5b, 0xecd4723d, -0x9167ad13, 0xc6588e4b, 0xb4de5667, 0xbd7780a7, -/* 2336-m106fbB6.inc */ -0x00000001, 0x000000b6, 0x07132007, 0x000006fb, -0x5e5a71a7, 0x00000001, 0x00000010, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x000000b6, -0x00000035, 0x2a000000, 0x20070712, 0x000002f1, -0x00000001, 0x000006fb, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc67566b4, 0x105501ed, 0x8a79141f, 0xd976d998, -0x39025e8d, 0xc8d4def9, 0x136f7e41, 0xd876436e, -0x58d10d9f, 0xb7f2421d, 0xe4d5fcf1, 0x02889a15, -0xad9bed07, 0xa32ab3e6, 0x3491afcc, 0x9c991c37, -0x2a1c2071, 0xf066191a, 0x3bd898e7, 0x2648d958, -0xc05f7908, 0x05864b9b, 0xbe4c1eee, 0x1e6c7ef4, -0x0e7a539e, 0x100b2ab3, 0x1273dceb, 0xfec8847d, -0x8f37946f, 0x634e3b5c, 0x691dbd61, 0xd89e3cb9, -0x094639d4, 0x7d972e1a, 0xd6dbd94d, 0x2001c3ec, -0x34f791f0, 0xeee0d794, 0x88b7459d, 0xc2c73aa3, -0x607a174d, 0x4f0f8304, 0x65790b35, 0x00532bfe, -0x1fd1e0cc, 0x7b91f873, 0x154ed42b, 0x7a7108e9, -0x81637c95, 0x192cb173, 0x28ccd94e, 0xb9bcc372, -0xac05171b, 0x867f47da, 0xf8e8c47d, 0x1edcdb4a, -0xd2ca6c2d, 0xe9ee9169, 0x5a6efedc, 0xb6825038, -0x09277eaa, 0x2a34e580, 0x0f794366, 0x86c99402, -0x211b98bf, 0xdf8eb0e3, 0xda11d7bd, 0xd440363e, -0xa7d49f1a, 0x16dd7395, 0x5b23c2fc, 0xab93ea3c, -0x00000011, 0x8d12ea76, 0xc5c9c349, 0x92308263, -0xf78e4c9d, 0x72c29f88, 0xd19a18ac, 0x1c90e94d, -0xeb8c5d92, 0xf7bb5a98, 0xa62ae1bb, 0x1d37396a, -0x191737e5, 0xe423c9c2, 0x1c16fae4, 0xb95f9692, -0xaeae4fbf, 0xbed4707f, 0x70f70fa6, 0x3e80ad8a, -0x668f54d9, 0xff968f7e, 0xc4e24190, 0x0872ccf0, -0x4fa39955, 0x55a1a6f5, 0xc36d7848, 0xe82e7047, -0x3ea79a72, 0x27411065, 0x55930d6f, 0x8e94ddfa, -0x6008c698, 0xb315b1d6, 0xedee441f, 0xd3875916, -0xd0a76bae, 0x14ef297d, 0x6393320d, 0x69d787dd, -0x7973bdd6, 0x7e5c4c27, 0xdfe61741, 0xc631b12d, -0xcc99b991, 0xbeed1d1b, 0x9b3c5535, 0x78a48b4a, -0xe278d8a2, 0xf1c80ebe, 0x70f3ed4f, 0x4744194c, -0x53503244, 0xf94ab448, 0x04f48675, 0xa91912e6, -0x0fbe4a37, 0x22dd31d7, 0xc7b0cb0d, 0x752eebc1, -0x83141b0c, 0xb59e8702, 0x5efa7721, 0xc8440cd4, -0x94a00db5, 0xfafd13f4, 0x878cc0a0, 0x735a935a, -0x456ae71e, 0x405aa5f4, 0xcb272526, 0xeb85d034, -0x91f58175, 0xbab6094c, 0x48426d3c, 0x18bb5eea, -0xe9ee4304, 0x0868f031, 0x29413b52, 0x29ab13c3, -0x575646eb, 0xb24f2668, 0x142b91b2, 0xfa969908, -0x12b79a91, 0x38bc2ba2, 0x525e5da2, 0xabc63db2, -0x9bce15d9, 0xa2d2a006, 0xa1744c42, 0xf64f876a, -0x4121f17a, 0x0e24d1b5, 0xb27a09dd, 0x2741ca03, -0xd83fe2bc, 0x59a0aeee, 0xe861ab21, 0xb304ca71, -0xb8bc5b2b, 0x1553f2c5, 0x5d078685, 0x3de43e77, -0x8e1f2eb1, 0xa9eb40bc, 0x3bcb1973, 0x4721b5b6, -0x73e23954, 0xa9464b92, 0x82ad836e, 0x56b8a136, -0x4bb95ff6, 0xa538c8aa, 0xe2bf3da3, 0x1347a40a, -0x34f844c2, 0x596ab878, 0xa9f94b32, 0xdad18fd1, -0x6f2fda04, 0x09c10ec7, 0xed4a2d3f, 0x375add96, -0x0ae45688, 0xa594039e, 0x8fdae080, 0x7f3f4a68, -0xef496e17, 0xab450c5e, 0x9a43c59c, 0xf5394c3a, -0xf09dd852, 0xb9b41813, 0x45ed7124, 0xcfe1955c, -0x7e3eedcc, 0xf4603b14, 0x1907131c, 0x5b45ade1, -0x154c8205, 0xcf98affa, 0xfaf58903, 0xa071e600, -0x0814f47e, 0xacd29fff, 0xa9246964, 0x7a638372, -0x3d1061b1, 0xba47647e, 0xd1fbee16, 0x896dd880, -0x1c100f37, 0x99cb8778, 0x48062c08, 0xd0366a79, -0xa6d7ddb8, 0x86c68a9f, 0x02ac6f34, 0x0e144676, -0x20d43c65, 0xcb6a9b99, 0x0e1c9291, 0x9cfd5b8f, -0xac43cbcf, 0x34a7974d, 0xce017104, 0x975c2efc, -0xd55c5dbb, 0x0e16766d, 0x890dfd62, 0x2934622d, -0x709fa149, 0x21a94f12, 0x43113498, 0xb146aa2f, -0xfbbca7ff, 0x1782cec2, 0x9ff3b595, 0xfe4b2b95, -0x0fd2fbd8, 0x1651f923, 0xa74fe4cc, 0xd07a49c0, -0x0d0adba2, 0x9c70bce9, 0x08e8b8d7, 0x32dbe104, -0x6168b74f, 0x7a24fdbe, 0x5e3b2564, 0x6ffe5439, -0x1e7721c4, 0x94af4976, 0x1391cec8, 0xafa04102, -0x79d64355, 0xd88737af, 0xa2f2298f, 0xc980628f, -0x465e2d9b, 0x8b2bfcf2, 0xc46fb4fd, 0xc352c65c, -0xa3064ff7, 0x3b9264da, 0x7427ca4b, 0x41c01632, -0xa2d1ed33, 0x6cca9f3f, 0xf8b67421, 0x305e1584, -0xc9732051, 0x89a0091d, 0xc374e441, 0x587ab4e7, -0x958dd99b, 0x286d9f81, 0x10c67cdd, 0xb85d1783, -0x67b38f42, 0x30b90891, 0x45894054, 0xd050199d, -0x130063b6, 0x7b5e0863, 0x8a61c4d6, 0x2c44fe2e, -0x148428aa, 0xaa587921, 0xf542fe2b, 0x7b7da7e5, -0xed3bd14f, 0xb2616902, 0xc840e668, 0xb2623ee3, -0xbfc63cca, 0xed8b82dd, 0xf7d3cb2e, 0x41eab7ed, -0x8c3bfe0a, 0xd24a3c82, 0xd6d3d9be, 0x3aedf032, -0x957a863f, 0x04d80868, 0x1a59e52b, 0x52ee31fb, -0x8aa7dfa0, 0x2dfb638d, 0x2967e9cd, 0x0aa67bda, -0xd87b2b96, 0xea23ba62, 0xd6c97957, 0xa6f1cc56, -0xac8c9465, 0x3408348f, 0xc82fc701, 0xdf1d0e14, -0x11f617a5, 0x93f4964c, 0xebfae6fb, 0x07f0a028, -0xb40c5b7c, 0x6c0f33f6, 0x854abf0a, 0x89e518d1, -0xfcb70776, 0x1cf65ddc, 0x1dc0ae2e, 0x418ff41d, -0xafbc49f4, 0x064e2e27, 0x35ce2cc0, 0xece5ac9a, -0x7c245d5d, 0xf22af2a7, 0x5a5df3a5, 0xf991e2f4, -0xcd0b15fd, 0x68bd046a, 0xd29d50c6, 0x1e691c01, -0x7a4d3cd5, 0x2f6275da, 0xf1cee3f3, 0x84261101, -0xd32ecfdc, 0xe75fdec2, 0xc02846a8, 0x13f19aa6, -0x3dafe115, 0x2c2b0488, 0xbb9da407, 0x196198eb, -0x897db3b0, 0x58813217, 0x917af6ba, 0xf7fa30ff, -0x277c26a1, 0xde9ffb6a, 0x85eb946a, 0xb9a6295b, -0x3f7f687a, 0x17fef8a5, 0x3af23085, 0x457a11a3, -0x2a73b9a7, 0xedbfd16a, 0xd2e88242, 0x1e3c02e5, -0x0ea74671, 0x1fc9e250, 0x5a313d7d, 0xd5a49528, -0xe749e126, 0xdf0de086, 0x35b60d77, 0x07fb5491, -0xdedda50a, 0x51325ec5, 0x8cef16c0, 0x5dbc5f47, -0x0c02a13e, 0x76604b7c, 0xbfef93fb, 0x3e7f0bf0, -0xd1add7e3, 0xdd6c3a85, 0x6e1e119e, 0x38278895, -0xa8df00b8, 0x19f99ab9, 0x368b3ea6, 0xcde20a8b, -0xf7acd01f, 0xc59c84f9, 0x0a0b6d38, 0x18cb2d96, -0x37544234, 0xc2c89561, 0x603d7483, 0x8049a647, -0x86cee8e1, 0xfab3b928, 0xbf53d180, 0x548aaaef, -0xd0840b5d, 0x56475635, 0xa29f7fea, 0x1db9078e, -0xc29beac4, 0xe34189e0, 0xae65a95a, 0x5ba92288, -0x50152e52, 0x9ce2d6cc, 0x1a602dca, 0x72671a71, -0xde59b037, 0x7adb5fe0, 0xcadf39c4, 0x7110db44, -0x00200eee, 0xf2a574d0, 0x7cc14a56, 0x9b01c7c7, -0x363a0d5b, 0xff8a60e8, 0x34e900dc, 0x567b5d4e, -0x6b52d659, 0x82e22016, 0xd2e6cb9f, 0x611391c9, -0xe99bad01, 0xc6e46ebb, 0x14e29144, 0xb8e85f81, -0xea508116, 0xae7aa3b1, 0x6d535779, 0x673ec856, -0x285dfb55, 0x4671b198, 0x21491515, 0x1fd77e2b, -0x1dfbfa06, 0x442161e9, 0x0dfa5161, 0x9ba818fe, -0x708a8e17, 0xc9754986, 0xeef3ab77, 0x8caa3151, -0xfe6d3b59, 0xcfba71e2, 0x780b6c3f, 0x0fedcdbe, -0xb3dfbdf4, 0xbb0d7953, 0x1d9450d3, 0x58d71d72, -0x09d71b70, 0x679bd3ed, 0xd68bfb24, 0xe93470ed, -0x36b2a64a, 0x6ddb8077, 0xd6968654, 0x29868706, -0x30af7610, 0x0fc9eb07, 0x10690e76, 0xfe62ee78, -0x9ffb3fc6, 0x0c34f0e5, 0xbc01db4f, 0xd4fbb08f, -0x4420b704, 0xa4af88c9, 0x0a3ae196, 0x6af40c74, -0x08d58801, 0x886ba013, 0xd70a4f3e, 0x924c5830, -0x494ee315, 0x90f62676, 0x727c427b, 0x78e0fb4b, -0xf9b4508b, 0xac37411e, 0x8e1f7b36, 0x54778002, -0x00080c22, 0xd55e89e6, 0xef8b0961, 0x43eab9ab, -0x98e8e142, 0x9ef7eb71, 0xb1b0a6f8, 0xb259fec7, -0xd04d9f7f, 0x873a79fc, 0x6dff58bb, 0x7747a1ef, -0xef25d604, 0x21eb7b76, 0xee7cf400, 0x11056351, -0x57ecdffe, 0xfe939145, 0xf52794bb, 0x55917634, -0x9fb4d599, 0x5bf73f5e, 0x11382735, 0xc6cba6b8, -0x3ce059fe, 0x88f1bfbf, 0x4ed5941f, 0x9009764a, -0xf9c7f463, 0x0f28df41, 0x8cad66cf, 0x3ea7591c, -0x6707c286, 0xd47cb952, 0xf53392e2, 0x94e1a29e, -0xd4fb88f4, 0xa5fcaf93, 0xf5ba3444, 0x91249b70, -0x0bbeb5c9, 0xf943bfe9, 0x92629f51, 0xbc10d3f6, -0x9564f091, 0xad4bb29e, 0x0a50af33, 0xe8f79296, -0x8bf25c64, 0x81bdf02b, 0xec22d493, 0x0d2efea1, -0x52e2a6cf, 0xd412701d, 0xa17df71c, 0xb9f62247, -0x4d7b517a, 0xa9bd93a0, 0x94fb1eaa, 0x2d4bc7fb, -0xcd857966, 0xaf4953b6, 0xf664d4a2, 0xf1e12279, -0x1827aa2d, 0x6db71721, 0x28159f88, 0x9df25ab6, -0xa97443a9, 0x378b6644, 0x6ceebaef, 0x0e01e9fa, -0x048cf8b0, 0x962c3d48, 0x2d375c33, 0x407593a6, -0x693e2d8a, 0x9d5a557c, 0x44863ad9, 0x6ab3e26e, -0x3ec52d9f, 0x0933fed7, 0xa7b06032, 0x266f3a2f, -0x02575fdc, 0x2224ba45, 0x71c02d29, 0x1b08c7d1, -0x8b2200cb, 0xfc1c9a92, 0xbddc0508, 0xf3220cb2, -0xcf373ecb, 0x0dce00e9, 0x59e970e7, 0x0bd36624, -0xbbd1ce75, 0xa8641ec8, 0x06937187, 0xc3f2d380, -0x8a7adc67, 0x79f67552, 0x7fdf88a5, 0xb6941a6e, -0x0aafe9d5, 0x1d86eab7, 0x9240d112, 0xca6c7aac, -0x6ebaa150, 0xbba6c64f, 0xf20ec41c, 0x14a3c3fd, -0x8e3db21b, 0x66ad6654, 0xd339f5e1, 0x749714f2, -0xb22ba620, 0x9f4f0119, 0x3745aaec, 0x5ba03b86, -0x10bb4d86, 0x96309fe1, 0xf93c8620, 0x901c3170, -0x3224e497, 0x453639b7, 0xc8cb8101, 0x860a60c7, -0x10a69fae, 0x5cd0cf62, 0xf0c9fe79, 0x49b7f0b5, -0x89c719bf, 0x8caf497a, 0xca747cd6, 0x4a0cfabc, -0xb2f2cc33, 0x2768703f, 0x89e7e499, 0x44dd965b, -0xf7a772d7, 0xdd508108, 0x8a43b845, 0xba5a74e5, -0x6ca47c79, 0x72b9e0bc, 0x9479ce84, 0x3342f0b1, -0x9a39e2c0, 0x57808b69, 0x288ff4b6, 0xe5fab877, -0xed07f654, 0x0ee79da9, 0x02e7b183, 0x456fdb53, -0x11aeeb6c, 0x8c2fadb9, 0x67f79309, 0x2f97a264, -0x02af0d27, 0xf07f9608, 0xb66fd12c, 0x25e6bbc7, -0x92001908, 0xc52170a0, 0xc9fa7f41, 0xbf361c71, -0x33cd7f76, 0x776f9b61, 0x459cdfe1, 0x065dbdb5, -0x67a6f1d1, 0xcbbee73d, 0x2f7b516c, 0x1fda5e43, -0xeba7d6ab, 0x337c3557, 0x1f2477f5, 0xeec7d493, -0x749fa13a, 0x3c37e01d, 0xa78babcf, 0x9ee438d4, -0xaa57066a, 0x9efe96c5, 0x8d45bd8b, 0xbc36930b, -0xfbf60974, 0xdbb7844b, 0x44001279, 0x14e036b9, -0xb524f4a6, 0xad1cee3d, 0x351aca37, 0x22861da8, -0x0648f10b, 0x394078f1, 0x4287ef8c, 0x5c52b8a2, -0xaa345739, 0x959a7de2, 0xb1cd8059, 0x29b3e4f9, -0x3ee210dd, 0x7a4e3104, 0x7e6ccae0, 0xb6d003d5, -0xfda934b3, 0x0e0a48d0, 0xd4109873, 0x2812c616, -0x635c5c94, 0xe3f9d4ac, 0xf0a6aaca, 0x7541e3f6, -0x3fc3b0c4, 0x49fb84e3, 0x710f44de, 0x7557e168, -0xa524128c, 0xb4ca4c26, 0x473e043d, 0x00d2821f, -0x39bc0871, 0xc0f825f8, 0xa22a8627, 0xe13c2de4, -0x2fec6683, 0xfe2b7af7, 0x23eb8e5b, 0x4e0e6e44, -0x0308ab02, 0xa228df71, 0xff5cec44, 0xacdcfbaa, -0x92c6c3e6, 0x68e4150d, 0x11087f00, 0xabdc3bd4, -0xb8dd26da, 0x18627343, 0x5ce82e6d, 0x11c05a6f, -0x8a609a73, 0x3bb8d2fb, 0x5aa4eb39, 0xf89751d7, -0xd2259651, 0x342d297f, 0xe4ab916a, 0x1c96d759, -0x42b26d03, 0x51771d78, 0xef2f8396, 0x9e7e7379, -0x6a28bb1f, 0x03155776, 0xb07e87e8, 0x53e37e86, -0x24c0874f, 0xe92c4b2c, 0x196392c2, 0xdd1208c6, -0x7c84ce52, 0xbd0babaf, 0xf2485778, 0xd8a2b514, -0x5f1c6f73, 0x88b4b082, 0x276e2be0, 0xf6589d80, -0xde140abb, 0x58a6d091, 0x0e42a6e1, 0xc972b503, -0x3c26a09a, 0xb266a0be, 0x94649d3b, 0x41115c79, -0xa0b7dbd2, 0x721acb50, 0xd7bf8b36, 0xc7f9f7cb, -0x74d852f8, 0x8528edb8, 0x77e2cc4e, 0x2ddd65da, -0x74ef8037, 0xe48969b2, 0x330e8588, 0xb633554d, -0x609d1eec, 0xc4bd5986, 0xf8129f98, 0x05ec27b8, -0x03ecbe2d, 0x2bcbaebc, 0xc2c47373, 0x12894413, -0x44754eda, 0xd3e34546, 0x1333bd0a, 0x124ef238, -0x8844e192, 0x0b55645f, 0xa4d57aa5, 0x2a868d45, -0x2a23afbd, 0xfa7355bd, 0xf5119cd0, 0xbb01cac3, -0x78667085, 0xd4aaa465, 0xda92200c, 0x72c6aa69, -0x7ee61a47, 0xdb5e8a13, 0x486b9ad5, 0x1a3e1497, -0xe484d83d, 0x8c01e389, 0xe71a32a6, 0x8eccec7b, -0xa5cc579d, 0x337431be, 0x89a1bfb2, 0x93dd4f6e, -0xd5417607, 0x3d321435, 0x4fbddc50, 0xcedb04ff, -0xf6a2ae51, 0x60bdcdef, 0x97e70b67, 0x0fbdc596, -0xa08d5b80, 0x05c8368b, 0x524819f2, 0x98e5708f, -0x1dd76543, 0x92f36601, 0xbacd9ed4, 0xa97f5533, -0x8f5aa949, 0x3fe4aaf4, 0x96a9280c, 0xadbb7c35, -0xb8f83f0f, 0xcc5a1f8a, 0x89752caf, 0xcd4c2e1e, -0x77d78e44, 0xb1aa165b, 0x67a987b4, 0xc23319c9, -0x16e8293e, 0x2cf911f0, 0x7bf83540, 0x61c5dcf3, -0xbd28d091, 0xea696427, 0xb06937e0, 0xe11eceff, -0xa69f2a87, 0xba41c16a, 0x8991d3b0, 0x5a15df6c, -0x5aa35438, 0xcb880a2f, 0x564f7cb7, 0x47cdc8e6, -0xe2e1a3ca, 0x3eed6e0c, 0x4b3e4200, 0x6a2bb79a, -0x425dd2e9, 0x5c3a0b34, 0xecbafc25, 0x5c2981c0, -0xead1c8c3, 0xc36e7dea, 0x9dfa32b9, 0x75cdfe6f, -0x29455323, 0xbaeb62df, 0xcf102c9f, 0xeccb75d3, -0x777f06a3, 0x10cda97b, 0xcc6c2ee1, 0xcb235b39, -0xcf8e7cdd, 0x01920c9a, 0x64b640a5, 0x4fa59fb4, -0x7425d18d, 0xc3eca5e4, 0x30997afa, 0x0abf8b3d, -0x7b10acf7, 0xd9729dfb, 0xc86419e7, 0xfc13aa07, -0xf1f6f7b2, 0x02a16930, 0x87dab49d, 0xcd2e2863, -0xf5222ad9, 0x13b4aa81, 0x2c7ac35e, 0xa96174ed, -0x766e67d9, 0xb2c19936, 0xa709bf29, 0x00e6b0f5, -0x832c1292, 0x6c3b45bf, 0xa09862c4, 0x8b734d08, -0x7531434d, 0x50f5810f, 0x5bd87aa6, 0x5475296b, -0xece2de76, 0xaad31105, 0xcb831e28, 0xb9fe36c6, -0xc183a0cb, 0xe8f968da, 0x2a41f474, 0x8aa7cc1c, -0xc43a68c3, 0xf8fc3386, 0x5f3301a6, 0xf7632604, -0x128436cd, 0xd16f3ce5, 0x667b508e, 0xbf5756f8, -0x8e0e3a42, 0x6cbcd0de, 0xbe5fedf4, 0x9b83de71, -0x937bd7a4, 0xe871eeb9, 0x6e5e611e, 0x6b29d325, -0x69fcccb7, 0x976b9570, 0xe896873e, 0x9d941355, -0xd726628f, 0x69776f84, 0x94e7b692, 0x9100e226, -0x92fb2e7b, 0x7c884944, 0x2479baae, 0xd13fab34, -0x9c8a6f04, 0x75b25e71, 0x2ccc54c8, 0x3d819a0a, -0x45043845, 0x5ff7efe1, 0x63bbeaf5, 0x28b57d96, -0x6c8f5378, 0x788400a8, 0xbafbb398, 0x246dfae2, -0x074495d9, 0x9f51fe8a, 0xb9026bde, 0xe3b2e2de, -0x2a4443b1, 0x6075ab0b, 0x3a4372eb, 0xedd7b9fd, -/* 2385-m806fa94.inc */ -0x00000001, 0x00000094, 0x09242007, 0x000006fa, -0x613bce61, 0x00000001, 0x00000080, 0x00000fd0, -0x00001000, 0x00000000, 0x00000000, 0x00000000, -0x92fd47ce, 0x10f09cd9, 0x8f9ef677, 0x6971cee1, -0xe3760388, 0x28b9f57f, 0xcbfd3d2e, 0x36755a57, -0x58a60a7a, 0x7284d969, 0x79a702f0, 0x66b3e382, -0xea218360, 0x3841f678, 0x884c32db, 0x1ec43072, -0x1e50452c, 0x6d6a79cf, 0x0607d723, 0x0a64a857, -0x2dbdc8c6, 0xdb12f63c, 0x2b9e534e, 0x41aac030, -0x5c4c58f5, 0xd77024bf, 0xfd24ef64, 0xe8bd51f9, -0xbbb3f061, 0xb1f936ff, 0x8bb07ba2, 0x537b0047, -0x199b65bd, 0xb3eca4a1, 0xcec8e142, 0xb9579b80, -0xaba924ab, 0xb7d53ba4, 0xd7ea5293, 0x2a50d735, -0x2452b188, 0xf03b3147, 0x7db5121e, 0xb2358d51, -0xc805c765, 0x865df5e7, 0x6d40f06b, 0xc761c4e8, -0x387dd0f0, 0xbc80eeb9, 0xe92c426b, 0x65cbc9b4, -0x9538d4b4, 0x63cc487f, 0xb760f820, 0x3b86ffef, -0xb1bd1ea5, 0xb12722fa, 0xb732adf2, 0xf421f446, -0xb18e4b57, 0xc95fa70c, 0x4730564f, 0xa921f11a, -0x99ab37d6, 0x4ce60951, 0xa6bd8a42, 0x61a14da7, -0x911105b5, 0x85948731, 0xd3041116, 0x068e5f6c, -0xa4f578ca, 0x508a653f, 0xf0c8ea8d, 0x74316838, -0xabfd3b0c, 0xa3f920d9, 0x5db364b9, 0x27dd1bf9, -0x06fefafa, 0x67811b14, 0x2643808b, 0x204a1032, -0x04d612a1, 0xdf10cd23, 0x8f0120a0, 0x1d2b7701, -0xee14f361, 0xd674c8b4, 0xc988792d, 0x74212138, -0xe540eb5a, 0xddd1a51b, 0xaf84b94e, 0x2143f7a2, -0x61e0f85f, 0x0633b153, 0xd5309996, 0x5533cd51, -0x4cbab2b6, 0x17b8b40b, 0x25bac4d5, 0x1f2275d3, -0xa1ac6d36, 0x4d92597f, 0x466f4b8b, 0xfdf126f2, -0x531a5d7a, 0xd6d4a487, 0xdb0d238c, 0x61f18b1c, -0x97a67f6a, 0x29924f9d, 0x27427d0d, 0x0d1eb39a, -0x2b1103c6, 0x99685f83, 0xf4cb8fb6, 0x97bca469, -0x20898983, 0x5bf74bb7, 0xa77c3cdd, 0x50be1e9f, -0xab69aa20, 0x55d76e56, 0x150aff1c, 0x29e2b7c0, -0x26aee693, 0xe744ef2d, 0xa38f0735, 0x7d4c6a8f, -0xc65e7fb5, 0x236ba91e, 0xb8cf1be7, 0xcc8b0bfb, -0x22da2b34, 0x3be52646, 0x73b86c2b, 0x920cc665, -0x94b61a5b, 0x97786dc5, 0x1a8912b4, 0x38a58e22, -0xcb5183c9, 0xdb977a8c, 0x7f122780, 0x9a657d7f, -0x8dbaa672, 0xe712cdf2, 0xc386869b, 0xc4211433, -0xf8a4588f, 0x39ad86bf, 0x2e50779b, 0x9a7c794c, -0x0df1f0b9, 0xd0159ee0, 0x5992f6c2, 0x951e6022, -0x41bd2401, 0xc961687e, 0x855326e6, 0xfccc4c2a, -0x0087bc35, 0xce5e122f, 0xf74d48e8, 0x6675c151, -0x8398d4a5, 0x9de7b65c, 0x9801dcd2, 0x3ce8da22, -0xa5840674, 0x234cc202, 0x108dd897, 0x1fa992db, -0x85d4f4cb, 0xbbd8b6f3, 0xaf2fe163, 0xb21a3d04, -0x1490c4eb, 0xe3ef4ef9, 0xeadfc144, 0xaaac2565, -0xce4659fd, 0x3cb70a0b, 0xc3b4b043, 0xf54129a6, -0x8349a551, 0xd18e753a, 0x526145e0, 0xdec9f03f, -0x73db07ea, 0x6e2c5618, 0x8989eb82, 0x9367c1c8, -0xd84f7e3c, 0x9ee11292, 0x5bf7ff68, 0xc654ada8, -0xbcaa8dd3, 0xb5aae79c, 0x67e00306, 0x8f76b1f1, -0x059b6e20, 0xca613e5f, 0xadc0d38e, 0xd74aa7c9, -0x88f51b72, 0x6fb62bc6, 0xb2c0b60e, 0x153e4ea1, -0xebfe87db, 0x35340df5, 0x6bf5bf7e, 0x714da776, -0x26795988, 0x214a3bce, 0x0602f74b, 0xccd2cee0, -0x77e60679, 0x496fc72c, 0xc6c902c2, 0x1f2efe4f, -0xb4f79c94, 0xc41afbdf, 0xb6d46516, 0xfebac219, -0x2cc57e9e, 0xdc23d815, 0x30cfaa54, 0xb2274ada, -0x4bc6454c, 0xe68a34e9, 0x7ec93dfa, 0xc025c478, -0xf8325907, 0x5c675d83, 0xf470fa06, 0xa523d410, -0x3221f28d, 0x0572f5d0, 0x70f94306, 0x8534bea9, -0x216d7668, 0xb0eb1431, 0x82009673, 0x464a3046, -0xf7e1e01a, 0xb5e59acb, 0x05acf463, 0xb6c1faf4, -0xf159ece1, 0x04a8c883, 0x099cce7b, 0xdfaaf89c, -0x454e03ad, 0x7c92c35f, 0x4b030844, 0x77d8a4c9, -0x146aa969, 0xd268c376, 0x46c04f6e, 0xa7d3f2c2, -0x6bee2732, 0x98b1d762, 0x9c5de9e7, 0xf4a1da1f, -0x578d91f1, 0x1e305651, 0xd54e7356, 0xfdce2bce, -0x07958e20, 0xc33fe30e, 0x26f4a5a7, 0x7216e316, -0xcbdefb6a, 0x4b08e63e, 0xad7a149e, 0x8917c4a3, -0x0366c10b, 0xd7ce39a5, 0x0a815df9, 0x16ed6b13, -0x7d669780, 0x21b0d9e0, 0x2f79076d, 0x9e8f2ee3, -0x654dcc28, 0x81377390, 0x22d0b924, 0x156a6296, -0xa0fcfe27, 0x3059f827, 0x99964303, 0x8934a4dd, -0xb4468baf, 0xba359157, 0xc0a61a90, 0xf4556666, -0x608a8297, 0xad441862, 0xb9c1702d, 0x8145dba5, -0x0f254115, 0x59a4b412, 0x8fc5c7a5, 0xeb4ccdaa, -0x73e90452, 0x9972be3c, 0xefb39d2d, 0x2521bdb9, -0xf8887014, 0x57fa05c3, 0x0730eadf, 0x5fbc0238, -0xbe97cdf3, 0xad6e7d72, 0xd0806a54, 0xcb39a4f7, -0xf75f9e1a, 0xa6b74bbd, 0x094051fd, 0x23ffb160, -0xc9fd9613, 0x4a3be12c, 0x65809263, 0x101d6a29, -0x3afc2485, 0x92ed66e5, 0x51ba582f, 0xef4f96ac, -0x4a6d1e4d, 0x4be612f1, 0xb4081a08, 0x848faf38, -0x0c35ca45, 0x0f9eeb04, 0xedd783ea, 0x7e1024eb, -0xd195dc4b, 0xf7b117cf, 0x4d362f21, 0x1a6cbc8b, -0xcb2df2f5, 0x730e6926, 0x2d2981cf, 0xf8a8bdcc, -0x96f35d56, 0x7f8759cb, 0x058621aa, 0xdb5237d7, -0x817f6446, 0x482202d2, 0xbc9dec06, 0xd481dda8, -0xdf9f0d2e, 0x596a296f, 0x1e393fac, 0x145dc600, -0xe38ccfde, 0xd80ce87d, 0x96b20bc0, 0x3350fd25, -0xa64215f5, 0x8c0525c8, 0xb462e6f4, 0xbcacdc94, -0x307abda3, 0xd00abb6f, 0x323859ea, 0xe331bd4e, -0x84c0d3e2, 0x6c3d63b8, 0xe3c0eea7, 0x33d6ce95, -0x5394e077, 0xf2050ebb, 0x9aaaf4c0, 0xc2c5d983, -0xc18af803, 0xd23701c5, 0x360244a1, 0x440fcbae, -0x55f25bcd, 0xff067fdc, 0xe674bc4b, 0xf5b22262, -0x7c8d0af3, 0x54b5cdb5, 0x8c2a9bc3, 0x16566ffb, -0x94a90e84, 0x9e1baf54, 0x4678e1a3, 0x22513f0a, -0x29a77692, 0x770025d2, 0x82bdcb61, 0xad9a632e, -0x59b727e4, 0xe9a02367, 0x4bdb418c, 0x3bf1edbe, -0xd6944e95, 0x451620be, 0x5bc342e4, 0x5e2d1a55, -0xf579eee3, 0x8e0a2861, 0x4b23da56, 0x7b9fde42, -0x34d9b2e7, 0x215f2be9, 0x6147f427, 0x71a9dde2, -0xaeaf26bf, 0x8679c6c1, 0x1ceeefc4, 0x5443db62, -0x8b8e0ec2, 0xb2b1fbb2, 0x64b541a3, 0x41e134d1, -0xfa1cda7f, 0x8f6496d7, 0x3c0d9866, 0xbb9a82cb, -0x37196a18, 0x3e181a89, 0xf0ef7f72, 0x5a664ee6, -0x5de26b20, 0x93fd754e, 0x5f4ae628, 0x9392b256, -0xdf0473a1, 0x72d6f8b7, 0x3fb33bcd, 0xa02785d6, -0xfb87096c, 0xb83dc5cd, 0x2467e913, 0x72e3c483, -0x8d277e1e, 0x16e5aaf2, 0xa371a484, 0x3dad20ac, -0xaa7e663f, 0x1e137ed1, 0x74a64067, 0xd538061b, -0x8b459ac5, 0x0ac1184d, 0xa85593db, 0x41c784e6, -0x2a31cfc0, 0x01ff3cea, 0x5c1545d2, 0x67116668, -0xfb6873e1, 0x20270ecc, 0x54413eef, 0x8e0bdf48, -0xc66c4bcc, 0x637840fd, 0x59deef08, 0xd1c1a3a7, -0xd86e63c5, 0xf2e5c27d, 0x8b6b1f8d, 0xb2bc73c7, -0x08c4aef0, 0x322ada3b, 0xf80ceb06, 0x421bc458, -0x17f16c07, 0xcf4171e3, 0x0940f2d5, 0x2b4790e0, -0xf0fac17e, 0xeb3000d3, 0x1e558c89, 0xa83c6fcf, -0x9f46e782, 0x69de7aa8, 0x73994547, 0xa0f18c30, -0x38c732b1, 0xd8cc513f, 0x7d5d1fd5, 0x00d15590, -0xf1d9e3a6, 0x4ec06f1a, 0xb4fd51ac, 0x4a4cba99, -0x8ac784fb, 0xa739a497, 0xc1d77735, 0x1a0bfe2b, -0x48282cfc, 0x53a95951, 0xad1e7438, 0x86fed107, -0x4927ca7f, 0x9e9b01f1, 0x8e1e028f, 0xad723b15, -0x2c18e064, 0x379f9f7c, 0xa2b52daa, 0xbe4394d4, -0x39c1b8fd, 0xcd2bce50, 0x98a3868b, 0x9d5f399c, -0xf3d67313, 0xf4098bfa, 0x44a9cffb, 0xbed84b99, -0x6772284a, 0x5913cd34, 0x56cdb402, 0x97c2a711, -0x960a393f, 0x831626e9, 0xc45f7819, 0x74117fa9, -0xb686cdeb, 0x822f5929, 0x5b2e5dbe, 0xdd6cf03a, -0x0af92686, 0x8116f734, 0x8b6443c7, 0x7c7e5b51, -0x8d6b25ed, 0x6f849ba4, 0xabc52549, 0x292936c9, -0x23345631, 0x3ec1139a, 0x1f455ceb, 0x8b471929, -0x54ba89ea, 0x447cf2ba, 0xc5199e32, 0xa90836e3, -0x30d32619, 0xcec448b2, 0x3ce9b002, 0xaf5daee0, -0xf9d866d3, 0xc01f9c7d, 0x0086c8a2, 0x4c41c4a2, -0xce6070b4, 0xbc440a45, 0x932a7bd5, 0x5a3967a2, -0xb73a4fa0, 0xac056431, 0x981f7a3a, 0x17f1fc4f, -0x79180a8d, 0x11ff6c3b, 0x2d2974ae, 0xf02a9d0c, -0xd519dca0, 0x985ae8a7, 0xff8cc562, 0xccd2959c, -0xc8e1755d, 0x582ed5cc, 0x6ea71364, 0xe7418b1c, -0x6863462f, 0x31a0afc5, 0x61e7d39e, 0xa62fd758, -0x224ef92b, 0x200ca33e, 0x435162a7, 0x93e98c95, -0x277c8ffb, 0xd40b6030, 0xa80231a7, 0xfc0bd44c, -0x1bf95e3e, 0x73107b2e, 0xa1053205, 0xacc2d1e4, -0x559ed170, 0x63855ebe, 0xbc624e8a, 0xc5d1069f, -0x4882fabd, 0xb8f37420, 0xd5296744, 0x89c3d999, -0x26920170, 0xd1b7dc19, 0xe39aa2fc, 0xe7d75841, -0xad8a3e42, 0x989872ab, 0x85490dec, 0x6f1b8d7b, -0xc27cb34e, 0xaece9777, 0x06aa95e8, 0xf0cd691a, -0x24b2b791, 0x6a680140, 0xdc57d1b3, 0xd76e7e09, -0x4179bf62, 0x5f9e7d46, 0xe1d17d57, 0x0de6ea3f, -0xaab63b79, 0xb248d9f9, 0x2abe84c9, 0xa4c6303b, -0x95d0d55b, 0x0bf485a1, 0x2349e2b1, 0xd58a673e, -0x20a9c547, 0xda06b618, 0x6940082a, 0xb04c29f6, -0xb8b71408, 0x749ced6c, 0x130b7f62, 0xaa9a780d, -0x1f582e4f, 0x4e489983, 0x827b9d04, 0xe06b40ba, -0x2897e19b, 0xed2c64a6, 0x48156465, 0x96b13665, -0x77adec3a, 0xe8aae08e, 0x246810c1, 0x8325d23c, -0xd8f532f4, 0xb7334bf0, 0x7c0ce51f, 0x6f6cffe8, -0x0eda13ab, 0xde4b3416, 0x2e317daf, 0xf83396ad, -0xf50d6031, 0x65b090ae, 0xde15edb2, 0x7036d85a, -0x2201b5be, 0xe03b6ea6, 0xcb2c5c54, 0xdaffcd2c, -0x2f3ce0eb, 0x1d03ee9a, 0x117c70c9, 0x0ff345b4, -0x8efc3b59, 0x4a31d035, 0x68b25cb9, 0x6d74e514, -0xc0c9def6, 0x64472616, 0x97b30c18, 0xdd78ca4a, -0x36a33ae3, 0x6be6ca3b, 0xafaed757, 0x1f7a24b1, -0xb23f1830, 0xf230c461, 0x5b099707, 0x6a968e41, -0xe20d0246, 0x68691c52, 0x4b2fb987, 0xcd1950c6, -0x5a0b2d14, 0x824015c8, 0x98d975aa, 0x60c87c2d, -0xa7f1f033, 0x972107da, 0x81e14228, 0x58edab99, -0x94307323, 0x04326fd2, 0x20660cd4, 0x02deeb94, -0x910a4c96, 0x0c513d4a, 0x76728ab7, 0x7e445af6, -0x9566286a, 0x31106e06, 0xc5dba959, 0x82cc4824, -0x2ce47924, 0x0ba7b3e9, 0x981ac74f, 0x7c082ce0, -0x2599b524, 0x654d2883, 0x1e4be10a, 0x39931fcb, -0xf64a47c1, 0x993a5a86, 0xd416a229, 0xf269beed, -0xf05d4c13, 0x572acaa8, 0x1d78d508, 0xcd843d85, -0x38520a79, 0x1b1fef2c, 0xe29b511c, 0x7c1aa95f, -0x2b6ecc4d, 0xea5908c1, 0x2b63560d, 0xc10db41a, -0x5e2514e1, 0x3d34c58e, 0xebf1fece, 0x56507222, -0xbe36a40b, 0x147fbf00, 0x6eb1f2df, 0xe466f1e4, -0x63c9f169, 0xcf6bd201, 0x98933c12, 0x60e2b81e, -0x3508f806, 0x9e67f8a5, 0x6ee1305a, 0x0f4ba23e, -0xcd340cdf, 0x7cfc8ab9, 0x00bf2a62, 0xbf9ed3a1, -0x9b245491, 0xae4637c9, 0xb0a0c618, 0x7facd30d, -0xcb8fbec2, 0xf04e8980, 0xc955c18c, 0x3d5425b1, -0x529210c7, 0x8945c8e2, 0x3db97f39, 0xed09fb5d, -0xc0cfa504, 0xf28f6542, 0xee9e5678, 0x4d292474, -0x57925cce, 0xb4e1c5e9, 0xfa2c00ef, 0x10f26af5, -0x05bf6469, 0xf9e160b2, 0xd71618ac, 0xc87934bd, -0xe96101d1, 0x55d1976c, 0x471c8505, 0x7a36d839, -0x5d62a9ee, 0xf3c54a8a, 0xa2be15d9, 0x244087c9, -0x042c8037, 0x23224689, 0x281c5d73, 0x2139ecfc, -0xffb8bc8a, 0x834fdd11, 0x9cd5a5bd, 0xa3368319, -0x7e5bef0c, 0x4ae2dbda, 0x86d90089, 0x6675dfce, -0x48876262, 0xcec72538, 0x11dc5c80, 0x86a730f9, -0x313565c9, 0xe3e5be11, 0x106d7cce, 0x752b8be2, -0x3d00a5bc, 0xe6f70e95, 0x44447ac8, 0x600df30c, -0x8335ac3b, 0x8816ddee, 0x700982fe, 0xee495741, -0x48c7e81c, 0xa3d55da2, 0xb0172982, 0x70ab2158, -0xd4460621, 0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, -0xa8454763, 0x70877bb6, 0x66005c97, 0xaf292c06, -0x7b843db1, 0xf343b59b, 0x25cdc7b5, 0xa41da617, -0x9e9d895e, 0xc936f475, 0x7270925a, 0x30024230, -0x8e72f53d, 0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, -0xfc18a2a3, 0xaf377cc1, 0xbff09a78, 0x4b4e0814, -0x95a0b2c1, 0x270398de, 0x201fca94, 0x2a032a4f, -0x131542b4, 0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, -0xa814ddc9, 0xa3b3a991, 0x17ee60c2, 0x852c0b8d, -0x11e5853a, 0x762002a7, 0x92c5311d, 0x0d4bf7e1, -0xfffec870, 0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, -0x0111a772, 0x9808e780, 0x29c336e8, 0xe9bc05df, -0x5bedde11, 0x945565af, 0xaff808fe, 0x87e3423d, -0x4de6f98f, 0x93b4adef, 0xbf704fa4, 0x09120e91, -0xd54f3692, 0xdf8eab1e, 0xfabbf59c, 0xe74318be, -0xaab87ffc, 0x29fa791c, 0xe3915552, 0xa652cb9b, -0xa1252e74, 0xb35b723b, 0x542aa28b, 0x12fcc5b0, -0x3941f962, 0x82bcc6cc, 0x47b11974, 0xb821611f, -0x78b34250, 0xf1be5659, 0x561b9e61, 0x6f3bd501, -0x584e6f5c, 0xd54ed547, 0xacebcd21, 0x7b5ff816, -0xb64ad233, 0x9f2f330d, 0x69fb1ece, 0xac8710dd, -0x58dc6c60, 0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, -0xebc0ce9d, 0xa733274f, 0x884d9b55, 0x42b08b63, -0xafa54a74, 0x1c7ccf64, 0x93a20191, 0xaaa3132e, -0xc69831d1, 0x54634889, 0xfbfe3efc, 0xd3cf68d4, -0x302e3117, 0xf5693131, 0xc3ce8c6c, 0x1f03cd89, -0x6243334c, 0xf16bc80f, 0xdca5f130, 0xcb2cd956, -0x4c1bb421, 0xe8de533c, 0x7f86703a, 0x29aa897e, -0xdd54acad, 0x76b2f2ae, 0x7ef82b71, 0x2e30970b, -0xba402597, 0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, -0x7f9efd1c, 0x2363d147, 0x5327289a, 0xe89229f3, -0xd63a535c, 0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, -0x26b6edfb, 0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, -0x6d65db4c, 0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, -0xe20e6dbb, 0x8488a45f, 0x8ebc2932, 0xd4767316, -0x3e8c4b8a, 0xbab7402c, 0xfc1e217e, 0xe5c5bf82, -0x6928fe2e, 0xc88528e9, 0x4b2e4e8f, 0xdd938b86, -0x0c964f98, 0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, -0x197d005a, 0x4d40b3b3, 0xcf203155, 0x0d2fa621, -0x752d2c58, 0xb12bac12, 0x1e7e8c23, 0x94215d54, -0x9854a71c, 0x4de63c64, 0x7a012529, 0x9c171f8d, -0x9e71def7, 0x3bd17d50, 0x11f175d9, 0xec78abf3, -0x7b529eee, 0xd3a69fc3, 0x5b718676, 0x58214d29, -0xa8bd2c34, 0x41ea00ab, 0xa03f64d6, 0x4ee342b0, -0x32b1e444, 0x1c1801a4, 0xc8424702, 0x334a7e35, -0x50cf1543, 0x3b22b495, 0x88683776, 0x8e2e0154, -0x6155c033, 0x4e2fa6ac, 0x42ace700, 0x8d64f97c, -0xaf9ced17, 0xb2a5cb92, 0xa558582d, 0x88705de7, -0x9e528d59, 0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, -/* 1644-m34f6404.inc */ -0x00000001, 0x00000004, 0x12232005, 0x00000f64, -0xc66dbf02, 0x00000001, 0x00000034, 0x00000bd0, -0x00000c00, 0x00000000, 0x00000000, 0x00000000, -0x2aa0fbf9, 0x0920514d, 0x0e4f4460, 0x49035deb, -0x383f3c80, 0x00e04783, 0x29a44f29, 0xa2a1b502, -0x931fae3f, 0x1b9afb5e, 0x96f2c85b, 0xb547bdfa, -0xe114d22b, 0x323b2bb1, 0x340c7daf, 0xc6998fe4, -0x9490962a, 0xed68542f, 0x173948af, 0xb8ae3c1f, -0x65ef9972, 0x75fb56e8, 0xa3af41cf, 0x3319cfaa, -0xeac5094e, 0xafe4e760, 0xfd8f0287, 0xe78d700c, -0x168afe29, 0xae1f391c, 0x43aec1d8, 0xbdf7b9a3, -0x7ab31cd3, 0xace4f49a, 0x73939ca7, 0x5344c4d0, -0xc8487bb6, 0x1764ce10, 0xebccd173, 0xc23fc82f, -0x86625a94, 0x4e949245, 0x89eee135, 0x7c9004fa, -0x8096a152, 0xea7cbf27, 0xb2c4cd70, 0xfc54cb8b, -0xab050bff, 0xf737c757, 0xd1bb463b, 0x6d61e7ca, -0xc1e872c4, 0x09d3b9bb, 0x63dc89a7, 0x68bf6c1b, -0x83d5b80e, 0xc5beef02, 0x91747e89, 0x34196e62, -0x668c6253, 0x0e9fdfb2, 0x90b52c89, 0x2e75189c, -0x9d80daf1, 0x10159f22, 0x7706342c, 0x35e7bfd1, -0x62cf9cf5, 0x32cda56e, 0x1acebf46, 0xad816987, -0xebacbfb4, 0x0debbebc, 0x756d15e7, 0x24f67bc6, -0x025903ee, 0x0970f26e, 0x96ad84ef, 0x4a5dd836, -0x82c363ef, 0x0ffc3ec0, 0xdd3ea62a, 0xb27428a5, -0x1dc79380, 0x7ec9f960, 0x6662aaae, 0xa01d8357, -0xaf5db8a1, 0xff90a0ec, 0x1fe8e423, 0xbb81c9b3, -0x6335faa9, 0xea374dad, 0x975191a4, 0x4138c587, -0xbeb5c7e7, 0x1eb0f716, 0xd723fb49, 0x354877ca, -0xfc334d55, 0xf9e58b90, 0x7ba2646f, 0xb84ef813, -0xaeab7ca7, 0x00d1dd06, 0xa08655f1, 0x4bbadc51, -0x14483285, 0xe910a771, 0x39670120, 0x0be8c920, -0x3c95e8f8, 0x1c14ab83, 0xa4415b4a, 0x87c6b236, -0x31c41106, 0x3ab34cce, 0x54b1875c, 0xcee69e83, -0x33c65751, 0x5ef3a1f0, 0x5090d272, 0x5a8e6d3b, -0x4303bdbb, 0x0b2c3159, 0xefaf2639, 0xec01fdb0, -0xfe3fd042, 0x20c46b4b, 0xabe99171, 0x354d909d, -0x4af6e116, 0x1b3f281d, 0x17f7d490, 0xc1b1e097, -0x2cacaa17, 0xa3393411, 0xebc00673, 0x9d95d079, -0x970ed0e6, 0x16950515, 0x9b178b59, 0x7fb00a9e, -0xbfffd2ea, 0x087b061b, 0xc092d48c, 0xf32f5fa7, -0xf90e99ab, 0xf9312dc2, 0xe4d74564, 0xa698e99f, -0x7111bcbe, 0xec3968cd, 0x5436fa2d, 0x4e99ba9f, -0x9f8dcd1b, 0xb465b9af, 0x15212d3a, 0xe6f6e5a0, -0xbd4058d2, 0xb6ad2f5a, 0xa3260b5b, 0x734a3ede, -0x0f6ea66e, 0xb223e5a6, 0xebdc5128, 0xc4233eef, -0x09715a54, 0x3dbed193, 0x876b0277, 0x3adec15b, -0xb700dc55, 0x10aa107c, 0xdb7dbb4f, 0x1b9fa169, -0xcca80ecc, 0x273a03cb, 0x91afbe93, 0x7e893ced, -0x02410cf4, 0x15a0d7fb, 0x325f6e3b, 0xd9a9ce1d, -0x60950dd3, 0x9e291404, 0x0ea0a7d7, 0x41a346e8, -0x3fa2bd77, 0x8d20e602, 0xc8964616, 0xd6e19ce4, -0x563abb53, 0xdfd2769f, 0x24ccd347, 0xa322eae5, -0xf9a54b69, 0x176ce20e, 0x0feb59ba, 0x2a8fea4d, -0x3150bf41, 0x080a9926, 0x3f5134f7, 0x83295a7c, -0xc46c81a3, 0x19b6eccb, 0x40428921, 0x1b810f1b, -0xb76b6ac1, 0xb2292755, 0x79529867, 0x59f9d7af, -0xdaf8b861, 0x7fb68662, 0xa056b25b, 0xf826a597, -0xb7a2ceab, 0xd2612873, 0xec1f4d81, 0xb808abef, -0x7073078e, 0x6b91402a, 0xa3fbd414, 0x02a41c67, -0x544d48fc, 0x015dcb48, 0x11199d22, 0x1593a95e, -0x2c79af8e, 0x3548292d, 0x4727d9e9, 0xfe8a3dd9, -0x97f018b9, 0x0a7571f1, 0x3c00b794, 0xd3ff0072, -0x30fe579d, 0x2546f2ab, 0x0202f6c2, 0x11c15bc0, -0x8b4451f4, 0xf112d73b, 0xbfafaafa, 0xef369dfd, -0x308c4f78, 0xf19c2960, 0x9c19ac8a, 0x11230a97, -0x10f31535, 0x3bd988a6, 0x0cbbd3ec, 0x0ed616a5, -0x3680c09b, 0x91428b6b, 0x27832f53, 0xb7c9358a, -0x4f799c7b, 0x322999ba, 0x77229b52, 0x9a08a9be, -0x51ed5e85, 0x4a901240, 0x3ea94c88, 0x1118c795, -0x77452790, 0xb5ad6941, 0x3d00fdf2, 0x673b244a, -0x05b9a17e, 0x99993324, 0x118016db, 0x75484d41, -0xb75d23d0, 0xd34fa5da, 0xcc408938, 0x7ece1817, -0x7ea1b29e, 0xe7c2d699, 0x0f3dfbc7, 0x0b4555b7, -0x2cc05a7c, 0xcd23c5b9, 0x60161008, 0x4ca245c0, -0x5a36a6ae, 0xe893e428, 0xc9b2b8b1, 0x5448fd9a, -0x8d42d55b, 0xfa8ad719, 0x87ce3922, 0x5aecf655, -0x13ac5a66, 0x24c562f6, 0xc46a075f, 0xf1e40a8b, -0x941e2816, 0x15f746fd, 0x4cca60e0, 0x299b2a62, -0x73478a0d, 0x567e8782, 0x80895e42, 0x9583cb92, -0x32c73b01, 0xdf7781a2, 0xbfd53199, 0x565307b2, -0xf9c03681, 0x545cd9ee, 0xdb6ef914, 0x8f3a0f60, -0xe2599fd7, 0xbd1469a3, 0xa10bac43, 0x8ee0f53b, -0xfb397bd3, 0x1320fd60, 0x0fae4a4b, 0x9643a2ef, -0x542fa912, 0xf66acb30, 0x8c01a04c, 0x9a61f428, -0x767779d3, 0x7500c159, 0x081c8e77, 0x43df3122, -0xc8a9bc06, 0x68576d2b, 0x52ce3a2e, 0x89256fcf, -0x9bc3175c, 0x884e9d8c, 0x840b9a09, 0x7596e0e2, -0xabf086b6, 0x2e67e693, 0x8fd9d5d6, 0x5c33a3c1, -0xb0db727d, 0x4a52de56, 0x38873f93, 0x369cd226, -0x6ddeb66d, 0xe15f2459, 0xd71f9b20, 0xbcdf4d99, -0x0121658e, 0xf9db6f89, 0xf84bbe80, 0xc2cdd90e, -0xb80fdedb, 0xd75667b5, 0x89946de9, 0xa32fdd8d, -0xd1b2a769, 0xa71af914, 0x52f47223, 0x7b5bbf94, -0xc5756339, 0x765700cd, 0x1b76522b, 0x10b2a7a7, -0xf66f0dce, 0x830e175c, 0x8ec5c90d, 0x78facdee, -0xd79ab3bd, 0x8be528ab, 0xdb19d4ea, 0x8920768a, -0xf1ee4c3d, 0x41ba7328, 0x3509df65, 0xa37d1a42, -0x850b7186, 0xb1436128, 0x5a08b8f2, 0x27a84ef3, -0x4699d660, 0xc3a647aa, 0x42ac787d, 0x5a12ad69, -0xe3eb464e, 0x5d02ddf3, 0x166599f8, 0xfb60f496, -0x99482b78, 0xdda70ccd, 0x328b223f, 0xc17b09f9, -0xfe33a376, 0x5761ee07, 0x9b886028, 0x090e71c7, -0xcb3e5f12, 0xd3eaa84a, 0x5236aca3, 0xaccdaae8, -0xb806ffd0, 0x9da669d8, 0xa279b4b8, 0x5bc2d750, -0xc909a6f2, 0xa0271dfb, 0x79192e10, 0x57328242, -0xfad4b03c, 0x88e6d952, 0x4ea097f9, 0xbeed008a, -0x8362f77b, 0x8cb35545, 0x967b7aee, 0x2a15cf5a, -0xec39bcba, 0x555a5795, 0x93a4a7bb, 0x6ca9ff79, -0x760ed185, 0x690c2e3d, 0x874a340d, 0x66da03f6, -0x40a0eb9b, 0xa4635c53, 0xd54f88e9, 0x8cf960fc, -0x9281e930, 0x4b871388, 0x93d5afc2, 0xa08ce066, -0x7e4e3285, 0x5dfe67cf, 0xd589f83e, 0x39686ea8, -0x309d8b6d, 0x5817b862, 0xb79e5697, 0x794fc22d, -0x88718d7b, 0xfea9919f, 0x61b6e97b, 0xa056590c, -0x2b7dec71, 0x6e3fe551, 0xde8fb690, 0x1e8432fc, -0x3a582da2, 0x43156828, 0x699aa0d2, 0x8b60c7c1, -0x42655a0d, 0xda3b2073, 0x1fcbd187, 0xb7e8ebdb, -0x38523922, 0x6ab4c58d, 0xa57c97ad, 0xe40da53c, -0x5ce24bf3, 0x0885391a, 0xa8d23e09, 0xb790bc3a, -0xdbe626ce, 0x9825b7dd, 0x750fff15, 0xf59e3455, -0x9fd77b23, 0x52056a91, 0xfe0485cd, 0x695c4d77, -0x1c1a7d87, 0xb4a216a5, 0x476ffcb1, 0x73d4b9e5, -0x667afb76, 0xae5123d1, 0x036b8c60, 0x6da02e1d, -0xd8efc647, 0x1fe6dd3b, 0xb240fa2e, 0x27ad57de, -0x71030362, 0xf032e223, 0xae0a3ce7, 0xa3986894, -0xcc0d3503, 0x353f0815, 0x5df4a1a3, 0xfac260bb, -0x202c7593, 0xbadafb32, 0x7bc64e14, 0x6cd4da2e, -0xf1519aed, 0x55510d45, 0xe28d483f, 0x28221d48, -0x01c0bd26, 0x5c301fd7, 0xa12045f5, 0x76b05ace, -0xa2bbbb82, 0x97ab1865, 0x8d4ce459, 0x268fb1eb, -0x5dd52280, 0x2a5967fa, 0x64a3e4bc, 0xb45e0a97, -0xe8966ce2, 0x4e71465c, 0x964109e7, 0xabed1708, -0x7a13e4a4, 0xfd5e1477, 0x9910d3b9, 0x9ae0a78a, -0xd3cc1536, 0x2dfd162d, 0x3a0902ca, 0xa72dd7e3, -0x61afb44f, 0x8b1c3a67, 0xbb3c94b9, 0xa32b02e8, -0x47c73d33, 0x5de41852, 0xae80d1ec, 0x09f3ce22, -0x8bf48c41, 0xc250e044, 0x7c4ea278, 0x409f5374, -0xe5940d9d, 0xd0bf2472, 0xa1bd617f, 0xcd1fdb18, -0x99858d2b, 0xb418d69a, 0x76bb3f87, 0x399bdc16, -0xfe99947c, 0xa8506ae2, 0xdf04a39f, 0x64161b49, -0x5551de8b, 0x32de95b4, 0x23b2e25a, 0xe8c0adb9, -0x8068c813, 0x4cdd0184, 0xdba81d02, 0x0bb87f6f, -0x0848c5a9, 0x09de62c3, 0x4c9f6c81, 0x93cfd4f0, -0xe732145d, 0x10f0a466, 0x634f4fca, 0x3d15a895, -0xb45b6281, 0x33141400, 0x68e1e66b, 0x9eb7fa62, -0x00b982a5, 0xdc30d528, 0x99353212, 0xb39b39cb, -0x9915ee79, 0x45b9019a, 0x2950a41b, 0xae7c06f9, -0xa549f671, 0xa577ead9, 0x6460b7ea, 0xd74ba7f0, -0xa153dfbf, 0xce43d0c8, 0x4db0cb22, 0x5fdc31a0, -0xc6d8343f, 0xe6c71f5d, 0x544b5e49, 0xc05aa5b0, -0xdee2e78d, 0x21a5a92c, 0xceff698b, 0xc2af2e98, -0xd21ff919, 0x253bfcb0, 0x38bb6000, 0x3bdc0d95, -0xf58720bd, 0x555571e2, 0x5f46c392, 0xed75a926, -0xfb2ea273, 0xcace1efd, 0xdee40d28, 0x825b887e, -0xb9f571d0, 0x5af0e2eb, 0x1e84e8d5, 0xe5faf18e, -0x09e6f9c4, 0x0275418d, 0x286a78e5, 0x67ce248b, -0x1d16cec4, 0xa7a91b4e, 0xb69073a5, 0x850c89b7, -0xf2fbb34c, 0xc20fdf4d, 0x400790e6, 0x426e089a, -0x33da3064, 0xecd24b1c, 0xafc86b04, 0x0741e20e, -0x78b2aee8, 0xcbdf174c, 0xb3ae59ef, 0x3304707f, -0xa7426892, 0x5daf5012, 0xa7cb63f5, 0x59a11f7c, -0xc6d07905, 0xe838459f, 0xfdf02a6d, 0x6f5e4acf, -0xe9e3226f, 0xb9725afd, 0x6241649f, 0x95988faf, -0xa081c6c5, 0xa9eb2d11, 0xc2443b09, 0xe0311918, -0x1ef297cb, 0xf443b6be, 0x26581e9b, 0x291fc191, -0xc77165f8, 0xdb430c89, 0x2d3758c4, 0x6c533994, -0x3ddc4401, 0x9a7c3ec7, 0xb51caeb7, 0x0b1af900, -0x965bcbec, 0x159c52a2, 0x79d3971e, 0x05450934, -0x35ec78f2, 0xf3f95c09, 0xaf428eac, 0x62cacb9f, -0x777a0f04, 0xc84c848b, 0x590bfbc0, 0x3278cf42, -0x80212999, 0x4b165cab, 0xfeb5061a, 0xd1edbcc4, -0x713368d9, 0x1166ae7f, 0x624ad72f, 0x8ad9e50c, -0x08c5a38d, 0xc69f14b5, 0xe72af0d6, 0xcaed6525, -0x90aa248b, 0x9c518708, 0xc2b61ceb, 0x03d96759, -0xf212ea2b, 0x5f208660, 0x86bfc04a, 0x5985bc07, -0xaa4fca93, 0x6a20c21f, 0xac11f3a5, 0xa37e81e6, -0x47e46f31, 0x0fbe92dd, 0xd7ced8a9, 0x7e0e9b17, -0x75d64f73, 0x1aa88320, 0x2c207cb3, 0xf15513e4, -0xd79bc9bd, 0x2e33fdc1, 0x605baa8c, 0x2c5a7f84, -0x13fdd5d4, 0x526bd3cd, 0x2dedb93a, 0x915f4b74, -0xbe8430ed, 0x1159024d, 0x42857f19, 0xc1421d60, -0xb37e98bb, 0x7041760e, 0x404ba9e0, 0xadfcb9d2, -0x5bb7904e, 0xb67a4814, 0x4dec413c, 0xc4aa8e09, -0x599a8813, 0x418af309, 0x1b70b3ef, 0xbcffb6d0, -0x32a221bb, 0x92807fd9, 0x9d71e8c5, 0x5d8e2809, -0x9356cc7b, 0x9e775e7e, 0x0639ab21, 0xaa7403b3, -0x878d82ee, 0x1c513739, 0xd1d56bab, 0xf72d5c2f, -0x0ec2b242, 0x33b9ee8d, 0x0921cb76, 0x96b903c0, -0x4b60e522, 0x651a2426, 0x678fec9b, 0xec785618, -0xbc930977, 0x8c7e369e, 0x10c46c62, 0x6f0cf663, -0x6b9c8438, 0xe28ff641, 0x1114ff3e, 0x58b7677f, -0xc81fc485, 0x8741210f, 0x0800b8f4, 0x8defc914, -/* 2972-m03106a4_00000011.inc */ -0x00000001, 0x00000011, 0x04212009, 0x000106a4, -0x24e504ac, 0x00000001, 0x00000003, 0x000033d0, -0x00003400, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000011, -0x00000000, 0x00000000, 0x20090421, 0x00000c51, -0x00000001, 0x000106a4, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xbd172fac, 0x034086f5, 0x34810939, 0xaea3ec98, -0x26866e06, 0x1389830d, 0x7a2a4b6a, 0x1e7fb2b1, -0xbab165d1, 0xfeb576d4, 0xc1edb5b2, 0xa44174b8, -0x0d1ad45a, 0x4fe5fe0f, 0x62feaf24, 0xafe7de28, -0x8b076222, 0x881b4891, 0x8daf9241, 0x98e8cf9e, -0x417b7869, 0xd7e266b6, 0xf07fa211, 0xd01aa170, -0xbd0ff37d, 0x883aefa5, 0x4313c7ef, 0x97e92355, -0x84df4fa1, 0x251a1422, 0xbffca04b, 0x80d1e0a9, -0x2de71585, 0x74f3cc3a, 0x06355b58, 0x404b01a9, -0x76867925, 0xd35afcf0, 0x2e220cdb, 0xb0c03e11, -0xff163ac7, 0x796b6c3b, 0x413f51d1, 0xfb5f33e6, -0x0d3408e5, 0x29f2fd21, 0xe5937245, 0x43a62312, -0x22bb80da, 0x517fd4cc, 0xd3b29526, 0xace3ace8, -0x22e26346, 0xf6fa7e9a, 0xe956d161, 0x72d9e32e, -0x87d1c6a2, 0xe2b89eff, 0xc94b7fba, 0xe61e89b4, -0xf2a0adaa, 0xac5edf25, 0xef730b2f, 0x64519e05, -0x59824baa, 0xeb00b868, 0xbf1e0a65, 0x95cebd35, -0x144fca7c, 0x6ac6e730, 0x1d86878e, 0x955b87bd, -0x00000011, 0xeb9a3ae2, 0xba19250b, 0xb6913770, -0x5dd1fadc, 0x7b61bda5, 0xfbe1046b, 0x62b40d10, -0xe32f8fcb, 0x76e9f340, 0x80120c6b, 0x8d04430f, -0x427e9ceb, 0x6c128159, 0x5de4d263, 0xfd9943da, -0x2c499c2a, 0x168d6819, 0x8cd27a89, 0xc2b2c39b, -0x4b40b5e9, 0xc5778358, 0x4e2716d1, 0x5329eb09, -0xb1af099c, 0x551e74d7, 0xba61069b, 0xd0d20004, -0x87a9b395, 0xdc791117, 0xdac97e23, 0xb29a2b31, -0xb1300d2b, 0x24dd5664, 0x96d20a3a, 0x09a6166b, -0xe458bd9f, 0x9914ee23, 0xbe60b4ef, 0x08881e03, -0xe9079bf9, 0x9ae7ae18, 0x1897bde2, 0xe00ec0a2, -0x1751088a, 0x3b204283, 0xffc815eb, 0x03e9fc77, -0x54f7b156, 0xb4d6b92f, 0xa269c536, 0xfee06fc4, -0x675f6d6e, 0x5268533b, 0x1e81c91a, 0x7575acf7, -0xbccff158, 0xd409a1cc, 0xb4cec032, 0xb62f4a58, -0x2d05e54f, 0x4093ea0f, 0x2466e0d6, 0x013b12fa, -0x19acb0f3, 0x2d93c94a, 0x85d74d7a, 0x1a8e7de1, -0xe8bc68c2, 0xe513c711, 0x0c2bedb1, 0x9b0c607c, -0x24ba9e59, 0xec825171, 0x8e3f5e82, 0x83a07f57, -0xfd85f5c4, 0x6ff83636, 0xd2080b7c, 0x8a17c257, -0xe485607a, 0x556dd558, 0x46c0f284, 0x907ddb4a, -0xa193cbab, 0x01c368e9, 0x20711144, 0x2738cc26, -0x1c188f11, 0xefe83056, 0xe0196cdc, 0x2cb6dfc1, -0xaeb2e1e7, 0xdddec8c7, 0x3b013363, 0x5407d3c1, -0x4eebc4bd, 0xb95113bb, 0x340974b6, 0x47e5796e, -0x4e95f12d, 0x44fd5064, 0x63ba8a31, 0x1bfbdb9f, -0xdf166650, 0xdb9cd257, 0x3e6d00cb, 0xe7049407, -0xc621b5e0, 0x5eb23371, 0xd003f1c1, 0x71e5b2c8, -0x241e906c, 0xc2f105d5, 0xa700f715, 0xd457b00d, -0x6d793928, 0x4483b5bb, 0x8eef9860, 0x85b613f5, -0x25f78837, 0x34e41c87, 0xf7d14ca7, 0x1123081f, -0xd1855d82, 0x7867ce93, 0x9882bb97, 0x54103ff1, -0x1e651ade, 0xedb906f4, 0xf4dc41f0, 0x6322dc5b, -0x099f62a1, 0x997850f8, 0x622265e7, 0xc8ff431a, -0x8232e9f9, 0xa0a5a025, 0x8dda3467, 0x8e09e48f, -0xa654d059, 0x415ddeec, 0x1aca17ab, 0x2d50a873, -0x45a54f63, 0xd589cad4, 0xd588d367, 0xae7b08f6, -0xadb29750, 0x1eb451af, 0xd47dc746, 0xe0cf7b71, -0x9e88e337, 0xe1bcef41, 0xd8e29460, 0x7d609923, -0x6a333eec, 0x321be9db, 0xf2398187, 0xeb1b838c, -0x01b7c02f, 0x03ac1d27, 0xd4aea785, 0xa989e71b, -0x84ba1913, 0x977cd99a, 0xd15853fe, 0x5018b240, -0x6af4d728, 0x735e00b3, 0x24a0cd6c, 0x7dd4f269, -0xede2d092, 0xe3b3039d, 0x8cf5822e, 0x1a8b92ea, -0x066f92ba, 0x3d912396, 0x1ddb6adb, 0x2679ddea, -0x4d0ade93, 0x710eacfd, 0x62ed9560, 0x291fd5c1, -0xe3423996, 0x0392eb57, 0x8b4291ec, 0xa7f66bc9, -0xde23a4da, 0x4e2ab73f, 0xbe3699c3, 0xb06331c0, -0x65b3f723, 0xc56eb5e6, 0x91bf1361, 0x6c17db61, -0x188ea732, 0x5a3b60f8, 0x5b6d8fe6, 0x56d77c42, -0x3e331203, 0x509723d0, 0xbf26b1ae, 0x59a3a439, -0x0c2cd228, 0xd96afee4, 0x8702a97a, 0x6553927d, -0x4a0004f5, 0x64d93ed2, 0x447178ce, 0xd220d7c3, -0xab5180a2, 0x8256f6ce, 0x20b8da64, 0xd716a140, -0x79692a21, 0xe934bacc, 0x9f6ea2ba, 0x412adb52, -0x1d2fac64, 0xbf0ae6b6, 0xf4c5de9a, 0x13e946db, -0x0f3310d3, 0xbd472972, 0x44f5c6c5, 0x3e470c3b, -0x351d0232, 0x21cf98a9, 0x4bf0ceb5, 0x0f2c7987, -0xccfedfdc, 0x3deea1dd, 0x86266017, 0x78a1fd9b, -0x19b5a8c0, 0x3aa5c795, 0x48132bc4, 0x7fefe965, -0x89b3690a, 0x90313a34, 0x7a2352bc, 0x06c73845, -0x6d6d1b65, 0x526d4e93, 0x607cc7ac, 0x89a77684, -0xeeffd1e3, 0xa86371af, 0x1e015c36, 0xbb977ef7, -0x185a984f, 0x1baa7128, 0xb6bc7577, 0xc185716a, -0xbf6e586f, 0xfa266eed, 0x17d984e6, 0x8a1c9595, -0xb32d9f4b, 0x4f44d51b, 0x4fff88b2, 0x1ed845b6, -0x2ef58c74, 0xc5decdc5, 0x5763cb7c, 0x1de72610, -0x3683c43f, 0x1b5a8841, 0xc845bbcf, 0x31d6a4b6, -0xc9afcb9e, 0x4ada1ab3, 0x2dd6a920, 0x26a181d4, -0x91ffe8b9, 0x10b7911f, 0x5ae0e496, 0xc8a1a306, -0x007bb229, 0x03721f9f, 0x2e023ece, 0x1d078279, -0xd159e0fe, 0x1c184355, 0x9c2812f5, 0x2fcc2063, -0x612e7dea, 0x7d126bb8, 0x1422e3c3, 0x1425036d, -0x28f8a945, 0x310da5de, 0xd395e6a7, 0x972ec389, -0x0e8deb4b, 0x52fceb6a, 0x74416288, 0xca6a74e2, -0xccdf3e5f, 0xf2ef0a8a, 0x4df24bb7, 0x1fcdb75c, -0xe1a60d5e, 0x7d1207af, 0x4cbdb551, 0x5849d606, -0x2f6b2c35, 0xfc033cf8, 0x21e1fc48, 0x539a19be, -0x9b2836d2, 0x4d799d7c, 0xd26f7491, 0x6d814ba3, -0x5d682bf9, 0x1c404f52, 0xcf845b7e, 0xfff3e64f, -0x75454bbe, 0x7632bacb, 0xf277a7a1, 0xa0a55c12, -0x32fa5cdc, 0x95929b55, 0x303254dd, 0x745fe3b8, -0x686ba00a, 0x7bfc754f, 0xe6a0a2ed, 0x2921d130, -0xfee7be58, 0x5b2a81cf, 0x663c25e2, 0xae19c4d9, -0xf0ff2517, 0xf78241bc, 0x866ba061, 0xcd26e9b7, -0xc0e7d263, 0xdef95515, 0xc4cd4fea, 0x7ea6c05e, -0xd8adcfea, 0x7a8be458, 0xe248b952, 0x11b737c0, -0x995299cf, 0xd3c45707, 0x58894624, 0xa6fd9f68, -0x7d80e2a9, 0x7f813143, 0x5a1d3a31, 0x7ecf8e80, -0x7dabdf8e, 0x480fec6a, 0x59ff3f4d, 0x1d993dae, -0x2f084f9d, 0xa1d9c94e, 0xfc302461, 0x40312d9b, -0xdbc844af, 0xe921007d, 0x84af6173, 0x6c502053, -0x15372cc5, 0x7485bdc2, 0x12fc4abe, 0xfd7a3d03, -0xf63d2207, 0x430a2197, 0x46ab82cc, 0x06e0568c, -0x207ab6f6, 0x9f4fc33b, 0xefaf957f, 0x9dea7897, -0x3e57c505, 0x2e4f2482, 0x84167744, 0x8c3320eb, -0x417adb23, 0x1da5865e, 0xcb980246, 0x9a5e168b, -0x8ef05027, 0x225c6c5b, 0x558a3de2, 0x8489acb1, -0x5fe1642c, 0xa024fa25, 0xd5888a64, 0x89e26a48, -0xe8edb76b, 0xe4da9dad, 0xf02d19a0, 0x9af5fab2, -0xad5bcc5d, 0x1ac1b93b, 0xc5aff3ef, 0xe9c793eb, -0x3a4ea426, 0xef4e4c81, 0x2c57d7c8, 0x0af13491, -0x72d96850, 0xd2b0098b, 0x6b2ec0af, 0x7845345b, -0xd9838943, 0x576e4433, 0x5bd9d0c7, 0xfacbf0f7, -0xb78747f3, 0x4d273b51, 0x3391945c, 0xda6c4e7a, -0x6fd26f1e, 0xaca3ca0a, 0x10a55561, 0x52a1dda5, -0xfb4fedc0, 0x36e6be5d, 0xb23c624d, 0x8ce07b51, -0xf45bcfb6, 0x35ccf849, 0x3b8e19e6, 0xdd4f57e1, -0x183a9fa4, 0x53d026d6, 0x28f71104, 0x238c777b, -0xb31ab449, 0x72e8eda9, 0xe1738dca, 0x5fa2006c, -0x83f83104, 0x6c3259c8, 0xddf6de43, 0x94b00058, -0x4142b380, 0x5471367e, 0xce78bc65, 0x54084381, -0xc7996df1, 0x6a3acf67, 0xf4a58a36, 0xdbdf961c, -0x5e8618e5, 0xfc1dcfce, 0xa961f562, 0x13371c2a, -0x4d3d913e, 0xc57f9483, 0x543aad60, 0xf1ec24ad, -0xe28f0d63, 0x56b9f65f, 0xba95e8f7, 0xda9a4254, -0x1394a39c, 0xf0e2d0e7, 0x388b456f, 0x9b592ebb, -0xc11db10d, 0xc2b7ceb0, 0x1c61bcc8, 0xa7a1dd92, -0xea0521c1, 0x6081481b, 0xca816197, 0x2ba9d281, -0x12b20667, 0x45598c32, 0x90529a90, 0x0a21378f, -0x1549ca66, 0xc04c3131, 0x1534ec89, 0x35aae47a, -0x9bc830e9, 0x7f86a355, 0x2cc79d4f, 0xb78f8d08, -0x6b8c576d, 0x9492fba5, 0xd6706091, 0x2e8771e5, -0xf1c8c7b1, 0x0afa15e3, 0x33ff38ba, 0x70ef6fae, -0x41319eb4, 0xe6ac37cd, 0x897cc145, 0x51241e90, -0xd98d6de8, 0x4f6d6294, 0x93303d3b, 0x2f4cb592, -0x69a5df81, 0x988d1e2a, 0x07549af5, 0x7c4a7546, -0xe1c60794, 0x8a5624ec, 0x1e3de955, 0x89481529, -0xe36366e0, 0x6533eeee, 0xa05516dc, 0x3c101f2e, -0x6e75bc76, 0x162ca709, 0xba6c2124, 0x5d18f071, -0x53b0aabc, 0x53cc284c, 0x67cdf931, 0xb4019d46, -0xdd1f8694, 0x48876d25, 0x14c833f0, 0x1facd2c2, -0x23407af4, 0xea3d3c45, 0x2e4de842, 0x7adeba15, -0x6aca8f3d, 0x147b22f2, 0x17a15f14, 0x5bbb0fa7, -0xfa69afd5, 0x61d61c55, 0x942421cc, 0x9054a907, -0x04ecd607, 0x4d21b233, 0xdfb00dfc, 0x664a2559, -0x36e1695f, 0x8b187b9e, 0x6cf961e4, 0x6760b930, -0x2532527d, 0xf43a4077, 0x7503e4e0, 0x4ec1cd02, -0x2e9a2bc6, 0x0cb07702, 0xb6d2a51d, 0xd86c340d, -0x0f51cd84, 0x9631a3d3, 0x3a0cffca, 0xca327a9c, -0x984b0695, 0x06ba099a, 0x0096f1e0, 0x9cbec8c3, -0x01c78c14, 0xc99fdab6, 0x3f7208ce, 0x15c16d93, -0x2bc4a623, 0x6a129c2f, 0xbd76ee3c, 0xac0fe4bb, -0xf80def17, 0xfb47f0b2, 0x400287dc, 0xf5c156f4, -0x1af2b4ae, 0xfc25414c, 0x3ae947f9, 0xa0c18d6d, -0xeda308e8, 0xc8ed5736, 0x6e08f1f5, 0x5235df3c, -0x1d2f644c, 0xf67302e2, 0x41eb0baf, 0x85d1d5e8, -0xdfaac749, 0x2e6f5568, 0x7637560a, 0xc3549faf, -0xd0ab2cd1, 0x278a7cd8, 0x4ed193b3, 0x84b22b1b, -0x2c3ecf89, 0x5a804460, 0xf74961a7, 0xdd21e0f9, -0x891651b9, 0x0d809b55, 0xb7b384dc, 0xd98986e7, -0xab1ca847, 0x7509c799, 0xc1f91529, 0x47540a9c, -0xbffa13a1, 0x5e32b40a, 0x00706a0e, 0xfb14e607, -0x9b2c4f57, 0x601bd09d, 0x12731e45, 0xb2f719ec, -0xb80042c1, 0x0d274614, 0xc44e8f1d, 0x6f847d59, -0xd52e86ea, 0xb198be47, 0x874c408e, 0x9796255f, -0x3a97245d, 0xab28be61, 0x1b1ca983, 0xd30e4d4f, -0x55402eec, 0x9992e9a1, 0xeb4d9c35, 0x11e4e399, -0xb4c6f7af, 0x3a263ba4, 0x467847c0, 0x7f88e34c, -0xf5d88b0d, 0xc074dd64, 0x0d7a1982, 0xfe0ba0fb, -0x859d62f9, 0x54408bf8, 0x158cd71c, 0xdf6abf90, -0xbc08fc31, 0x90172b35, 0xe8835c4c, 0xe9dfe2a3, -0x31c70bde, 0xaca7eeb7, 0x22d9c89a, 0x03a09da4, -0x1f6aaa97, 0x69875916, 0x5202feca, 0x8fb4b4da, -0x26f2f9f2, 0xb9d454e3, 0x2ba8ba48, 0x728c78a3, -0xae59a64c, 0xb10e3eee, 0x2363985a, 0x634ad668, -0xcfabf3c5, 0xddae4056, 0xe678a770, 0x780627d3, -0xdf9360c3, 0xc5da9020, 0x8da43677, 0x21cf988f, -0x85af6686, 0x8ced5e79, 0xd87097a5, 0xb669eee9, -0x86cf6940, 0x6333431b, 0x9057f31c, 0xfdd0a878, -0xe205471c, 0xc57ac3fa, 0x175adf47, 0x82330a65, -0x75ff0f7e, 0x96ba0efb, 0xa783ae1d, 0xaa30b2b8, -0xcdfd237c, 0xb187a599, 0x2a6f32cc, 0xa6d759ce, -0xdafa26f2, 0xef3aac74, 0xb78a7ce8, 0xe7681faf, -0xa803cafb, 0x1932b833, 0x29954c10, 0x4c27c02a, -0xb3390b63, 0x45a7a656, 0x15968d5d, 0x8db4d7ca, -0x0fafef03, 0x49fa8fef, 0xe2d8e1ec, 0x29a3fd0c, -0x1e4417fd, 0x880bea78, 0x777efb2c, 0x0ded6ca5, -0x6d75511f, 0xf09f20e6, 0xf135cca2, 0x1748bec1, -0xf501afe5, 0x12b13a46, 0xd32ba485, 0x3af701b4, -0x3cce44e2, 0xd2295b64, 0x1c2b6a2b, 0x1ed53738, -0xc35929c9, 0xfbf9a3d3, 0x1090c32e, 0x593f67bd, -0xd72ee065, 0x4546e14d, 0x5b5eb122, 0x90595ee5, -0x66e295f5, 0x90636ff2, 0x91495ece, 0xb8085ff9, -0xd52e413a, 0xeebdf818, 0x7210a9a6, 0x4e69162a, -0x1d87746b, 0x78bcdd0a, 0xe3cd0bf9, 0x8cf6fb6e, -0x3ddb321d, 0xde64faf9, 0x85432f8d, 0x9fe898aa, -0xabb62682, 0x648fe85a, 0x10a2b168, 0x2f4e6f40, -0x25cf1f7d, 0xa7094727, 0xa37836c4, 0x1a500fba, -0x996a467c, 0xdac51ba4, 0x5302884a, 0x4499a7eb, -0xb6c37b74, 0x3033c91f, 0x00f39932, 0xc43c7ebe, -0x28234041, 0x0008fa40, 0x02ee946f, 0x1018dfa0, -0xbe74defa, 0xe3a90b78, 0x9765f2e0, 0x818d1ede, -0x0483ce60, 0xcea9ea79, 0x9651556e, 0x552a27b7, -0x138ed241, 0xcbd38e5f, 0xad15387f, 0x31d5c7d4, -0x443af6f2, 0xc2fe7ff7, 0x29db77d0, 0x5e78a202, -0x897b48e8, 0xd6517ae9, 0x4c82f424, 0xf541acb8, -0x60e843fd, 0x0f9a5d41, 0x6d0d39cc, 0x5ad2ae84, -0x4501e2be, 0x296bd4f3, 0x979fe84d, 0x2209535c, -0x16b768a6, 0xe4ec2221, 0x8303445d, 0xf09ce428, -0xa7974dee, 0x21df013b, 0x841ce40e, 0xc3dcb4ac, -0x1dffbe41, 0xff9ba686, 0x76ac6f6c, 0x15a8f314, -0x12462cd5, 0xff5420dc, 0xf42056b6, 0x50689be6, -0x3de042b4, 0x9a8b850f, 0xba4eab79, 0x875d59c6, -0xadd5dd45, 0xbf3001f1, 0x46e88000, 0x9509b620, -0xd35acc8e, 0xbce596d4, 0x3e017144, 0x98686134, -0x90220297, 0xfe0be716, 0x0c4f94dc, 0x46935424, -0x68c6c03e, 0xa3820973, 0x052da67c, 0x0786d78f, -0xffb71a67, 0xddfa3f0d, 0xd0bb0442, 0xf1d28e48, -0x1ccd3624, 0x1646f541, 0x06de5e60, 0x38f0890f, -0xc67dc1db, 0xa6084221, 0x15cef80c, 0x0cab0c97, -0x2b5a4403, 0x5247b5df, 0x07a9727c, 0x3eda0c9a, -0x561d9408, 0x50dbb4b4, 0xba8bc023, 0x93e9dd1a, -0xfe2cdd03, 0x9df4be7d, 0xf67b4020, 0xbe177ffd, -0xae58895a, 0x9533ce36, 0xd4db9bb2, 0xb0c4b820, -0xee808e03, 0xf6aaf6c1, 0x64878887, 0x59c01683, -0x808c2023, 0x88a8dbfd, 0xd2196b3b, 0x2638bade, -0xf98da4df, 0x415492d9, 0x8a48c040, 0x7f237a28, -0x048404e6, 0xb67ac6a6, 0x8612a74d, 0x419f83d7, -0x7e25fc7a, 0x51522244, 0xa66bb57a, 0x85c49809, -0xdb1beb59, 0x4a92f612, 0x133d41c2, 0xeba6d046, -0xab1a1991, 0xb0b60102, 0x6fa2f6c3, 0x40a065d2, -0x9fa7af2e, 0x541154b0, 0xd152b419, 0x8fca6da8, -0x266ebbed, 0xc7c6fd56, 0xc6eeffe0, 0xbaf24600, -0x53ac35e9, 0xbf96734a, 0xd824cef8, 0x2e06271f, -0x98dc396b, 0xfd691a91, 0xb3316c04, 0x55a9556c, -0x40460791, 0x016fae00, 0x9e80936d, 0x865c48be, -0xbbf9e7c0, 0x8605e52a, 0xd4cf7fcb, 0xae424090, -0x19f4919e, 0x7869306c, 0x0d975851, 0x6d6e209e, -0xf450e97f, 0xe07b4025, 0x6768c9f5, 0x8101efa8, -0xf267ca1e, 0x14e63f3c, 0x9e0402cb, 0x7d752938, -0x75bf01d2, 0x0c648c71, 0xbc16ef47, 0xf25788e4, -0xfdd4f4f8, 0xfdb9b51b, 0xce95124f, 0x79b49c17, -0xa3ad1812, 0x69f67653, 0x3d7f0557, 0x2374c778, -0xfb7fd252, 0x72e87895, 0x9c28c801, 0x8f3a1eb4, -0x6cdc9fee, 0xc0eddfc8, 0xd750a1a2, 0x5c59ba95, -0xb6800268, 0xe47d74c2, 0x6e8a5bf1, 0x237d78b6, -0x59576285, 0x4b68a491, 0x541446e0, 0xd0f2a058, -0xe35ceffe, 0x3a6a6f55, 0x69c7aae8, 0x60f24589, -0x985133d2, 0x06563d24, 0x3e859aa5, 0xa9fec8e3, -0x6638afc7, 0xcbce1aa5, 0xf7355507, 0x6928bc3d, -0x0e9cd473, 0xcf8368da, 0xf0de4f65, 0xf9267098, -0xcea9cb2b, 0xd4fa0821, 0xa5ce1f5f, 0xdfeaa430, -0x31a2cd59, 0x95a9cc20, 0xfa2ae166, 0x79ae79f5, -0xbf526a3c, 0x6650746c, 0x44cf2dda, 0x550215a0, -0x4f0c13ce, 0x2abb8b26, 0x518fa50f, 0x6b391300, -0x77755d34, 0x54312269, 0x3939dc93, 0x734dd8f1, -0x6d59151f, 0x39fe6eb1, 0x3c86282e, 0x60196a41, -0xf402d6dd, 0x98d39ef2, 0xf85ed6e8, 0xb3c715cb, -0xa6bf790e, 0x1a000dc5, 0xbe2d812c, 0x6d312e9c, -0x344d1abd, 0xcdfa61f6, 0x5a8ba942, 0x5d85335c, -0x7cccb15e, 0xa51563db, 0x25a0a0b2, 0x2646c04f, -0x70bb163e, 0xee753340, 0x1d564aaf, 0x3f8e52eb, -0xe2f94390, 0x088692b2, 0xe98d5fbb, 0x432d6848, -0xebcc7c07, 0xc006e435, 0xa4ed57c3, 0xd8337440, -0xcd87eab6, 0xda5b4f74, 0xd59e9be7, 0xa03ccbdc, -0x29116dbe, 0x66af819f, 0x08361160, 0x8afafd05, -0xeda29b2f, 0x727fabc1, 0x9f7ebe4f, 0xa59af345, -0x4397c33d, 0x6d638a4e, 0x5dd5c73d, 0x3830af05, -0x04a6e070, 0x7dd7a7fe, 0xe04e8511, 0x58e722db, -0xc0b10a49, 0x3afdfd7b, 0xe90893da, 0xb28df676, -0x5820aedd, 0x98827732, 0x67773622, 0x9bd02312, -0xf8b40ba3, 0x953b41e5, 0x3fdaccb8, 0xb586205c, -0x31038d52, 0xd9750ce0, 0x1eb706a2, 0x63635238, -0x9763fc4f, 0x0234a005, 0x88fe50b9, 0x9e0acedd, -0x54f05d4e, 0xde4070a1, 0xe6d1ffe2, 0x20fcd772, -0xe0c81b43, 0xb5163405, 0xa11af3ae, 0x72be6f34, -0xf1f76254, 0xf6f7479f, 0xa96ae92d, 0x34327289, -0x2aa5c4aa, 0xa1dfd44b, 0xb1b07289, 0x8e540bfc, -0xec094d38, 0xafc811f3, 0xa20f2e52, 0xed09d405, -0xb76ec720, 0x5c156f2e, 0x0ef1d38e, 0x2db4f6f8, -0x281f9fd5, 0x46b1f2eb, 0x9be4dfbd, 0xeb315383, -0x19c2a683, 0x908950ec, 0xb8745c73, 0x3cdb90e3, -0x9fb7ec13, 0xc37e7a54, 0xb1217c04, 0x6ce6e918, -0x31d4bc3d, 0x580e0706, 0x0c679bd8, 0xa5a09d65, -0x614e2adb, 0xbb123d00, 0xd134dcf2, 0x0eb45806, -0x94a950c6, 0x4e8ec2a4, 0x56320afb, 0x710585a2, -0x41dc0457, 0x37c4e759, 0xe1e0a084, 0xe95fbd3e, -0x19d70436, 0xc688c94f, 0x90255cf3, 0x2516a509, -0x31df0804, 0x56d2da5a, 0x02fc845c, 0xc0f075ad, -0xaff2e3ef, 0x46f4fb49, 0xbd6652d0, 0xea14d768, -0xb76a3d39, 0xbc3b1cfc, 0xd49c2b9e, 0x5d532619, -0x9f5d2219, 0x89eca480, 0x0bba7260, 0xd285889e, -0xd902272a, 0xd87f6650, 0xd6d25c23, 0x6fb4fec6, -0x196c23dc, 0x672185d9, 0xe6ae5a33, 0x7563c23d, -0xe7afbe73, 0x76ccdf49, 0x461e3696, 0xed8b238c, -0x216d46df, 0x88c149d6, 0xf6d4ab92, 0x30718da7, -0xefcb6edb, 0x90fffc89, 0x34e9d2b6, 0x27139e31, -0x3556ebc2, 0xb7d3c804, 0x86ca3b30, 0xe7a4c236, -0xe6cee875, 0x715b374a, 0x9b15879e, 0x4cddc9a9, -0xbc3f44f1, 0x470a0dae, 0x1afc4183, 0xca46569e, -0x281d1b88, 0x8c82845f, 0xe70e00e2, 0xf9b8d849, -0x84fea5f9, 0x51c93d93, 0xacfbd7d6, 0x5c79209e, -0x3ae52088, 0xe985210e, 0xb20f972f, 0xb048ad54, -0xcec68543, 0x9b3fce97, 0x89f9d1c6, 0xf5e98ecb, -0x9a5ec8f7, 0x8dbfcd63, 0xda17fc16, 0xb6fcb687, -0x12f869d8, 0xcac6e7c4, 0x678fa5bb, 0xb3e9d922, -0xb7bfe2a8, 0x1c1eee4b, 0x7cea677e, 0x1996a42d, -0xeba47427, 0x8993c0b1, 0x1799971d, 0x5e7064e1, -0x0532627b, 0x7a48147b, 0x79fdafb3, 0x9d9cb3b0, -0x4fbfaa6a, 0x21a9671a, 0x60570804, 0x8fb66807, -0xc3a49480, 0x2805c91d, 0xd3515af6, 0x57edfe32, -0x3ef3fb8c, 0xb9b3f95d, 0x1b022d82, 0x6ac3cdc8, -0x93533461, 0x0cc29053, 0xb53679f9, 0x72536952, -0x59649588, 0x174da5b2, 0xe60fcb68, 0xe283a204, -0x2f1ddc9c, 0xdd06e047, 0x831e2c61, 0xdab727cd, -0x3c2b5739, 0x1e3eda44, 0xbce6b352, 0x42d28a6c, -0x1853b1bc, 0xee1e42c4, 0x12a956cb, 0x580268d0, -0x3d38ba37, 0x116c2ffb, 0x0dfe6ab5, 0x7d5e4124, -0x0fd87017, 0xb2c764b8, 0xb1f2d593, 0x55d0c550, -0x3128f13f, 0xc57f355b, 0x71358d13, 0xa366b148, -0xa5999caa, 0x0810500f, 0xde6f01ca, 0x8e804f14, -0x1bf416c7, 0x9ed5c10a, 0xac57fdf6, 0x0adc8452, -0x87c10dfe, 0x9e91e726, 0x5318e4ce, 0x5e5c61a2, -0x82184d50, 0xabd125bd, 0x1099d5b0, 0x37bb1aff, -0x922e7b9c, 0x26dcffa0, 0xc475d907, 0x605ce8bd, -0x917dc18c, 0xb82f532c, 0x0fc4cac9, 0x7a906c10, -0x9fc533ae, 0xaead9ae1, 0x06bd7f84, 0x5f260e51, -0xea0a2a6b, 0xbdd6a14b, 0x8a5dc413, 0xd10c6dae, -0x57da8c47, 0xfee24743, 0x3667543f, 0x16dbca1a, -0xae745aa9, 0x0d0704d7, 0x6c0c7b87, 0xcaad8cf5, -0xf4253fa7, 0x34a938e8, 0x8859c3fd, 0x873c0ef6, -0x32231439, 0x4d10cb3e, 0x71f42b74, 0x8a1cf7f6, -0x74a894b4, 0xde6cac18, 0x73a68234, 0xd4d39962, -0xc9a966a3, 0x6336797c, 0x754d2166, 0xb5f6d9a9, -0xbc3ffb62, 0xdfa78a6d, 0x36fffa5e, 0xa50eb15f, -0x137e1dc9, 0x5e182fff, 0x5950daea, 0x6c196698, -0x20edd7ca, 0xa8545918, 0x14ad0958, 0xcd9d41c5, -0x6ac0641a, 0xb4433283, 0x9b3bd42a, 0xba3b53ed, -0x0db8e3aa, 0xa625208f, 0x0b45b37b, 0x86a2c3aa, -0x396f4971, 0xc4ff5d1f, 0x7e0bb235, 0x9fc0fa85, -0xe2d301a7, 0x45fed48a, 0x7b6346b0, 0x32870ec4, -0xe5e401d3, 0xc02ce749, 0x4463c76c, 0x3d433355, -0xbdcf9d76, 0xa9807de4, 0x618dcc22, 0x0fa04ef2, -0x3cc5f03c, 0x3efa8e43, 0xd6135458, 0x67e6b697, -0xd7183c35, 0xc549b990, 0x9ac7c86b, 0x9faaad31, -0x32e67f1f, 0xac089c6a, 0x740414f6, 0xb2eeffaf, -0x5cdecb51, 0xadae2872, 0x5cbe9f47, 0x6f61f816, -0x8ebea745, 0xda4dae33, 0xfab5beec, 0x6f918a13, -0x80c0d157, 0x38ec316d, 0x5ac2159d, 0x183222a0, -0xbdb1acde, 0x2818e447, 0x7c83489a, 0xd862dd8d, -0x39a9ec81, 0x5cb4b17c, 0xa21e593e, 0x80558237, -0x94abe977, 0xc9a7aafc, 0x9a46a332, 0xe840a903, -0x84f138cf, 0x4df461b3, 0x8eaef0cb, 0x7dff383c, -0x8aa5a95d, 0x1b5b18b8, 0x04649b75, 0x27ba2c97, -0xe0c53823, 0xd367e126, 0x51cee98f, 0x7641edec, -0x4cc92c61, 0xaad0cbf7, 0x580e6ef2, 0xc1d71b7a, -0xaff0e069, 0x8bfc7bdd, 0xd011b5ed, 0xcef17089, -0xd8043cc6, 0xa2928a72, 0x80c0c894, 0x7761bccf, -0x5207a887, 0x91350033, 0x4933943e, 0xf8f966db, -0xaa596d59, 0xdd4eee07, 0x8bc3f666, 0x5d2c317f, -0x4f884baf, 0x9656f8ed, 0x06960b18, 0xb854c6a2, -0xadb2111c, 0x87ec6839, 0x198d0349, 0x4bf8adea, -0x3774599f, 0xef939fa2, 0xa679ef16, 0xa4fcd9ff, -0x2266d9c3, 0x83bba05d, 0xf52cf76b, 0xbce694ad, -0xe7c72760, 0x8d1ea17a, 0xace588ec, 0x807156ad, -0xda75a2a7, 0x39aac1ff, 0x7baead56, 0x9069c021, -0xfc8fff1a, 0x7b6dbd4c, 0x20206990, 0x07c6e33b, -0x42399b00, 0x21c5c7b7, 0xbf63cbb9, 0x3826b73f, -0x352bb32b, 0xb9399307, 0x175009bd, 0x9c84ebb9, -0x10052749, 0xc688b555, 0x03e33f18, 0x6721a126, -0x19abdae7, 0x64f09e3a, 0x2a22e801, 0xa2713b17, -0x06a4726d, 0x6f4b5001, 0x59448714, 0x31cb2a1a, -0xf6de12b3, 0x99b843ed, 0xebb0167f, 0x71fd1234, -0x4c21a09f, 0x16e74415, 0x448e1a29, 0xb231f58a, -0xf285fb09, 0x1a1fd69f, 0x8014d055, 0xe6457a61, -0xf5fb7454, 0x84692b92, 0xc95945ce, 0x5edf180c, -0x87b224ae, 0xe527b249, 0x70b92e8d, 0x222ffacf, -0xfc157ef7, 0xdddecac5, 0x2835b04a, 0xbd3a47b6, -0x4cf46a93, 0xd2e21769, 0xf17f68d7, 0xb357c4a5, -0x2897c2f3, 0x33d36f62, 0xde21b713, 0xf31fb93a, -0xfa426665, 0x40db2038, 0xa0a64518, 0x039a4901, -0xa62dfcd5, 0x415eef87, 0x1b4fff92, 0xd052150a, -0x62765368, 0x085033dd, 0xe689328b, 0x75e91e36, -0xd84b42ac, 0xe7c5b3b0, 0x406148de, 0x292110b8, -0xfa865732, 0x47b9bcda, 0xb60f0ecd, 0x47823acd, -0x0ee97131, 0x82887810, 0x02ce6d38, 0x17569eb6, -0x93d99227, 0x06b9ddae, 0x4edbff17, 0x143e9971, -0x4b3930b6, 0x193584f2, 0xaff7ba40, 0x5e2306d1, -0x80871fa1, 0x75dcd3a5, 0x5b41a3a2, 0x37789713, -0x5f4a2dd8, 0xf864f01e, 0xe042a3e8, 0x4148ccba, -0x827a61df, 0xf5dbd5ac, 0x67cd2158, 0xd4b6d338, -0x1b1aea2f, 0x23faa332, 0x1194b5cf, 0x2f0f9f2c, -0x7f969cff, 0x96d0fd45, 0x38d28fde, 0x60cec7a7, -0xed38edf1, 0xbaad9030, 0x128b3b1a, 0xf4ea7a25, -0xcdb0accc, 0x583ca262, 0xa6e1a5cf, 0xba31cb5b, -0xde2b746a, 0x752270dd, 0xcebf4dd9, 0xef01a663, -0xb69ec990, 0x6931f11f, 0xac096cd9, 0x73475308, -0x84b4c642, 0x66033d8e, 0xae232f55, 0x28cb582f, -0x34d9b8bb, 0x5edf44d4, 0xd1181d1a, 0x4ad90f85, -0x3ff56f90, 0xdbcd8501, 0x94a1819c, 0x3271541b, -0x27ada641, 0x2dfc9ca8, 0xe62d5a90, 0x088b3d3f, -0xb3cf5f12, 0xaf069a37, 0x63679b19, 0xaad7d449, -0xcc5fd5b8, 0x5a9142fc, 0x0281927c, 0x2d0ce3fe, -0x3037817c, 0x94d06391, 0xc13fa032, 0xc636a8c4, -0xa1a0c778, 0x65aa8b75, 0x9599c263, 0xd94cdd90, -0x8eb558d6, 0x4f3749f7, 0x78e950e0, 0x38643ddb, -0x65ee43c0, 0x9e363d33, 0x3b87741e, 0xde6e407f, -0x19de335b, 0x19e8d2f6, 0x90802537, 0xe7d6d63b, -0x1787f368, 0xcbf66cbe, 0xba3a37b3, 0xe263b083, -0xb64aaf3e, 0x4dec8202, 0xc4f5e604, 0x27ee4210, -0xbed9cf46, 0x358781a4, 0xaf9eab78, 0x18be9c90, -0x6a623920, 0x7c057b86, 0xf882d402, 0x50c46ea1, -0x803649c9, 0xcf3d7300, 0x3089fe4b, 0x9b7e1531, -0x61f911d2, 0x4136335a, 0x69170b86, 0xc62a5260, -0x450e0b60, 0x3c0b08b5, 0xe44c8860, 0x145726b9, -0x97813960, 0x37b361ad, 0x6b1b616b, 0x9989ea33, -0x01f7789f, 0x61e28cf3, 0x40e1512d, 0x8a8f9865, -0x55124a0a, 0xaf373d35, 0xeb7fa4b3, 0x6a4add68, -0x012b5446, 0xd3ab99bc, 0x9b6db31b, 0xd10c995e, -0x98ccaf6a, 0x9bf82cb4, 0x54682b04, 0x2f631ee7, -0xdd94cb6d, 0xb7f94c14, 0xec5c57d6, 0xbc65b92e, -0x70f7668f, 0x00ee9567, 0x3ed5c805, 0x13fba1b8, -0x5af52407, 0x1856675a, 0x365594d4, 0xc3a83e4e, -0x6515d279, 0xc2979baa, 0xe7cc9eda, 0x61f01f53, -0xf9411245, 0x94bec7fa, 0x50549553, 0xdc19a9c9, -0x681f8f34, 0xcf46edda, 0xb8375cb0, 0xc70b2756, -0xd399d9ab, 0x4dffdf90, 0xeebac705, 0x2d44101a, -0x65964dd3, 0xbe60aed4, 0xd1b290a5, 0x290da975, -0x62eff9db, 0x35009e42, 0xe27a522d, 0xb24ce07f, -0xd2ca2fd6, 0x0d5a5a9f, 0xf6cff261, 0x26ec16a6, -0xacd666ff, 0x5fee597d, 0x8467e190, 0xb8cfc7be, -0x82fb971c, 0x441e6b0e, 0xfee1caf8, 0xf5fb071f, -0xb056ab46, 0x75c330b1, 0xf0bc85bf, 0x69b331f3, -0x0256e176, 0x1435996b, 0x702f75df, 0x4154cced, -0x4b40453b, 0x3f7abb20, 0xce3b0aa1, 0x766fc3bb, -0x81fd4c44, 0x17b8ba52, 0xd7fb0e9e, 0xff374026, -0x0b698083, 0xe4a6c9b0, 0x18eb2f49, 0x9aae1e7a, -0x32484742, 0x6139d119, 0x9350ea46, 0x7ed9de20, -0x2131f58f, 0x52549b17, 0xb201f3ac, 0xeb7caf13, -0xf4036d92, 0x9428e976, 0x89421ca7, 0xf60b6995, -0x59bd4fa2, 0x89b86ce6, 0xa469f764, 0x48d8c8d0, -0xe66cbf97, 0x8dc7d81d, 0xe3f905b8, 0xd7b4cb0c, -0x9132fa6b, 0x4aaec41f, 0xabf68871, 0xef4802dc, -0x12526fda, 0x45526faf, 0x3932bfef, 0xef6dfc38, -0xc080d9b7, 0xc72f8598, 0x573ab055, 0xdfb72b23, -0x9dc53edc, 0xfd3ac5ec, 0x84e50e7c, 0xbfc9eb65, -0xb3056c3d, 0x5a396aa4, 0x6180b509, 0x219e1fd4, -0x7e138823, 0xd2e65b21, 0x5fd36b8f, 0xe6d8abf8, -0x56b88085, 0x66c05230, 0xe22ca851, 0xd720f405, -0x856f9be8, 0x35a8682e, 0xf275d0d2, 0x7288a85c, -0xb255eabf, 0x2f3e676a, 0xdd0d28bd, 0x8a8fcc09, -0xd8428b2d, 0x22e52a0d, 0x7b483bdf, 0x14d41be6, -0x05ae59cb, 0x063658cf, 0xb24da744, 0x48cd0f2b, -0xbca96305, 0xa999b0d1, 0xa2c42f68, 0x2bfe1725, -0x9ab27e6b, 0x4f79bb59, 0xa64ed14d, 0x5c46ff15, -0x2e660ef7, 0x0e8f0bd1, 0x2bb94584, 0x190d693a, -0x5dfe96af, 0xc5d7361c, 0xf9be47e2, 0xea6fa47f, -0x0d8a0095, 0x272553da, 0xb2737912, 0x49ecee43, -0x33df06fb, 0x17760780, 0x97947161, 0x1fa88e08, -0xe88078be, 0x5f759a63, 0xc9844461, 0xce746b70, -0x2b72adfd, 0xd19d71d3, 0x7238c74e, 0xb55d71ed, -0x17fcdfcf, 0x1e6c0047, 0xa9bf858e, 0x5d296185, -0xae4161d8, 0x2d56e96f, 0x7d060ca2, 0x6e799e8d, -0x1e587bad, 0x57ea2e0b, 0x33614106, 0x2b484b37, -0xb10269ce, 0x7c974af9, 0x75f443de, 0x9717aa1e, -0xabc80de1, 0xfd1dbed1, 0x71621211, 0x60cc7d40, -0x54e1ec96, 0xdc91d8f1, 0x2393f240, 0x4a3dbc49, -0x29222229, 0x2c0c5518, 0x470aa74b, 0xcddb9fb3, -0x61e605f3, 0x337cf31b, 0x1ba0b540, 0x398d5f76, -0xa22b6df2, 0x8bb89ee6, 0xbbfc6357, 0xf74e79f9, -0xefda480b, 0x30ba8b7e, 0xfe4e03b0, 0xd04fc0c7, -0x86258634, 0x2adfdd62, 0x4e4f2674, 0x93e56b8c, -0x2e78c5c6, 0x4e76bca5, 0x48679d44, 0x3a846da9, -0x5d6b12e9, 0xda73232b, 0xe34251b0, 0x17572f6b, -0x6729b544, 0x7990f599, 0x7554c71b, 0x1fb8bad4, -0xb8f81a89, 0xdd65611a, 0xc513ff44, 0xbe474f5b, -0x5e80d269, 0x74df7437, 0x3229f1b7, 0xad061e9f, -0x859ded69, 0x50d5d7af, 0xb7f7694e, 0x9d6f43f4, -0x5f9aa11d, 0x27d7765e, 0x959e33dd, 0xd1bd686e, -0x501d92e2, 0x78713be5, 0x790e3965, 0xe500cbdf, -0x10eb1fd0, 0x4928cfe5, 0xdf1c5a8f, 0x05b87e8f, -0x701ed594, 0x767ffa32, 0x68856c65, 0xe2f77b4e, -0x56e77c33, 0x29ed2f13, 0x28188b9a, 0x7571dafa, -0x3f41e634, 0x127a9d8a, 0x995f90de, 0x629b5f7b, -0x22b8bc77, 0xe6676784, 0x047d5585, 0x02ca1b60, -0xcb355de1, 0x87c0874b, 0xd0397ac8, 0x2fec1fa8, -0x1db32444, 0x19fdca51, 0x51b00b88, 0x89a639a0, -0x6bba927a, 0xe9c450d2, 0x4fc2e197, 0x5a51e78b, -0x05591a54, 0x37aec32d, 0x561e2be7, 0x8a32f3fa, -0xb11b25d4, 0x29fb5a20, 0xd6ca46e4, 0xb07fa849, -0xd9957eb8, 0xc9f1a9fa, 0x2c7d8fe8, 0xfe6a0c00, -0x827104b5, 0x46ab8392, 0x67b92aa9, 0x7092a67c, -0x50f21bf0, 0x1606d8a6, 0x54719270, 0x82d4396e, -0x8a104a73, 0x4bc8d4da, 0x304c9461, 0xe1bf9cd4, -0xa192be94, 0x785a2869, 0xbe01cbd6, 0x01f0db0a, -0xaa8344d6, 0x86e888d6, 0x9b5a12ac, 0xe854ac02, -0xda115ff4, 0xb51036c4, 0x22576a19, 0x485e719b, -0x1cfa4ec0, 0x5e595cca, 0x04ba7b4d, 0x8ec44bc6, -0x1fb7cee3, 0x7b0b14d0, 0x04e5d7d0, 0xeba53547, -0x6bbb70a1, 0x4400a5ee, 0x9a9812a5, 0xa205ed91, -0xf3ee9643, 0xa06c7cb3, 0x353769ef, 0xbc09cc16, -0x416e44f2, 0x377c09ad, 0x3aea4eb9, 0xac3e0267, -0xfddda8df, 0x7e14d6c3, 0xa9cacbc1, 0x29097dac, -0x429a81b3, 0x7599f50f, 0x13e76171, 0xfd9decfd, -0xea8f3e9c, 0x5d294f3f, 0x0ee430a1, 0xc1e5a5cd, -0xe52520e7, 0x21d11ee0, 0x1737107e, 0x442337a4, -0xf9280fb8, 0x2fb5a79b, 0xce7a2d53, 0x14726542, -0x75442521, 0x5b857d70, 0x5e4b99ac, 0x083ee63c, -0x0e119350, 0x645bff73, 0x79675cfd, 0x0e97488b, -0x45324433, 0x519f148c, 0x5f633f22, 0xe7dae749, -0x4bc5ed84, 0x41b75046, 0x4c896935, 0xbe62efed, -0x2daaa2bd, 0x35847f0d, 0xb2c0f967, 0x93bdfe83, -0xe727d414, 0x2ec67c2b, 0xfaab854b, 0x41f3d471, -0x607aacb1, 0xd57e119d, 0x1b8bd447, 0xd0e142de, -0x9f1e077a, 0x1c17468f, 0x1a280618, 0x22afd414, -0x777f95af, 0xc826fec0, 0x94d48e76, 0xef1c2700, -0xe244406e, 0x3de39dcc, 0x940ea18d, 0xabd1e1c4, -0x43e86576, 0x56854524, 0xe145c15e, 0x77c8451e, -0xd324eaca, 0xcad6624c, 0x71a3f2f0, 0xfad46198, -0x990e97a9, 0x2c446253, 0x98fe1658, 0xf2310f28, -0x1533c8ce, 0xc0e1b15d, 0xc7b6d88e, 0x899bf940, -0x1ad68ce3, 0x9aa8a706, 0x99d17ba8, 0x920af51c, -0x91a608df, 0x4464df39, 0x715838cd, 0xf6c922e0, -0xe258422b, 0x1994f795, 0x074006b0, 0xc464ddfd, -0x1920413d, 0x4b083da2, 0x7a1176c1, 0x992107a9, -0xc521b43a, 0x10d41801, 0x5dd7305c, 0x6087ac71, -0xdb685110, 0xee9362ea, 0x85ed6159, 0x53c25065, -0x054ab00b, 0x71f7502b, 0x9c63ff30, 0x31c61d73, -0x2252d5df, 0x2b6003c9, 0x6556a10d, 0xbc818248, -0x6670ae3b, 0xacc67d1f, 0xabaa2c5e, 0x4d466a07, -0xa871ee83, 0x49ba540f, 0x7c84296c, 0x7f4f595e, -0xce6f9fe5, 0x4c519f34, 0x56f6c5ef, 0x6ab2488f, -0xd3dc9fe0, 0xe5d3d063, 0xd553424f, 0x4e20c7b5, -0x3b0bf2ca, 0x6be78ea2, 0x5d13cc5e, 0xd1140e2a, -0xf06a2c44, 0xd4413646, 0x332ed443, 0xc03cbf94, -0x7ccff645, 0x6252264f, 0xb96f108c, 0xaf3a11b9, -0xee9f9544, 0xe851ebab, 0x5b607b84, 0xcb9c2960, -0x1048922c, 0x44b0a0b1, 0x79d18be0, 0x26b80688, -0xdbaa475e, 0x811bdcbd, 0x4cee3d7c, 0xc74db453, -0x5f9ace5d, 0xd9aec19a, 0x20561be2, 0xaaf822ac, -0xf430145f, 0xe6e3cac3, 0x48bd2a97, 0x24d72d5b, -0x966fb875, 0x64c3d7a9, 0x5e71a697, 0xf1884978, -0x48dcc4db, 0xad3e0810, 0xb90f4750, 0x319d0d37, -0x7a8b8c5f, 0x9f3d53e1, 0xd87f1c6f, 0x8d9101c1, -0x3f1b112b, 0x3bf5dc58, 0x7ad04a6a, 0x94ef3321, -0x916e4210, 0x51c7e5d8, 0x91d4aaba, 0xa3e92a47, -0xf56b2eec, 0xfff66c52, 0xa9e13a9c, 0x0e96167b, -0x355497e7, 0x24338ae3, 0x45b2bb97, 0x0bc273b5, -0xf6a51e39, 0xe7248a3f, 0x60415a1d, 0x0010160b, -0x1dafe42b, 0x48c1e4fc, 0x02953f7a, 0x218acf1e, -0x388cf8fa, 0x28795d41, 0x10359290, 0x501fae08, -0x632cf79e, 0xdbe8fe58, 0x65eb9215, 0x017d15bb, -0x931e266e, 0x314f2c88, 0x8eab618a, 0xcea54b6f, -0xaa0a8989, 0x7da3bc7e, 0x32d0dba9, 0xf3688c01, -0xb0bf7b1f, 0xd9da409f, 0x993d9ea8, 0x5af04221, -0x95128910, 0xf158568f, 0xb042f372, 0x7b17439d, -0x23e94398, 0x313dcc98, 0x5845bbfa, 0x33b01435, -0x2bf39159, 0x9d0163d5, 0x8ed36b3b, 0x8e2cb1b3, -0x5ad64e67, 0x0b24b30f, 0x9c423d07, 0xee38d2c2, -0x4598587b, 0xa52a5a8b, 0x881bd68a, 0x769980fd, -0x2214a562, 0xd702ab7c, 0x1c2b0138, 0x0c62a1e1, -0xdc7ad108, 0x52686332, 0xfd49ba5b, 0xf647862f, -0xf4b4c25e, 0xbecff488, 0x3d112666, 0x4151440c, -0x8f88957e, 0xc7383393, 0xa2d5a80c, 0x83c77173, -0xeeb5a0c7, 0xd1fbb00a, 0xffaba1b8, 0x2414d540, -0xaf6d282b, 0xd3969374, 0x425f56be, 0x1baa5bf6, -0x011d6396, 0xfb391bf4, 0x58302ef0, 0x7ee79065, -0xde53c818, 0xd2e4da9c, 0x465ce80c, 0x0ceb8e12, -0x9e66863c, 0x79906fc9, 0x4c0e2950, 0xd1956004, -0x7cdbd82c, 0x3441c0cc, 0xcfa22192, 0x295cc89d, -0xcc555616, 0x9b85a047, 0x2e77b8a4, 0x7b39da59, -0xe15a873d, 0xf20cc541, 0x335c495f, 0xad4ba104, -0xb07dd44a, 0xe7edbefa, 0x3085a397, 0x38d20199, -0xb2cb8c58, 0xbe4f5b8e, 0x24071764, 0xeb0164ff, -0xd9772703, 0xb4a36e97, 0xa4a7a9ca, 0x604b41c7, -0xe532829e, 0x168229c1, 0x76af50db, 0xd54afb5f, -0xca210b15, 0x175f6203, 0xd2fb4e6e, 0xf547b193, -0x188452a3, 0x94b32fe9, 0x5c829304, 0x9e979e44, -0x29130895, 0xd0f53fe6, 0x4317f4f3, 0x2017a46e, -0xd327054c, 0xf2660046, 0x328eb545, 0xf15a68c4, -0xd43050a1, 0x9efc1075, 0x15d55067, 0x102212a9, -0xb7f7b5f5, 0x248c4355, 0xa637a511, 0x17b73dc9, -0xf8d8ce75, 0xa0b93c92, 0xa4d0f2ba, 0xada786c9, -0x9f0e1ed5, 0x81b07c6d, 0xa8c90b39, 0xa747a8c1, -0xf1456a32, 0x54ea6ee5, 0x72ae1925, 0x95c94ac0, -0xc4b0fa59, 0x79732e29, 0xfe575e46, 0xa0e7debe, -0x29fb8dce, 0x83b49983, 0x46569a83, 0x5057c58e, -0xbd8081b5, 0x92a2c2c0, 0x793fbeaa, 0x0f4c3880, -0xa2c7638a, 0x1581b3af, 0xf67a4923, 0xeacbfaf4, -0x7b9d4a6e, 0xeecb97d5, 0x7d0516e5, 0x9962e310, -0xc245572d, 0x65b71f33, 0xb44b9d58, 0x3517e28d, -0xbc16c41d, 0xd0b66301, 0xe3416d81, 0x585e029a, -0x9aed1a96, 0xc2086505, 0xd4cf4192, 0x744f0c24, -0x632e8411, 0xa44f1511, 0x81f59fc5, 0x8cc6c2ac, -0xfed3beea, 0x34c110a8, 0x7cb634b2, 0x62456643, -0xc504313a, 0x98c26f55, 0xd4ed7e11, 0x7bfeadf6, -0x7c68d58e, 0x65e66a1b, 0x2f1d6e7c, 0x8c1c08a1, -0xb563a4d5, 0x312f84f6, 0x8401e81d, 0xccfabe08, -0x61fdc464, 0xffd65aba, 0xd8bd89eb, 0xce23114b, -0x31e128aa, 0xaf95b80c, 0x84270ee9, 0xcb137f47, -0x79410289, 0x07a93471, 0xe68ef23c, 0xe1fef2a6, -0x6e0e8314, 0xda2cce7d, 0x894121a3, 0xfb1c20c5, -0xd1752395, 0x5626b1dc, 0x05053336, 0x86ba92be, -0x23370320, 0x94f8549f, 0x5f5b72d3, 0xaf78f301, -0xaab0a8b6, 0xadace3b9, 0xdefdb66b, 0x0ce3b4e0, -0xee9b4962, 0x5719d4d2, 0x2ff50570, 0x0702fcfb, -0xc5e3630f, 0x8eaa58c4, 0x9ea47bb1, 0x881a17da, -0xe6fb697b, 0xaac71f0f, 0xfa62241c, 0x2ccb5198, -0x94cc4c46, 0x366aa148, 0xbcb59a64, 0xe1cfc0d7, -0xa38458db, 0x51a86430, 0x66495b4c, 0x571e1a8b, -0x2114fcae, 0x69dbaec8, 0xf3a66ba1, 0xd23994e2, -0x57fe8cf7, 0x204a3626, 0x7f03d4a9, 0x59250a4f, -0xb45a4c83, 0x6aa274c6, 0x31290be8, 0xeed74069, -0x33aa8f54, 0xdd2c206b, 0x0d5ea41b, 0xf8328f3e, -0xe6cbc951, 0xb799de80, 0x43829de5, 0x328e0b46, -0xd6ec89e3, 0xf529db37, 0x7ea69733, 0x62de055b, -0x2056a292, 0xce1c1a8b, 0x8e357d35, 0xd2417621, -0x04a01591, 0xee3b5744, 0xc06f5726, 0x99a3adda, -0x09d0feb0, 0x14cccd6f, 0xd83e76e0, 0x222e6a5f, -0xe5632e53, 0xdeccde3f, 0x1a0c0867, 0x507df575, -0x22ed6f2d, 0xb3ef1d47, 0xfc6063b8, 0xe60ba55e, -0x7825ab4d, 0x2371145b, 0x5ad1fdba, 0x19d4bcd9, -0xb722e8ba, 0xbad38438, 0x9b48640e, 0x73b84413, -0x0e97c7df, 0x0946d2de, 0x229b14c9, 0xe86393e6, -0x81ddc735, 0x68062add, 0x41958b5f, 0x5124eb16, -0xd94d6103, 0x381dfb2d, 0x61aa9925, 0xa7dd0b80, -0x9b53ab59, 0xb9d42823, 0x04dcbd9f, 0xfaeb3642, -0x6aa38344, 0x4027c476, 0x555b44d6, 0x8eb0afeb, -0xfe7306f1, 0xe76f488b, 0x3b7a503f, 0xb6759184, -0xaeeaadd1, 0x2e29c3a8, 0xe24a70b4, 0xe4479032, -0x7771f192, 0x64f84949, 0xc94fc39d, 0x373a5e00, -0x36da2363, 0xe3041a6d, 0x4b2b99e4, 0xd78e9084, -0xbf85da93, 0x2f205941, 0x40417315, 0x13c24a8d, -0x1c10b3b2, 0xdbb78ee9, 0x7253a034, 0x731ecefd, -0x6cbd8f22, 0x89d3f5f0, 0x2bfa135a, 0x333743d2, -0xdb92aa03, 0x90b6b014, 0x63dbde46, 0xd1882651, -0xc2bdbd5e, 0x00894dcf, 0x1b03a8f0, 0xbab43173, -0x96aae94a, 0xfbfdc1cd, 0xafbeb8ec, 0xcb355db4, -0x08c378bc, 0x0ba33d68, 0x85085217, 0x1ad58bbc, -0x8dfc9a71, 0x738a1272, 0x9dca5e36, 0x449d6a9b, -0x7b4f18b9, 0x38fb74a8, 0x8af301ff, 0x3374f77c, -0x89f5bd81, 0x97ee33b6, 0x5b3c2abf, 0x77959b7f, -0xe7a9e3d9, 0xfe61f610, 0xeec7aa5d, 0xde51356d, -0x608257bf, 0xf63043d5, 0x5d7c9ed2, 0xc5840799, -0x359a23e3, 0x55af6d85, 0x6d1f36d1, 0x5656d4fc, -0x832d9232, 0x2d2f1b9a, 0x657acf9a, 0xba7453fe, -0x1e4353bb, 0x032b7e1c, 0xffc9545d, 0xe7070df0, -0x0cbe6d83, 0x17e09169, 0x424d17bf, 0x9b00a500, -0x4eb5f38a, 0xc28b10e7, 0xbd33f464, 0x7249d152, -0x3bfd62cd, 0x970eccb8, 0xb80363d9, 0xacd54c7a, -0x1029a85c, 0xf0134460, 0x23fbc0c7, 0xca2239b8, -0x56e00b18, 0x3bb4e8e6, 0x4c6e8615, 0xfe76765a, -0xa67d48f1, 0x5a0e654d, 0x1e5074bc, 0x11458823, -0x45be96c3, 0x72d2bbbd, 0xf9ecca30, 0x939a0c23, -0xd8635ef9, 0x79e067e4, 0x1484f9eb, 0x7dcc8542, -0xf4929883, 0x493ea4ca, 0xed8f3860, 0xf04ae72e, -0x80a2053a, 0x538c4988, 0xea3362a7, 0x4fbfc698, -0x581aa5b7, 0xdf65bc6b, 0x7d31a626, 0xf531c7bf, -0x927f6fa8, 0x8055a9ba, 0x8dc807a6, 0xd81f09a8, -0x68c2dc82, 0x3af8c10f, 0x73a53137, 0x08b4e64e, -0x76304c20, 0x52c08eb2, 0x5a882a35, 0x6b67f389, -0x4fbc83fa, 0x2ca8fa77, 0xd11668bb, 0xbad67e00, -0x85f0a180, 0x0d8b1ae4, 0xd38a322f, 0x60da109b, -0x593bd498, 0xe51b2bcb, 0x14648c80, 0x726800ab, -0xa3eeb97e, 0xcaef519b, 0x1908766f, 0xe80ea4d0, -0xbac31e8a, 0x9beb5e13, 0x6fa0eea7, 0x6bf95c26, -0x3e6deb1e, 0x9786dce1, 0x70e9bf69, 0xfb302104, -0xc8e16ca7, 0x519738cb, 0x37149a41, 0x381f5178, -0x3ad0350f, 0x5ea9af95, 0xf4461908, 0xc87a9ce6, -0x6f52e0c2, 0xd1769989, 0x0a744f5f, 0x3b8fecb5, -0x52a949d4, 0x4babad95, 0xb0341b77, 0xd809acba, -0x651a3f0d, 0xa9801f9f, 0x39ce6bd9, 0x54ba7ecd, -0x696986f3, 0xed029c7b, 0x906b778d, 0xdff29490, -0x38602541, 0xf58f4ff6, 0x86b4b9bb, 0x790607c6, -0xc37401a6, 0x9030efee, 0x8cd44992, 0xe70c9534, -0x3530865c, 0xc390247b, 0x13550b6c, 0x87894843, -0x955ad8f4, 0x95440ce6, 0xd1c22858, 0xb499cf5c, -0x5e83df19, 0x81056e1f, 0x6d5112e3, 0x75638145, -0x39bf2dbe, 0xd72161f3, 0xde557eb6, 0xf6356398, -0x2db46a89, 0x4557d1c8, 0x8c6a0ecc, 0x0bae6c6b, -0xcc7f6792, 0x204b7e6c, 0x30fb0b31, 0xa9fcf48b, -0x2663fbf2, 0xee93a15f, 0xbe4a98e4, 0x19a8385a, -0xfbe22598, 0xb359c818, 0x95b82ff9, 0xf3a6ce4b, -0xfa116c0c, 0x0fda53a4, 0x4a685f72, 0xdd4d1832, -0x3755e730, 0x7aed0ba0, 0x4633fa17, 0xd7758b45, -0xfa089372, 0xb91b36cc, 0x6a7260cf, 0xb4918d74, -0x7eda9ce9, 0x8dd13de9, 0xcad651cd, 0xa6a338dc, -0x8c6813ff, 0xff9c45d2, 0xacb2fcfe, 0x95ae0113, -0xf70cd5d6, 0xd4dee57f, 0xa58c4343, 0xbe104819, -0xff3ffdc6, 0xd7f64302, 0x4ca59221, 0x08793ce8, -0xb9c821a6, 0xa99c55e3, 0xabcadfc8, 0x0b88f942, -0xbd08e78a, 0xaca643dc, 0x1b30e3f9, 0x12bfac11, -0x9796af2a, 0x9a7f3972, 0x65e221ab, 0x6d7594a3, -0x54b82988, 0x6b278381, 0x8769e5d1, 0x965b6fe3, -0xbebe9b21, 0xb6f36bac, 0x8f8da33c, 0xd77aedb8, -0x1775b5a1, 0x2984fbf8, 0x3b0fbf44, 0x17773ea5, -0x760f6088, 0x018bd34e, 0xeb774a8d, 0x567fa718, -0x17ca8b3f, 0x8220432c, 0x0f68e4a9, 0xff117c90, -0xd67b800a, 0x7a461e15, 0x82c188cb, 0xba47152b, -0x13b23fea, 0x8e61dee1, 0xd9f1c761, 0x8ff89de5, -0x62cab21a, 0x8f85728c, 0xc6408884, 0x43a2a469, -0x8b3e8f18, 0x043f4824, 0x14659589, 0xb090d5f2, -0x05a91efd, 0x224d84b8, 0xc79f169e, 0x1d8046c7, -0x3d4ea750, 0x221c9d30, 0x2c5c2087, 0x7fdbac5f, -0x91fc2da8, 0xa736e278, 0x39038cf8, 0x67b0b71e, -0x0f250a19, 0x53087b1c, 0x9729ebe3, 0x348b2d1b, -0xb3a24d9e, 0xd08da55c, 0x74538332, 0x5cfc072b, -0x694e58ce, 0xb394df82, 0x91588d91, 0x02996ac4, -0xf013b27e, 0x07f66569, 0xc1753619, 0x3ddebd53, -0xfc2ac824, 0xff42acf6, 0x977393db, 0xf67b0e95, -0x4fe47e2d, 0x87907f18, 0x107db3b3, 0xdb35340a, -0x28769056, 0x80edeb2e, 0x747d2f05, 0x01f73d97, -0x173beab9, 0x2a040ce3, 0xc129d573, 0x1251d4d2, -0x73c76801, 0x0f878167, 0xdc036e20, 0x53e3f76d, -0x2323c75a, 0xe340042f, 0x964a789b, 0x89a041f2, -0xe67a8448, 0xe3671b2c, 0x710d8f54, 0x6d694024, -0x74a7aad9, 0xfc1837e1, 0x38a71de9, 0x5006c498, -0x641f95b7, 0x7d864289, 0xd342a49a, 0xe5010ef9, -0x8c496b4a, 0xfb358af9, 0xf1f9368b, 0x7cca6a36, -0x8618bc87, 0xeb3ae8bf, 0x61f48970, 0xc6e5062d, -0xd2461f57, 0xadc1e245, 0x2dd9e925, 0xa9b2e37c, -0x697b8bec, 0x3b451a73, 0x76e080a6, 0x7b912795, -0x97d2e126, 0x50c2f330, 0x9bc93379, 0x9d7b0df4, -0xd83e5fd8, 0x8c5e8721, 0xac7f7b98, 0xb3a91e35, -0xa7cc3d9c, 0x747bea50, 0xe1678746, 0x21c5f8f0, -0x628ae8cc, 0xcff34e1e, 0xcba82f25, 0x3bd5ec0b, -0xd7e1372d, 0x0da6304e, 0x1d32c4a6, 0xa9d49a28, -0x544e2e21, 0x7264fd82, 0xe7fbeda6, 0x9ba8dbc8, -0xd24a521c, 0xc785dd05, 0x698b547c, 0x71a9c242, -0x507586a0, 0x4dcaf039, 0x5f217691, 0x188831ae, -0x060ed9b0, 0xde29bf1e, 0xc6b29e32, 0xa0e030dd, -0x899343c8, 0x294cf5e9, 0xb877c367, 0xc62a6c28, -0xef88131b, 0x702282e4, 0x6429b119, 0xdd745d70, -0x6bdf924b, 0x8357bf5f, 0x75eed80f, 0xf16e71b5, -0x29889692, 0x8af3075d, 0x8cd9ca44, 0xcb8845ae, -0xbbeb0ca1, 0x9d596b21, 0x5f5a1ec5, 0x6cc0c183, -0xc608ded5, 0xd31604e0, 0x3d85e5e8, 0x9bd4fa8e, -0xcc34132e, 0x5940460e, 0xe268dbe4, 0x52cf9287, -0x1b7dbb06, 0x25730036, 0xaa32d1e7, 0x5c1fdd22, -0xec1cb109, 0x44087118, 0xe09798e5, 0xab01caa1, -0x9bcec119, 0xd5fdd6f5, 0x27aeaea1, 0xea78729e, -0x1f420935, 0xa1d70ee6, 0x049df2ae, 0x83c20e63, -0x424f97ab, 0x82d47ad3, 0x1d83d1df, 0xb4161ca7, -0x3f5e0b50, 0x958a9041, 0x857a9d99, 0x7d9d91f8, -0xf99e7712, 0xbe771046, 0x51be59d5, 0x66ea6488, -0xeb6650ac, 0x97c180a2, 0x21dc2bed, 0xfd8d86ad, -0x640d9a16, 0xc41c9b74, 0xd88a707d, 0x92cb7073, -0x85e68614, 0x139f86ad, 0x6627608d, 0xe9fba87b, -0x5a3d3b3f, 0xea153824, 0x393feea6, 0x642338bf, -0x48ff83a1, 0x62abc55b, 0x0454c198, 0xf8515e0f, -0x8f0604c5, 0x4e8ddd6c, 0xc0edf728, 0xff750695, -0x78a7776a, 0xfbbd9cb4, 0x46d78b35, 0x32c0aeb3, -0xe45bf2f2, 0xd5c3bc58, 0x8b3e46c6, 0x24400769, -0xc64bf282, 0xb30596e2, 0xdf516e75, 0x80527d5a, -0x5abf0966, 0x0872d2f9, 0xde4b188f, 0xea935446, -0x841ab5e1, 0xdc1322fc, 0x652e58b7, 0xec7bb00a, -0xdc48b52e, 0x603f7d3d, 0x02752a69, 0x24627060, -0xaf9745a6, 0x38f20f01, 0x5633a1b9, 0x8a1970e8, -0x09246a35, 0x6fa51a58, 0xd2b27306, 0x74103348, -0x7941c71c, 0x9f3e195f, 0x9ba8cef9, 0xb99d6c7d, -0xbe43300b, 0x1ed69899, 0xd6ef4ae2, 0xbd3fe197, -0x23cc030e, 0xd0bef932, 0x2db820c1, 0x8877612e, -0x9128ed01, 0x0e755f8a, 0xfe2c9806, 0xa15d724f, -0x95d18472, 0x1eedb954, 0xe744521c, 0xf7c96972, -0x1ed14fe3, 0x53cce19f, 0xaf56d69e, 0x9cce0147, -0xf66e30fc, 0x1d67d01d, 0xd7b7e307, 0xc4a6385a, -0x0ab2a974, 0xefe450b5, 0x943700b8, 0x63348d22, -0x0f9174c1, 0xcde51bdc, 0xb7f8d4e0, 0xbb7e75e4, -0x3cb583d9, 0xd7e0dda5, 0xd0875b4a, 0x8a64f15b, -0x4d9cabd4, 0x629cc9f5, 0x27e71c36, 0x8bf12d0f, -0x3ef45763, 0x6f0b34d4, 0xdd8b2dff, 0x82a5095c, -0x02bab80d, 0xe5a68cd3, 0x68995a29, 0x0df37ce7, -0x14d44f9b, 0x90e6505f, 0x0dc08cbf, 0x56f5b89d, -0xf4f14479, 0x4ebe183e, 0xccd9360f, 0x53879eed, -0xcc70e90f, 0xe617267b, 0x57338015, 0x54552eec, -0xceb90d51, 0x44a3ae6b, 0xa0f7cf7a, 0xb525e534, -0x413f377e, 0x269d35f5, 0x4c0a3729, 0x55a81cd6, -0xb5d498f7, 0x06e32c31, 0x6740688f, 0xaec33d8a, -0xed352319, 0xb11b6b74, 0x59345c58, 0xb8539660, -0x38bd4440, 0x2e1316ae, 0xc0ee6600, 0x37fc4283, -0x3932a038, 0x203ec984, 0x13caa3fb, 0xb490d47a, -0x70e3cff4, 0xaba8ced9, 0x677d746e, 0x6303c4d2, -0xfa740ec4, 0x71bf15bd, 0x263bd4c7, 0x62dfa93e, -0xb90d9d4b, 0xfeb8e8e9, 0x624358af, 0x89b70973, -0x81cb8cf6, 0x438f014a, 0x1d65b30f, 0xce203f65, -0x11aa98bf, 0x5ccc683d, 0x2045a241, 0x1c0330a3, -0x1e42aa70, 0xf398c278, 0xec636e99, 0xfd81d6f7, -0x7313adb8, 0xfbce08cc, 0xeb3e10d3, 0x0c957e90, -0xd8385cc1, 0x6f10683f, 0x3c0c8426, 0x933e5847, -0x72bec41f, 0xea07ff15, 0x68dbbdfd, 0x18e77edb, -0x69f25646, 0xbe6070dd, 0xdb274397, 0xdd37d62c, -0xe06a88d6, 0x212cd794, 0x1f245c16, 0x69a23bd0, -0xba9c2078, 0x9aa26c67, 0xe4536bb6, 0x74555886, -0x403a8213, 0xc1895ebc, 0x31221b33, 0x484e026d, -0x60bf9a95, 0x99aeb46c, 0x6ea68ca5, 0xc7cc87fd, -0x46c8309d, 0xa238ba76, 0xc8b60544, 0xe75a6c26, -0xf132bdb5, 0xbdbf818a, 0xddf921ee, 0x31281410, -0xbc273ef4, 0xa3701e22, 0xe2a1e259, 0x7974a770, -0x1f74c73a, 0x75ace81e, 0x27f1953e, 0x6e33ec5c, -0x6ae3ff52, 0x6fe7c21a, 0x71c3f609, 0x153d3813, -0xf4802aae, 0x5ab384e1, 0xa2b29ab9, 0x9dafa630, -0xffe7b99a, 0x9a4607bf, 0x0e8f2703, 0x2246a835, -0xa117ebfe, 0x38d8e29a, 0x325197fa, 0x1be0a760, -0x00638a25, 0x43b5f305, 0xa7ae61b6, 0x4c6ce339, -0xb0794319, 0x2edae1ca, 0xe9f106ba, 0xdbf0ef5c, -0x3a9ed279, 0xb8776285, 0xe8dc472c, 0x3a7e3354, -0xa094a9f9, 0xf2b8ab62, 0x7597040e, 0x1b239793, -0x56c47cd9, 0xaf9daf11, 0x4cf77900, 0x85411aed, -0x24abb609, 0x87d3f779, 0xe1b47d57, 0x8adc640b, -0x6c9e93c7, 0x1acd9bcf, 0x103f1378, 0xabbd82c1, -0x97675df4, 0xf397b109, 0x9560abcd, 0x4e81fd4b, -0xc347ee60, 0xb318bfd8, 0x77cb26c7, 0x01ebf5c7, -0x61688cd4, 0xbdc33fac, 0x944bcfb4, 0x6a24ac82, -0x1fcff29e, 0xafebd257, 0x23394071, 0xd6a7e3de, -/* 3180-m1220652_00000009.inc */ -0x00000001, 0x00000009, 0x11122009, 0x00020652, -0xe580b1fe, 0x00000001, 0x00000012, 0x00001bd0, -0x00001c00, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000009, -0x00000000, 0x00000000, 0x20091112, 0x00000621, -0x00000001, 0x00020652, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xdce14aa6, 0xd82a62d8, 0x1a50462a, 0x40f3fd31, -0x27fc5cef, 0xd6b052d3, 0x2a1a06b3, 0x44b13284, -0x5d5f57b5, 0x9926d84a, 0xdaaf70e7, 0x91786b18, -0x82da740d, 0xae90be68, 0x8b6a07cf, 0xc2c37ebc, -0xde451f9c, 0x7a1444c0, 0xce6700b1, 0x5c29e58a, -0x12eb603f, 0xaaf6cb53, 0xd807a1c9, 0xf51ed696, -0x90d9e2c3, 0x641bff09, 0x732ab820, 0xfef7aa2f, -0x8f518e1d, 0xf0d8c4d9, 0x73aefe19, 0xf6d7ae12, -0xd50a095b, 0xdf21cbb8, 0x4b81ff9a, 0xe1a6d1f8, -0xbe78b0de, 0xda86826f, 0xc4f9c057, 0x306f1761, -0x7aae81f0, 0xdbab0ae2, 0x789ec0ff, 0xbaacd096, -0x68fa4733, 0x2f3fd406, 0xd287247f, 0x79eefe4c, -0x6f674a41, 0xd6948ad8, 0x90388682, 0x5a4bf35d, -0xadab41ff, 0x89e9dc62, 0xb2eccfee, 0xd4d52153, -0x34301d19, 0x8a2f38a6, 0x35b05e56, 0x482f029a, -0x296cb5a3, 0xce64f437, 0xae1dfa06, 0xb9f29132, -0x1960a103, 0x70bb6f46, 0x152a5d83, 0x171a19d9, -0xac9aa4b7, 0x54b719f7, 0x5b781cb1, 0xaea548bb, -0x00000011, 0x2e969375, 0x5a0c3042, 0xdeda547d, -0x57713817, 0x3fcb3fe2, 0x700c8b79, 0x383a2bf9, -0x54c97193, 0xf7ed88cf, 0xa562b29f, 0xfbd73613, -0xa4de2f32, 0x90ebe900, 0x5d6d0cd8, 0xcac0f1ca, -0x481aa1d1, 0x4fc2712f, 0x00395dac, 0x649f1093, -0xc424d1c3, 0x80a2aef9, 0x26d77ea4, 0x58d881aa, -0x08ea63ca, 0x9a6cf85e, 0x608494cc, 0xefa3d439, -0xc4348579, 0xe55614dd, 0x4af75b96, 0xdcd91562, -0x5a43a1cf, 0x049d6889, 0x4b103037, 0x2884587c, -0x5d95f479, 0x4909d9e3, 0xdba2b6b8, 0x7357bf99, -0xcfc8ed25, 0xe426b749, 0xc40bfb90, 0xf7d3cab5, -0x9f6ae2b5, 0x1e377c38, 0x1a2fc035, 0xdece9b06, -0x13602f9f, 0x227542c0, 0xd6393283, 0xcd314e87, -0x974f45b5, 0xd70a2f21, 0xb5c87a4b, 0x2bd1501f, -0x74c320c2, 0x30e3402c, 0xfe7cd541, 0x4791cf6e, -0xd1304a5f, 0x58913c1a, 0x461cc615, 0xf673f34d, -0x46e01d21, 0x583f1f57, 0x2c6c26e0, 0x49cb29af, -0x868f2076, 0x2ee9ac2a, 0xda6a816f, 0x1050fc42, -0x849847d8, 0x643eca38, 0x59724cb9, 0x855093be, -0xa407d0c4, 0xd9a0bac1, 0x1f51f95a, 0x64ca2848, -0xcea97e49, 0x1ec83f2e, 0x3b36451b, 0x7cc376b8, -0x502c28db, 0x412b53ef, 0x4f80d266, 0x39c2c46a, -0xdd8696ed, 0x8b4b6a71, 0xf4a30013, 0xd4451aee, -0x3dd4a35c, 0x08d97080, 0x5b2622f5, 0x0786a611, -0x07b71c05, 0x98f3db3f, 0x1a1300c7, 0xaffdee91, -0xc3006a26, 0x8faa0c86, 0xb1565ee0, 0x10a4768c, -0x7375a1e7, 0xfbee0667, 0xe13f532a, 0x34b5f5f3, -0x48f0650e, 0x84acedcf, 0xcc31c269, 0xee8efc60, -0xb7620966, 0x07685c8d, 0xd079ee7e, 0x27c80660, -0x3dffb8ca, 0xf29c773f, 0x65c5071d, 0x5a32a715, -0x5abb9fd8, 0x4605163b, 0x6fda02bf, 0xb816bf1a, -0xa3bd6959, 0x4330562e, 0xb8a0fc2e, 0x9808ddd5, -0xc4da8f4e, 0xa21f9e52, 0x17d9ca40, 0xf6ca8232, -0x747c8cab, 0x65a56a38, 0x5602e5f2, 0xe348aaab, -0x6e0bd504, 0x825381d0, 0x092911ba, 0x990eeec6, -0xc3122bf8, 0x8baab8cc, 0xbd4cd41c, 0xabf61bd0, -0xec181e8a, 0x0a30d8f3, 0x7c93ee0f, 0x2f57eac5, -0xe373f24d, 0xd75b6a50, 0x6cc186ee, 0x2d2b4869, -0xfa4ec563, 0x54e1896c, 0x80dae8af, 0xbccbc604, -0x24bb3fb0, 0xf1aff085, 0x37ca0dc4, 0x3b4d1cfb, -0x95eacf56, 0x21040c81, 0xd9bf5f5a, 0x278fe036, -0xc9e31f1d, 0x8b947e50, 0xe615bf9d, 0x29f6331c, -0x94343090, 0x897d81fd, 0x3b936a1a, 0x79a87927, -0x293dd101, 0x39c2a56d, 0xaf162b08, 0xdbe932a0, -0x6d2454a3, 0xcd56ba0f, 0x63608e99, 0xef1baa23, -0x3f1e6842, 0x31a4153a, 0x2436d3fc, 0x8188bbf4, -0x5bedee92, 0xc64660df, 0x8de6f099, 0x7c1ae433, -0x6badcadb, 0x088baf56, 0x5e6a6b23, 0xe0bbdc56, -0xb5a3a7f4, 0x7397f4d6, 0x5f4b79ec, 0x4e82c2ae, -0x55cf7d09, 0xfce4f1e2, 0x908cac9e, 0x975b0f7c, -0xbe0c5211, 0x413b14dd, 0xb4d54868, 0x7b2b5dbd, -0x087eb1ae, 0x8ad40fef, 0x1b6f2f1a, 0xd1b53848, -0x4b379216, 0x2f06f2ec, 0x47b76338, 0x9a2e0a7e, -0x02012585, 0x228272bd, 0xda90e7f9, 0x70d5e74a, -0x3f96f251, 0xd83db7a7, 0x4a126c68, 0xb80e0dcd, -0x9c7150ba, 0xabbc68ca, 0x41ac7528, 0x3b36474e, -0x13408d0a, 0xb4e77850, 0xce29de79, 0xfa6b8e4e, -0x9bae6ee4, 0x55e0234e, 0x8d1634b0, 0xcfc0894f, -0x50e8b98f, 0x3552b58e, 0xbd46d4fa, 0x54330fdc, -0xf8e2a7af, 0xa5fd2882, 0x5584e766, 0x8ec3c4b6, -0x842205da, 0x949a7f9a, 0x8d1c4302, 0x3a33890f, -0xcae35fca, 0x544117d2, 0xe5c5756e, 0xa9a67bcd, -0x902e83ef, 0xb5e33469, 0x9f4374fc, 0xf67b198e, -0xd80067d5, 0x99b3fe3a, 0x9161db71, 0xda72b60b, -0x1fbb5e0d, 0xc59ef3b2, 0x9d667e4b, 0x87b032fa, -0x88ef4c97, 0xc7a6958e, 0x4bc451d0, 0x35233b0f, -0x707691b0, 0x91d28863, 0xbbf6b8e7, 0x501d6387, -0x2d44838a, 0x27ab3930, 0x574e6093, 0x1b84070c, -0x29a39e90, 0xc0d4d375, 0x3ec0241c, 0x8d5130de, -0xd71c6ad6, 0xa9099fdb, 0x4a5dbc4b, 0x4a822124, -0x3745b2fa, 0x3116e2d1, 0xbc1c4878, 0x49a2e870, -0x7e798e4d, 0x755d1ea6, 0x18a29c16, 0xcaa3c6c5, -0xa02f7331, 0xd6439679, 0xe77641a4, 0xfc06a227, -0x7ca99576, 0xf6704e41, 0x304fd33e, 0x1be47cfa, -0x9f341342, 0xeade8228, 0x58a2318a, 0x5666a767, -0x70233529, 0x014e5b3a, 0x7958ebdd, 0xbfd30535, -0xe787a3e7, 0xf1e61119, 0x221316ee, 0xbd6ffb66, -0x5bafb598, 0xbe7adc9e, 0xd4cb2470, 0xf71cf4e4, -0xb91117ea, 0x0aae09d0, 0xd2c575d6, 0x9fe50981, -0xbd6f16d7, 0x0407e468, 0xfc6175b0, 0x980aaba2, -0x2ae3f449, 0x687c7bcd, 0x1e2bef21, 0x1297950e, -0x3c49a1c4, 0xb7931e58, 0x3700607d, 0x6ccffc16, -0xb5f0b8df, 0xe3b454b8, 0xc78172ce, 0x38d6bc8e, -0x2fbe9a06, 0x91bb3870, 0x4729cdd2, 0xc3991b5f, -0x52fc90b1, 0xc1f9ebac, 0xc9dbea10, 0x08833b4e, -0x053b0c4d, 0xce3097d1, 0x8b4773fc, 0x227b8412, -0x7bf7205d, 0xaa36912d, 0x96176f25, 0x9e17de06, -0x298b6697, 0x1748d7d5, 0x042cff8f, 0x57dfad2e, -0x497a04e4, 0x0f94838e, 0x9a2f337d, 0x98db046e, -0xf59c604c, 0x67aa30b5, 0xc7281e21, 0xf81867f3, -0x25de2896, 0xf6d3239e, 0x1928b65d, 0x5f72fa81, -0x3b5c7c57, 0xc51bb21c, 0xeeb51c3f, 0xbd7d077a, -0x6f385685, 0x6775eff9, 0x1c481b0c, 0xdbc7dd36, -0xfbe2917e, 0xa7e399fe, 0x82ae4f84, 0x6919da96, -0x9f4cb810, 0xe9125bd9, 0xebad62bc, 0xef958fcf, -0x41d40a4b, 0x76a44ae9, 0xef445a6b, 0x01f9a43f, -0xb18a1508, 0xd0764dc5, 0xfd2a1517, 0x07021da7, -0x6f8af923, 0xbab451e8, 0x112b2843, 0x9f2534f4, -0x5835ce51, 0x43c3e61c, 0x10b6df6d, 0x55f03306, -0x63993d96, 0xef6064ae, 0x83a10859, 0x68710064, -0xf5c79677, 0xd3d044bd, 0xdbfaa51d, 0xc5295594, -0x041a43c1, 0x4347bbf1, 0x04a712d7, 0xb2bf4715, -0xdc5528f3, 0x4ea6a1ad, 0x97826d45, 0xd6dace9b, -0xe4500ed8, 0x08705291, 0xb8f075d4, 0xa89c1468, -0x7a4bd60d, 0x6cb1459a, 0x5feec3c0, 0x893cd43b, -0xe8d32a19, 0xfcf64a81, 0xf1c1d329, 0x2d751696, -0x1a05e652, 0xa0d20414, 0x6fdeeac7, 0xfdf139b0, -0x700a92b3, 0xe29f8616, 0x8a59adb0, 0x47da12ce, -0xe873864c, 0x0aa0c7b2, 0x1f1a3d44, 0x4530a1fe, -0x110d987b, 0x60144ae5, 0xcd4e503d, 0xcb273839, -0xf7467cc8, 0xea97cb96, 0x2f66a7f0, 0xea1793a6, -0xe5694859, 0x11ee5eff, 0xea78bf84, 0xdabcb643, -0x7dfc3865, 0x15244d6a, 0x712c4ebe, 0xd77e813c, -0xb5d40714, 0xaa83450a, 0xc90b1071, 0x1b6562f4, -0xa89c9740, 0xa9d7d4e8, 0xdf34d965, 0x452ddd26, -0x5c166d10, 0xdd3d931f, 0xf2d150c6, 0xcb842852, -0x730d442b, 0x90ca4c52, 0xb0e8cb69, 0x962dc596, -0x7dd63013, 0xb4bda47b, 0xadd1f372, 0xa73c25c9, -0xdc9bafda, 0xb8151a31, 0x07689397, 0x040c7849, -0xa5751181, 0x0f5db328, 0xfcc48a27, 0xe481fda6, -0x988b6732, 0xc2d75d03, 0x066807be, 0xe3a8401c, -0x10e71bf3, 0xb646fc3d, 0xf17828ca, 0x1c2d65b7, -0x5ba1f9b0, 0x9f4641f0, 0xb6868cf3, 0x2a91c83e, -0x1d2fb15c, 0xfbb6c98f, 0x0103b7b2, 0x6c6aa67d, -0xff3aa0d6, 0x79e36b26, 0xbc2849bc, 0x02631f2c, -0xdbdf4d5a, 0xc2292642, 0x311ef07d, 0x582208e8, -0x57c30f5b, 0x32f4ffb7, 0xb423daac, 0x44e28ce5, -0xdad60ee4, 0x0f45d185, 0xee26da95, 0xde0fbdff, -0xf3c8fead, 0x0c8a0394, 0x998a0977, 0x0e430050, -0x6260e49e, 0x30fa15fb, 0x6d0b6161, 0x67b00c86, -0x656a1c2a, 0xcc0cecc7, 0x00471f20, 0x4554c9ab, -0xf852fda7, 0xb7ce8bfe, 0x8c8e8929, 0x45f578c3, -0x1ffef096, 0x2102c22e, 0x8946ca24, 0xea2e3028, -0x004ce35e, 0x925712a4, 0xc213544c, 0x03ae3b1b, -0x1d01b5d6, 0xa82001ac, 0x4018f4c7, 0x070c0037, -0xa12e0731, 0x9e34492f, 0x95cbe15f, 0x2a1c2fc7, -0xb73d36ae, 0x7abe5853, 0xd6affbff, 0x6e7de37a, -0x59911c0e, 0x6b0a727d, 0xa2eed2b7, 0xa0856940, -0xcb77f34a, 0xac065ab9, 0xcd1f4163, 0x51dd137d, -0x461ecb88, 0x5985e106, 0x99261061, 0xf6fe30bb, -0xa8b3c696, 0x44d8af69, 0x0e24c57c, 0x476ed422, -0x7e0d9c9a, 0x8b43021e, 0xfe8d4651, 0xae73bd30, -0x25655851, 0x27dd08b1, 0x584dc8a3, 0x5b5856ca, -0x2f5dadb7, 0x43cd30d3, 0xaafbef65, 0x747113c5, -0x2be2ddbf, 0x979a2087, 0xdb16f3b8, 0x5e2f0b6a, -0x651c7621, 0x543078c9, 0xc72a99a3, 0x85da26f3, -0x2ab0e29e, 0x5f2fa684, 0x24e248c2, 0x08b58ba4, -0xdca148da, 0x1a482dd2, 0xbec8c654, 0x4dcf5e0c, -0x1e78a7bf, 0x3c224cfa, 0x386108bc, 0xe7ee136b, -0x915502f1, 0x67427a3d, 0x9a319abd, 0xfe5dab62, -0x197b3c5d, 0x9e58aed2, 0x36e86822, 0xd54ea06d, -0x2a29f58b, 0x30cdb3a9, 0x67add423, 0x9d54d29d, -0xff79d362, 0xd753f02e, 0x2773a35e, 0x4d6235a3, -0xf6046459, 0x63cf41d2, 0xcd4e0119, 0x683133bd, -0xf31bc973, 0x3ed90047, 0x1d87066a, 0x5f54a2ed, -0xe3f974a9, 0x407c412c, 0xf7ece0fb, 0x4db2b354, -0x4ad9744d, 0x2d4d828c, 0x8b9a423a, 0x904bf383, -0xc4b6ecf6, 0x2e0ced8a, 0x7a4688a3, 0xc788c45c, -0x1b0aae44, 0xd816b959, 0xe16e7e71, 0xd3c51d56, -0xc4afa70e, 0x7d0d507a, 0xf061b5c0, 0xf9312d1a, -0xc2930c2c, 0x265bcb08, 0x18e64f07, 0x1eda0e94, -0x50f722d2, 0xef7e1734, 0x8c566799, 0x4180c2a5, -0x4c4f43b3, 0xc721a418, 0xbb90f6ca, 0x85e9aa92, -0xb85ab6a4, 0x23a1325b, 0x7d0b13ab, 0x1184c4f7, -0x75004486, 0xc5b91959, 0xdb1a5c37, 0xc3c6489f, -0x21ad43c6, 0x73dadb3a, 0xcd876613, 0xe03be70d, -0x0ae3dfde, 0x60186345, 0xba141ddc, 0xff9cec78, -0x1cd5ec01, 0x39648944, 0xe2d00449, 0x8bc87563, -0x91409db5, 0x9d055050, 0xf5b050c8, 0xb5f12fec, -0x6b9c4d69, 0xeb6d78a2, 0x38f65bd5, 0x796a77c0, -0xabeff652, 0xaa37828c, 0xbef5f4e0, 0xf7b84c82, -0x934f6bfa, 0xd13469f6, 0x9d165a0e, 0xdf40634e, -0x0ffc26a4, 0x279cdb7e, 0x8b8849b5, 0x878cbd81, -0x29c18e16, 0xb55416e2, 0xf026e93c, 0xd434e9e0, -0x00d2a434, 0xab5335e1, 0x1621abb9, 0xda1015aa, -0x6f085944, 0x63d9d376, 0x07067dd9, 0xc9c559e0, -0xdb360e3e, 0xcf6f5b16, 0xf132554e, 0x130b9a57, -0x4407ba48, 0xb8f04672, 0xc3c3d832, 0x3ca78393, -0xa3439daf, 0xd8fb34bd, 0xc50427aa, 0xc7701afd, -0x811410a0, 0x7207e87b, 0xcc4d7a06, 0x0c9ae6ca, -0x809522b8, 0x9333214d, 0x1a7ddbdf, 0x32c8cd22, -0x13690f1c, 0x366f8b2f, 0x73ef5d51, 0x7717552d, -0x26ec3774, 0xec20392b, 0xd5e05fa2, 0x5923eaf3, -0xdfd6f7af, 0xc1ffd7e6, 0x886be75f, 0x080a0ad2, -0xc5b65fbd, 0x5d4cec82, 0xde7a21d1, 0xa4428d0f, -0x79a3180c, 0xbccee103, 0xc9c94a31, 0xd6114680, -0x7f4ad2a9, 0xa234296c, 0xded816a7, 0x88654183, -0x4fe6e7df, 0x327182ce, 0xc91b8650, 0x48b3a89c, -0x25fdc758, 0x22447525, 0xbcea00f7, 0x456f2628, -0xa7cfcefa, 0xbce11441, 0x9a0a2fe1, 0x23db4f11, -0xec1bddb5, 0xc15a7116, 0x9f51486e, 0xab9dd629, -0x4f1b3b11, 0x6b1d8be0, 0x6afe9c76, 0x6d1ff04c, -0xceaf08c4, 0x59d6977d, 0xb37cb7d5, 0x5b97fa12, -0x1d5b67bd, 0x06d734ec, 0x3fd6ccca, 0x4227b960, -0x65a83bac, 0xd01b02e6, 0xf9b10687, 0xb129d69d, -0xcba37843, 0x8a1ca760, 0x06fa8137, 0x9434e1a7, -0x772b1b19, 0x225c8b9d, 0x1c4e7f57, 0x15804f93, -0x8eb0c6e4, 0x3b772073, 0x107f094c, 0x0b5bd492, -0x61c52992, 0xeb778ba6, 0x225dc545, 0x940a49b1, -0x4606ffc9, 0xc5396baa, 0x4c308487, 0xe49efbe0, -0x44c591aa, 0xa3281491, 0xf6397b18, 0x6126862c, -0x96143f38, 0xfcf129b2, 0x135e0687, 0x2126a7ce, -0x9b013e77, 0xe4cc6632, 0x286e78c1, 0x154b6c1e, -0xe80244ce, 0xc38ed913, 0xbe0e6df4, 0x8fd6a926, -0x0fc49da9, 0x237f98cd, 0x119e07fa, 0x02ca66af, -0x0ef67214, 0xadb9ebb7, 0x8f4f7a23, 0x94a6460e, -0x1007e2e1, 0xd5cbb217, 0x68bf2c3f, 0xba337d7e, -0x62982958, 0x49f72096, 0x54a7acf3, 0x36ff55df, -0x1b6e9dde, 0x68869f09, 0xff0db710, 0xbd117369, -0xd763ca6a, 0x9492b3bb, 0x4fe52ec2, 0x59b9adbd, -0x08191156, 0x206974b4, 0xbb6882bb, 0x5677baeb, -0x916d5267, 0x7ddd2f4a, 0x45e0c3c6, 0x471e3c32, -0x026c5cb4, 0x5fbc7abe, 0xf77acf3c, 0x5ba1a10d, -0xa230832d, 0x598e9168, 0x30eda9d3, 0x63866326, -0x33b2062a, 0x29572008, 0x65ad9c72, 0xadb494e7, -0xe6f9cb0a, 0xe077d568, 0x630ea1cb, 0x89da22ba, -0xb7708d69, 0x2e11bdb2, 0xc530a947, 0x5feccad1, -0x25376788, 0x4ed9b80f, 0x97a96e7f, 0x65a9d6c0, -0x6069c8d9, 0x9b1930a8, 0x4bfb02c8, 0xc8478d77, -0x2f0036b1, 0xf09867b4, 0x769b1453, 0x1d59e994, -0xa364d18e, 0x91050732, 0x5abf2f30, 0x07c5101a, -0x212c98d2, 0xf620b893, 0x45d83e05, 0x0ecb3c02, -0x944faf4b, 0xc957602f, 0xad5bda61, 0x543059f8, -0x16788783, 0xda83e288, 0x73d4e779, 0x07973be4, -0xe135dcce, 0xf1fd41ec, 0x19a748f1, 0x0e28feea, -0xa252a5b7, 0x0f11fe6d, 0x757fd157, 0x63f78e15, -0x68827464, 0xdbd610a9, 0x02ebafd4, 0x3afe41f6, -0xa9472f8a, 0xa384098d, 0x7094b8c3, 0xfcc7adf0, -0x44c58ea4, 0xe65cd530, 0x7a122746, 0xdbf13003, -0x9f57d2b9, 0xb55a5a1a, 0x6ca62cd6, 0xefc9ba15, -0x9c9fb9ca, 0x50505660, 0xcb0059d6, 0xa648c2ca, -0x077f5e57, 0x9224d452, 0x22eb6a38, 0xf7d25656, -0xbeb960e6, 0x087e4968, 0xd49d00da, 0xf92513ae, -0x97e46810, 0x2003cc49, 0x23252ab3, 0xaab56cdb, -0x67d1d81d, 0x7275eaef, 0xdfc091e2, 0x6c8866c7, -0x72957a15, 0x4b61a0e8, 0x199bc27d, 0xe4c3df97, -0xabea3e53, 0x93fff185, 0xd914c77a, 0x4f67e6b3, -0x11b6347c, 0xc2ab8c52, 0xa34cd39b, 0xe8301350, -0xddf5105d, 0x089ce370, 0x586fc82e, 0xddb28af1, -0x770f5f96, 0x2b803b4d, 0x0177a06b, 0xe9d7266b, -0x5283db3a, 0x77a4738c, 0x895c64d5, 0x198840b5, -0x44e75d8e, 0x0453c208, 0xd97f8034, 0xd124da5b, -0x7e10dfa4, 0x5daf8481, 0x083d61f7, 0x8768f36d, -0x1bd40103, 0x618745dd, 0x1ae3d766, 0xeedf4c5f, -0xa943603e, 0x26fc122c, 0xafa214b9, 0xc097726f, -0xc8d9ddbc, 0x06c94859, 0xc3094868, 0x3a10cbaa, -0xb0b1e713, 0x8f330f14, 0x1e9e2a16, 0xe38b35f0, -0x12b19c5b, 0x9b82d51d, 0x9c718177, 0x7b5d5a37, -0xab440241, 0x20748d43, 0xba81c01c, 0xe8795fe1, -0xe7e8725e, 0x1530140f, 0x0eb1d8b2, 0x23e0ce43, -0xb57f2b06, 0xc79828eb, 0x813b7463, 0xf3554ef8, -0x3d9806c4, 0x946014ee, 0x2e9860a8, 0xeca1f3cc, -0x354512b8, 0x2c0ed962, 0xe5e1de89, 0x29af6549, -0x991d845a, 0xf51e59a6, 0x55b3d9b7, 0x941ffa05, -0xd5df180b, 0xcc7c4304, 0xa8fa4c4b, 0x878fe9f2, -0x6d14bd98, 0x3c16e8e0, 0x047118d9, 0xa2559ee4, -0x26c659c6, 0x64d89305, 0xd403088b, 0x633b6652, -0xab5cd44f, 0x195540c3, 0xc7b8bd37, 0x98441da1, -0xfdf2390e, 0x00bdfffc, 0x0ff192b2, 0xdfad3aeb, -0xf2fa21d8, 0xd332c81f, 0xd05a0147, 0xb747bec2, -0x4e15eb40, 0x317a8acb, 0x8bb8a62b, 0xf31c4531, -0x038a3b77, 0xf3e0b7a1, 0x8380fb96, 0x671dce8f, -0xb09fc642, 0xce84ac90, 0x9fd593c8, 0x9bea5f40, -0x527ed77c, 0x0a8eb67f, 0x910480e5, 0x796540f8, -0x97384f3a, 0x523e9fd3, 0x585531d3, 0x141934d6, -0x5b433d8a, 0xb89d963b, 0xecb59640, 0xd86af753, -0x509bd87e, 0x38abf89d, 0x98f46f7f, 0x7c126320, -0x7a9d96c4, 0x20210752, 0x78f217a0, 0xf84b4fa1, -0xa5cc10c5, 0x1cee885d, 0x9b702a2f, 0x81fc8e81, -0x8fdaadc9, 0xb7ff012c, 0x3784225a, 0x9d6e1953, -0x816c58fb, 0x96cc9782, 0xb76424db, 0x206d301a, -0x673df176, 0xe3b2874d, 0xb9ad4bed, 0x5a33c3c7, -0xccd68959, 0x1db07388, 0x30ee761c, 0x94057222, -0xff398940, 0x093c67bc, 0xc2ec3d63, 0xc3287a78, -0x5101c9d7, 0x1c610d3b, 0x68a2678c, 0x09a15914, -0x37c6c2b5, 0xace48588, 0x6035efc1, 0x0fa0eb5a, -0xf84787c1, 0x70c1aa13, 0x96f6495b, 0xc0c6ceae, -0x2913fa1d, 0x79225531, 0xf97c39b3, 0x7d91a06d, -0x10f478d7, 0x42ce4453, 0x96d18ff6, 0x3243572f, -0xf0350c8d, 0xa86a07cf, 0x8f3bbbbd, 0xb1a6989e, -0x775dc382, 0x9e856021, 0xc8a9591d, 0x69f0a204, -0xe58586ca, 0xd486d04b, 0x60ed0e27, 0xb6ba3528, -0x46aecbd1, 0xc6b4c011, 0x150ba6c8, 0xfab2115b, -0x78a70d54, 0xcca240eb, 0x21100870, 0x99592b43, -0xe6a90a5b, 0xf4c367a2, 0xd0b3d4f7, 0x8c55cd56, -0xf913104b, 0xc39c32fb, 0xcb1459bb, 0xb672ebac, -0x3a503f30, 0x0e803b42, 0x53b25382, 0xc7ab27b2, -0xa2f03e2f, 0x4a184c68, 0x4a31338c, 0xdd663612, -0x4e6b30a7, 0x4876a2b9, 0xae6b9357, 0xc2344b12, -0x9b8802a9, 0xe874c1a2, 0xf858a226, 0x8ceecd21, -0x95587d9f, 0x2ff1a932, 0x43176066, 0xa7ac6aba, -0x842971f0, 0xf6c09fa5, 0x1ec27f7d, 0x552ab9e9, -0xbd5c6612, 0x0e124f3e, 0x03080605, 0x6fa9217b, -0x9bf2777b, 0x6d6b1d4e, 0xaa5f1867, 0x46996c41, -0xd5a2e662, 0x488c7241, 0x8d8d4405, 0xbe1de5c4, -0xc9dbf418, 0x0748b9b3, 0x9067568a, 0x5fe02c3c, -0xb722f621, 0x128cef75, 0x7d9eb1bd, 0x5bedbfe3, -0x156e114d, 0x7c11ba26, 0x3df3bc99, 0x355ed039, -0x2a3e597e, 0x78784643, 0x6005eb6f, 0xfaba1333, -0x29da4622, 0x9b62158d, 0x2cd32ad9, 0xe9192eb0, -0x4ac8a46f, 0x187ae9ad, 0xb6535290, 0xca8e587e, -0x81fd1e8e, 0x16059241, 0xcbf0caee, 0xec605f0a, -0xf54b8d6d, 0x66c40b5c, 0x4d76e42e, 0xd7d9eecf, -0xc38247b0, 0xe9c4db96, 0x9c879481, 0x67ab597e, -0xc93ee33d, 0x8126ec0b, 0x4af2a217, 0x63142cea, -0xe3361b1c, 0x9c2dcb93, 0xbd48845d, 0x4e7dc93d, -0x4bd0c6e3, 0x821051c1, 0x059de9c1, 0xba72e10d, -0xa281837d, 0x46934466, 0x52432bfe, 0x217a20ee, -0x281b7c03, 0x28630962, 0xd8a78a62, 0x1b8518c2, -0x99e1817b, 0x8af56f40, 0xa8d67b2c, 0xe0e8a47f, -0x26f0f8b3, 0x02add88b, 0x21efb2d7, 0x15fa4312, -0x0fc09777, 0xab6a195e, 0x13fe1fe8, 0x375bb5d0, -0x43d62056, 0x36df85c1, 0xfe9b57f3, 0x467f2673, -0xf12ab72c, 0x6b871beb, 0xe3373fc8, 0xcc589ede, -0xc6604e25, 0x7fe2bb55, 0x7063f150, 0x042a5a13, -0x39892307, 0x56f1e8b9, 0x231d8da5, 0x55deb85f, -0x9ae239c7, 0x8245cf92, 0x70671327, 0xb9949185, -0x17e64d51, 0x7fdb797b, 0x96a8ca43, 0x41c2eba5, -0xd851d1ac, 0xd13c6e5a, 0xdbe937d9, 0xa63c4092, -0xbf792848, 0xb31f40d1, 0xeab87850, 0x10df9cb3, -0x7ffd0ef8, 0xbd0eb376, 0x18403f6b, 0x0abe8c4d, -0x99fa87eb, 0x6d52ea5a, 0xb9696851, 0x43edc80a, -0xc6ad48c3, 0xbebb194e, 0x853d2b4c, 0x8edeba8b, -0x1811374f, 0x8ba7c655, 0x160fe9cd, 0x51bb93a7, -0x092b3734, 0xe41719ff, 0x9a67f26f, 0x1047e1d4, -0xb87c127a, 0xf502c7f4, 0xc6706269, 0x16fac08d, -0xec04a48f, 0x42415fda, 0x14ef4a32, 0x81e58994, -0x5e6fdaeb, 0xc89171a0, 0x15f600d7, 0xda4a12d7, -0x877f8ffa, 0x752f4043, 0x84d3c5d6, 0xbfc0ea8d, -0x51a8afde, 0x12202665, 0x0a9bb025, 0x2d66010b, -0x7a7571ff, 0x9c25a6d6, 0x3ee6d794, 0x996c6c31, -0xe8f2468e, 0x3fad8694, 0x81e23c7a, 0xbcd64732, -0x8531f6e5, 0xb134201b, 0xc5f2514e, 0x9dadc1d5, -0x6ad87fb4, 0x139065c3, 0x9e2e258a, 0x47b6eb20, -0x6073f54b, 0xccb10599, 0xa560c5b8, 0x92904ff1, -0x44586039, 0x70ffed96, 0x2b67ed00, 0x8d403b13, -0xe9f057d2, 0x808dd996, 0xa901fcbf, 0xc1e9afd0, -0xf009a713, 0xf8518b43, 0x14538c49, 0x7448122e, -0xb46e690d, 0x6ae7ee20, 0xdbe680e4, 0xf5cf7d8e, -0xb8227f90, 0xe1cd249c, 0xd92343cd, 0x50a47622, -0x1ad28805, 0x453c76a1, 0x29a0050a, 0xe1c25523, -0xfe6ac455, 0x5708ec26, 0x47574872, 0x7d975d41, -0xe820d206, 0x0cf38629, 0xe0251795, 0x8ceb99c7, -0xdf5b0b57, 0xa7464445, 0x56955520, 0x594e5b28, -0xabbd6069, 0x11598def, 0x1db2f245, 0x36c3a49f, -0x6094c0b5, 0xf0f31056, 0x418ac833, 0xef2b2810, -0xb1074bbe, 0xe8806e8b, 0x19361160, 0x8f11a1f6, -0x660c4471, 0x01b6a91a, 0xbebf128f, 0x3e7a09e6, -0x2164379c, 0xe94c49b8, 0xd76606f7, 0x838acc87, -0xd962ec79, 0x6f847472, 0x8eb28012, 0x99512db7, -0x1b6c6bf0, 0xa86f6c4e, 0x30094ed8, 0xf1a2f87b, -0x96678c29, 0xc08b0291, 0x897acb70, 0x6c0c5315, -0x3557eb4f, 0x0d870866, 0xebd4b86e, 0x45e7dd92, -0x4faf75e0, 0xf23f0aad, 0xdfc2ca9c, 0x0024540a, -0x14f975ac, 0x6d7e57fc, 0xf501bf1a, 0x3830eb5d, -0x1db8146b, 0xd45c6713, 0x78945d10, 0x119ae70c, -0xc6b11c75, 0x8e048ea0, 0xb8d2d655, 0xafcd9dfd, -0x3bef9054, 0xa3665dcd, 0xe5ebd611, 0x2551db2a, -0xf9e95ded, 0xa2f7b55e, 0xd9735fab, 0x4f9d28ab, -0xd96f5492, 0x044d797d, 0xaa49926f, 0xa71dbd71, -0x3ca16944, 0x5556fb76, 0x2d403448, 0x18fb0041, -0x094960fe, 0x79b5c5ec, 0x11942949, 0xffbfb4d0, -0xab70fbed, 0x9f66a579, 0x2925b30d, 0xa6dc4162, -0x0d97fb40, 0xd77f75fb, 0x92b8e288, 0xed8d939a, -0x1703e83c, 0x2882ed5a, 0xb58e38ef, 0xa010c043, -0xe8c3aeeb, 0x541f8a10, 0x52327624, 0x401e3aac, -0x73bf9796, 0xf619f653, 0x0cfb6f6d, 0x0b003d30, -0x94f63d3f, 0x9b682b62, 0x2a2ef47f, 0x46ba40a0, -0x456cd98e, 0xb4b6432a, 0x17a74670, 0xc090493f, -0xc716b923, 0xd91476c2, 0x0b4008ce, 0x5f6f5c81, -0xe62e22a8, 0x5df3fc43, 0x2a701553, 0x07101a9d, -0xb3411e01, 0xaadf8447, 0x8a8a058a, 0x360e5110, -0x0ce7fda8, 0x6eb7fb89, 0x9e0075ef, 0x67e86bec, -0xc3d30f81, 0x97d57af3, 0xf53bccac, 0xc0c49e90, -0x328557e0, 0x666652f7, 0xb5402b2f, 0xe23fd65e, -0xf21807f5, 0xaef029ad, 0x8b977c49, 0x24d7340b, -0x2261bb8f, 0x683fdf5e, 0x8e5446f1, 0x8ad60840, -0x96ba6443, 0x0d34f16a, 0xc6392bd4, 0xc2d258bb, -0x3c30aa6c, 0x30255fd1, 0x1841ba49, 0x7917c32c, -0x38f6769f, 0xdadfadb2, 0xe32b9759, 0x08a22b72, -0x984c486d, 0xfb6d718e, 0xecb8c7ee, 0x557802f9, -0xd141f9a8, 0x2b270e2c, 0x29b54d5b, 0x3b811f56, -0x19fa8f75, 0x92cd9965, 0x831f29cd, 0x86330673, -0x4469c4e7, 0x8b8eaa2e, 0xf9d95059, 0xd6b64ed4, -0xd49d0cea, 0xe258c3b1, 0x71cffab9, 0x374f32d4, -0x1c1be3b7, 0x4fc95750, 0xfc895cee, 0x5c2ebde0, -0x68df6a29, 0xcc92e3cb, 0xb27bb547, 0xbb010b08, -0xc1f26f8d, 0xe73d8c05, 0x099345a0, 0xb3dee476, -0x3ece40e4, 0x25919c03, 0x1edbd8c6, 0xff5db3a6, -0xc1e3cea2, 0xc90ed735, 0x9836154d, 0x77061a5b, -0xc1f2fc5f, 0x033c171d, 0x9a790561, 0x165dbcbe, -0xd92f380b, 0xc3c5b5de, 0xcf78e93d, 0xc43dbd28, -0x044ac895, 0xcf967c55, 0x9ec4a066, 0x0d3d2a64, -0xd6c39e25, 0xbd834fb6, 0x8b2ab3d6, 0x795a2996, -0x6d4cd03d, 0xca20a6e0, 0x1e4751a8, 0x9027f4f8, -0x92056077, 0x31d3e3d3, 0xea9e58fa, 0xf02ae112, -0x59d04ab5, 0xe55009fd, 0xf420eb11, 0x173b7a3f, -0x7d2265e8, 0xfa04ee57, 0x3e12d500, 0x9aff748a, -0xd1f31ad3, 0x2d1aea7a, 0x54a68b4d, 0x99df9837, -0x97c68065, 0x2d225021, 0x67d65f5b, 0x1e0d0d8d, -0xb9e7ff98, 0x238d56cd, 0xf4410ca1, 0x05716ab0, -0xc74c3ae4, 0x2478017d, 0x061bb9df, 0xc2a4aea2, -0x22c497c3, 0xc08586a4, 0xd97a10e5, 0xf441e4af, -0xd96172cb, 0xf1b318de, 0xfa7f1da6, 0x613583ed, -0xa03fb953, 0x01758b02, 0x0f3c3b99, 0x61e3be8c, -0xb61c5dc2, 0xd38a2e99, 0x244476a7, 0x1f2fdd12, -0xc85fdde0, 0x363a77da, 0xac4c6b2f, 0x59da71da, -0x8688dcdf, 0x760966a6, 0x6248dedf, 0x9db3a95b, -0x4221a4e1, 0x780c7034, 0xe4f30264, 0xdd913c13, -0xd4a63e3e, 0x0b63a961, 0x31a38a2e, 0x76158f28, -0x0810acd1, 0xf7833dcf, 0x1bdb92d3, 0x7ea86106, -0xe9ddcdfb, 0x8a62d452, 0x7e0193cd, 0x2137f79f, -0xc3d4443d, 0x0ea65d4d, 0x27227997, 0x6a9a2608, -0xf0e2d78a, 0x9f64ebfc, 0x78b05e6d, 0xa6b5a79e, -0x67b5b3b1, 0x441ca7df, 0x3ea13f25, 0xe4b03eec, -0xa016f880, 0x1cf297a8, 0x8b5e77fa, 0xb0e5bef8, -0x6b0d218b, 0xac630377, 0x4865cb36, 0x6b51a5be, -0x7154e5af, 0xf8e2703a, 0xbb903201, 0xe2b036ed, -0x4eb150b4, 0x5627c27e, 0x785fbde7, 0x0599163f, -0xac3003b7, 0x231beb0b, 0x13c75fb9, 0x8c3338ee, -0x4e53bb38, 0xaea89c0e, 0x78467ef1, 0x7656a62b, -/* 2618-m441067AA07.inc */ -0x00000001, 0x00000a07, 0x04092008, 0x0001067a, -0x83067f27, 0x00000001, 0x00000044, 0x00001fd0, -0x00002000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000a07, -0x0000001a, 0xa4000000, 0x20080408, 0x00000401, -0x00000001, 0x0001067a, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc4294866, 0x3e20a114, 0x8387f19c, 0xdafb14aa, -0x33a38309, 0x68b0f8ea, 0x2a20b200, 0xcdc7aa9e, -0x170ce7c7, 0xd727c705, 0x019b1ba5, 0xe0414a29, -0x57d45458, 0x26a8a411, 0x9faad966, 0x095ec8b0, -0x083a7c2a, 0x17cfc70f, 0x3c8e78a8, 0xce18c419, -0x5f2ddeb7, 0xc9c95d71, 0x437a5116, 0xe0253ad0, -0xec78db42, 0x681e436f, 0x7fd028bb, 0x1149a501, -0x0bdf0d05, 0xc2321514, 0xd6866cd8, 0x64942685, -0x21e0276b, 0x0817a288, 0x09138669, 0x792985dc, -0xbd60d6aa, 0xfbf902ec, 0x43fee69d, 0x5c5823c0, -0x9dca1fe6, 0xb528b0c5, 0x22fd29ab, 0xac4fe251, -0x77207813, 0x0637a1f9, 0x16bfcf73, 0x80497f6b, -0xe5bca939, 0x1539fa1a, 0x66607fea, 0x2276c06f, -0xd003229e, 0x3622fda7, 0x18d0b8af, 0x9f399760, -0x3ac6387b, 0x6c7148fa, 0xfaf4df9f, 0x965db840, -0x7c142542, 0x7b805f4c, 0x3f2002a3, 0x061399ce, -0x2f1a03c4, 0x7f1c7616, 0xb2f9ab42, 0x4e6a92a2, -0xb44b96d6, 0xe1167017, 0xec4b2fb3, 0xa15376be, -0x00000011, 0x9f63eb61, 0x64816577, 0x10c68141, -0x1cc5fd18, 0x156703a6, 0xe3315c33, 0x62a1db21, -0xb6135848, 0xa306d2fe, 0x117cb585, 0x54c3a133, -0x722cf721, 0xa693cd57, 0xd02c0e2d, 0xf17b96ca, -0x97d2a408, 0x2e776501, 0x667f7664, 0x1568cf83, -0xa044dee1, 0xe6a879aa, 0x4ff23d0a, 0xd559de49, -0x2dabb17a, 0xc6c39e38, 0xc3ae5451, 0x2d03f3dd, -0x7ba226ed, 0x69a19529, 0xc2865715, 0x8b95e6c2, -0x7a7ee1cf, 0x74b5e43f, 0x69aeeefb, 0x5d95aaa5, -0x0afeb5dd, 0xdb837be6, 0xed6f9d79, 0x2ad96eb4, -0xcd60dd82, 0xc3ff7d75, 0x7030a02b, 0xdbbe45dc, -0x203cd7ba, 0xc3b90579, 0xa21f54f2, 0xc79853ce, -0x5e3f74eb, 0x06c63742, 0xb1fa50ef, 0x0e8e950e, -0x97d44b72, 0xa48dc8ad, 0xf3803fb8, 0x946e4d5e, -0xf0f1e9f6, 0x272b9764, 0x567efb67, 0x82deebcc, -0x614f61e8, 0x3bea41b8, 0x31a12485, 0x682e10ae, -0x954c7b7f, 0x0e4bccf0, 0x8cb1eb25, 0xb5018c6e, -0x50957531, 0xcc60f1c9, 0x11181c5c, 0xa4dc1468, -0x3310423f, 0xd2550a2a, 0x3bd2ac80, 0x2be006d9, -0xf57f3e2d, 0xb4387cc7, 0xe96c48f9, 0x722975a2, -0x4506717f, 0xaf92aa6e, 0x7de4eb6e, 0x3600e58d, -0x898cc58f, 0x271c467f, 0x1c5cd377, 0x5858e9bc, -0xd3ad9408, 0x513c936c, 0x0dc54b7e, 0x0226d703, -0x4cc95088, 0x78bbb408, 0x573d07e2, 0xa4e9cd4e, -0x4a2930cc, 0x3082d573, 0x68c8c48e, 0x883d27f8, -0x4e91dd95, 0x850f6d80, 0x5f7f3e37, 0x452cc29a, -0xf2f9cc40, 0x278be406, 0x356eb275, 0xda301857, -0xdbc49113, 0x7007d110, 0x06f49bc2, 0x74712f32, -0x73176720, 0xcebc66e2, 0x592acf0a, 0x8818dd3f, -0xd599d562, 0x54199a46, 0x6472129b, 0x47058cd1, -0xac4a74f5, 0x1cac471a, 0xf1b4758a, 0xfa6f8e1d, -0x1013e19a, 0x59252c0b, 0xa764c600, 0xfba01968, -0xc7c11589, 0x2b4bf080, 0x0157b32c, 0xc09788fa, -0x1be99aed, 0x19c1799c, 0xb1d03201, 0x8bfb5374, -0x44e04a89, 0x895d3a8b, 0x5b3a53dd, 0x4704a722, -0x0d4ac344, 0x8a3f81f2, 0x3513e05d, 0x04e89637, -0x39f3d4a3, 0x883f2acd, 0xbc2ec5aa, 0x3a26f17e, -0x3de2b026, 0x49cffb83, 0x9cdece0f, 0xdaaddd7f, -0xc884a2fe, 0xe4244359, 0x493030d4, 0xb87e816a, -0x3b2481a1, 0xa2eaa4eb, 0x33d7ad6a, 0x64947485, -0x65f85855, 0x088388d8, 0xf6dfc3eb, 0xbceddbca, -0xf72f47e1, 0xd1d06e25, 0x76ff3bc0, 0x9b8f2139, -0xec7bc702, 0xfe6e6c0f, 0x42d31d20, 0x7e0397f9, -0xb20b40ff, 0x45a5ce27, 0x31949159, 0x7013a868, -0xdef2e0d9, 0x30c62ff4, 0x9b5a9b24, 0x0e4e4b1d, -0xecbbbe85, 0x4cca116b, 0x341fa1fc, 0xfa64b033, -0x43007f76, 0x710238e0, 0xa995a864, 0x5125d448, -0xc20c49c5, 0xea370734, 0x9bb92154, 0x596f42c2, -0x8d8919f6, 0xdd875cf4, 0x3b76b70b, 0xe96291c9, -0x2814c6d4, 0x0baf988f, 0x9880af78, 0xcbb57ca5, -0xf9580819, 0xebe041cb, 0x051d6dab, 0x5170746b, -0x6f04bfec, 0xca10ec0b, 0x2a870ec1, 0x551af839, -0xcfbbbb16, 0xef91d864, 0xe9b9dde1, 0xf1fade18, -0xe306f50b, 0xeb5253aa, 0x30010729, 0xb4169d72, -0x3320e4f1, 0x9c6946e1, 0xdee63588, 0x4b2967be, -0x167720ed, 0x6f27e397, 0x83419fdc, 0xac4386f3, -0x0ac58383, 0x55c0dd4e, 0x62b4a145, 0x91d64a01, -0x0e8acdb5, 0x40de995a, 0xc850ada1, 0xaa95a50a, -0x14516378, 0x294a976e, 0x544fa118, 0x904c471c, -0x8a5896d3, 0xb1486188, 0x237498dc, 0x1a1980b3, -0xd339968f, 0xe735a8b1, 0xc5ee31e3, 0x35c64060, -0x79cd8f43, 0xa2bb1974, 0x00189576, 0xf7bd74be, -0xdd52d07c, 0xa20b9c8b, 0x98dadf9d, 0xf75c05be, -0x476ac3a5, 0x6fb2bf82, 0x914c23c7, 0xd91c35e8, -0x709ef212, 0x3d8f3ca6, 0x14c20046, 0x7015482e, -0xb3fa2331, 0x78933f36, 0xc73c72b5, 0x645b4476, -0x299fa727, 0x701d7717, 0xf6c4bfed, 0x3213dc65, -0xfe66e1b4, 0x8040904c, 0xc536845b, 0xd1764a8d, -0xdeb49b88, 0xdaf26115, 0x8160aa13, 0x206d4929, -0x92fdb80a, 0x4f1aaab2, 0xfbbac21f, 0x2dc479da, -0xd2ce1eab, 0xa7da6602, 0xa9fbe019, 0xdd58fac1, -0x747ab469, 0x946a3b93, 0xc7b9cbe7, 0xc6f74040, -0x8a8bee87, 0x07f65d07, 0xe79eb820, 0x64ef2fc1, -0x72b1eccf, 0xc71f601b, 0x2812ab18, 0x48415edf, -0x45a80c6d, 0x7f616640, 0xfeaa98d0, 0x1024f1e8, -0x37b3735c, 0xc136f513, 0x5df10182, 0x1bd2ec03, -0x07f04b3c, 0x59beeff2, 0xea0388f8, 0x2f6addc8, -0xe0f282e2, 0xf9772673, 0x6bd0dc01, 0x3b4d6f9b, -0x29b81515, 0x6c553377, 0x1136b69a, 0x50e03397, -0x9c483ccd, 0xb0a13c9d, 0xea8e6bd6, 0xb8129b95, -0xc085a4d1, 0x52f64f7f, 0x178aad6e, 0xe5c4d92a, -0x4c35f2de, 0x8f179df7, 0xba405091, 0xd756e10d, -0x23bfae39, 0x74015fee, 0x15dc3e64, 0xdfc05a18, -0xa51ac3a0, 0x0ad4595a, 0x801363f0, 0x3db1f0c5, -0x97a8ca8f, 0x7e74b015, 0x124d1664, 0x71b26596, -0xaf073d4e, 0xf45d87d4, 0xd73c1dd0, 0xd1ade30b, -0x8127545f, 0x4ba0585c, 0x5bb26da4, 0xd64fb76b, -0x5c9c8190, 0xc1603512, 0xf7a69779, 0x1529ac38, -0x8d9422c9, 0xac132697, 0x5f9ce586, 0x8d5ca1ce, -0xba409dbd, 0x184b0698, 0x71bc5a54, 0x294e6b1c, -0x085c38df, 0x629e955b, 0x73f5c2b8, 0x219166e4, -0x9805fea9, 0x7602d837, 0x0932604b, 0x06a1509c, -0x2afe3b47, 0x61050264, 0x0fba8fc2, 0x9f648238, -0xbf3adf84, 0xdb8d2f92, 0xba2d9b51, 0x3d4415df, -0x32811e41, 0x176a4519, 0x1ffd7d6b, 0xffe56807, -0xca7db7a3, 0x5c811c87, 0x6bf1fe24, 0xc3013434, -0x4ccc937e, 0x0a04797c, 0xca7dd4b5, 0x20ba4643, -0x2b18ed89, 0x2ccf7a54, 0xd1a9e7a8, 0x67d96e26, -0x9dd29473, 0x0f26a8f8, 0x164fb823, 0x17c5d3fc, -0x26361bf0, 0x02544619, 0x32bbe44e, 0x12fbec8d, -0x0a928412, 0x23652975, 0xe67465e7, 0xd1f49edc, -0x200ce053, 0x1276b87a, 0xf5150061, 0xf509028d, -0x4aa27234, 0x6fbc6156, 0x89e61e73, 0x612a7618, -0x20783c3e, 0x152fda0c, 0x9a5c7b17, 0xebd39bba, -0x9793ab7e, 0x053f88e4, 0xef9499c7, 0xdf5efc36, -0xa2792729, 0x068ba6d6, 0xa5c5687e, 0x3924364a, -0xa4c6c2e4, 0x45364a92, 0xda08f6ba, 0x1551c9a5, -0xb4787235, 0x73d99aae, 0x584e52ec, 0xd76c6379, -0xf852e104, 0xa335ab55, 0xd2b1013a, 0xc2c591f1, -0x91ac865d, 0xe82497be, 0x39f62b27, 0x3d6a9530, -0xb74f7711, 0xca3f54d4, 0x466e17e8, 0xe91d700d, -0xbe8197a7, 0x04218b87, 0x587e7832, 0x838c1a71, -0x39d27956, 0x36ecc542, 0x36b22957, 0x5c44fe01, -0x86ae0bfe, 0x2ffa7c08, 0x603db66a, 0x69d7eed9, -0xd96761bf, 0x44bc3358, 0x2c04707e, 0x290a0631, -0xac627cd8, 0x1dd90751, 0x41e91a35, 0xf5dc1260, -0x36564120, 0x1ac71792, 0x87e0a694, 0x063d0388, -0x4f282802, 0x026fdbfd, 0x11102f9a, 0x5932ad11, -0xc5f266d3, 0x27587435, 0x6fecaeb7, 0x191e6dda, -0x50daedc2, 0xa282f89d, 0x89ceb660, 0x4564adc8, -0x0cee73af, 0xed4f399f, 0x10085cac, 0x0d9ded47, -0xa88956dd, 0x242798ad, 0xae708815, 0xf7edf1f7, -0xb9fa65b7, 0xe8b4fcc1, 0x00fd86c4, 0x7ad67bce, -0x66e3f423, 0xee1b4874, 0xccbc4116, 0x04a72b4b, -0x39a640f0, 0xef9f5c48, 0xe8d1470d, 0xee1ef5d1, -0x90784af3, 0xbc0b3389, 0x49aac119, 0xdf65d921, -0x1023547c, 0x486b404a, 0x834d359c, 0xf5dbbd50, -0x68b5997b, 0x7aee9417, 0x42e48286, 0xa9d8ee77, -0x181a3e1e, 0x607cb99f, 0x5f53c78d, 0x5a60a6a8, -0x39cfc04c, 0xfbe6eb32, 0x84348beb, 0xa278662b, -0x398c625d, 0x3f9859e8, 0x5517ef17, 0x15856fe2, -0xba4d33c1, 0xc93d7652, 0xcf40a2aa, 0x2ac37060, -0x5efc6cab, 0xced95484, 0xf39ceed8, 0x4ecc8045, -0x13c1e742, 0xd93d87f1, 0x695cf766, 0xcb53f961, -0x15e0fc91, 0x37178627, 0x5e832076, 0x8c72db35, -0x2ce047e6, 0x11d9e791, 0x45e4d466, 0x8b7a7c71, -0xa83e9738, 0x7c54e924, 0x2ff12bda, 0x6b1ca347, -0x2957b0a8, 0x1fdb23fa, 0x91f98947, 0xe02c3f1b, -0xc42cbb06, 0xf0421ecc, 0x1716fce4, 0x1bb34813, -0xc67853bd, 0x3a27d8f1, 0x8e38f3be, 0x9e5dc781, -0x245017b1, 0x8cade69f, 0x44642f90, 0x3ef4215a, -0x879c78ad, 0x371ddad7, 0x7c629ddb, 0xe5f61d71, -0xbb3896fd, 0xcd3067f4, 0x4cfc2e12, 0xe7d69e64, -0xcd35c838, 0x6af17c65, 0x322fec99, 0x81221d8b, -0xa586497b, 0xb2cecfa9, 0xebbdaef4, 0x074fef30, -0xf825db99, 0x2f916b7b, 0xdc32f01d, 0x915eddd6, -0x96238f76, 0xf61c60df, 0x68795cf1, 0x46f1f13f, -0xc9654740, 0x63872bc0, 0x51e210b6, 0x17b5c27b, -0x7adf79d9, 0x7a823cc1, 0x02011b40, 0x6434a855, -0x56eca557, 0xa14f4132, 0x8c120524, 0x778266f4, -0x04ad9ca3, 0xccceab50, 0xecd117cc, 0xf0defcc9, -0x4f573e38, 0x5393033b, 0x88684c7b, 0x1a33f3a7, -0x898f45f0, 0x355ffa68, 0x174542c3, 0xa3dcfb8d, -0x6cd09199, 0x67339d62, 0xd29348c7, 0x37431b9f, -0x508c487c, 0xe4668bdf, 0xcbba1b72, 0x1b1b10a1, -0xcd4447c0, 0xf9ee7e83, 0x871a0f4f, 0xa94572d2, -0xac77a5c1, 0x3b84dbd4, 0xd45a09b6, 0x8e73228d, -0x59f2bb36, 0x4855a81b, 0x3fafe19b, 0x2f612920, -0xb9d216f3, 0x937e6a7e, 0xf31a2011, 0xfb7ca7fb, -0x1ca50eef, 0xd1d2baec, 0xa19d932b, 0x620d57d4, -0x086b7270, 0x5fcc7905, 0xb0dbe594, 0xf16f0a1d, -0xd47563f5, 0xe54eeb3a, 0x588766e4, 0x0280ef61, -0x8f26923d, 0x14b892bd, 0xdd11550f, 0x3e5ec618, -0xed825fca, 0x52a04ef9, 0xaad0c980, 0xdff1a4ea, -0x68f8954e, 0xc0f1664d, 0x6bc36a13, 0x5d36fbca, -0x05f7883f, 0xd2da1028, 0xe3cd0e3e, 0xa4038605, -0xb48e7f32, 0x1f5ffb16, 0x7c4899b2, 0xb3073d46, -0xe2acb6e2, 0xefe17316, 0xca66163c, 0x93d4b562, -0xa86a9d63, 0x07449ca1, 0xb499c9d4, 0x6c666b70, -0x0d8c9f9d, 0x78c926a0, 0x99e4d31f, 0xd73c49ca, -0xfd7e352a, 0xd710b7c6, 0x18100555, 0xb4e79321, -0x5efc693a, 0x703180ef, 0x9bbb238b, 0xa105a3e4, -0xdaa3ce4d, 0xff7cc846, 0x2bfbd556, 0x5f5ba34d, -0x0ef8537b, 0xb0bc4e7b, 0x224f6dbf, 0x3b9ddb96, -0xf731880a, 0x00d8d325, 0x55e4908e, 0x63bc2811, -0xafa6f5cd, 0x5219a8c7, 0x4609390d, 0xd68e7ae1, -0xc2e5e5dd, 0xf232712f, 0x1c52c242, 0x5a6cb79f, -0x26667cb4, 0x0de1b656, 0x42ca30c0, 0x4ab64de9, -0x26b0cfa4, 0x2897b6d1, 0xefc5d75e, 0x67ca7a04, -0x805a805d, 0xf2e454cc, 0x837877a1, 0x8ca7dc3b, -0x40620ce0, 0x5ac019fb, 0x6ee93d19, 0xae137f12, -0x0cedbd2f, 0xacc51979, 0xec7ae13f, 0x4537c7b6, -0xe3491fd6, 0x8e63f870, 0x1e08f6b3, 0x219dae5b, -0x8db5d524, 0x8de9f8ee, 0x04913730, 0x7a11db72, -0x6e4d0088, 0xa8713aba, 0xf2e72fd0, 0x2ba5695f, -0xe11da489, 0x6a5ecdf5, 0xc2133568, 0x994cc9f4, -0xed6825cc, 0x3d104599, 0x4d7679b6, 0x3bfe94f0, -0xc6a131db, 0x6dfcc31c, 0x9ec5c4f6, 0x3a386a48, -0x5d0b6f61, 0x059b5114, 0xd4831a86, 0x37460179, -0x02f23600, 0x1c04bd2e, 0xbf689d81, 0x2bf0be1c, -0xd8d5974c, 0x0d9d0709, 0x5dcade38, 0x167df39e, -0x96942861, 0xf1e6a09c, 0x16ac7082, 0x5037af19, -0x69c40dbb, 0x10728698, 0x71d52ed0, 0xa77036b8, -0xa050ea5f, 0xa7ca5494, 0xa25b4acd, 0x7f8ceb12, -0x8f03bc78, 0x6b7ee0f3, 0xa97d44b3, 0xeda32377, -0x852c4597, 0x3f81aa95, 0xf148a2da, 0x770e5cb6, -0x90fe1806, 0x50620299, 0xd7f4042b, 0x0d356595, -0x5596e5dd, 0x6c797c13, 0x500c0ee5, 0x7e5ae4c5, -0xecf3ac43, 0xae09d902, 0x95b72b10, 0x7597d441, -0x8d719da8, 0x151b5d1c, 0x1f6790f9, 0x1147be9f, -0xee857fb4, 0x6f34c63c, 0xb5211613, 0x831687d1, -0x80e19a47, 0x1bb032f0, 0x5341a6f2, 0xc9a32ec1, -0xad2521c2, 0x359e67d5, 0xeb4fa538, 0x1cc294ee, -0xab08e4ee, 0x491c2562, 0xe1e38431, 0x039787ad, -0xa3cc1cd4, 0x3ff47385, 0x0f442100, 0xd40d9c3e, -0xcd033c28, 0x400eaf93, 0x5017c05d, 0x98554fb3, -0x3de23fb4, 0xaa7d549c, 0x6be71942, 0x78577be6, -0x47aa0dd7, 0xa1226946, 0xcb703f76, 0x023e8ff2, -0x649fd255, 0xa927f029, 0xe2cfa7b3, 0x03a6ce51, -0xf674945b, 0x77f3c516, 0x41eb2b88, 0x5be10c42, -0x88a250be, 0xc30b371b, 0x8711bcb0, 0xaba1efe7, -0x0446f6d0, 0xe7ff87ba, 0x879b4aa6, 0xb033052e, -0xa388c8ab, 0x3344d7ab, 0xa81b3a68, 0x895fb4ff, -0xe4efddc9, 0x7c69bba5, 0xbd7226cf, 0xca2e3b74, -0xba316a72, 0x087b68ba, 0xa0234a53, 0x51f6447a, -0x1c6c1312, 0x52e597e7, 0xc50f49ee, 0x064ce0c7, -0x70f67efe, 0xcaf13ee0, 0xd68fc906, 0xa5a173a8, -0xde41697f, 0xc8b09415, 0x8a08cd8f, 0x2ac8a7ed, -0xac323499, 0xf55a3c3e, 0xd487d5c3, 0xb8940642, -0x73cd4073, 0xfb15c814, 0x775f4fe8, 0x2b42622c, -0xa53339a1, 0x305c5717, 0xcdae12bf, 0x8facff91, -0x86728c4f, 0xde5967a7, 0xaefa7393, 0x60fc32e4, -0x4ddd7ad9, 0x020ac80d, 0xd87b74e7, 0x7ffcdc79, -0x6e7ebe24, 0x561f95a0, 0x2523a129, 0xd40136d7, -0xd253e4db, 0x8339b140, 0x71f6d4cf, 0x9bbfd0df, -0xc54f7b50, 0x6c13a6fd, 0x09e9596d, 0xa71eaa48, -0x5b8a7c0a, 0x5cf679df, 0xcab512b5, 0x61623502, -0xe002bd96, 0x5e7b9889, 0xb029fae3, 0x85ae825e, -0x0cb81cf4, 0x7b8d598e, 0x1b1b4c43, 0x723f793e, -0xc2d0120d, 0xfa704e12, 0x0529301e, 0x6d7c1536, -0xe4008061, 0x319c2fce, 0x4dbb7c85, 0x989ae3e5, -0x877539d3, 0x9d77a472, 0x75e0ec43, 0x5243baa3, -0x7866e10c, 0xd71618ac, 0xc87934bd, 0xe96101d1, -0x55d1976c, 0x471c8505, 0x7a36d839, 0x5d62a9ee, -0xf3c54a8a, 0xa2be15d9, 0x244087c9, 0x042c8037, -0x23224689, 0x281c5d73, 0x2139ecfc, 0xffb8bc8a, -0x834fdd11, 0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, -0x4ae2dbda, 0x86d90089, 0x6675dfce, 0x48876262, -0xcec72538, 0x11dc5c80, 0x86a730f9, 0x313565c9, -0xe3e5be11, 0x106d7cce, 0x752b8be2, 0x3d00a5bc, -0xe6f70e95, 0x44447ac8, 0x600df30c, 0x8335ac3b, -0x8816ddee, 0x700982fe, 0xee495741, 0x48c7e81c, -0xa3d55da2, 0xb0172982, 0x70ab2158, 0xd4460621, -0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, 0xa8454763, -0x70877bb6, 0x66005c97, 0xaf292c06, 0x7b843db1, -0xf343b59b, 0x25cdc7b5, 0xa41da617, 0x9e9d895e, -0xc936f475, 0x7270925a, 0x30024230, 0x8e72f53d, -0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, -0xaf377cc1, 0xbff09a78, 0x4b4e0814, 0x95a0b2c1, -0x270398de, 0x201fca94, 0x2a032a4f, 0x131542b4, -0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, -0xa3b3a991, 0x17ee60c2, 0x852c0b8d, 0x11e5853a, -0x762002a7, 0x92c5311d, 0x0d4bf7e1, 0xfffec870, -0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, 0x0111a772, -0x9808e780, 0x29c336e8, 0xe9bc05df, 0x5bedde11, -0x945565af, 0xaff808fe, 0x87e3423d, 0x4de6f98f, -0x93b4adef, 0xbf704fa4, 0x09120e91, 0xd54f3692, -0xdf8eab1e, 0xfabbf59c, 0xe74318be, 0xaab87ffc, -0x29fa791c, 0xe3915552, 0xa652cb9b, 0xa1252e74, -0xb35b723b, 0x542aa28b, 0x12fcc5b0, 0x3941f962, -0x82bcc6cc, 0x47b11974, 0xb821611f, 0x78b34250, -0xf1be5659, 0x561b9e61, 0x6f3bd501, 0x584e6f5c, -0xd54ed547, 0xacebcd21, 0x7b5ff816, 0xb64ad233, -0x9f2f330d, 0x69fb1ece, 0xac8710dd, 0x58dc6c60, -0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, -0xa733274f, 0x884d9b55, 0x42b08b63, 0xafa54a74, -0x1c7ccf64, 0x93a20191, 0xaaa3132e, 0xc69831d1, -0x54634889, 0xfbfe3efc, 0xd3cf68d4, 0x302e3117, -0xf5693131, 0xc3ce8c6c, 0x1f03cd89, 0x6243334c, -0xf16bc80f, 0xdca5f130, 0xcb2cd956, 0x4c1bb421, -0xe8de533c, 0x7f86703a, 0x29aa897e, 0xdd54acad, -0x76b2f2ae, 0x7ef82b71, 0x2e30970b, 0xba402597, -0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, -0x2363d147, 0x5327289a, 0xe89229f3, 0xd63a535c, -0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, -0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, 0x6d65db4c, -0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, -0x8488a45f, 0x8ebc2932, 0xd4767316, 0x3e8c4b8a, -0xbab7402c, 0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, -0xc88528e9, 0x4b2e4e8f, 0xdd938b86, 0x0c964f98, -0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, -0x4d40b3b3, 0xcf203155, 0x0d2fa621, 0x752d2c58, -0xb12bac12, 0x1e7e8c23, 0x94215d54, 0x9854a71c, -0x4de63c64, 0x7a012529, 0x9c171f8d, 0x9e71def7, -0x3bd17d50, 0x11f175d9, 0xec78abf3, 0x7b529eee, -0xd3a69fc3, 0x5b718676, 0x58214d29, 0xa8bd2c34, -0x41ea00ab, 0xa03f64d6, 0x4ee342b0, 0x32b1e444, -0x1c1801a4, 0xc8424702, 0x334a7e35, 0x50cf1543, -0x3b22b495, 0x88683776, 0x8e2e0154, 0x6155c033, -0x4e2fa6ac, 0x42ace700, 0x8d64f97c, 0xaf9ced17, -0xb2a5cb92, 0xa558582d, 0x88705de7, 0x9e528d59, -0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, -0x10462123, 0x30080f7d, 0xb346cd81, 0x0049c396, -0x4e24165f, 0xa7c66809, 0x2e60bdcf, 0xaad70a08, -0xa73ea713, 0xe28f97a7, 0x283a9eab, 0xd4366489, -0xe776f963, 0x64ffa8ae, 0xde717b50, 0xbd2ca2b5, -0x3bae5f6d, 0x8d2bbef1, 0x7e9181e6, 0xf06aa121, -0xd06b2d20, 0xa83ea826, 0xef935e4f, 0xdfd27456, -0xa3451468, 0xc6820a63, 0x43463105, 0x787697aa, -0xcba5543d, 0xdf7e1e2d, 0x6998a8af, 0x98ce6c08, -0x89de731a, 0x943a3510, 0xb36ead85, 0xd5258d4b, -0x1cd6df61, 0x82a5c59d, 0xd078e7a4, 0xa33d4317, -0x24dc45f8, 0x3f3daf27, 0x0478bc6f, 0x92dfa16c, -0x952a872e, 0x7a34e03f, 0x0f088084, 0xa40937fe, -0x38fc7749, 0xa157e8a4, 0xbce94344, 0x7045ff7b, -0xf3e1ab66, 0xe62a6058, 0x5564ff10, 0x38198f1e, -0xf326f0f1, 0xe262bc0c, 0x2f0b851a, 0xc7bcbe11, -0xe79f1d1a, 0xc2f93c29, 0x54f3ea9f, 0x8f8f9141, -0x9f45e13c, 0x7a5b86bd, 0xa764efd8, 0x35f04729, -0xdd8c4b54, 0x5fa12e51, 0xa5824af9, 0xad328f71, -0x0f11fbb9, 0x9048e950, 0x04d7a900, 0x02538d1f, -0x99f745b7, 0xe31f63bb, 0x2c4e3d78, 0x7cdb9245, -0xa3966ee7, 0x27c4433a, 0xe1d79f3e, 0xe640fa06, -0x79ce31eb, 0xf25634fa, 0xdd9ce5cb, 0xb7fab8d2, -0x2f1f0ff2, 0x2acb625c, 0xa0494989, 0x206d7f11, -0xf268b8ca, 0x292bbf9f, 0x763bd7d0, 0xea4b14fc, -0x9d3d6aeb, 0x64cca57e, 0x6fc3e29e, 0x3e7bf4bf, -0x90efc7e3, 0x08e39173, 0xd05bee2c, 0x5b3c8f37, -0x0921ec6f, 0x3371b715, 0xb324e114, 0xe3abc53f, -0x576b18f8, 0xc4469024, 0xb2ded6c6, 0xe7783782, -0xc0a1fd5d, 0xcf324bde, 0x97527c8e, 0x19f8f48c, -0x3e806a5d, 0x96cff225, 0xe3b9d04a, 0x0e5856ae, -0x781372f6, 0x9645f2b7, 0x95a743ed, 0xd0c7eded, -0x86ca3cd9, 0xbab94db0, 0x43a1233a, 0x89c55554, -0xee776239, 0x34aa0098, 0x66a6e1d4, 0xae0e233e, -0x717e7b29, 0xb403a4c1, 0x36eb96c5, 0x42140832, -0x04250936, 0xda375dca, 0x524cb2e6, 0x86deaa0c, -0x400dc9d1, 0x12c00364, 0xe3ca7cf5, 0x87f20da7, -0xf57df9ef, 0x580dbdfc, 0x0b3e0369, 0x014d27fd, -0x4afaf6a1, 0xd1f4ca09, 0x77abc831, 0x30e49729, -0xec61cd2c, 0x159c1e92, 0xb61b40b1, 0x17c66fd6, -0xde11c061, 0x79d7f792, 0xc709cbfa, 0x94201c89, -0xbe65137d, 0x18aea1b4, 0xf248bbc3, 0x465f957d, -0xcf4a9672, 0xbf293fd2, 0x2c5e31c9, 0xc2c73011, -0xfb29cbf2, 0x576f7f0b, 0x74de1745, 0xa76e172b, -0x99b96223, 0x14ce1502, 0x231013fb, 0x1d4df40a, -0x951b0c16, 0xab173e66, 0x4ff65f74, 0xc4a87a47, -0x09cc3370, 0x66385490, 0x73e09118, 0x4ee96432, -0x0164d347, 0x205069b5, 0x158dd226, 0xc932c238, -0xe9048fa2, 0x100b626a, 0x86ee08cd, 0xed87cb1c, -0x6353ec37, 0xa36edcc3, 0x8a16dd6b, 0xd28a4198, -0xebea1127, 0xca0b761a, 0x61c31acf, 0xced5ff4f, -0xbf4dbd8f, 0xd969d8a7, 0xb6e4e9e8, 0x8421c402, -0x809d7222, 0xabfd1d2f, 0xc1857ce5, 0x23958fd7, -0x3226f1d3, 0xd822b4cc, 0x2f1cc3aa, 0x501fe01e, -0xe36f8c94, 0x7ad27716, 0x3321308b, 0xa85b957b, -0x38cfdf6e, 0xc7497dd5, 0x2462090c, 0x8f9e42e7, -0xdf97684a, 0xac8af621, 0xd5224866, 0xc5f64e50, -0x9724f297, 0xc386097b, 0x48c6f98a, 0xe1478b1a, -0x2dd23fd8, 0x716b2d85, 0xa5c3789b, 0x53625e80, -0x9b8b312c, 0xce482165, 0x66161e35, 0x64ecb56a, -0x9981c46a, 0xe6cb6bb3, 0xe1983186, 0x75ed470f, -0x4adcbd27, 0x3efeda68, 0x4d193a2a, 0xbfdb3cd4, -0x7c6167b6, 0xdbddea68, 0x4b0d2d62, 0x00ba3860, -0x49ec2544, 0xa68698c9, 0x2ce7be1b, 0xf5afc9fc, -0x1cebf9c3, 0x350f8f5b, 0x893eefb8, 0x77414f6f, -0xe46f26fa, 0x67bf6398, 0xd6858f5d, 0xac73db2a, -0x58e20acc, 0x750dd76a, 0xb7930e80, 0x8a8796c0, -0x44c86997, 0xb1807742, 0x3c827dc1, 0x381aaa3c, -0x83ac76f3, 0x57f0a2d6, 0x18261009, 0xe107138f, -0x85711c22, 0x2e1d982f, 0x7062179a, 0xaedfa298, -0x62e438f2, 0x6d325a9a, 0x99b489d3, 0x1bf77b3a, -0x28ca20e8, 0x502d1b21, 0x74a833c0, 0xbeb91634, -0xf56ffef9, 0x05401164, 0xe5dbab51, 0x0a2b460d, -0x2f0d9c22, 0xc74472f9, 0x12da5199, 0x68b2d628, -0x9a118f9a, 0x9035d200, 0xcda0221f, 0x12430cde, -0x79a43fbb, 0x5bb5e1b7, 0xeab5ed62, 0xe6a11e32, -0x3118b0fa, 0xedbcfb64, 0xd2285490, 0x824023c6, -0x30311fb1, 0xa0a4a475, 0xbfa8ac55, 0xb8c8fbda, -0xdf3cab63, 0x8d805566, 0xf52c1b1a, 0xa3471090, -0x02328a4a, 0x5d1dce57, 0x196aea39, 0xcd0f640b, -0x2fa01c27, 0x6175f783, 0xb2b6a0e4, 0x02fe6171, -0x2d3cb20b, 0x25f331e6, 0xacfa8085, 0x46a09a58, -0x27bbfb9e, 0x3914f970, 0x73e35206, 0x8bb87194, -0xdb58fc4b, 0x62fd53ff, 0x2c942c7c, 0x3f4681ba, -0xeada1780, 0x5dfbb960, 0x8473948a, 0x80787902, -0x049c20ba, 0x9e95a4fc, 0x8526d8ac, 0x3dcdcd2d, -0xb9562f16, 0xc9c8eb08, 0x533ed0a2, 0xa34d5d73, -0x3e579c8e, 0x235bb378, 0x36576983, 0xc71f11b2, -0x035eae76, 0xbec23972, 0x8613e5e9, 0x3982899a, -0xe5a55d62, 0x3c45a7e9, 0xbd4d6def, 0x17ae0a5f, -0xf0f53bb8, 0xa3dd1e29, 0x36f9520b, 0x72cbd950, -0x4d762d12, 0xe03cb7a8, 0xf8c8c1fe, 0xa4ff17a1, -0xcc779472, 0x83f9b379, 0xa2fc038c, 0xdd3b8104, -0x95936bb0, 0xf36c9705, 0x93939e08, 0xc98576ac, -0xec9196d1, 0xc8bce622, 0xb48e1075, 0x98dbd77d, -0xd1b04c3d, 0x85d1d422, 0x20765885, 0xc6a17eb5, -0x8e913cdc, 0x3f7a6758, 0x08176f48, 0xba2ea15f, -0x3638114d, 0xf08cb49b, 0xb8b6d9ce, 0x4e55891a, -0x2775c022, 0xc8d45982, 0x529c2eb3, 0xde080e24, -0xdac9c028, 0xeec68934, 0x8eaace11, 0xe82e05aa, -0x00033a20, 0x4ec94b5e, 0x445f5562, 0xa5c58462, -0xb6942526, 0x44631607, 0x5065644c, 0x14946f9c, -0xa9cb0e63, 0x53dff50a, 0x3f18fa24, 0x20b3b811, -0x95c1e57b, 0x1523d301, 0xc4e24932, 0x41a9be80, -0x24fc45b0, 0xccff2cbc, 0x996af6a1, 0xe3f201c3, -0x0917ea23, 0xbf4a1ac3, 0xbb0db6f1, 0xd15772df, -0xb1465383, 0x61400275, 0x571f6b1d, 0x0a4407f7, -0x916cfbce, 0x114f042a, 0x1cb9b3a6, 0x1b34c85a, -0xe36acc8d, 0xab109469, 0x5af9a63a, 0xccd4defc, -0xb758adfd, 0xbd8ddecf, 0x5ffe8424, 0xd73e2a4b, -0xb41cb99e, 0x01a52553, 0xba70e749, 0xf81d7557, -0x2b4f0847, 0xa22e281f, 0x5c653c31, 0x89bdb546, -0xa596e592, 0xbca4cbf4, 0xc3d1dfe3, 0x64a21c2e, -0x159aa4b7, 0xed90f2d6, 0xb1164cb0, 0x86de0088, -0xfd4e49e6, 0x70702b0d, 0x946b532b, 0x03a0144e, -0x71fb19ed, 0x07c41763, 0x63312ce9, 0x0e2f5ee4, -0xc6501661, 0x09599e4e, 0x544fd5cc, 0x054d842c, -0x902bb57d, 0xdf82a365, 0xb7ae9427, 0xa6750881, -0xeee3c9cd, 0x6cbe0f45, 0x7f72d3f9, 0x430b786f, -0x162b6004, 0xbfcd440b, 0xdc4f5c81, 0x82249f6b, -0x98d1cdca, 0x2cc2692e, 0xf977f83a, 0x570c1e1f, -0x24ed6461, 0xcae5afea, 0x9cf06576, 0x9199d69c, -0x883febfe, 0x0f254c42, 0x6eb50978, 0xf91fade4, -0x9cfe5488, 0xfe3bf66b, 0x86ea94e3, 0x1bed23f5, -0x0bded397, 0x0cde064b, 0x7abd7a81, 0x8efb798e, -0x9a78e5f2, 0x7c46d76f, 0xcb3ae1ea, 0xc33e7ab1, -0x0c3993f0, 0x5b2d8de7, 0x24948ba8, 0xffce06e6, -0x0d3c2dc2, 0x3ae09142, 0x7e6b932e, 0xb3e22558, -0x9f7c425e, 0x8fa1329b, 0x24aa5012, 0xb9e49bc7, -0x787dd5a6, 0xf68c8171, 0x440d2146, 0x9734857f, -0x8c30c31a, 0xcb3352a1, 0x46b04f38, 0x72572ef8, -0xc90c56df, 0xe8103fa8, 0x04057577, 0xd1c250d9, -0x5cb390a9, 0xbdba74b9, 0x80012fa3, 0x408216c2, -0xadca83bc, 0x3c39bcdf, 0xf0da9459, 0x421d5a3d, -0xc5cf55c9, 0x2dcfa63d, 0xd852066b, 0x606b2204, -0x4d5e9576, 0xe8d6475f, 0xe46ec6b0, 0xf4e3c2c6, -0x1bfe1bb0, 0xc2803818, 0x2a3e4809, 0x947e50a1, -0x3a10e713, 0xc9e070cc, 0xa4244fe4, 0xa7f5d2e7, -0x194f77ee, 0x76754ab4, 0x75ed4e5f, 0x92ffdbaa, -0x1f5bce6a, 0x14aeeec7, 0x366fbb47, 0x44ecec7b, -0xbc31e911, 0xee6c224f, 0x0a6f7376, 0xbe79fce3, -0x53a18077, 0x6f6ad5fe, 0x945938bd, 0x61bb760c, -0xed26220f, 0x9f492f0a, 0xaf0f2d80, 0x265f5449, -0xae1f2dc3, 0xd235910c, 0x44a0f4a0, 0x36fcc004, -0x1e8fa223, 0xe7440ed0, 0xa8535548, 0x6d7e7029, -0x2e1b7968, 0xf3baa61d, 0xf447ef12, 0x701d62d6, -0x2da5dcf4, 0x44828196, 0x41af9c9a, 0xab210662, -0xa5ee18f2, 0xd45eb369, 0x947814fe, 0xeb62eb49, -0x30c555c6, 0xdc06ccbd, 0x786705d2, 0xd50c80d3, -0x266d8313, 0x68f63164, 0x1e3e4322, 0xfc23834e, -0xe879261f, 0x28992a8f, 0xab86dac9, 0x19f88d1a, -0x5110c867, 0x3c050155, 0xf9b1b3f5, 0x98909489, -0xfa0ee6bc, 0x038fb4ce, 0xbe1c9e33, 0x18f96bcd, -0xa1635c9a, 0xff3e9374, 0x5b033171, 0x0b84bfd9, -0x3c091bae, 0x6da61a4e, 0x07d81b5d, 0x3904ea3c, -0x75f4e7f1, 0x3e70c12e, 0x9c70d835, 0x9a1ea5a6, -0x4b99b705, 0x08f6ab89, 0x7649901c, 0xee3e7687, -0xa3deb48c, 0xd74e8c78, 0xe8e120c3, 0x425d3d96, -0x16f136bd, 0x0c7a32ef, 0x37a0ff53, 0x77b035e4, -0xba8808c1, 0x1d3d8330, 0x8d224cce, 0xed789fed, -0x550a8352, 0xe2715912, 0x185f62d1, 0xe301002a, -0xbe2ed99b, 0xbb1dfd60, 0x9d22d8f9, 0xcbfa36d5, -0xad7e92e0, 0xd2db61d4, 0x1df386f5, 0x92b5797c, -0x00ac8ed1, 0x2f7470b1, 0x674e258b, 0x6689df79, -0x135c5c1a, 0x87abbc50, 0x19ac082b, 0xe7f7d64c, -0x24fd4922, 0x7eeadc29, 0xa0910eaa, 0x763231d6, -0x23597ccb, 0x332f33c3, 0x93992b6a, 0x19c8937c, -0x75d6a9f4, 0x221395e1, 0x662914d0, 0x997d7860, -0xd196adeb, 0xa5402fd9, 0x8bd6f12f, 0xc31d97e0, -0x304dd9dc, 0x72f35c72, 0x8ced870e, 0x1eef8a14, -0x323321fa, 0xf193079f, 0x18026b1c, 0x5a1107a5, -0x54979f4b, 0x6afee492, 0x04c012e6, 0x3446250c, -0x25a691a8, 0xc19a76ea, 0x66bd5b14, 0x6250bd2d, -0xc6c082d9, 0x67ea1d78, 0xbe68a7ef, 0x03f50dc8, -0xd8f76566, 0xb6681752, 0x00e2b087, 0x7ed2e598, -0x8c9cbc83, 0x103b03f5, 0xee4d2723, 0x67b3903f, -0x1e057dec, 0xc5703ba6, 0xae0615f9, 0x1bce0df2, -0xfd041279, 0xc874a2c3, 0x0a91d2fa, 0xac098457, -0xc1efc5f9, 0xd48208eb, 0x72e9baa8, 0x184dc658, -0x3d26b8b4, 0x90e2469d, 0x6d07f351, 0x3f6898a7, -0x21e4de0b, 0x0fd04a43, 0x2c99cd2b, 0x44b28cdd, -0xaf5483a5, 0xe50b9a12, 0xd98fe031, 0x9d6e8f08, -0xf385ba19, 0x5e531cb0, 0xc545867a, 0x65f5ebf5, -0x9f27ad5a, 0x2de11f0d, 0xef6f0970, 0x973b11f2, -0x72228c07, 0xe13fdb84, 0xd2a7b46f, 0xc85a38db, -0x331a9807, 0x3be38ebc, 0x3e7bf15d, 0xa82a1e68, -0x4b42b5bc, 0x9871203e, 0x7d1e1e24, 0x12f57b6b, -0xf5403ec8, 0x28746c33, 0xae20522f, 0xf6042fba, -0x66bada5d, 0xbefe376f, 0xfd3773a5, 0xbb5fc6e8, -0x34c0433d, 0x3cfc83e9, 0xd096736a, 0xa53be016, -0xeba3dd6c, 0x2c626561, 0x3c160c8d, 0x8506c719, -0x802e7b47, 0x16079396, 0x6d29b175, 0x4e91abb4, -0xe350ce95, 0x0d481aa5, 0x94e95371, 0x10dc4dec, -0xbfeb3735, 0x3ce3cb4d, 0x32ff742a, 0xac5ad3cb, -/* 2617-m111067AA07.inc */ -0x00000001, 0x00000a07, 0x04092008, 0x0001067a, -0x83067f5a, 0x00000001, 0x00000011, 0x00001fd0, -0x00002000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000a07, -0x0000001a, 0xa4000000, 0x20080408, 0x00000401, -0x00000001, 0x0001067a, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc4294866, 0x3e20a114, 0x8387f19c, 0xdafb14aa, -0x33a38309, 0x68b0f8ea, 0x2a20b200, 0xcdc7aa9e, -0x170ce7c7, 0xd727c705, 0x019b1ba5, 0xe0414a29, -0x57d45458, 0x26a8a411, 0x9faad966, 0x095ec8b0, -0x083a7c2a, 0x17cfc70f, 0x3c8e78a8, 0xce18c419, -0x5f2ddeb7, 0xc9c95d71, 0x437a5116, 0xe0253ad0, -0xec78db42, 0x681e436f, 0x7fd028bb, 0x1149a501, -0x0bdf0d05, 0xc2321514, 0xd6866cd8, 0x64942685, -0x21e0276b, 0x0817a288, 0x09138669, 0x792985dc, -0xbd60d6aa, 0xfbf902ec, 0x43fee69d, 0x5c5823c0, -0x9dca1fe6, 0xb528b0c5, 0x22fd29ab, 0xac4fe251, -0x77207813, 0x0637a1f9, 0x16bfcf73, 0x80497f6b, -0xe5bca939, 0x1539fa1a, 0x66607fea, 0x2276c06f, -0xd003229e, 0x3622fda7, 0x18d0b8af, 0x9f399760, -0x3ac6387b, 0x6c7148fa, 0xfaf4df9f, 0x965db840, -0x7c142542, 0x7b805f4c, 0x3f2002a3, 0x061399ce, -0x2f1a03c4, 0x7f1c7616, 0xb2f9ab42, 0x4e6a92a2, -0xb44b96d6, 0xe1167017, 0xec4b2fb3, 0xa15376be, -0x00000011, 0x9f63eb61, 0x64816577, 0x10c68141, -0x1cc5fd18, 0x156703a6, 0xe3315c33, 0x62a1db21, -0xb6135848, 0xa306d2fe, 0x117cb585, 0x54c3a133, -0x722cf721, 0xa693cd57, 0xd02c0e2d, 0xf17b96ca, -0x97d2a408, 0x2e776501, 0x667f7664, 0x1568cf83, -0xa044dee1, 0xe6a879aa, 0x4ff23d0a, 0xd559de49, -0x2dabb17a, 0xc6c39e38, 0xc3ae5451, 0x2d03f3dd, -0x7ba226ed, 0x69a19529, 0xc2865715, 0x8b95e6c2, -0x7a7ee1cf, 0x74b5e43f, 0x69aeeefb, 0x5d95aaa5, -0x0afeb5dd, 0xdb837be6, 0xed6f9d79, 0x2ad96eb4, -0xcd60dd82, 0xc3ff7d75, 0x7030a02b, 0xdbbe45dc, -0x203cd7ba, 0xc3b90579, 0xa21f54f2, 0xc79853ce, -0x5e3f74eb, 0x06c63742, 0xb1fa50ef, 0x0e8e950e, -0x97d44b72, 0xa48dc8ad, 0xf3803fb8, 0x946e4d5e, -0xf0f1e9f6, 0x272b9764, 0x567efb67, 0x82deebcc, -0x614f61e8, 0x3bea41b8, 0x31a12485, 0x682e10ae, -0x954c7b7f, 0x0e4bccf0, 0x8cb1eb25, 0xb5018c6e, -0x50957531, 0xcc60f1c9, 0x11181c5c, 0xa4dc1468, -0x3310423f, 0xd2550a2a, 0x3bd2ac80, 0x2be006d9, -0xf57f3e2d, 0xb4387cc7, 0xe96c48f9, 0x722975a2, -0x4506717f, 0xaf92aa6e, 0x7de4eb6e, 0x3600e58d, -0x898cc58f, 0x271c467f, 0x1c5cd377, 0x5858e9bc, -0xd3ad9408, 0x513c936c, 0x0dc54b7e, 0x0226d703, -0x4cc95088, 0x78bbb408, 0x573d07e2, 0xa4e9cd4e, -0x4a2930cc, 0x3082d573, 0x68c8c48e, 0x883d27f8, -0x4e91dd95, 0x850f6d80, 0x5f7f3e37, 0x452cc29a, -0xf2f9cc40, 0x278be406, 0x356eb275, 0xda301857, -0xdbc49113, 0x7007d110, 0x06f49bc2, 0x74712f32, -0x73176720, 0xcebc66e2, 0x592acf0a, 0x8818dd3f, -0xd599d562, 0x54199a46, 0x6472129b, 0x47058cd1, -0xac4a74f5, 0x1cac471a, 0xf1b4758a, 0xfa6f8e1d, -0x1013e19a, 0x59252c0b, 0xa764c600, 0xfba01968, -0xc7c11589, 0x2b4bf080, 0x0157b32c, 0xc09788fa, -0x1be99aed, 0x19c1799c, 0xb1d03201, 0x8bfb5374, -0x44e04a89, 0x895d3a8b, 0x5b3a53dd, 0x4704a722, -0x0d4ac344, 0x8a3f81f2, 0x3513e05d, 0x04e89637, -0x39f3d4a3, 0x883f2acd, 0xbc2ec5aa, 0x3a26f17e, -0x3de2b026, 0x49cffb83, 0x9cdece0f, 0xdaaddd7f, -0xc884a2fe, 0xe4244359, 0x493030d4, 0xb87e816a, -0x3b2481a1, 0xa2eaa4eb, 0x33d7ad6a, 0x64947485, -0x65f85855, 0x088388d8, 0xf6dfc3eb, 0xbceddbca, -0xf72f47e1, 0xd1d06e25, 0x76ff3bc0, 0x9b8f2139, -0xec7bc702, 0xfe6e6c0f, 0x42d31d20, 0x7e0397f9, -0xb20b40ff, 0x45a5ce27, 0x31949159, 0x7013a868, -0xdef2e0d9, 0x30c62ff4, 0x9b5a9b24, 0x0e4e4b1d, -0xecbbbe85, 0x4cca116b, 0x341fa1fc, 0xfa64b033, -0x43007f76, 0x710238e0, 0xa995a864, 0x5125d448, -0xc20c49c5, 0xea370734, 0x9bb92154, 0x596f42c2, -0x8d8919f6, 0xdd875cf4, 0x3b76b70b, 0xe96291c9, -0x2814c6d4, 0x0baf988f, 0x9880af78, 0xcbb57ca5, -0xf9580819, 0xebe041cb, 0x051d6dab, 0x5170746b, -0x6f04bfec, 0xca10ec0b, 0x2a870ec1, 0x551af839, -0xcfbbbb16, 0xef91d864, 0xe9b9dde1, 0xf1fade18, -0xe306f50b, 0xeb5253aa, 0x30010729, 0xb4169d72, -0x3320e4f1, 0x9c6946e1, 0xdee63588, 0x4b2967be, -0x167720ed, 0x6f27e397, 0x83419fdc, 0xac4386f3, -0x0ac58383, 0x55c0dd4e, 0x62b4a145, 0x91d64a01, -0x0e8acdb5, 0x40de995a, 0xc850ada1, 0xaa95a50a, -0x14516378, 0x294a976e, 0x544fa118, 0x904c471c, -0x8a5896d3, 0xb1486188, 0x237498dc, 0x1a1980b3, -0xd339968f, 0xe735a8b1, 0xc5ee31e3, 0x35c64060, -0x79cd8f43, 0xa2bb1974, 0x00189576, 0xf7bd74be, -0xdd52d07c, 0xa20b9c8b, 0x98dadf9d, 0xf75c05be, -0x476ac3a5, 0x6fb2bf82, 0x914c23c7, 0xd91c35e8, -0x709ef212, 0x3d8f3ca6, 0x14c20046, 0x7015482e, -0xb3fa2331, 0x78933f36, 0xc73c72b5, 0x645b4476, -0x299fa727, 0x701d7717, 0xf6c4bfed, 0x3213dc65, -0xfe66e1b4, 0x8040904c, 0xc536845b, 0xd1764a8d, -0xdeb49b88, 0xdaf26115, 0x8160aa13, 0x206d4929, -0x92fdb80a, 0x4f1aaab2, 0xfbbac21f, 0x2dc479da, -0xd2ce1eab, 0xa7da6602, 0xa9fbe019, 0xdd58fac1, -0x747ab469, 0x946a3b93, 0xc7b9cbe7, 0xc6f74040, -0x8a8bee87, 0x07f65d07, 0xe79eb820, 0x64ef2fc1, -0x72b1eccf, 0xc71f601b, 0x2812ab18, 0x48415edf, -0x45a80c6d, 0x7f616640, 0xfeaa98d0, 0x1024f1e8, -0x37b3735c, 0xc136f513, 0x5df10182, 0x1bd2ec03, -0x07f04b3c, 0x59beeff2, 0xea0388f8, 0x2f6addc8, -0xe0f282e2, 0xf9772673, 0x6bd0dc01, 0x3b4d6f9b, -0x29b81515, 0x6c553377, 0x1136b69a, 0x50e03397, -0x9c483ccd, 0xb0a13c9d, 0xea8e6bd6, 0xb8129b95, -0xc085a4d1, 0x52f64f7f, 0x178aad6e, 0xe5c4d92a, -0x4c35f2de, 0x8f179df7, 0xba405091, 0xd756e10d, -0x23bfae39, 0x74015fee, 0x15dc3e64, 0xdfc05a18, -0xa51ac3a0, 0x0ad4595a, 0x801363f0, 0x3db1f0c5, -0x97a8ca8f, 0x7e74b015, 0x124d1664, 0x71b26596, -0xaf073d4e, 0xf45d87d4, 0xd73c1dd0, 0xd1ade30b, -0x8127545f, 0x4ba0585c, 0x5bb26da4, 0xd64fb76b, -0x5c9c8190, 0xc1603512, 0xf7a69779, 0x1529ac38, -0x8d9422c9, 0xac132697, 0x5f9ce586, 0x8d5ca1ce, -0xba409dbd, 0x184b0698, 0x71bc5a54, 0x294e6b1c, -0x085c38df, 0x629e955b, 0x73f5c2b8, 0x219166e4, -0x9805fea9, 0x7602d837, 0x0932604b, 0x06a1509c, -0x2afe3b47, 0x61050264, 0x0fba8fc2, 0x9f648238, -0xbf3adf84, 0xdb8d2f92, 0xba2d9b51, 0x3d4415df, -0x32811e41, 0x176a4519, 0x1ffd7d6b, 0xffe56807, -0xca7db7a3, 0x5c811c87, 0x6bf1fe24, 0xc3013434, -0x4ccc937e, 0x0a04797c, 0xca7dd4b5, 0x20ba4643, -0x2b18ed89, 0x2ccf7a54, 0xd1a9e7a8, 0x67d96e26, -0x9dd29473, 0x0f26a8f8, 0x164fb823, 0x17c5d3fc, -0x26361bf0, 0x02544619, 0x32bbe44e, 0x12fbec8d, -0x0a928412, 0x23652975, 0xe67465e7, 0xd1f49edc, -0x200ce053, 0x1276b87a, 0xf5150061, 0xf509028d, -0x4aa27234, 0x6fbc6156, 0x89e61e73, 0x612a7618, -0x20783c3e, 0x152fda0c, 0x9a5c7b17, 0xebd39bba, -0x9793ab7e, 0x053f88e4, 0xef9499c7, 0xdf5efc36, -0xa2792729, 0x068ba6d6, 0xa5c5687e, 0x3924364a, -0xa4c6c2e4, 0x45364a92, 0xda08f6ba, 0x1551c9a5, -0xb4787235, 0x73d99aae, 0x584e52ec, 0xd76c6379, -0xf852e104, 0xa335ab55, 0xd2b1013a, 0xc2c591f1, -0x91ac865d, 0xe82497be, 0x39f62b27, 0x3d6a9530, -0xb74f7711, 0xca3f54d4, 0x466e17e8, 0xe91d700d, -0xbe8197a7, 0x04218b87, 0x587e7832, 0x838c1a71, -0x39d27956, 0x36ecc542, 0x36b22957, 0x5c44fe01, -0x86ae0bfe, 0x2ffa7c08, 0x603db66a, 0x69d7eed9, -0xd96761bf, 0x44bc3358, 0x2c04707e, 0x290a0631, -0xac627cd8, 0x1dd90751, 0x41e91a35, 0xf5dc1260, -0x36564120, 0x1ac71792, 0x87e0a694, 0x063d0388, -0x4f282802, 0x026fdbfd, 0x11102f9a, 0x5932ad11, -0xc5f266d3, 0x27587435, 0x6fecaeb7, 0x191e6dda, -0x50daedc2, 0xa282f89d, 0x89ceb660, 0x4564adc8, -0x0cee73af, 0xed4f399f, 0x10085cac, 0x0d9ded47, -0xa88956dd, 0x242798ad, 0xae708815, 0xf7edf1f7, -0xb9fa65b7, 0xe8b4fcc1, 0x00fd86c4, 0x7ad67bce, -0x66e3f423, 0xee1b4874, 0xccbc4116, 0x04a72b4b, -0x39a640f0, 0xef9f5c48, 0xe8d1470d, 0xee1ef5d1, -0x90784af3, 0xbc0b3389, 0x49aac119, 0xdf65d921, -0x1023547c, 0x486b404a, 0x834d359c, 0xf5dbbd50, -0x68b5997b, 0x7aee9417, 0x42e48286, 0xa9d8ee77, -0x181a3e1e, 0x607cb99f, 0x5f53c78d, 0x5a60a6a8, -0x39cfc04c, 0xfbe6eb32, 0x84348beb, 0xa278662b, -0x398c625d, 0x3f9859e8, 0x5517ef17, 0x15856fe2, -0xba4d33c1, 0xc93d7652, 0xcf40a2aa, 0x2ac37060, -0x5efc6cab, 0xced95484, 0xf39ceed8, 0x4ecc8045, -0x13c1e742, 0xd93d87f1, 0x695cf766, 0xcb53f961, -0x15e0fc91, 0x37178627, 0x5e832076, 0x8c72db35, -0x2ce047e6, 0x11d9e791, 0x45e4d466, 0x8b7a7c71, -0xa83e9738, 0x7c54e924, 0x2ff12bda, 0x6b1ca347, -0x2957b0a8, 0x1fdb23fa, 0x91f98947, 0xe02c3f1b, -0xc42cbb06, 0xf0421ecc, 0x1716fce4, 0x1bb34813, -0xc67853bd, 0x3a27d8f1, 0x8e38f3be, 0x9e5dc781, -0x245017b1, 0x8cade69f, 0x44642f90, 0x3ef4215a, -0x879c78ad, 0x371ddad7, 0x7c629ddb, 0xe5f61d71, -0xbb3896fd, 0xcd3067f4, 0x4cfc2e12, 0xe7d69e64, -0xcd35c838, 0x6af17c65, 0x322fec99, 0x81221d8b, -0xa586497b, 0xb2cecfa9, 0xebbdaef4, 0x074fef30, -0xf825db99, 0x2f916b7b, 0xdc32f01d, 0x915eddd6, -0x96238f76, 0xf61c60df, 0x68795cf1, 0x46f1f13f, -0xc9654740, 0x63872bc0, 0x51e210b6, 0x17b5c27b, -0x7adf79d9, 0x7a823cc1, 0x02011b40, 0x6434a855, -0x56eca557, 0xa14f4132, 0x8c120524, 0x778266f4, -0x04ad9ca3, 0xccceab50, 0xecd117cc, 0xf0defcc9, -0x4f573e38, 0x5393033b, 0x88684c7b, 0x1a33f3a7, -0x898f45f0, 0x355ffa68, 0x174542c3, 0xa3dcfb8d, -0x6cd09199, 0x67339d62, 0xd29348c7, 0x37431b9f, -0x508c487c, 0xe4668bdf, 0xcbba1b72, 0x1b1b10a1, -0xcd4447c0, 0xf9ee7e83, 0x871a0f4f, 0xa94572d2, -0xac77a5c1, 0x3b84dbd4, 0xd45a09b6, 0x8e73228d, -0x59f2bb36, 0x4855a81b, 0x3fafe19b, 0x2f612920, -0xb9d216f3, 0x937e6a7e, 0xf31a2011, 0xfb7ca7fb, -0x1ca50eef, 0xd1d2baec, 0xa19d932b, 0x620d57d4, -0x086b7270, 0x5fcc7905, 0xb0dbe594, 0xf16f0a1d, -0xd47563f5, 0xe54eeb3a, 0x588766e4, 0x0280ef61, -0x8f26923d, 0x14b892bd, 0xdd11550f, 0x3e5ec618, -0xed825fca, 0x52a04ef9, 0xaad0c980, 0xdff1a4ea, -0x68f8954e, 0xc0f1664d, 0x6bc36a13, 0x5d36fbca, -0x05f7883f, 0xd2da1028, 0xe3cd0e3e, 0xa4038605, -0xb48e7f32, 0x1f5ffb16, 0x7c4899b2, 0xb3073d46, -0xe2acb6e2, 0xefe17316, 0xca66163c, 0x93d4b562, -0xa86a9d63, 0x07449ca1, 0xb499c9d4, 0x6c666b70, -0x0d8c9f9d, 0x78c926a0, 0x99e4d31f, 0xd73c49ca, -0xfd7e352a, 0xd710b7c6, 0x18100555, 0xb4e79321, -0x5efc693a, 0x703180ef, 0x9bbb238b, 0xa105a3e4, -0xdaa3ce4d, 0xff7cc846, 0x2bfbd556, 0x5f5ba34d, -0x0ef8537b, 0xb0bc4e7b, 0x224f6dbf, 0x3b9ddb96, -0xf731880a, 0x00d8d325, 0x55e4908e, 0x63bc2811, -0xafa6f5cd, 0x5219a8c7, 0x4609390d, 0xd68e7ae1, -0xc2e5e5dd, 0xf232712f, 0x1c52c242, 0x5a6cb79f, -0x26667cb4, 0x0de1b656, 0x42ca30c0, 0x4ab64de9, -0x26b0cfa4, 0x2897b6d1, 0xefc5d75e, 0x67ca7a04, -0x805a805d, 0xf2e454cc, 0x837877a1, 0x8ca7dc3b, -0x40620ce0, 0x5ac019fb, 0x6ee93d19, 0xae137f12, -0x0cedbd2f, 0xacc51979, 0xec7ae13f, 0x4537c7b6, -0xe3491fd6, 0x8e63f870, 0x1e08f6b3, 0x219dae5b, -0x8db5d524, 0x8de9f8ee, 0x04913730, 0x7a11db72, -0x6e4d0088, 0xa8713aba, 0xf2e72fd0, 0x2ba5695f, -0xe11da489, 0x6a5ecdf5, 0xc2133568, 0x994cc9f4, -0xed6825cc, 0x3d104599, 0x4d7679b6, 0x3bfe94f0, -0xc6a131db, 0x6dfcc31c, 0x9ec5c4f6, 0x3a386a48, -0x5d0b6f61, 0x059b5114, 0xd4831a86, 0x37460179, -0x02f23600, 0x1c04bd2e, 0xbf689d81, 0x2bf0be1c, -0xd8d5974c, 0x0d9d0709, 0x5dcade38, 0x167df39e, -0x96942861, 0xf1e6a09c, 0x16ac7082, 0x5037af19, -0x69c40dbb, 0x10728698, 0x71d52ed0, 0xa77036b8, -0xa050ea5f, 0xa7ca5494, 0xa25b4acd, 0x7f8ceb12, -0x8f03bc78, 0x6b7ee0f3, 0xa97d44b3, 0xeda32377, -0x852c4597, 0x3f81aa95, 0xf148a2da, 0x770e5cb6, -0x90fe1806, 0x50620299, 0xd7f4042b, 0x0d356595, -0x5596e5dd, 0x6c797c13, 0x500c0ee5, 0x7e5ae4c5, -0xecf3ac43, 0xae09d902, 0x95b72b10, 0x7597d441, -0x8d719da8, 0x151b5d1c, 0x1f6790f9, 0x1147be9f, -0xee857fb4, 0x6f34c63c, 0xb5211613, 0x831687d1, -0x80e19a47, 0x1bb032f0, 0x5341a6f2, 0xc9a32ec1, -0xad2521c2, 0x359e67d5, 0xeb4fa538, 0x1cc294ee, -0xab08e4ee, 0x491c2562, 0xe1e38431, 0x039787ad, -0xa3cc1cd4, 0x3ff47385, 0x0f442100, 0xd40d9c3e, -0xcd033c28, 0x400eaf93, 0x5017c05d, 0x98554fb3, -0x3de23fb4, 0xaa7d549c, 0x6be71942, 0x78577be6, -0x47aa0dd7, 0xa1226946, 0xcb703f76, 0x023e8ff2, -0x649fd255, 0xa927f029, 0xe2cfa7b3, 0x03a6ce51, -0xf674945b, 0x77f3c516, 0x41eb2b88, 0x5be10c42, -0x88a250be, 0xc30b371b, 0x8711bcb0, 0xaba1efe7, -0x0446f6d0, 0xe7ff87ba, 0x879b4aa6, 0xb033052e, -0xa388c8ab, 0x3344d7ab, 0xa81b3a68, 0x895fb4ff, -0xe4efddc9, 0x7c69bba5, 0xbd7226cf, 0xca2e3b74, -0xba316a72, 0x087b68ba, 0xa0234a53, 0x51f6447a, -0x1c6c1312, 0x52e597e7, 0xc50f49ee, 0x064ce0c7, -0x70f67efe, 0xcaf13ee0, 0xd68fc906, 0xa5a173a8, -0xde41697f, 0xc8b09415, 0x8a08cd8f, 0x2ac8a7ed, -0xac323499, 0xf55a3c3e, 0xd487d5c3, 0xb8940642, -0x73cd4073, 0xfb15c814, 0x775f4fe8, 0x2b42622c, -0xa53339a1, 0x305c5717, 0xcdae12bf, 0x8facff91, -0x86728c4f, 0xde5967a7, 0xaefa7393, 0x60fc32e4, -0x4ddd7ad9, 0x020ac80d, 0xd87b74e7, 0x7ffcdc79, -0x6e7ebe24, 0x561f95a0, 0x2523a129, 0xd40136d7, -0xd253e4db, 0x8339b140, 0x71f6d4cf, 0x9bbfd0df, -0xc54f7b50, 0x6c13a6fd, 0x09e9596d, 0xa71eaa48, -0x5b8a7c0a, 0x5cf679df, 0xcab512b5, 0x61623502, -0xe002bd96, 0x5e7b9889, 0xb029fae3, 0x85ae825e, -0x0cb81cf4, 0x7b8d598e, 0x1b1b4c43, 0x723f793e, -0xc2d0120d, 0xfa704e12, 0x0529301e, 0x6d7c1536, -0xe4008061, 0x319c2fce, 0x4dbb7c85, 0x989ae3e5, -0x877539d3, 0x9d77a472, 0x75e0ec43, 0x5243baa3, -0x7866e10c, 0xd71618ac, 0xc87934bd, 0xe96101d1, -0x55d1976c, 0x471c8505, 0x7a36d839, 0x5d62a9ee, -0xf3c54a8a, 0xa2be15d9, 0x244087c9, 0x042c8037, -0x23224689, 0x281c5d73, 0x2139ecfc, 0xffb8bc8a, -0x834fdd11, 0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, -0x4ae2dbda, 0x86d90089, 0x6675dfce, 0x48876262, -0xcec72538, 0x11dc5c80, 0x86a730f9, 0x313565c9, -0xe3e5be11, 0x106d7cce, 0x752b8be2, 0x3d00a5bc, -0xe6f70e95, 0x44447ac8, 0x600df30c, 0x8335ac3b, -0x8816ddee, 0x700982fe, 0xee495741, 0x48c7e81c, -0xa3d55da2, 0xb0172982, 0x70ab2158, 0xd4460621, -0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, 0xa8454763, -0x70877bb6, 0x66005c97, 0xaf292c06, 0x7b843db1, -0xf343b59b, 0x25cdc7b5, 0xa41da617, 0x9e9d895e, -0xc936f475, 0x7270925a, 0x30024230, 0x8e72f53d, -0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, -0xaf377cc1, 0xbff09a78, 0x4b4e0814, 0x95a0b2c1, -0x270398de, 0x201fca94, 0x2a032a4f, 0x131542b4, -0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, -0xa3b3a991, 0x17ee60c2, 0x852c0b8d, 0x11e5853a, -0x762002a7, 0x92c5311d, 0x0d4bf7e1, 0xfffec870, -0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, 0x0111a772, -0x9808e780, 0x29c336e8, 0xe9bc05df, 0x5bedde11, -0x945565af, 0xaff808fe, 0x87e3423d, 0x4de6f98f, -0x93b4adef, 0xbf704fa4, 0x09120e91, 0xd54f3692, -0xdf8eab1e, 0xfabbf59c, 0xe74318be, 0xaab87ffc, -0x29fa791c, 0xe3915552, 0xa652cb9b, 0xa1252e74, -0xb35b723b, 0x542aa28b, 0x12fcc5b0, 0x3941f962, -0x82bcc6cc, 0x47b11974, 0xb821611f, 0x78b34250, -0xf1be5659, 0x561b9e61, 0x6f3bd501, 0x584e6f5c, -0xd54ed547, 0xacebcd21, 0x7b5ff816, 0xb64ad233, -0x9f2f330d, 0x69fb1ece, 0xac8710dd, 0x58dc6c60, -0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, -0xa733274f, 0x884d9b55, 0x42b08b63, 0xafa54a74, -0x1c7ccf64, 0x93a20191, 0xaaa3132e, 0xc69831d1, -0x54634889, 0xfbfe3efc, 0xd3cf68d4, 0x302e3117, -0xf5693131, 0xc3ce8c6c, 0x1f03cd89, 0x6243334c, -0xf16bc80f, 0xdca5f130, 0xcb2cd956, 0x4c1bb421, -0xe8de533c, 0x7f86703a, 0x29aa897e, 0xdd54acad, -0x76b2f2ae, 0x7ef82b71, 0x2e30970b, 0xba402597, -0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, -0x2363d147, 0x5327289a, 0xe89229f3, 0xd63a535c, -0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, -0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, 0x6d65db4c, -0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, -0x8488a45f, 0x8ebc2932, 0xd4767316, 0x3e8c4b8a, -0xbab7402c, 0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, -0xc88528e9, 0x4b2e4e8f, 0xdd938b86, 0x0c964f98, -0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, -0x4d40b3b3, 0xcf203155, 0x0d2fa621, 0x752d2c58, -0xb12bac12, 0x1e7e8c23, 0x94215d54, 0x9854a71c, -0x4de63c64, 0x7a012529, 0x9c171f8d, 0x9e71def7, -0x3bd17d50, 0x11f175d9, 0xec78abf3, 0x7b529eee, -0xd3a69fc3, 0x5b718676, 0x58214d29, 0xa8bd2c34, -0x41ea00ab, 0xa03f64d6, 0x4ee342b0, 0x32b1e444, -0x1c1801a4, 0xc8424702, 0x334a7e35, 0x50cf1543, -0x3b22b495, 0x88683776, 0x8e2e0154, 0x6155c033, -0x4e2fa6ac, 0x42ace700, 0x8d64f97c, 0xaf9ced17, -0xb2a5cb92, 0xa558582d, 0x88705de7, 0x9e528d59, -0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, -0x10462123, 0x30080f7d, 0xb346cd81, 0x0049c396, -0x4e24165f, 0xa7c66809, 0x2e60bdcf, 0xaad70a08, -0xa73ea713, 0xe28f97a7, 0x283a9eab, 0xd4366489, -0xe776f963, 0x64ffa8ae, 0xde717b50, 0xbd2ca2b5, -0x3bae5f6d, 0x8d2bbef1, 0x7e9181e6, 0xf06aa121, -0xd06b2d20, 0xa83ea826, 0xef935e4f, 0xdfd27456, -0xa3451468, 0xc6820a63, 0x43463105, 0x787697aa, -0xcba5543d, 0xdf7e1e2d, 0x6998a8af, 0x98ce6c08, -0x89de731a, 0x943a3510, 0xb36ead85, 0xd5258d4b, -0x1cd6df61, 0x82a5c59d, 0xd078e7a4, 0xa33d4317, -0x24dc45f8, 0x3f3daf27, 0x0478bc6f, 0x92dfa16c, -0x952a872e, 0x7a34e03f, 0x0f088084, 0xa40937fe, -0x38fc7749, 0xa157e8a4, 0xbce94344, 0x7045ff7b, -0xf3e1ab66, 0xe62a6058, 0x5564ff10, 0x38198f1e, -0xf326f0f1, 0xe262bc0c, 0x2f0b851a, 0xc7bcbe11, -0xe79f1d1a, 0xc2f93c29, 0x54f3ea9f, 0x8f8f9141, -0x9f45e13c, 0x7a5b86bd, 0xa764efd8, 0x35f04729, -0xdd8c4b54, 0x5fa12e51, 0xa5824af9, 0xad328f71, -0x0f11fbb9, 0x9048e950, 0x04d7a900, 0x02538d1f, -0x99f745b7, 0xe31f63bb, 0x2c4e3d78, 0x7cdb9245, -0xa3966ee7, 0x27c4433a, 0xe1d79f3e, 0xe640fa06, -0x79ce31eb, 0xf25634fa, 0xdd9ce5cb, 0xb7fab8d2, -0x2f1f0ff2, 0x2acb625c, 0xa0494989, 0x206d7f11, -0xf268b8ca, 0x292bbf9f, 0x763bd7d0, 0xea4b14fc, -0x9d3d6aeb, 0x64cca57e, 0x6fc3e29e, 0x3e7bf4bf, -0x90efc7e3, 0x08e39173, 0xd05bee2c, 0x5b3c8f37, -0x0921ec6f, 0x3371b715, 0xb324e114, 0xe3abc53f, -0x576b18f8, 0xc4469024, 0xb2ded6c6, 0xe7783782, -0xc0a1fd5d, 0xcf324bde, 0x97527c8e, 0x19f8f48c, -0x3e806a5d, 0x96cff225, 0xe3b9d04a, 0x0e5856ae, -0x781372f6, 0x9645f2b7, 0x95a743ed, 0xd0c7eded, -0x86ca3cd9, 0xbab94db0, 0x43a1233a, 0x89c55554, -0xee776239, 0x34aa0098, 0x66a6e1d4, 0xae0e233e, -0x717e7b29, 0xb403a4c1, 0x36eb96c5, 0x42140832, -0x04250936, 0xda375dca, 0x524cb2e6, 0x86deaa0c, -0x400dc9d1, 0x12c00364, 0xe3ca7cf5, 0x87f20da7, -0xf57df9ef, 0x580dbdfc, 0x0b3e0369, 0x014d27fd, -0x4afaf6a1, 0xd1f4ca09, 0x77abc831, 0x30e49729, -0xec61cd2c, 0x159c1e92, 0xb61b40b1, 0x17c66fd6, -0xde11c061, 0x79d7f792, 0xc709cbfa, 0x94201c89, -0xbe65137d, 0x18aea1b4, 0xf248bbc3, 0x465f957d, -0xcf4a9672, 0xbf293fd2, 0x2c5e31c9, 0xc2c73011, -0xfb29cbf2, 0x576f7f0b, 0x74de1745, 0xa76e172b, -0x99b96223, 0x14ce1502, 0x231013fb, 0x1d4df40a, -0x951b0c16, 0xab173e66, 0x4ff65f74, 0xc4a87a47, -0x09cc3370, 0x66385490, 0x73e09118, 0x4ee96432, -0x0164d347, 0x205069b5, 0x158dd226, 0xc932c238, -0xe9048fa2, 0x100b626a, 0x86ee08cd, 0xed87cb1c, -0x6353ec37, 0xa36edcc3, 0x8a16dd6b, 0xd28a4198, -0xebea1127, 0xca0b761a, 0x61c31acf, 0xced5ff4f, -0xbf4dbd8f, 0xd969d8a7, 0xb6e4e9e8, 0x8421c402, -0x809d7222, 0xabfd1d2f, 0xc1857ce5, 0x23958fd7, -0x3226f1d3, 0xd822b4cc, 0x2f1cc3aa, 0x501fe01e, -0xe36f8c94, 0x7ad27716, 0x3321308b, 0xa85b957b, -0x38cfdf6e, 0xc7497dd5, 0x2462090c, 0x8f9e42e7, -0xdf97684a, 0xac8af621, 0xd5224866, 0xc5f64e50, -0x9724f297, 0xc386097b, 0x48c6f98a, 0xe1478b1a, -0x2dd23fd8, 0x716b2d85, 0xa5c3789b, 0x53625e80, -0x9b8b312c, 0xce482165, 0x66161e35, 0x64ecb56a, -0x9981c46a, 0xe6cb6bb3, 0xe1983186, 0x75ed470f, -0x4adcbd27, 0x3efeda68, 0x4d193a2a, 0xbfdb3cd4, -0x7c6167b6, 0xdbddea68, 0x4b0d2d62, 0x00ba3860, -0x49ec2544, 0xa68698c9, 0x2ce7be1b, 0xf5afc9fc, -0x1cebf9c3, 0x350f8f5b, 0x893eefb8, 0x77414f6f, -0xe46f26fa, 0x67bf6398, 0xd6858f5d, 0xac73db2a, -0x58e20acc, 0x750dd76a, 0xb7930e80, 0x8a8796c0, -0x44c86997, 0xb1807742, 0x3c827dc1, 0x381aaa3c, -0x83ac76f3, 0x57f0a2d6, 0x18261009, 0xe107138f, -0x85711c22, 0x2e1d982f, 0x7062179a, 0xaedfa298, -0x62e438f2, 0x6d325a9a, 0x99b489d3, 0x1bf77b3a, -0x28ca20e8, 0x502d1b21, 0x74a833c0, 0xbeb91634, -0xf56ffef9, 0x05401164, 0xe5dbab51, 0x0a2b460d, -0x2f0d9c22, 0xc74472f9, 0x12da5199, 0x68b2d628, -0x9a118f9a, 0x9035d200, 0xcda0221f, 0x12430cde, -0x79a43fbb, 0x5bb5e1b7, 0xeab5ed62, 0xe6a11e32, -0x3118b0fa, 0xedbcfb64, 0xd2285490, 0x824023c6, -0x30311fb1, 0xa0a4a475, 0xbfa8ac55, 0xb8c8fbda, -0xdf3cab63, 0x8d805566, 0xf52c1b1a, 0xa3471090, -0x02328a4a, 0x5d1dce57, 0x196aea39, 0xcd0f640b, -0x2fa01c27, 0x6175f783, 0xb2b6a0e4, 0x02fe6171, -0x2d3cb20b, 0x25f331e6, 0xacfa8085, 0x46a09a58, -0x27bbfb9e, 0x3914f970, 0x73e35206, 0x8bb87194, -0xdb58fc4b, 0x62fd53ff, 0x2c942c7c, 0x3f4681ba, -0xeada1780, 0x5dfbb960, 0x8473948a, 0x80787902, -0x049c20ba, 0x9e95a4fc, 0x8526d8ac, 0x3dcdcd2d, -0xb9562f16, 0xc9c8eb08, 0x533ed0a2, 0xa34d5d73, -0x3e579c8e, 0x235bb378, 0x36576983, 0xc71f11b2, -0x035eae76, 0xbec23972, 0x8613e5e9, 0x3982899a, -0xe5a55d62, 0x3c45a7e9, 0xbd4d6def, 0x17ae0a5f, -0xf0f53bb8, 0xa3dd1e29, 0x36f9520b, 0x72cbd950, -0x4d762d12, 0xe03cb7a8, 0xf8c8c1fe, 0xa4ff17a1, -0xcc779472, 0x83f9b379, 0xa2fc038c, 0xdd3b8104, -0x95936bb0, 0xf36c9705, 0x93939e08, 0xc98576ac, -0xec9196d1, 0xc8bce622, 0xb48e1075, 0x98dbd77d, -0xd1b04c3d, 0x85d1d422, 0x20765885, 0xc6a17eb5, -0x8e913cdc, 0x3f7a6758, 0x08176f48, 0xba2ea15f, -0x3638114d, 0xf08cb49b, 0xb8b6d9ce, 0x4e55891a, -0x2775c022, 0xc8d45982, 0x529c2eb3, 0xde080e24, -0xdac9c028, 0xeec68934, 0x8eaace11, 0xe82e05aa, -0x00033a20, 0x4ec94b5e, 0x445f5562, 0xa5c58462, -0xb6942526, 0x44631607, 0x5065644c, 0x14946f9c, -0xa9cb0e63, 0x53dff50a, 0x3f18fa24, 0x20b3b811, -0x95c1e57b, 0x1523d301, 0xc4e24932, 0x41a9be80, -0x24fc45b0, 0xccff2cbc, 0x996af6a1, 0xe3f201c3, -0x0917ea23, 0xbf4a1ac3, 0xbb0db6f1, 0xd15772df, -0xb1465383, 0x61400275, 0x571f6b1d, 0x0a4407f7, -0x916cfbce, 0x114f042a, 0x1cb9b3a6, 0x1b34c85a, -0xe36acc8d, 0xab109469, 0x5af9a63a, 0xccd4defc, -0xb758adfd, 0xbd8ddecf, 0x5ffe8424, 0xd73e2a4b, -0xb41cb99e, 0x01a52553, 0xba70e749, 0xf81d7557, -0x2b4f0847, 0xa22e281f, 0x5c653c31, 0x89bdb546, -0xa596e592, 0xbca4cbf4, 0xc3d1dfe3, 0x64a21c2e, -0x159aa4b7, 0xed90f2d6, 0xb1164cb0, 0x86de0088, -0xfd4e49e6, 0x70702b0d, 0x946b532b, 0x03a0144e, -0x71fb19ed, 0x07c41763, 0x63312ce9, 0x0e2f5ee4, -0xc6501661, 0x09599e4e, 0x544fd5cc, 0x054d842c, -0x902bb57d, 0xdf82a365, 0xb7ae9427, 0xa6750881, -0xeee3c9cd, 0x6cbe0f45, 0x7f72d3f9, 0x430b786f, -0x162b6004, 0xbfcd440b, 0xdc4f5c81, 0x82249f6b, -0x98d1cdca, 0x2cc2692e, 0xf977f83a, 0x570c1e1f, -0x24ed6461, 0xcae5afea, 0x9cf06576, 0x9199d69c, -0x883febfe, 0x0f254c42, 0x6eb50978, 0xf91fade4, -0x9cfe5488, 0xfe3bf66b, 0x86ea94e3, 0x1bed23f5, -0x0bded397, 0x0cde064b, 0x7abd7a81, 0x8efb798e, -0x9a78e5f2, 0x7c46d76f, 0xcb3ae1ea, 0xc33e7ab1, -0x0c3993f0, 0x5b2d8de7, 0x24948ba8, 0xffce06e6, -0x0d3c2dc2, 0x3ae09142, 0x7e6b932e, 0xb3e22558, -0x9f7c425e, 0x8fa1329b, 0x24aa5012, 0xb9e49bc7, -0x787dd5a6, 0xf68c8171, 0x440d2146, 0x9734857f, -0x8c30c31a, 0xcb3352a1, 0x46b04f38, 0x72572ef8, -0xc90c56df, 0xe8103fa8, 0x04057577, 0xd1c250d9, -0x5cb390a9, 0xbdba74b9, 0x80012fa3, 0x408216c2, -0xadca83bc, 0x3c39bcdf, 0xf0da9459, 0x421d5a3d, -0xc5cf55c9, 0x2dcfa63d, 0xd852066b, 0x606b2204, -0x4d5e9576, 0xe8d6475f, 0xe46ec6b0, 0xf4e3c2c6, -0x1bfe1bb0, 0xc2803818, 0x2a3e4809, 0x947e50a1, -0x3a10e713, 0xc9e070cc, 0xa4244fe4, 0xa7f5d2e7, -0x194f77ee, 0x76754ab4, 0x75ed4e5f, 0x92ffdbaa, -0x1f5bce6a, 0x14aeeec7, 0x366fbb47, 0x44ecec7b, -0xbc31e911, 0xee6c224f, 0x0a6f7376, 0xbe79fce3, -0x53a18077, 0x6f6ad5fe, 0x945938bd, 0x61bb760c, -0xed26220f, 0x9f492f0a, 0xaf0f2d80, 0x265f5449, -0xae1f2dc3, 0xd235910c, 0x44a0f4a0, 0x36fcc004, -0x1e8fa223, 0xe7440ed0, 0xa8535548, 0x6d7e7029, -0x2e1b7968, 0xf3baa61d, 0xf447ef12, 0x701d62d6, -0x2da5dcf4, 0x44828196, 0x41af9c9a, 0xab210662, -0xa5ee18f2, 0xd45eb369, 0x947814fe, 0xeb62eb49, -0x30c555c6, 0xdc06ccbd, 0x786705d2, 0xd50c80d3, -0x266d8313, 0x68f63164, 0x1e3e4322, 0xfc23834e, -0xe879261f, 0x28992a8f, 0xab86dac9, 0x19f88d1a, -0x5110c867, 0x3c050155, 0xf9b1b3f5, 0x98909489, -0xfa0ee6bc, 0x038fb4ce, 0xbe1c9e33, 0x18f96bcd, -0xa1635c9a, 0xff3e9374, 0x5b033171, 0x0b84bfd9, -0x3c091bae, 0x6da61a4e, 0x07d81b5d, 0x3904ea3c, -0x75f4e7f1, 0x3e70c12e, 0x9c70d835, 0x9a1ea5a6, -0x4b99b705, 0x08f6ab89, 0x7649901c, 0xee3e7687, -0xa3deb48c, 0xd74e8c78, 0xe8e120c3, 0x425d3d96, -0x16f136bd, 0x0c7a32ef, 0x37a0ff53, 0x77b035e4, -0xba8808c1, 0x1d3d8330, 0x8d224cce, 0xed789fed, -0x550a8352, 0xe2715912, 0x185f62d1, 0xe301002a, -0xbe2ed99b, 0xbb1dfd60, 0x9d22d8f9, 0xcbfa36d5, -0xad7e92e0, 0xd2db61d4, 0x1df386f5, 0x92b5797c, -0x00ac8ed1, 0x2f7470b1, 0x674e258b, 0x6689df79, -0x135c5c1a, 0x87abbc50, 0x19ac082b, 0xe7f7d64c, -0x24fd4922, 0x7eeadc29, 0xa0910eaa, 0x763231d6, -0x23597ccb, 0x332f33c3, 0x93992b6a, 0x19c8937c, -0x75d6a9f4, 0x221395e1, 0x662914d0, 0x997d7860, -0xd196adeb, 0xa5402fd9, 0x8bd6f12f, 0xc31d97e0, -0x304dd9dc, 0x72f35c72, 0x8ced870e, 0x1eef8a14, -0x323321fa, 0xf193079f, 0x18026b1c, 0x5a1107a5, -0x54979f4b, 0x6afee492, 0x04c012e6, 0x3446250c, -0x25a691a8, 0xc19a76ea, 0x66bd5b14, 0x6250bd2d, -0xc6c082d9, 0x67ea1d78, 0xbe68a7ef, 0x03f50dc8, -0xd8f76566, 0xb6681752, 0x00e2b087, 0x7ed2e598, -0x8c9cbc83, 0x103b03f5, 0xee4d2723, 0x67b3903f, -0x1e057dec, 0xc5703ba6, 0xae0615f9, 0x1bce0df2, -0xfd041279, 0xc874a2c3, 0x0a91d2fa, 0xac098457, -0xc1efc5f9, 0xd48208eb, 0x72e9baa8, 0x184dc658, -0x3d26b8b4, 0x90e2469d, 0x6d07f351, 0x3f6898a7, -0x21e4de0b, 0x0fd04a43, 0x2c99cd2b, 0x44b28cdd, -0xaf5483a5, 0xe50b9a12, 0xd98fe031, 0x9d6e8f08, -0xf385ba19, 0x5e531cb0, 0xc545867a, 0x65f5ebf5, -0x9f27ad5a, 0x2de11f0d, 0xef6f0970, 0x973b11f2, -0x72228c07, 0xe13fdb84, 0xd2a7b46f, 0xc85a38db, -0x331a9807, 0x3be38ebc, 0x3e7bf15d, 0xa82a1e68, -0x4b42b5bc, 0x9871203e, 0x7d1e1e24, 0x12f57b6b, -0xf5403ec8, 0x28746c33, 0xae20522f, 0xf6042fba, -0x66bada5d, 0xbefe376f, 0xfd3773a5, 0xbb5fc6e8, -0x34c0433d, 0x3cfc83e9, 0xd096736a, 0xa53be016, -0xeba3dd6c, 0x2c626561, 0x3c160c8d, 0x8506c719, -0x802e7b47, 0x16079396, 0x6d29b175, 0x4e91abb4, -0xe350ce95, 0x0d481aa5, 0x94e95371, 0x10dc4dec, -0xbfeb3735, 0x3ce3cb4d, 0x32ff742a, 0xac5ad3cb, -/* 3014-m13106e5_00000003.inc */ -0x00000001, 0x00000003, 0x05292009, 0x000106e5, -0x65b9a532, 0x00000001, 0x00000013, 0x000017d0, -0x00001800, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000003, -0x00000000, 0x00000000, 0x20090528, 0x00000581, -0x00000001, 0x000106e5, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x802733c7, 0xe44c25e6, 0x5ce4df72, 0x63d3c85d, -0xd280241a, 0xc0965849, 0x78d40625, 0xd62849fe, -0xbab165d1, 0xfeb576d4, 0xc1edb5b2, 0xa44174b8, -0x0d1ad45a, 0x4fe5fe0f, 0x62feaf24, 0xafe7de28, -0x8b076222, 0x881b4891, 0x8daf9241, 0x98e8cf9e, -0x417b7869, 0xd7e266b6, 0xf07fa211, 0xd01aa170, -0xbd0ff37d, 0x883aefa5, 0x4313c7ef, 0x97e92355, -0x84df4fa1, 0x251a1422, 0xbffca04b, 0x80d1e0a9, -0x2de71585, 0x74f3cc3a, 0x06355b58, 0x404b01a9, -0x76867925, 0xd35afcf0, 0x2e220cdb, 0xb0c03e11, -0xff163ac7, 0x796b6c3b, 0x413f51d1, 0xfb5f33e6, -0x0d3408e5, 0x29f2fd21, 0xe5937245, 0x43a62312, -0x22bb80da, 0x517fd4cc, 0xd3b29526, 0xace3ace8, -0x22e26346, 0xf6fa7e9a, 0xe956d161, 0x72d9e32e, -0x87d1c6a2, 0xe2b89eff, 0xc94b7fba, 0xe61e89b4, -0xf2a0adaa, 0xac5edf25, 0xef730b2f, 0x64519e05, -0x59824baa, 0xeb00b868, 0xbf1e0a65, 0x95cebd35, -0x144fca7c, 0x6ac6e730, 0x1d86878e, 0x955b87bd, -0x00000011, 0x8a5d7279, 0x9c746993, 0x65f4696f, -0x1fd6fbfd, 0x0619db81, 0x7b4f59f0, 0xf724e268, -0x921f6df0, 0x67ea325e, 0xa916f5e6, 0x4f9bb015, -0x53bd3a15, 0xdc37230d, 0x201b4191, 0x57683cd0, -0x7131e23f, 0x0abbcc11, 0x6108a870, 0x11cf4c27, -0x4ee54cb5, 0xf7aab170, 0xb11529cb, 0xced1bfd2, -0x253eb69d, 0x29d9d2d4, 0x9ae0f219, 0x39707861, -0x5bc96dde, 0x9ced1328, 0xf8767084, 0xfab69d32, -0xf29a942f, 0x1bf0e5ea, 0x46be0754, 0xbdf61298, -0x34098811, 0x99e93e06, 0xdefbecd7, 0x4d9fd90a, -0x155485ef, 0x72bed1ed, 0xc46720a5, 0x7b4b2110, -0x73131296, 0x1318681a, 0xcd63a97c, 0xfdce4e46, -0x8210aafc, 0x943d8ba4, 0x286dc6e2, 0x5666bdbf, -0x9ae5b64c, 0xbeee7ad6, 0xa9a65347, 0xe10e2a82, -0x6d6545d3, 0x1b97c56b, 0x656a03f2, 0xe7dfdb99, -0x0e1b1789, 0xd01eb119, 0x8aee76c4, 0xac391b9c, -0x294621bd, 0x8394638a, 0xc08a9c08, 0xc99a7a57, -0xbb436796, 0x03760dd1, 0xd0544a8a, 0xa396a3c1, -0x760fed3e, 0x725e78f7, 0xed5c8256, 0xbaf43d31, -0x808978c9, 0x397960a3, 0x16e4eec8, 0x66bd9268, -0x2036afdd, 0xe3367296, 0x6e3f168a, 0x5070f01a, -0xd2f9b589, 0x80af1175, 0xecae4347, 0x4225d4fd, -0xcd104130, 0xcd45153c, 0xe97dc329, 0x1e52907f, -0x32aeb7fe, 0xf2a8a2de, 0x852e92d2, 0x3f4cb6aa, -0x6d077bee, 0x06ea83fb, 0x3baba8d0, 0x22576cf9, -0x452f650e, 0x236b3c00, 0xc7a52b4d, 0xbabb66ac, -0x4976bbc8, 0x34a142ea, 0x6149273f, 0x02c906d8, -0x6499ec30, 0x894b05f5, 0x62ee4b82, 0x1f991da5, -0xec219385, 0x590798f2, 0x430ceba7, 0x6af36c95, -0x06014c6e, 0x5d9b6835, 0x04814759, 0x8e3595e4, -0xcf7157e0, 0x9c430b29, 0xb0713963, 0x44be2501, -0x31360c1f, 0x6ea62dbb, 0x440ce093, 0x6a9d1ae8, -0x1427f921, 0xd6f30ff9, 0x3b9a5548, 0xba74665b, -0x7504a05f, 0x8a846257, 0x57075ad7, 0x0792056c, -0x1b972be1, 0x7420c1e9, 0x34c14b21, 0xd9ca92a6, -0x74086da2, 0x5bb8b64c, 0x879132d9, 0x4664bf87, -0x34c8cf8f, 0x8053580c, 0x4cdf0195, 0xce67526b, -0x3785a4fd, 0x1783d9a3, 0x13057cb3, 0xfddada8b, -0xa62b7622, 0xe4e983cd, 0x19fc1b13, 0x4670b4f5, -0x88d9fde2, 0xe4d47232, 0x428282e1, 0x3b1eba3a, -0x0dda9ac3, 0x976935e9, 0x17e6f394, 0x75d1e6c6, -0x52e7ba8d, 0x6d17dc05, 0xdcf08d2e, 0xbfdd8aab, -0x682724e5, 0xa40adacb, 0xc2250bde, 0xdf86c17f, -0xec3f3b6c, 0x50b17482, 0x7e05a0bf, 0x113727c8, -0xdb87ed9b, 0xe8b758bb, 0xe5a2129f, 0xec0b1711, -0x134538ac, 0x52f40b43, 0x35fee2ed, 0x03cfac0f, -0x74241fd6, 0x4b51a1e2, 0x31174d18, 0x35419363, -0xe0f97a27, 0xab90db73, 0x115fafc8, 0x609e07a0, -0xe261e748, 0xabd7c91e, 0x738e7142, 0x8518ad47, -0x00b9b691, 0x1076eb06, 0x738cb977, 0x4fccb90b, -0x7c2aa1b1, 0x3970280d, 0x142f7d0e, 0xf3e38308, -0x0bbd9cf8, 0x5aefa105, 0xc2921c37, 0x631affa2, -0xc20931d8, 0x19f17804, 0xb7e67dbc, 0x9027e886, -0x3f2948ce, 0xc5702b47, 0xe376984b, 0x6e63130b, -0x8a6f5871, 0x6ca5e5ab, 0x6d8ebe20, 0x060b445d, -0x54236d34, 0x4c142f6b, 0x0cf5eb25, 0x5eda0772, -0x67d245be, 0x5e8737f8, 0xffc42eb6, 0xd7bbfdde, -0x48e5bac9, 0x6711bd95, 0xe128c9eb, 0xe7815f6a, -0xf88674b6, 0x2761ed9c, 0x02c42951, 0xbb83c0e5, -0x8e0fabc9, 0x77e53f25, 0x52cebe8b, 0x39cfb402, -0x08482f83, 0x17d91e60, 0x9a824632, 0x0ec0afe6, -0xea7463d3, 0x4c346028, 0xa79561c1, 0xe69d90dd, -0x6bee4ba8, 0x2d6b4e9c, 0xa4a72d31, 0xdbf037fd, -0xe23e2140, 0x4bf6650a, 0x1d197b40, 0xe16bbc9d, -0x95489286, 0x5ccfec21, 0xbcd6ed2a, 0x8b51751b, -0x99a34459, 0xc1ba3625, 0x5c6a434b, 0x9d3bdc7d, -0xc0eb1470, 0x2cfa5d3d, 0x7a64b7e7, 0x679d7876, -0x04cfbdad, 0xa5a7dee0, 0x9aef436e, 0xc7f35e2b, -0xfa2a022a, 0xdacfd63c, 0x17c6eee9, 0xde2b8669, -0x7e3172f8, 0x029b3981, 0xcfe3ff3b, 0x74221b32, -0xae9928f2, 0xfc99f0da, 0x4b112ec3, 0x21f38a76, -0x8731e59f, 0xa8eca24c, 0xaba78f87, 0x74d2dc54, -0xa0e630d8, 0x73f47462, 0x6e7cb59b, 0x125e9a64, -0x4d2a40fd, 0x3c2875ce, 0x8f1b7f6b, 0x014ab0b4, -0xe50f73f7, 0x2be41240, 0x06a9d2c0, 0x9f39cff1, -0x1a0d69d2, 0x4d0c5cc7, 0x69e9b767, 0x8a6b4e13, -0x72922286, 0x65e5884e, 0x8318861f, 0xe9307a16, -0x70fb8bd1, 0x0a645be4, 0x399806c2, 0xb413e41f, -0xa27d9640, 0x65c43792, 0x2007a334, 0x8f087dd8, -0x88ca6ebf, 0xf75aba41, 0xba68cfe8, 0x628d6353, -0x1d4f3bf8, 0x46a5ebf1, 0x4345fa25, 0x59a0bc69, -0xa2a19acf, 0x0e8d709f, 0x76298f1b, 0xee299f73, -0xf49bf3fc, 0xd51c6717, 0xcb3fdf2f, 0x5110cf90, -0x1a3202bc, 0x5f86ed89, 0xa6bf1bf8, 0x92eacfd5, -0x9f4b7524, 0xb1c273cd, 0x52234f50, 0x15aeea4f, -0xc3c17fd6, 0x321f62d1, 0xb953b64f, 0x9168aac4, -0xc73cc63b, 0xaf5d74bc, 0xa8a11fe6, 0xc3de7a37, -0x52b2a1bd, 0xef5e711a, 0xd093d7d5, 0x0a0866d2, -0x1fc1a218, 0x92eb9f67, 0x1c3190d1, 0x648b25fc, -0xe7ffa26a, 0x5678af8d, 0xba63def0, 0x6c8aea2c, -0x1e0860ef, 0x2d0cb10c, 0x5617d52a, 0x19536ae2, -0xa23efb12, 0x611eef26, 0x48a73e13, 0xe1ef7cd8, -0x0d6436b1, 0x25efe9a2, 0x595ecc0c, 0x0d07efc0, -0x414c9df3, 0x62fe0fa2, 0x1dafd029, 0x66cf2940, -0xe3975f19, 0xb2c62aaa, 0xb45db313, 0x23dc0a9b, -0x08edfabb, 0xcfbd6e5a, 0x68c9a9c2, 0x1eea36c6, -0x5761f066, 0xc6dd6e62, 0x98cb5b90, 0x5a41d283, -0xf510e920, 0x541a9ea3, 0x8fcac32b, 0xabd90d7b, -0x5481655e, 0xbd13133d, 0xfb4cc24c, 0xa0a99cc4, -0x04efbd1a, 0xaeb552ea, 0x75328c80, 0xdc081e71, -0xcfa214dc, 0xc0a238fd, 0x642640d9, 0x0f083250, -0xcbab6584, 0xde3a91e5, 0xfb879e07, 0xa00d52ee, -0x73c03e40, 0xbf93bf6d, 0x327ab31e, 0xfea1630d, -0x23e0f0c7, 0x94924b1c, 0xeecd2e08, 0x9dd16fbd, -0xdae1e521, 0x586043ac, 0xa01549e8, 0x9e122423, -0x47f3fd62, 0x71c97a95, 0xe43e4a17, 0xa43ac11a, -0xd4d9f454, 0xa820388e, 0x2b16b6da, 0x709ac630, -0xf70ea530, 0x48d466aa, 0x39bb38ee, 0x31cda5ba, -0x8342db6e, 0x40740780, 0xb2e17c11, 0x132d1a01, -0x97901286, 0x3d43e1de, 0x04605139, 0xcc7b8731, -0x5ef56e11, 0xd34194a4, 0xaabb6829, 0x46977a26, -0x86d9748a, 0xfe6b4014, 0xefca5796, 0x954a2586, -0xe0f317c2, 0x18c3a130, 0x89bcfacb, 0x77fb4dcb, -0xd6372f7e, 0x0ecde9b3, 0xea47d59b, 0x4759c2f1, -0x30929b1c, 0x5dc4319e, 0x637a2206, 0x25a1f1b7, -0x26b95f8a, 0x2692e94d, 0xb54dd7b8, 0x5e9ec946, -0xd8ed8dc2, 0x5d8b52fa, 0x320ee3f0, 0x09deb80d, -0x1fe2e77d, 0x4d93f4dd, 0x2265c462, 0x8cdbe3c9, -0x4b1c41c6, 0xfeebbe24, 0xd9acb970, 0x4e14e1c4, -0xeb0da317, 0x789f0ba7, 0x86a154ca, 0x862151af, -0xe508512f, 0x5196ce0d, 0xad959006, 0x29f97fb9, -0x2a39f335, 0x06fc939f, 0x05fd2755, 0x500f3748, -0xcf1fc25e, 0x7abcbd2a, 0xc42181f4, 0xb4779d5e, -0x995b0ba4, 0x7579792b, 0x13d4a1ad, 0xf8ff2015, -0x0a2bdbac, 0x934b340e, 0x03e02ef1, 0x19290229, -0x47fab766, 0xaa7257cd, 0xcc7063b0, 0xc11902c3, -0x201333bb, 0x573c2f93, 0x60c1c68b, 0x1ae38fc8, -0x585aeba3, 0x558d45c5, 0xde0c9d47, 0x7529b837, -0xafc0a08a, 0x8d01dbc8, 0x4bc297fd, 0xc41415e0, -0xd3047b5a, 0x8b1cf332, 0x51f3a3ce, 0x48cf1952, -0x00771b16, 0x8dd45645, 0xaab7c228, 0x5bd8048a, -0x9e2fa34b, 0xa36dacbe, 0xb7e33750, 0xd0a3ece9, -0xc635e2a7, 0xb9c5d9b3, 0xfaf4095c, 0x524f39e2, -0x0a617851, 0xaab1226c, 0x7ab1887b, 0x8dbedd52, -0xec941fc6, 0x35a9ecc9, 0x354c0f8e, 0x61630d83, -0x58da1b53, 0x3de4bc5f, 0x267eaba7, 0x3a009f25, -0xba75a77c, 0xdbe3c946, 0xb082bed8, 0xe6642afd, -0xf8085316, 0xf75a954d, 0xcc024795, 0xd83340f4, -0xdb2afc3f, 0x24d7e9b2, 0x3518c25f, 0x622fbe69, -0xa4db98d3, 0x1a1fae72, 0x4d6d22a1, 0x33dbe86f, -0xf989a2fd, 0xeeb5c906, 0x9477db3a, 0x6ecaee34, -0x053498bd, 0x73f14e38, 0xf76125ad, 0xb40de437, -0x6b1e1da1, 0x6c877763, 0xc0b081af, 0x51b21d7f, -0x3aa99b73, 0xdbf533d6, 0x8ae2f2dd, 0xbf83a341, -0x2252ec55, 0x385e0a83, 0x5673e233, 0x83ff4671, -0xe6347c52, 0x8b5494b0, 0x506bae4a, 0xdd5d1b54, -0xc7211bf3, 0xad4c375b, 0x09fc722e, 0x836a125d, -0xf1ce6cd1, 0x4e004732, 0x45f7e7e8, 0x189cc88e, -0x53f11de9, 0xb014ac8f, 0xf244c0da, 0xa9b4d92e, -0xcccbc4bb, 0x9ed8b7e2, 0xa58419a7, 0x8019e89f, -0xb7e4efca, 0x3e233701, 0xc2023412, 0xbda94692, -0x6f8c9da3, 0xdfb51303, 0x5586792d, 0xc19c58f6, -0x93b66c90, 0x79c5ccfe, 0x297cfa67, 0xa50f6b8c, -0x98a24f04, 0xdcfe16f9, 0x0e0042dc, 0x4174ac2b, -0x4df88e79, 0x1abd907a, 0xca211f21, 0x0e473dbc, -0x6e10908d, 0x36234bff, 0x95c845bc, 0xbafb34f9, -0x41d54e2f, 0x4a261f72, 0x09b6e48b, 0x8a499516, -0x1c6b6f2b, 0xddf7e08e, 0x920bedae, 0xdd7c0f33, -0x570bcfe2, 0x1dbed4d3, 0x3887d3e4, 0xd877f68f, -0xb5568e1f, 0xe4b01f29, 0x25539b7f, 0xf81cc5e3, -0x2f05ce77, 0x43699f38, 0x352c2a57, 0xe0278f93, -0x6140a9b9, 0xdda9d389, 0x91910552, 0x9b41909f, -0x32b40b7c, 0x22399fb4, 0xfcbb1abb, 0x625b0174, -0x30fb7fa7, 0x3389069e, 0x9a80e897, 0x3eb2c91c, -0xc6e43be6, 0xb128a976, 0xbb8eba63, 0x7ffd7409, -0x1d2124dd, 0x57ae9f67, 0x89091f51, 0xd8fc44b4, -0x0889725e, 0xcce3f234, 0xc14d2983, 0x2aa24003, -0x2a140a28, 0xca15e70c, 0x2bb1c504, 0x9011e8c8, -0x1e2982cc, 0x63c87acc, 0x07fda6a7, 0x9b2c5655, -0x90608d02, 0xa137f077, 0x73614efd, 0x5be6be23, -0x582c5f4b, 0x3cdc8fde, 0xac235e80, 0x6eb67f6a, -0x746baa4a, 0x7d318049, 0x918ae8b6, 0x9ea176eb, -0xac37f0a3, 0x7289996c, 0xb84c86ed, 0xa7b8b637, -0x08f9cb99, 0xa1cd352d, 0x8e196fdd, 0x52f8c399, -0xee5bd1ad, 0x98096e4c, 0xa4515066, 0x2ce6fa29, -0xb003db8f, 0xa2414cc6, 0x78343d47, 0xbb85d269, -0xf2c86218, 0x16e05eee, 0xc0e55954, 0xd76030c2, -0xddc72cb5, 0xbe700586, 0x2a4631c8, 0xc07ad787, -0x86f0aef7, 0xf93e185e, 0x88e016e0, 0x2ea4c7b2, -0x179e5569, 0xd47588cc, 0x5b0866e6, 0x6683d356, -0xa454cea9, 0xcc02e868, 0x37f2a467, 0x40fde385, -0x447e9902, 0x33bea872, 0xd70f95d0, 0x3972589f, -0x9213edc4, 0x82a76612, 0x19413c75, 0x68d4f11d, -0x05ff5eb2, 0xfbb940f8, 0x3a26d663, 0x5313ce18, -0x0cf98331, 0x3d0724aa, 0x85af2d4c, 0xb998374f, -0xb362a0da, 0x74d13212, 0x7e4d45c8, 0x7911a9ad, -0x3adf3a73, 0x84aca215, 0x6f2a24ab, 0x9708d602, -0x2186daee, 0x70c93f07, 0x0e74ba5a, 0x0f79ef3b, -0xc07392ef, 0x370ec49c, 0xd1c6da49, 0x8db82e27, -0x9ce7b81f, 0x93bd76d0, 0x3b3e72e5, 0x4edc654d, -0x1777418c, 0xc683c115, 0xd5d37eab, 0x1cd90d99, -0x8c57b41f, 0x5aab35f3, 0x6d545e65, 0xd4e185a6, -0xc38b76f3, 0x5362090e, 0xf345b910, 0xc4fa539a, -0xdf84f239, 0x81e6fef6, 0x01cbbb8b, 0x1f98ab87, -0x262a555c, 0x81350387, 0xc3ee3650, 0xfe5bf8e7, -0x5387759e, 0x8eef23f1, 0x14b93a7b, 0x77a39ea6, -0x577b0141, 0x8d1503ee, 0xd8233384, 0x04bcfca1, -0x73b4395c, 0x0d89975e, 0x346554db, 0xc05d1216, -0x0ce4ab8d, 0x02be6474, 0xc2a37fa7, 0xc432fa35, -0x80c4eea7, 0xa5de577d, 0x3aa62c31, 0x5c6af29c, -0xd1e4396c, 0xf05616e1, 0x61a5a835, 0x981a5670, -0x02cc70ec, 0x589a11bf, 0x2322abef, 0x6d4b3a28, -0x1235d2c1, 0x970ecba1, 0x2cf9a4f1, 0xe05e02d4, -0x6d73176a, 0x91f1b5c5, 0x530f2ea8, 0x7bc355c3, -0x4a32c97c, 0xd8a360a7, 0x0494f0a4, 0xb848e796, -0x7712a6f9, 0x975917cc, 0x2830f7b5, 0x6b7fcf55, -0x70cf032b, 0x54b697ca, 0x709aa0b1, 0x82bc0190, -0x221abed0, 0xc737b95f, 0x25f96bf0, 0x04e00c6e, -0x5fb3d0e6, 0xfc0032f3, 0x47a19113, 0xe4842062, -0xf8a72b5b, 0x7ce20960, 0x234005fe, 0xf284298b, -0x33e002fd, 0xd9c5b363, 0xa66fcf42, 0x65a37469, -0x09696c31, 0x18ddb8ec, 0x0f075890, 0x852772d9, -0xc1ea3d00, 0x407565ca, 0x996ae302, 0x9d213a3e, -0x15444477, 0xe40731ec, 0xa59d6d18, 0xa31bb351, -0x1ad6a1b8, 0x2004f299, 0x753742dd, 0x7372e33e, -0x6b294af0, 0x423534e8, 0x613c7af9, 0xd269ccf8, -0x7a0e77f8, 0x4a5eb9dd, 0x0fdfdf8d, 0x3ab0a078, -0x3aa3eae7, 0x4b757b52, 0x17556503, 0xbd955aad, -0x04e445b2, 0x0038b108, 0x6d838228, 0xcd1d17a9, -0x8d78679e, 0x0b09cb2a, 0xac4dd75b, 0xfeb39610, -0xc6e37be9, 0xf609647e, 0xfcd96878, 0x595ce2a3, -0x74672113, 0x5b322d40, 0xbe20b3f7, 0x4255e891, -0xe2a471b4, 0xddd07ef4, 0xdfad4fd5, 0xf3c0d6d6, -0x939ee2b7, 0xa74bc8a6, 0x237e40ec, 0x45e6429d, -0x397bc731, 0xd1f63359, 0x92c76b6c, 0x4f6112f0, -0xf2e3bfa9, 0xa449c13a, 0x1b7cf9f3, 0x30294cc5, -0x3af1840a, 0x436bcaa4, 0x817caf6c, 0x9e68df61, -0xadcf5eec, 0x3c63ebb8, 0x66f0cd34, 0x6e886e94, -0xbe5593c6, 0xf21f8cd0, 0x86e5e6cb, 0xa3417e69, -0x09179628, 0x3d476fe7, 0xe2ed9b67, 0x55218979, -0x68342ef2, 0x06e0ddab, 0x4d871654, 0x7c168efd, -0x80ccdd97, 0xe1739478, 0xb2c2dcb2, 0x9b974b23, -0x65b16064, 0x06fdbf82, 0xc0dc57ad, 0xe4291150, -0xe2f9b6b1, 0xe6ef2a27, 0x0affe770, 0x3cb97901, -0xd9de038f, 0x5773ee10, 0xc7933848, 0x95110990, -0xd276b467, 0x58ba3959, 0x3beb0190, 0xca1a8999, -0xfb2b7362, 0x2f9fb1c2, 0x5e64606d, 0xc90bfc22, -0x11bff3d5, 0x62ba296b, 0x18a85760, 0x9e91e187, -0xb08e8384, 0x84e05e6e, 0xbd7a053d, 0x03dcb1f5, -0xee3e835f, 0x08682331, 0x25713eba, 0x117598e0, -0x84017c6b, 0x2fceca7d, 0xdb4910db, 0x8c56f19c, -0x2eb47787, 0x2c272d3d, 0x1e22cfc4, 0xd8039ded, -0x6a716406, 0x1f2d2e58, 0x73e952a9, 0x9f143020, -0xfd5aa09c, 0xb847b863, 0x5c6a96ce, 0x74d2408a, -0xd1adcd3a, 0x04743f2b, 0x3338049d, 0x5dca4eb5, -0xb17c75c0, 0x04572f3d, 0x01092ab2, 0xf0e109a0, -0x9ec2ee0c, 0x87633773, 0x62b265e3, 0x3fecd536, -0xf8a1c1a5, 0x3a829ab4, 0x3f3b6e24, 0x10e012a5, -0xcaed2a6e, 0x0dd09f2c, 0x2fe46e0f, 0xf7aa1f52, -0x6b1fcb03, 0x194c5f41, 0x4f7af49b, 0x29fc1834, -0x5e9264b6, 0xc681dc8f, 0xc4eebc41, 0xbb7a8c59, -0x1a8e5663, 0x468eb0a1, 0xc2668a43, 0x70c727a8, -0x75d77c09, 0xad512995, 0x20c8389d, 0xe88c856d, -0x1854aee8, 0x19a322f0, 0x72c3e46f, 0xa4d3a350, -0x7e770143, 0x0a7b6b4d, 0x56da15c7, 0xe8a1b24b, -0x34ad72cb, 0xc714ba95, 0x7f26adbf, 0x2b816fa0, -0x4f44c3f6, 0x3c36f9b2, 0xe858ec74, 0x6211f907, -0x5ceb4ece, 0x91a09eee, 0x53614a7a, 0x19ab3615, -0x8511ae38, 0xeed314fb, 0xf618f4b4, 0x530d125d, -0x0e610ecd, 0x388e0b06, 0xef038ce6, 0xdf413d65, -0x2d1702fc, 0x472e173d, 0x9c4469aa, 0x49e9e3ed, -0x59039c67, 0x074b0e60, 0x93277121, 0x1fa8da95, -0xaed27f11, 0x34335728, 0xcb9ee889, 0x19c59763, -0x4e23eac8, 0xc2422812, 0x808dff75, 0x9afd8f19, -0xfc37ed83, 0x6283bf6e, 0x19c2ec7f, 0x1ca3a1b5, -0xfca6cd26, 0xcd1b3aef, 0x2421e54f, 0x66f6e7a7, -0xde65ac52, 0x36fed3e9, 0x11b4c62d, 0xd1f2df58, -0xea8c8ca1, 0xf30644d8, 0x5578cdc1, 0x0c7ff948, -0x3c13ce37, 0xaa67ecc9, 0x117d09d4, 0xbdec7fbd, -0x0ea632d8, 0xa47550d1, 0xe5864aaf, 0xca38606e, -0x214184d5, 0x4e3edc08, 0x7ba82d34, 0xa523b4d7, -0x4eeeedbf, 0x28f34f12, 0x1cb908aa, 0x8f4eb512, -0x64dbb127, 0x863f17fb, 0x77a498d4, 0x4939ed2a, -0xb670d49f, 0x162639e0, 0x5a6b3c5d, 0x6f9f3f05, -0xe34f170e, 0x3b99b90a, 0xfe921edd, 0x30c4f749, -0x26e5ef05, 0x759acaec, 0x1c854733, 0x14181551, -0xd34d2498, 0xbde9a644, 0xd0feaabd, 0x2962a027, -0x243a6bdc, 0xad16fef9, 0xd669e6b3, 0x8456fccc, -0xc7a2fd9a, 0x3338f5ea, 0x79a492b7, 0x42486d39, -0x9759f8de, 0x143915b9, 0x085b7978, 0x78b5633f, -0x629a4ae1, 0x3ca739a2, 0x19c716ee, 0xad821ccc, -0x36d70a54, 0x1bead519, 0x8cef2e80, 0xde9ae54f, -0x1bc68e6a, 0x80f842b3, 0xefa3e944, 0x4420c686, -0x6dfa3cb0, 0x613c63fe, 0x7c92e7c3, 0xecd3790b, -0x7e9fb016, 0xb730cd81, 0x5c182417, 0x4c281fb0, -0xf239bc43, 0x14c95eff, 0x182a357b, 0x2e16c61a, -0x34064f9b, 0x8adf21f4, 0x38cf7ebc, 0x2be77af4, -0x3838ceec, 0xef72fabc, 0x872acb4a, 0x355345fc, -0x6828f170, 0x030e5880, 0xd9ce9388, 0x7887b69d, -0x3570e157, 0x8c9d7610, 0x2b620707, 0x76893209, -0x8b5f31fc, 0xc416df56, 0xeaabdc42, 0xcef4d6aa, -0x5a24bbab, 0x70f89081, 0x89839cbb, 0x87d94a22, -0x01098b5c, 0x910955bf, 0xf75ed5f9, 0x5b384307, -0x486b50a4, 0xdc57b82b, 0xd97180b6, 0xd8302d17, -0xd09e9743, 0xce3fdb16, 0xa19a8cbc, 0xed5de4b1, -0x0bfb295a, 0xc1497632, 0x9b4e68ab, 0x17788368, -0x0932ed86, 0x1c4c9b98, 0x404d5718, 0xd30c5d91, -0xc29318d3, 0x01e38be1, 0x1e6c36f3, 0x972264ae, -0x3b6e6579, 0xab439cb3, 0x13fc7072, 0x0a6c6259, -0x290cd185, 0xb918c43b, 0xceddde1d, 0x8bb7f761, -0xbed75235, 0x3f65fadb, 0xb7a1664a, 0x45538b20, -0x5b42ea03, 0x24ed4153, 0xa9b53360, 0x5683f9d8, -0x50adb3f8, 0xcd968773, 0x685b1b76, 0x27fd37df, -0x6d1060cc, 0x957bbd76, 0xa56dca4d, 0x1d03ca44, -0x06f3f5ac, 0x29c86570, 0x45b97619, 0x76678831, -0xa7351089, 0xfd930b11, 0x178a7b5b, 0x5c020765, -0x7b08e49b, 0x8544314d, 0x6f3a876a, 0x95b8e384, -0x129a9694, 0x24528f7d, 0xf98f78dd, 0x35c22e3e, -0x19185e86, 0x644076eb, 0xb6ac0b60, 0x132eb040, -0xe616b6ab, 0x780bfb69, 0xf5b59888, 0xe3449f98, -0x44f7ea9c, 0xcb2b9646, 0xcb745c49, 0xb8a8f7a5, -0xc6933531, 0x15c25e1d, 0x6c156174, 0xffb7191e, -0xfb82bcad, 0xf12abf5b, 0xdb7fcff1, 0x89c1edd7, -0x7819218c, 0x321fa895, 0x50d6ab08, 0x07099a20, -0x8ef3c05a, 0xc0b37b12, 0xe4a7d71f, 0x0becdac6, -0x14f6856b, 0xca44a4f3, 0x03a4d53b, 0x28332123, -0xfe3d66d9, 0x0f2f325d, 0xf0352398, 0xece1acfb, -0xb2889ca2, 0xb6c9d0b2, 0xa25224cc, 0x13f71aad, -0xbb26b8dd, 0xab78f2fb, 0x5b406304, 0x8f8e0802, -0x4c70ac4c, 0xad684f75, 0x311758be, 0x6b010266, -0x89f6e69e, 0x10dd266d, 0x2b85bbd9, 0xdaf1e1e6, -0x087213b4, 0xc6da2394, 0xc35983d3, 0xf4a7a538, -0x7e88eed9, 0x88351509, 0x4a481807, 0xeecd5537, -0xd64435b8, 0xb4c42704, 0x3a4b8f2b, 0x8b784114, -0x65675942, 0xac785ca7, 0xb29ae86d, 0x31d6cf5b, -0x00c32bc2, 0xa3aaa694, 0x92cc776d, 0xabcce86b, -0xac09f48d, 0xfbe9f2e9, 0xbc5bd96f, 0xc1ff3a57, -0x08d37d5b, 0x3167058b, 0x60a00a2e, 0xb262305f, -0x7850494c, 0xa4fb3ecf, 0xdac39624, 0xeec5fa15, -0x103078e9, 0x2b0b5e48, 0xe7ac5af4, 0x409a9fc6, -0x860d00b6, 0x71977bed, 0xcbf5474e, 0x6e60281d, -0x9b688a52, 0x2e0ed739, 0x72413498, 0x8f4d0fd0, -0xd9a25c27, 0xe624d9f4, 0xacc190d7, 0xdf6c1355, -0x7da3b4bd, 0x15f59e44, 0xd40fab70, 0x795e4d9f, -0xcd946bb7, 0x30615009, 0xdbccecb8, 0xf92ce0d9, -0x4ba70e49, 0x8f9360fa, 0xa494ea1b, 0x43aee5ab, -0x3c3982f3, 0x70eb432b, 0xf9f8fed9, 0xc77c9de4, -0xd09a1aaa, 0x84cc61fc, 0xfaa94f98, 0x8d65ef96, -0x4b40d7dc, 0x6fff5d99, 0xa004e55a, 0x57e3fdfa, -0x9d369dde, 0xd9b7217e, 0xb995da81, 0xe20d4da2, -0x5002edb4, 0x46504aba, 0xf85c6b00, 0x07f441e0, -0x0a6ccf51, 0x0c6776d3, 0x94d916e4, 0x437ae95e, -0xa1be88ab, 0x26ee808d, 0xb225ecc2, 0x7203004c, -0x7483ce57, 0x843a63fd, 0xdfb47fca, 0x4891c6a5, -0xbed32b73, 0xb74a7f99, 0x02710380, 0x3535c967, -0xb3a97919, 0x9dc02c41, 0x7d56855d, 0xadd905d6, -0x69e85fb5, 0xa2423262, 0xa8b342da, 0x15d9de06, -0x16f106d6, 0xc03c76bc, 0x86c6a8ad, 0x74e42e59, -0xa4074a6e, 0x53495564, 0x2b5a9e2c, 0x332073ad, -0x66ce0694, 0x09ad8605, 0x7b815e25, 0xef8e5a5e, -0xa8b24d30, 0x06a3108f, 0xc1af44ad, 0x4f203e5a, -0xb3fda333, 0x5e78cdc3, 0x11c9a799, 0x540a1cec, -0x50e6b53f, 0x9bad2b4b, 0x9fdc05b7, 0x66313909, -0xf7e64ddd, 0xe99a6f59, 0xfbaa96fa, 0xb6cb3b29, -0x8215b9a0, 0xd64583fa, 0x9a298e28, 0x1299e60a, -0xcb6b2fe5, 0x5a79668a, 0x35b12ab7, 0x873a91ea, -0x8e1248fd, 0xfc3eb405, 0x54700ff7, 0x7993800b, -/* 2967-m03106a5_00000011.inc */ -0x00000001, 0x00000011, 0x04142009, 0x000106a5, -0xc2d891c3, 0x00000001, 0x00000003, 0x00001fd0, -0x00002000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000011, -0x00000000, 0x00000000, 0x20090414, 0x000007d1, -0x00000001, 0x000106a5, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x6bc10bea, 0x686acd6b, 0xc80c6d31, 0xcaf132a2, -0x25d69530, 0x7d6d7e4c, 0xf47a6ac2, 0x2a0af140, -0xbab165d1, 0xfeb576d4, 0xc1edb5b2, 0xa44174b8, -0x0d1ad45a, 0x4fe5fe0f, 0x62feaf24, 0xafe7de28, -0x8b076222, 0x881b4891, 0x8daf9241, 0x98e8cf9e, -0x417b7869, 0xd7e266b6, 0xf07fa211, 0xd01aa170, -0xbd0ff37d, 0x883aefa5, 0x4313c7ef, 0x97e92355, -0x84df4fa1, 0x251a1422, 0xbffca04b, 0x80d1e0a9, -0x2de71585, 0x74f3cc3a, 0x06355b58, 0x404b01a9, -0x76867925, 0xd35afcf0, 0x2e220cdb, 0xb0c03e11, -0xff163ac7, 0x796b6c3b, 0x413f51d1, 0xfb5f33e6, -0x0d3408e5, 0x29f2fd21, 0xe5937245, 0x43a62312, -0x22bb80da, 0x517fd4cc, 0xd3b29526, 0xace3ace8, -0x22e26346, 0xf6fa7e9a, 0xe956d161, 0x72d9e32e, -0x87d1c6a2, 0xe2b89eff, 0xc94b7fba, 0xe61e89b4, -0xf2a0adaa, 0xac5edf25, 0xef730b2f, 0x64519e05, -0x59824baa, 0xeb00b868, 0xbf1e0a65, 0x95cebd35, -0x144fca7c, 0x6ac6e730, 0x1d86878e, 0x955b87bd, -0x00000011, 0x8a8170de, 0xd10d06ce, 0xc8c5be0f, -0x90dd9f93, 0x33f21057, 0x49a2cb43, 0x38978e30, -0x3e44dc99, 0xee4c00cb, 0x9b43977a, 0x55ad844c, -0x2acb7c34, 0x4df289b5, 0xd1ee8b68, 0xad81a7cf, -0x68890206, 0x3c0b3589, 0x4323cd0f, 0x7955ed62, -0x8c00153b, 0x0cee1be6, 0x16c043a9, 0x6c246ddc, -0x9ef69c06, 0x5244967e, 0xbca580c0, 0x0a9e79a8, -0x0f45c155, 0xdbe8002d, 0x9ddc7a7f, 0xf9d7a300, -0x0f06272f, 0xeed04a38, 0xaa2d0fd7, 0x8c876464, -0xa4ff9f0a, 0x6076c9ea, 0x12ed412b, 0x13d4764c, -0x22c475c3, 0x94624946, 0xe89cb40f, 0x0675f8e8, -0x63925a71, 0x285f56f6, 0x0e0c866f, 0x10bb7c62, -0x75ce1168, 0x5ce8d5ab, 0xabaad871, 0x4bc0fa65, -0xadafd47b, 0x12443c0d, 0x30ee4e24, 0x2a6f37cb, -0x27a160ab, 0x314fef8f, 0x643d1d8e, 0x3d2cca91, -0x6f7665fd, 0xfe98926e, 0xbcb3320e, 0x69bfa9df, -0x1037ba06, 0xeaca3762, 0x2085669c, 0x6f42a9d3, -0x04485d9c, 0x01fd4918, 0x18a37b78, 0xeb6454df, -0x22311b8a, 0x397b6aa2, 0xbccd4e00, 0x12c303dd, -0x54a54c9e, 0x0e57721d, 0x799c4a7b, 0x21b9e5b7, -0xd807d3d0, 0x422f275c, 0x047434a2, 0xc1eafe8c, -0xf80462b7, 0xe6cc9a0e, 0x08d6022b, 0xd63cd746, -0xcf942daf, 0xa8007a0b, 0x570f86df, 0xcfab5360, -0x9ccd67d7, 0xc8e5e7f5, 0x05db1dd2, 0xb744c8cb, -0x75e47f9c, 0x7be9010d, 0xeeb042ca, 0xe78d3f6d, -0xbb80bd7a, 0xa104a2a6, 0xa0659f06, 0x33c10de0, -0xfacde597, 0x713e29af, 0x6a5da65c, 0x300223fc, -0x08377053, 0xf7850f61, 0x821c7b96, 0x497adc28, -0xb0fcb15d, 0x8f2a664b, 0xd9e02595, 0x07d72584, -0xf971dbb8, 0xe77a9b49, 0x12d39696, 0x7facbd65, -0x4c69e1c8, 0xe5a2e138, 0x3ee12b1c, 0x11faf846, -0xf047fdc6, 0x5174ec3b, 0x27539917, 0x75a18a77, -0xe373dd79, 0x4d027a22, 0x79cabc1e, 0x5da13b15, -0x733c1aea, 0xdc9339cf, 0x77954f6f, 0x317e0fdb, -0x3d487c05, 0x772d3072, 0x3c416d33, 0xffc83a26, -0xd21d625c, 0x35a341ad, 0xd545cf16, 0xc4933882, -0x2bbf013c, 0xe4a32d3c, 0x5ad6b995, 0x194d8145, -0xd80ac4a3, 0xccb99758, 0x3828ff1e, 0x5a613893, -0x997d0199, 0xfbef864b, 0x3cffeea5, 0x2d0fad2b, -0xbf95098c, 0xb638f1bf, 0x77301c26, 0x28a6829f, -0x93f225ae, 0xd1436889, 0xf643195a, 0x7a44c5cb, -0xc113bedb, 0x85b7b246, 0x2094bbea, 0xbb72cac7, -0x869b103f, 0x29a85e3f, 0x513b6d51, 0x8c4d5fc9, -0x6deeef8c, 0x3e8c9f71, 0xd455da6f, 0x73fb6783, -0x73dda9b0, 0x686b81af, 0x0ceb3bc1, 0xab0fc52c, -0x3d9cd3de, 0x38cd05c4, 0x257a9bbd, 0x8c682333, -0x30d4e4de, 0xe43bb560, 0xcbbc7d6c, 0x2da3ecbb, -0x6af5ae77, 0xd65e86fa, 0xf8cb6bf1, 0x46dbd901, -0x3e04eedd, 0x522eafa9, 0x005acb72, 0x75f7adfe, -0x18d73690, 0xd7a345de, 0x6d08c19e, 0x730043ad, -0x43c07c0c, 0x6a029de4, 0xc6014e7e, 0x8531206d, -0x9d4445e6, 0xf176523d, 0xacbef340, 0x1f7efeb2, -0x9c2586a0, 0x343f3655, 0x366fdf00, 0x965612d1, -0x12ac8030, 0xefa47a83, 0x8238463d, 0x75bce199, -0x7905a945, 0xff7db90d, 0xa6829c03, 0x787680bb, -0x5f7d48ac, 0x802a2e6d, 0x1fb3fa50, 0x8a32ced3, -0xaa9ba886, 0xe4944495, 0x362b82d8, 0xe1e24b85, -0x1e0ce3f1, 0x45a639af, 0x23b3b20b, 0xec6eb1d9, -0xbcdfa403, 0x404c7eb0, 0xd5db0e5e, 0x94982c87, -0xc7d46b91, 0x7d59f946, 0x475fa1f0, 0x61b33c3c, -0x1260c066, 0xbe0ff392, 0x62af5364, 0x9ec54670, -0x64301adf, 0x8f4e36e3, 0x6bde11cc, 0x24da8736, -0x456e7f69, 0xf12b7fd8, 0xf97bee3d, 0xeeceaaa5, -0x180e5386, 0x9bdd9bd3, 0x25d85bb3, 0x70c8fb56, -0xeb5edb54, 0xb665841f, 0x17b06b72, 0xc98c14ed, -0x691eeb46, 0xc8be93b2, 0xa7f78b00, 0xf35cfdaf, -0xe47ad2f5, 0x11a98085, 0x93366e6a, 0xfcf3f38f, -0x92dc5b21, 0x0ff0c5e8, 0x3031a65c, 0x1487430e, -0x21c87cad, 0x3f64162e, 0x3105e461, 0x39eda0a4, -0x8617ecb6, 0xe4c18423, 0x8a7c8202, 0xc7713cb6, -0x7b226148, 0xa5f40dd9, 0xdef14be6, 0x2054ad6e, -0x5d4e3573, 0x3051a2db, 0x8ea4b412, 0x13e5f361, -0x933bec35, 0x636b448f, 0x01913981, 0xa7fecad8, -0x99346761, 0x29ce840c, 0xf603fa48, 0x6e32edf7, -0x177ebef4, 0xacf914c9, 0xcce81e3f, 0x6dd19cfc, -0x4252ca88, 0xa6a9d279, 0x88bcb402, 0x0a2b47ea, -0x8fa3de99, 0x9d072c8c, 0x55040f1b, 0xe14d90fe, -0xd4b073ff, 0x6d57e946, 0x3acccdf5, 0xb43f7b8e, -0xe8c912a0, 0x86e80218, 0xe64859a7, 0x09e623ee, -0xa400e93a, 0xe56ae585, 0x7b6cc20e, 0x2ab7bae9, -0xf82dea7f, 0xc23825c4, 0xb3c2235c, 0xba0080e2, -0xa315a436, 0xd07c9b59, 0x7ef5df37, 0xbd603302, -0xfead0343, 0x019dc025, 0x31c0c859, 0xaf5b058b, -0x28ea5b26, 0x77ebd828, 0xf4fd39be, 0x9e1c5192, -0x3ae6ed41, 0xc27af351, 0x991d48c2, 0x1054edd9, -0xca18dc26, 0x065a7271, 0x74589868, 0x8f4ea5a2, -0xe074839a, 0x7aa8cfb6, 0x9be3bac5, 0x2b4b628a, -0xa795cbf7, 0xfa468b9e, 0x111b5661, 0x7a655b4f, -0x32310029, 0xffab4d35, 0x5656ab7f, 0x4a0ccde7, -0x1fd07f42, 0x4897649f, 0xa8d7be82, 0x2192ec28, -0xa803e289, 0x057806bd, 0xfadb5fd1, 0xbd6a8a21, -0x92e6bed6, 0xeb37ba97, 0xc10c144d, 0x4967241d, -0x59bd2f5c, 0x0cce80ac, 0xb0ee1579, 0xa8ec7ece, -0x2db4fd07, 0x8cde113e, 0xd51e1b01, 0x86ad5e6b, -0x95a5e1aa, 0xc6f63d38, 0xf6f03355, 0x05ebed9c, -0x4c04d76b, 0x55e25673, 0xd67ab038, 0xb0aa406c, -0x29a3bbfd, 0x1192103e, 0xe456e66d, 0x70707751, -0x2f55b620, 0xf5265133, 0x9055d2ff, 0x2449c073, -0x1142f28a, 0x821edb92, 0x8338c648, 0xd16869eb, -0xc4d1f3b2, 0xcf764c9b, 0x2e58865f, 0xfafb9de4, -0x275ea4de, 0xc8af0076, 0x0b0d620f, 0x9e0322be, -0x563fa45f, 0x9f6074d1, 0xa1514c3b, 0xb8cf3602, -0x593e3f0d, 0x21ef09a4, 0x514125db, 0xed77b906, -0x0832b9ce, 0xdb2c8a75, 0xe98fb2cb, 0x041bc898, -0xc69d0047, 0x1f6278af, 0x2d6d2293, 0xcc9c2265, -0x33f7ef50, 0xc01e571c, 0x83f40f55, 0x1ec7192d, -0xf9dbc386, 0x55182c05, 0x21bedd94, 0x414fb160, -0x84b5d9be, 0x7d2a8175, 0xf700c11e, 0x3f0d128f, -0xcf584f4c, 0x6a068ae3, 0xc1b0fd6b, 0x34b702b2, -0x62b02091, 0xf1bc4380, 0x63dc3414, 0x441394db, -0x9c0da5aa, 0xa35952bb, 0x45bef333, 0xf2691e88, -0x5bb426c6, 0x9b22dcf6, 0x504b9451, 0x3f796def, -0xaa07c979, 0x7a5fb961, 0x545d6f2f, 0x49856407, -0x2cf2f265, 0x6fadb95a, 0x4a783c0a, 0x483cf776, -0xf9e18dfd, 0xf3c529c8, 0xd6688fb5, 0x022ad1fe, -0x4da7ca78, 0x9f8f7dd9, 0x47544935, 0x112be48b, -0x7d954dab, 0xc76f2f89, 0x78e42199, 0x5f687270, -0x29f36506, 0x9592fdaa, 0xa4dc5495, 0x4c7a0062, -0x93a5e085, 0xfec0243a, 0x77eee838, 0xcd9c5653, -0x97de8020, 0x5758abf8, 0xa316c9a8, 0x4bad66e5, -0xdab802ad, 0xe97b432a, 0xff3d3782, 0xd2c100d8, -0x2ed0371b, 0x559b6e06, 0xeac577f6, 0xce55e17a, -0x4b62041c, 0x161f5f9f, 0xa133a36e, 0xc4009e6c, -0x8079afd1, 0xb3b75a67, 0x9e3d88b4, 0x8e0410b8, -0x7b1d6232, 0xb789dfd2, 0x7d76b850, 0x27920218, -0x14aa4a75, 0xac239649, 0x8f014e4e, 0x5925bcb4, -0x785d1a7c, 0xd83798d8, 0x5126d93f, 0x1e5cf0df, -0x328d6fb4, 0x08d47bff, 0xb210e6e3, 0xc3ae7b72, -0xd5b648d6, 0x96fccd4e, 0xff5a8510, 0x99e7c00c, -0x34009d9e, 0xc0fe39a0, 0x04df8b67, 0x6d3f0f19, -0x9e0087c6, 0x7a6cc6ad, 0x5595d794, 0x1831441a, -0xd15b1a5a, 0x6a0f2e46, 0x5b4fc836, 0xbbd04d60, -0x26e9c7e3, 0x2b23dba3, 0xc7bdcc5d, 0xf010825f, -0x6b87160c, 0x3b9f39f1, 0x5a7cb594, 0x5cfa9deb, -0x0230925d, 0x66b2fe9e, 0x5a3f705d, 0x6b644dd0, -0x92e24c5a, 0x3296477f, 0xd7e529fd, 0xc8bd6fb6, -0x52d623b0, 0x1e2dbd10, 0x50b11ab9, 0x61630977, -0xab39cfef, 0xf590f660, 0x195eca7a, 0xa4719978, -0x852c409a, 0x9a893622, 0xcbe1eef7, 0x830d0835, -0xdd64ccc1, 0xc57b9adc, 0xe4ea99ff, 0xf59dbf3c, -0xd2ad8664, 0x9a267e80, 0xe7b5654c, 0xba079f81, -0x10d77ca9, 0x620776cb, 0x72d30b5c, 0x3709c64f, -0xfa8ae134, 0xa76d5de5, 0x16d0c43e, 0xb3e0eb6c, -0xb29d6055, 0xed7f9770, 0xf59f2b52, 0xaea14f7a, -0x55555667, 0x429613fe, 0x9192091e, 0xefc3fa0c, -0x5b57b348, 0x784ff046, 0xf06bdf46, 0x7f772849, -0x2f5831dd, 0xadd45015, 0x9a550a7a, 0xec516793, -0xf852e46d, 0x339d0c26, 0xa42da41b, 0xf082bb62, -0xdca32c44, 0x4cfa7706, 0xdcd17e16, 0x2cd3798c, -0x6d097168, 0x1ef0b3b1, 0x50a831f9, 0x90466bda, -0xb9a008d6, 0x60806e77, 0x01b31846, 0x48fec336, -0xb169f54a, 0xdc7596ce, 0xea9a8f38, 0x048ca4da, -0x79c1582d, 0xecace961, 0x84404601, 0xd5acf76b, -0x9fc7fa4c, 0x0a39c68e, 0xd6c26cba, 0xa29e95af, -0xc9cd9186, 0xbb5f0a57, 0x58d88a0d, 0x062908e6, -0x32fe647b, 0x8658c809, 0xc2e0d2c7, 0x7bb9039b, -0x7500c6f9, 0x51c201ca, 0xfbcd4ca5, 0x2836b352, -0xd57ab38f, 0xc261f3b5, 0x91606246, 0x7fa42b46, -0xdcb911c1, 0xd7fccb18, 0x2eec8397, 0x16eccd3f, -0x0f0ff08f, 0xeab63455, 0x7fca5f02, 0x2aee4eda, -0x9ce2ca9c, 0xb26b115e, 0x5eaccb32, 0xe135e2ab, -0x15c95f3b, 0x9487d7a1, 0xe59407eb, 0x24832f87, -0x97bacdcf, 0x68f80a70, 0x4cd0c2c2, 0x2e4e056a, -0xc4331004, 0x8f4dffca, 0xf0a617a9, 0x05544788, -0x4b44d10f, 0x147070c0, 0x0da56940, 0xaf190457, -0x91e927b4, 0x51397c96, 0xc400458e, 0xca20ba1e, -0xaa7fa86b, 0xb13caa61, 0x61da85af, 0x287c3f4c, -0xce7c0be0, 0x72387d77, 0x3e65de67, 0xf86a18dd, -0xf8d6540e, 0x3e681318, 0xe2989d26, 0xb9e1c745, -0xdc71ee8e, 0x3db05e6c, 0x883a048e, 0xc5c35513, -0xa1bbcc6f, 0x26072dac, 0x11982c78, 0xf6b0deb2, -0xc1020189, 0x632829a3, 0xf8797582, 0x824a362b, -0x1c24ba47, 0xb5183931, 0xbd7736d6, 0xf9d778f2, -0xca55e789, 0xc5bef424, 0x2274c87d, 0x9d7cb0bc, -0xde597991, 0xe085bc6a, 0x37d288e8, 0x8b222375, -0x6ed1939a, 0x70516fab, 0x7c66d58e, 0x2912d6be, -0xe778f97e, 0x40304808, 0xeb30652a, 0x43fa3109, -0xcbcf8563, 0x5f324e6e, 0x375dced3, 0x9e67d97d, -0x590c330d, 0x3adda68d, 0x7a4a32ee, 0x5db03885, -0xacdc6149, 0x8180dc4d, 0x0022950d, 0x58ece5f7, -0xe671d4c2, 0x84ab201e, 0xd403a7b4, 0xe674512b, -0x49cbff07, 0x5721f935, 0x1a623898, 0x4a6b656d, -0xb0ed7698, 0x8c0d2b98, 0xfba35247, 0x7438b0b1, -0x1184bc22, 0xd511b6e5, 0xe1fe111e, 0x67f37c3d, -0xddea5711, 0x8ce3f768, 0x43048733, 0x2dedd922, -0x903e9ef4, 0x009db5a0, 0xaef6e7b6, 0xfa78c7e9, -0xfac768c6, 0x30e9300c, 0x22a92a52, 0xd58a96ea, -0xca86b581, 0x9e6f86b1, 0x978f3788, 0x58ed1fea, -0xd95ee669, 0x5b7e7ae0, 0x8b6735e0, 0xc26330fa, -0x2b6f8708, 0x18b48518, 0xb27d2a16, 0x083f68bb, -0xb351da07, 0x1332fd21, 0x92d5227c, 0x5caa0da8, -0xb48fd33a, 0xa98e2474, 0x8f561ed6, 0xb0572587, -0x0c22ad2e, 0xc43c2258, 0x9d669bbc, 0x27def2aa, -0xbc4134b1, 0x7e89bee6, 0x9537f017, 0x13706540, -0x0b2befcc, 0x5f72ddee, 0x49d82cfd, 0x22e4f8a9, -0x53737b54, 0xcecc2653, 0x95709612, 0x4bb49197, -0x50678a99, 0xb945a61f, 0xa5067e19, 0x0286193c, -0xd0c6d89a, 0xa98c9860, 0x58794310, 0x20a2519a, -0x4fd6b897, 0x43cdfa26, 0xe98383ae, 0x46f94998, -0xed179ecb, 0x711671e0, 0x599cd144, 0x15a123d5, -0xf16ee833, 0xdbee4f93, 0x57933549, 0xcce5151b, -0x8ee1704e, 0x69ec7225, 0x7ae00937, 0xcfcc0f29, -0x502b2b62, 0x38437316, 0xe51cde5f, 0x11592292, -0x3cea5e42, 0x07bc78db, 0x1085885e, 0xf08c5069, -0xf07da087, 0xf81d3650, 0x03c1859b, 0xd7a0919b, -0xd7c04104, 0xb58ce296, 0xb23e27ac, 0x74ac7318, -0xe50fb21e, 0x0db08556, 0x72b2fadf, 0xecb96f8b, -0x365781db, 0xf828b440, 0x39d602ad, 0x4f6369de, -0x140092e9, 0xfd149cb5, 0xdeb1d729, 0xe9b30c03, -0xa1f080ae, 0x135b4032, 0x7186fa21, 0xc298e242, -0x6be8bcbd, 0xe63d5d59, 0xf9b7580e, 0x1a1b2bb3, -0x77d6a64b, 0xca758d88, 0xb965706a, 0x6ffb7da1, -0x771db6e1, 0xe00ee7d7, 0x7c101a40, 0xf04c5bda, -0x3ccae916, 0x0772ac09, 0xace75764, 0x29f2837b, -0xe5a7c3d9, 0xe7a935cc, 0x0c226bb1, 0xe6f8f848, -0xb9c779db, 0x5715df94, 0x161d4946, 0x8fb76b7d, -0xb86e2818, 0x1d1f3d99, 0x5bf5bdf9, 0xb785c01d, -0x15c53680, 0xdad1fbec, 0x3846978e, 0x53a72f1b, -0x1af27e6d, 0xe6ddea06, 0x625a7049, 0x74ad71bd, -0x73a86cbb, 0x9b538614, 0x8535c0bb, 0x66c47d6a, -0xb7ed47af, 0xa297c56c, 0x9dd35465, 0xffb13459, -0x0d69f3dd, 0x7697b0e9, 0x1add55c6, 0xfa3963fa, -0xd30d4cc1, 0x54a0b2be, 0xdd93da03, 0xb52847e7, -0xf6d21210, 0x8a8b164a, 0xf83ddd39, 0x030a875d, -0x3f02d2cf, 0x0238f0d6, 0xb3010c35, 0x4a98bbf3, -0xd4920a33, 0xf5de9f63, 0xee883399, 0x20b10b06, -0x1fa40b12, 0xf40aedb9, 0x28fede9d, 0x026a77c1, -0xb9d96bf2, 0xd0a0f7b0, 0x1186d373, 0xdedc1045, -0x3afb6238, 0x1f6f0af8, 0x508a05fb, 0x9a8b7022, -0x0dc66b47, 0xf4ab674e, 0x94877e94, 0x45dfb09e, -0xe3a411f9, 0xa8d32903, 0x9014082f, 0xc474985c, -0xc8770185, 0xb13b2fa7, 0x056079d1, 0x35c3e399, -0x1b87882a, 0xae9c8263, 0xcc503dd6, 0x3d24d955, -0xe9ad61da, 0x8e43d188, 0x26b71302, 0xceec1a51, -0x94df99f8, 0x8bb501a4, 0x50960bf7, 0x96eeb5a1, -0x08dfb4a8, 0x9b4637a9, 0x00cb4dec, 0x440d9bd9, -0x4c7fb6e5, 0x96dea61c, 0x03f6608a, 0xd781c730, -0x5f289b28, 0x0f14f5f6, 0x589d83b6, 0x81d32394, -0xe1bdcbdb, 0x92a6c463, 0x98b1072d, 0x42e20173, -0xf654ca85, 0x972309f4, 0x8086fca6, 0x229cb98b, -0xd35454c4, 0x73ecd871, 0x27c302c2, 0x78a8b0da, -0x845dccd0, 0x3dd7b5a9, 0x5fcdd32e, 0x17134d76, -0x844067b9, 0x053f4599, 0x24eb01a7, 0x73224c94, -0x64d29109, 0xd38f2df3, 0xe3aa04e0, 0x94eade7a, -0x84593b17, 0xf70a0417, 0x5a89f117, 0x87d837cf, -0x27a5732d, 0x17d4bfcf, 0x7b7b358d, 0x4b7fbe93, -0x061d7ae1, 0x708fb12e, 0x6ce88f03, 0xfa34a6bc, -0x3d85cd39, 0x6c8880f9, 0xab8d33e3, 0x4643e6e0, -0xf8cd5b51, 0x717eb87b, 0x26846d1f, 0xebd94ff2, -0xe7903934, 0x472811c1, 0x0f6b0c95, 0xbf994808, -0x287732b7, 0x66ec0fd5, 0x319dc562, 0xfcaf97e2, -0x623e2113, 0xe34e4c58, 0xf1959bca, 0x4fd868eb, -0x3aaa6cb1, 0xa28f2d9c, 0x94c957e6, 0x772eefa2, -0xb61e0b69, 0x294db056, 0x8e76bed8, 0x0a33286c, -0x25f1b73d, 0x26c0ed67, 0xd4525924, 0x4dbac1d5, -0x06e9249b, 0xe1a7d83c, 0x8924230b, 0x669b3731, -0xfba030e2, 0x2dcac1b6, 0x35effc51, 0x229dd16d, -0x485fdddb, 0xf1d96a78, 0x6f09b534, 0xf8e78e0b, -0x1f073656, 0xaf0bbff3, 0x1a913c11, 0x092be9cd, -0x377266d1, 0xdda6ed82, 0x0d1c3894, 0x4b7ad157, -0x74aa8d20, 0xa071dcc7, 0xb9106d7e, 0xef01236a, -0xf6063dbc, 0x29f3c98e, 0x982caec9, 0x1cdc08c6, -0x8dbc64ab, 0xa83a8eeb, 0x74298948, 0xabc33cfd, -0x07d0b8b1, 0x5fedb1c4, 0x126752c1, 0xe7c3f4be, -0xbf09f75a, 0x27199269, 0x5eb2945d, 0xc52efb9d, -0x90428300, 0x13d5a9ca, 0x838f5cdd, 0x73e934fa, -0x6d7cfa3d, 0x48b9f96d, 0xe3374584, 0x752ac718, -0xc925aa16, 0xfa660428, 0xe9d1de54, 0x82f079e9, -0x762760e6, 0xeabac4fe, 0x54436530, 0xba655050, -0x928088fe, 0x215b593c, 0x7a07d6dc, 0xb4dab921, -0xac8b264d, 0xcfc3324a, 0xe20f417b, 0x040838e3, -0xdcf58c52, 0xb84daf82, 0x6541ffa9, 0x6afa707c, -0x0d875f5e, 0xfb94c514, 0xf80ef226, 0x3a0da940, -0x0ce66076, 0x1ed9af3b, 0x59994986, 0xa109a00f, -0x28c7b3f6, 0xdbc50554, 0x37a97daa, 0x5572d0c0, -0x84a25ba6, 0x29d0c7da, 0x424814b7, 0x796c3af0, -0xea2d2a79, 0x5440915d, 0x868616da, 0x63cda2fc, -0xdd956523, 0x2fd44435, 0x1478b7a3, 0x9a48728b, -0xb069562d, 0x67f0378e, 0xf776d649, 0x5f682002, -0x3d98b6d7, 0x78873d15, 0x4ddc674f, 0xc8dfdeeb, -0xa28d4c2f, 0x0ed17b8f, 0x25752288, 0x108811ea, -0x8727b8e1, 0xafcaeb34, 0xb08ee613, 0x21a76843, -0xae3dc6a1, 0xb9b41ccb, 0xae40b539, 0xf6ee369b, -0xc33256cf, 0x97e63b33, 0x281ecbca, 0x03d27cef, -0x2cec16d2, 0x4fb0965b, 0xd619969c, 0x63d7ccc1, -0xf39a0271, 0x0fb76532, 0x331077ec, 0xd961fe4e, -0x42c36d59, 0x3f5a2eb1, 0x4a8c998b, 0x8db7cfff, -0x6fb068b7, 0xaa92ee13, 0xa8a01101, 0x00e09470, -0x99d1be9b, 0xcc38f497, 0xf070d411, 0x6de05db7, -0x07af935d, 0x963e1dc5, 0x6e026e91, 0xbe9c79a1, -0x020fca5f, 0x95dcaa0c, 0x855e9b6c, 0x274cb6b5, -0x37636bb8, 0x1f5aad66, 0xc4a946c8, 0x96ced169, -0x09889005, 0x64abe905, 0xf95fced8, 0x56f0bd7a, -0x7ac20530, 0xc486ded3, 0x44dc1794, 0x84946e0c, -0xd0c87c95, 0x15050fcf, 0xa7f8bf24, 0x805915a5, -0xfa737701, 0xc8d471fa, 0x6cbc5acd, 0x740db31a, -0xb279c813, 0x59ccc4fc, 0xf70d86bd, 0xf5f28c17, -0xc73237f4, 0x973f206c, 0x8de25431, 0x3e2b50a7, -0xa6d645bd, 0x5e330b16, 0x2b41120c, 0x1a942798, -0x62ada7e5, 0x2fe8cfa9, 0x441d159e, 0x7469223a, -0x1e13ff34, 0xc6398698, 0xe637521e, 0x55eea649, -0xed19f31f, 0xa4c588c1, 0x165997b5, 0x6fa55b04, -0xbd5a0881, 0xb61d7803, 0x19a98a57, 0x1006ba25, -0x6bcf5ac7, 0x8202f782, 0x655023a4, 0xb0ddd31e, -0x45063696, 0x5e725e3d, 0x19ce39f9, 0x1192e2cd, -0x824b7ddd, 0x8e42bdb3, 0x58026854, 0x6fb264fc, -0x49670166, 0x3694b535, 0x74fd3614, 0x084d98fe, -0x986509e2, 0xd5f17199, 0xc7e39caf, 0xe572c94f, -0x3d1761a3, 0x478c3c67, 0x5ff9ea89, 0xe471b06d, -0x0fe32378, 0x073d67f9, 0xf20593f0, 0xf99bbfed, -0x7b20e635, 0x35c99773, 0xda97200a, 0x3405fa29, -0x69242039, 0x9a6ea1f8, 0x754cc661, 0xee80347a, -0x852b4249, 0x8ee4ff7d, 0x3f970b59, 0xde832b32, -0x336dba9e, 0xf25e1b12, 0xe126e598, 0xd54db071, -0x1e0096f2, 0x6af7f632, 0x7f6373a3, 0x8c22258f, -0xd2050025, 0x6054a184, 0x6ec82954, 0xd410eeaf, -0x14185987, 0xf09150dc, 0x4d0c9e17, 0x4ccf3760, -0x5d42a123, 0x7ce82ee5, 0x0d4921f2, 0xe4d7f1f6, -0x6f6683b5, 0xe2c7ce05, 0x4a72ee67, 0xbafab496, -0xafcb5088, 0x1d9291fe, 0x200d498f, 0xe555459b, -0xb409d75c, 0xf24b40b0, 0xb3ff50b4, 0x4268510c, -0x4554d6bd, 0xe48a0828, 0x484de584, 0x72dd9066, -0x71f10567, 0x80315f9c, 0xab3d8cca, 0x30291f03, -0x9f79c26c, 0x3255f780, 0x800c868e, 0xff7e95a5, -0xf2f9ee4f, 0xdbf39bb9, 0x75c754c6, 0xccc5d8f5, -0x6f762135, 0x384f6434, 0x8e37913b, 0x355bcbfe, -0x3861e062, 0xf589349b, 0x00cbd441, 0x117f4fd0, -0xf683d175, 0xf4bb0c9e, 0x01b30261, 0xd2a07292, -0xbd6e56d5, 0xb93c9d68, 0xc0cce49f, 0x9097d4ea, -0xfad1585b, 0xd98ea1e8, 0x9ffd376c, 0x9e9ccf1b, -0xb2479982, 0x52ab0797, 0x9acd5ae9, 0xaa05a0c8, -0x0981c9ce, 0x7b616203, 0xe5578586, 0xc2dda6c1, -0x7587081c, 0x44e674bb, 0xfb42e52d, 0x3f1f5ae9, -0xeb0a829a, 0x49fd1207, 0xb18e3649, 0x1d1dd143, -0x5904f261, 0x9a034a08, 0x15042e98, 0x9c39694a, -0x1c54673c, 0xa6b09ba8, 0x1a2aea4b, 0xb0912513, -0x8719d675, 0xc68be9b1, 0xd1e52f1c, 0xdf18c798, -0x662b0111, 0x75a13396, 0x3bc0a2ea, 0x61c8642e, -0x04186415, 0xb5432f6a, 0x4d9f4664, 0x061b1437, -0x762c2b5e, 0x773639b6, 0x64021a2a, 0xb7f5f7f2, -0x46002757, 0xa1f51f41, 0x33639bbd, 0x52697994, -0x3b8d3688, 0xbd57a937, 0xaef18b6e, 0xafd681a4, -0x36832466, 0x1fb9d3dc, 0x03d772da, 0x9f019ef7, -0xe63b23f2, 0x397703eb, 0x3923a7b7, 0x8e2e4907, -0x86fe45f5, 0xb83908be, 0xf2db94e9, 0x0e6c660f, -0xb34578ed, 0xb5f76b53, 0xf102443d, 0x04ecfa73, -0xe11f1aaa, 0xe2801701, 0x578de538, 0xeaeca46f, -0x2934beb8, 0x3f534e49, 0x579a8331, 0xaa31325e, -0xd69731f0, 0xc54b03ed, 0x39f2ae81, 0x864dae23, -0x223ea49b, 0xdeaa30fc, 0xb6ee08b2, 0xffe8ab5a, -0xd5d29fba, 0x540dcffb, 0xe6eb53b1, 0xc1f1d24c, -0xa4d62e2d, 0xa40ad711, 0x95fb746f, 0xca68b0bb, -0x5e328eb2, 0xda9482c5, 0xd6e0e281, 0xcc2ca0db, -0x3959032d, 0xb4057dbd, 0x0e588bf8, 0xbb1a002e, -0x26273ae5, 0x9c178acc, 0xf9aa1796, 0x3aed26bf, -0x73312ab1, 0x6ee0cd08, 0xc0de30b6, 0x71c12a7b, -0x15abb19d, 0xf0e20a1d, 0xb3559a97, 0x5e91aa7f, -0xcae974a7, 0x756ff00c, 0x4509aae4, 0xe4b8a22e, -0x86f886e7, 0xe6050093, 0xb31e8471, 0xbe23dcee, -0xe10933a7, 0x542d8936, 0x38f37c10, 0x7231170c, -0x10a10f7b, 0xaad1b02a, 0xa986e85a, 0x461a3222, -0x2cbf24f3, 0x4f8cef54, 0xb4e90ee7, 0xd9334d8b, -0x9546a4fb, 0xd1c4eab1, 0x2c81a30a, 0x41d36c0e, -0xdef84879, 0x75a7d8eb, 0x60b90423, 0x36f90dbd, -0xb4f1c7e3, 0xadfe9980, 0x329f6088, 0xbd6475b3, -0x810cda6b, 0x88981d17, 0x50a028ee, 0xa86313dc, -0x780af375, 0x70aa0aed, 0xd9c5a36e, 0xe1cdae7b, -0xc14fa6c2, 0x98b7cff5, 0xad39494b, 0x4667d47d, -0x92b684cf, 0x85f99f8a, 0xa89f5d6f, 0xab060866, -0x9c398638, 0xb5330912, 0x6d694560, 0x1b95d8ab, -0x633c8e08, 0x155290a0, 0x5b0f7401, 0x36738de8, -0xb16ee807, 0xa5cf61c8, 0x64cf4dda, 0x025eb139, -0x3177bf83, 0x4f5f157c, 0x926d0e91, 0x5a93121a, -0x6df97b7f, 0x44954344, 0xa2cacb2d, 0x75f1aaf8, -0x16cc89c3, 0x8d43eaea, 0x691d93fb, 0xee923d52, -0x712dc56d, 0x04aaa6eb, 0x414130cc, 0x7e1b5d0f, -0x3815a3a0, 0xfdb87870, 0x3285ca3a, 0x7c5dfbdc, -0xa7b20545, 0xd4f730d9, 0x7953112e, 0xc44342ee, -0xdafc8bf7, 0x087d2bfb, 0xd7012598, 0xcb0859f6, -0x6fd45f65, 0x6abaf912, 0x79ec7fbd, 0xd02c70de, -0x3d8d9786, 0x34fbafe7, 0x0a26b4fa, 0x6d7f3bdb, -0x4be93d5d, 0x3d7b3e71, 0xe0ef7059, 0xdb30147d, -0xbbc4ea79, 0x7ccc8b2c, 0x3c3a70db, 0xbbb1f02e, -0xabcc59ee, 0xf3fb098c, 0x60d7734e, 0x12c40adb, -0xd6510acc, 0x2d488553, 0x4d774ba7, 0x4f896ccc, -0x38e656b1, 0x23a5ab48, 0x6f8486fc, 0x2dc72806, -0xc2f88696, 0x721807aa, 0x95ea9f15, 0x663458fe, -0x043f4552, 0x8ce32d80, 0x227b6b35, 0x4c387d57, -0x87413fe5, 0xcfc463d6, 0xc1e4bfe9, 0x3d8748cd, -0x14fa25c3, 0x1267b792, 0x72d80b1f, 0x373ee917, -0xfbceee14, 0x2fa20260, 0x5a36940c, 0xa1f86183, -0xa5db09c9, 0xef2d937e, 0x9de1276e, 0x2ac894d5, -0xacb1eea9, 0x7e9a8759, 0xbf41db22, 0x42841ac0, -0xa1a7ebec, 0x0c9f99c9, 0xc71ef76f, 0x73b9c929, -0xf861fd51, 0xb2ab25f8, 0x06feceed, 0x773b280a, -0xbe4ddf97, 0x252d87e8, 0xd33ff702, 0x0bdaecb2, -0x25f439d6, 0xff7f4ee8, 0xe3558956, 0xeb5fb5f6, -0xa0611f79, 0xb2c23dd1, 0x5bd3d94f, 0xc9934f18, -0x44a20e55, 0x0034ee18, 0xd5a2498c, 0x8c5515f8, -0x77276a27, 0xf9f99493, 0xec172ff2, 0x3dd2dc1d, -0x534d3493, 0x9f7e6e0b, 0xde8e2692, 0x326ffb6d, -0xa7b6437e, 0x7048718f, 0x0f96a862, 0x19f57db9, -0xf8b9459f, 0x45fa3067, 0x51e2a309, 0x2ae18f1b, -0x4caa107e, 0xb420181f, 0xb1c864e3, 0x42c1ba34, -0xc6795c27, 0x3bb910df, 0xb21ca5f9, 0x6a85e37a, -0x57fd06e0, 0x0787ae29, 0x4dbe62ff, 0x689d444c, -0x864fcc2a, 0x2efd0bbb, 0xa0dbe9d3, 0x6bcff644, -0x7b20db2a, 0x88baee81, 0x7a4eb92a, 0xfcda45c5, -0xfd71896b, 0x462289d1, 0xb5639397, 0x0dd6d058, -0xbf8dde56, 0x2ab3dcc0, 0xda04cfdc, 0x535353c4, -0xbf565509, 0x02b8404c, 0x43ceffbe, 0x961271d8, -0xaa5443c7, 0x47492ae9, 0x81549370, 0x03eb958b, -0xa8d0ecb3, 0x55d8125b, 0x96c1714f, 0x8a6bc861, -0x1dec9236, 0x8df7fcea, 0x7c986009, 0x6542a33f, -0xe9fea1dc, 0xe379c77b, 0xc7927ece, 0x24f700a3, -0xcc4852f9, 0x13b986ed, 0x04280402, 0x81ab3fd7, -0x85aba585, 0xfcc388f6, 0x9884bf12, 0x7625fe22, -0x07831c4c, 0x7819fa5c, 0x49601768, 0xe5f1c013, -0x4538fb8e, 0x1e902d71, 0x52fe80f0, 0xe1db0549, -0xea38d0fb, 0x8b78a4d6, 0xb0d08524, 0x092b8dd0, -0x1ee1bf78, 0xc7e41884, 0xb5a03a1f, 0x9380b0ad, -0x6dc87fa0, 0x1cf24649, 0xb4da7466, 0xcaab5119, -0x14f081c5, 0x70ae8c97, 0x56e6b35b, 0xeb1b671a, -0x04f3f9c0, 0x99c0f5b3, 0xc96eb118, 0x935739f0, -0xaf6cfb61, 0x23428ab0, 0x65b6acda, 0x389e5c3c, -0xa40d4e57, 0xf3566e45, 0x10a94ee9, 0x53ba357d, -0xe3182a64, 0x6b6bb867, 0xef0ba098, 0x3ff560a2, -0x46773eb2, 0x23d41447, 0x89fad151, 0x71be33d3, -0x29936e61, 0x4b3a128c, 0x5f1c4a5a, 0x3887b26f, -0xd4300535, 0xb98f3276, 0x77cfcb4a, 0x8d174b17, -0x4a7692b6, 0x85a93236, 0xe776350c, 0x456e835b, -0xf3c6fc30, 0xd4fe260b, 0x4ea04774, 0x67e79f8d, -0x51bda66d, 0x347f402d, 0xf66c87ed, 0xfe1dd07e, -0x49a5f1d0, 0xa5c79a90, 0x09440639, 0x9665b964, -0x3b0f061a, 0x19ac22fd, 0x2747ca11, 0xa61c4a0d, -0x175af504, 0xfd046876, 0xa646e1f1, 0x60d2057a, -0x327c0cff, 0x06760628, 0x36362506, 0xad21edfc, -0x2e3503da, 0x796385b4, 0xadaa8c6b, 0x75c3d3b5, -0x801d0551, 0x8ce308c0, 0x6211b022, 0x7392b6df, -0xdce62588, 0xb9791841, 0xc1279996, 0x1e40896d, -0x17732a68, 0x46e758b9, 0x9e9e6944, 0x8c4f9dd7, -0x92bbfb4b, 0xa357ea1c, 0xe8caab82, 0x501a0596, -0xdeeed569, 0x60f39f0a, 0x6e0c61e8, 0xae47150f, -0xc4afe67d, 0x29a261c5, 0xbee79d7d, 0x6f12632e, -0x341f1d75, 0xe3861acf, 0xae9bc146, 0xb355af33, -0x011af2f2, 0xc1c45374, 0x0d855646, 0xad8cf696, -0x24ca0fcc, 0x760d01f5, 0x84be2e7d, 0x27a5d933, -0x120ce78a, 0x427e2c81, 0x2dd9c1f2, 0x08eed0a2, -0xaf8d7d0c, 0x4bcd15ad, 0x2267f2fb, 0x898c1ea5, -0xd6e55fa8, 0xc4dd0a14, 0x3069e08c, 0xec55ea22, -0x9ec6ff40, 0x2f426be2, 0xfd312cd3, 0x451e06ce, -0xf4a74729, 0x1a2956cc, 0x75dd0978, 0x44f7b347, -0x585565ff, 0x83e52dca, 0xba4b52d6, 0x6ef2218a, -0xf3fb9bdf, 0x3f186040, 0xfb99b28e, 0x5840695d, -0x17c76b5f, 0xe9e0c488, 0xee505517, 0x48ac3c2d, -0x8451a406, 0x6141eb0e, 0x7babb696, 0xddf06e87, -0xbc5a48df, 0xe39aa692, 0x09ace8c0, 0x93141fc5, -0x3be8be1f, 0x6ef6f882, 0xe273e9e4, 0x46f27023, -0x83740547, 0x8665645e, 0xaee17f61, 0x814ca683, -0x6dfbb1bd, 0xf2f15771, 0xbb4ff803, 0x96f0d941, -0xa3e0aeea, 0xf9cf9021, 0x6b4e56de, 0x262c78cd, -0xa01c7bdf, 0x1464fde1, 0x315b05f6, 0x8144a541, -0xb41045bc, 0x435b8e51, 0x54879dd2, 0x5cb04317, -0xfc703e05, 0xbbc1ea5c, 0xa9d17bea, 0x73941913, -0x8a9bc3e9, 0x462b9d40, 0x41a3e549, 0xcfd40b77, -0x847c17a4, 0x55cee3fd, 0x54c2d844, 0xd265fbcc, -0xe25930c3, 0x7256e82e, 0x00f38bf3, 0xe6ab0ee4, -0x896e64b5, 0xb41bb1d5, 0xaeccee3b, 0xcbf25cbe, -0xb2a585d7, 0xe68fa39d, 0x6c935602, 0x7855ef91, -0x28bcf8f5, 0x03ad869a, 0x11c3ca6c, 0x1f858276, -0xaa3aabc8, 0xe787c982, 0x554342aa, 0x5b195148, -0x680d9deb, 0x4750dd7e, 0xc656d356, 0xa3f4c6bd, -0xf0b34039, 0x4b92db60, 0x690f8cb5, 0x2c05175c, -0xfc6e7a59, 0xdba2c23b, 0xd1b369fc, 0xd76f4069, -0xea804212, 0xe9d2a82a, 0xff076107, 0x0f2f9a93, -0x1299743c, 0xfbb303d5, 0xfd0b8703, 0x28cc6ab5, -0xb5544c0a, 0x62e33953, 0x117bb601, 0x27c3f195, -0xa844bb03, 0x63b9f935, 0x9e8e5a86, 0x0070cc59, -0x07b68daa, 0x56df73c4, 0x4abc039d, 0xf037f0a5, -0x6c70d8b8, 0xdd743bee, 0x676a3d9f, 0xb844e348, -0xa2193e77, 0x81e51abd, 0x151821da, 0xd8a661a1, -0xf8758699, 0xf01d3f69, 0x443f5d49, 0x7c12ca61, -0x1b149944, 0x47d88ab6, 0x6bf46227, 0x8cb5503a, -0x06203578, 0x9f2ced0d, 0xbdd1b617, 0x2d9eb330, -0x8e7f6ed3, 0xd0778b04, 0x45f804df, 0xeda77d3d, -/* 2619-mA01067AA07.inc */ -0x00000001, 0x00000a07, 0x04092008, 0x0001067a, -0x83067ecb, 0x00000001, 0x000000a0, 0x00001fd0, -0x00002000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x000000a1, 0x00020001, 0x00000a07, -0x0000001a, 0xa4000000, 0x20080408, 0x00000401, -0x00000001, 0x0001067a, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0x00000000, 0x00000000, 0x00000000, 0x00000000, -0xc4294866, 0x3e20a114, 0x8387f19c, 0xdafb14aa, -0x33a38309, 0x68b0f8ea, 0x2a20b200, 0xcdc7aa9e, -0x170ce7c7, 0xd727c705, 0x019b1ba5, 0xe0414a29, -0x57d45458, 0x26a8a411, 0x9faad966, 0x095ec8b0, -0x083a7c2a, 0x17cfc70f, 0x3c8e78a8, 0xce18c419, -0x5f2ddeb7, 0xc9c95d71, 0x437a5116, 0xe0253ad0, -0xec78db42, 0x681e436f, 0x7fd028bb, 0x1149a501, -0x0bdf0d05, 0xc2321514, 0xd6866cd8, 0x64942685, -0x21e0276b, 0x0817a288, 0x09138669, 0x792985dc, -0xbd60d6aa, 0xfbf902ec, 0x43fee69d, 0x5c5823c0, -0x9dca1fe6, 0xb528b0c5, 0x22fd29ab, 0xac4fe251, -0x77207813, 0x0637a1f9, 0x16bfcf73, 0x80497f6b, -0xe5bca939, 0x1539fa1a, 0x66607fea, 0x2276c06f, -0xd003229e, 0x3622fda7, 0x18d0b8af, 0x9f399760, -0x3ac6387b, 0x6c7148fa, 0xfaf4df9f, 0x965db840, -0x7c142542, 0x7b805f4c, 0x3f2002a3, 0x061399ce, -0x2f1a03c4, 0x7f1c7616, 0xb2f9ab42, 0x4e6a92a2, -0xb44b96d6, 0xe1167017, 0xec4b2fb3, 0xa15376be, -0x00000011, 0x9f63eb61, 0x64816577, 0x10c68141, -0x1cc5fd18, 0x156703a6, 0xe3315c33, 0x62a1db21, -0xb6135848, 0xa306d2fe, 0x117cb585, 0x54c3a133, -0x722cf721, 0xa693cd57, 0xd02c0e2d, 0xf17b96ca, -0x97d2a408, 0x2e776501, 0x667f7664, 0x1568cf83, -0xa044dee1, 0xe6a879aa, 0x4ff23d0a, 0xd559de49, -0x2dabb17a, 0xc6c39e38, 0xc3ae5451, 0x2d03f3dd, -0x7ba226ed, 0x69a19529, 0xc2865715, 0x8b95e6c2, -0x7a7ee1cf, 0x74b5e43f, 0x69aeeefb, 0x5d95aaa5, -0x0afeb5dd, 0xdb837be6, 0xed6f9d79, 0x2ad96eb4, -0xcd60dd82, 0xc3ff7d75, 0x7030a02b, 0xdbbe45dc, -0x203cd7ba, 0xc3b90579, 0xa21f54f2, 0xc79853ce, -0x5e3f74eb, 0x06c63742, 0xb1fa50ef, 0x0e8e950e, -0x97d44b72, 0xa48dc8ad, 0xf3803fb8, 0x946e4d5e, -0xf0f1e9f6, 0x272b9764, 0x567efb67, 0x82deebcc, -0x614f61e8, 0x3bea41b8, 0x31a12485, 0x682e10ae, -0x954c7b7f, 0x0e4bccf0, 0x8cb1eb25, 0xb5018c6e, -0x50957531, 0xcc60f1c9, 0x11181c5c, 0xa4dc1468, -0x3310423f, 0xd2550a2a, 0x3bd2ac80, 0x2be006d9, -0xf57f3e2d, 0xb4387cc7, 0xe96c48f9, 0x722975a2, -0x4506717f, 0xaf92aa6e, 0x7de4eb6e, 0x3600e58d, -0x898cc58f, 0x271c467f, 0x1c5cd377, 0x5858e9bc, -0xd3ad9408, 0x513c936c, 0x0dc54b7e, 0x0226d703, -0x4cc95088, 0x78bbb408, 0x573d07e2, 0xa4e9cd4e, -0x4a2930cc, 0x3082d573, 0x68c8c48e, 0x883d27f8, -0x4e91dd95, 0x850f6d80, 0x5f7f3e37, 0x452cc29a, -0xf2f9cc40, 0x278be406, 0x356eb275, 0xda301857, -0xdbc49113, 0x7007d110, 0x06f49bc2, 0x74712f32, -0x73176720, 0xcebc66e2, 0x592acf0a, 0x8818dd3f, -0xd599d562, 0x54199a46, 0x6472129b, 0x47058cd1, -0xac4a74f5, 0x1cac471a, 0xf1b4758a, 0xfa6f8e1d, -0x1013e19a, 0x59252c0b, 0xa764c600, 0xfba01968, -0xc7c11589, 0x2b4bf080, 0x0157b32c, 0xc09788fa, -0x1be99aed, 0x19c1799c, 0xb1d03201, 0x8bfb5374, -0x44e04a89, 0x895d3a8b, 0x5b3a53dd, 0x4704a722, -0x0d4ac344, 0x8a3f81f2, 0x3513e05d, 0x04e89637, -0x39f3d4a3, 0x883f2acd, 0xbc2ec5aa, 0x3a26f17e, -0x3de2b026, 0x49cffb83, 0x9cdece0f, 0xdaaddd7f, -0xc884a2fe, 0xe4244359, 0x493030d4, 0xb87e816a, -0x3b2481a1, 0xa2eaa4eb, 0x33d7ad6a, 0x64947485, -0x65f85855, 0x088388d8, 0xf6dfc3eb, 0xbceddbca, -0xf72f47e1, 0xd1d06e25, 0x76ff3bc0, 0x9b8f2139, -0xec7bc702, 0xfe6e6c0f, 0x42d31d20, 0x7e0397f9, -0xb20b40ff, 0x45a5ce27, 0x31949159, 0x7013a868, -0xdef2e0d9, 0x30c62ff4, 0x9b5a9b24, 0x0e4e4b1d, -0xecbbbe85, 0x4cca116b, 0x341fa1fc, 0xfa64b033, -0x43007f76, 0x710238e0, 0xa995a864, 0x5125d448, -0xc20c49c5, 0xea370734, 0x9bb92154, 0x596f42c2, -0x8d8919f6, 0xdd875cf4, 0x3b76b70b, 0xe96291c9, -0x2814c6d4, 0x0baf988f, 0x9880af78, 0xcbb57ca5, -0xf9580819, 0xebe041cb, 0x051d6dab, 0x5170746b, -0x6f04bfec, 0xca10ec0b, 0x2a870ec1, 0x551af839, -0xcfbbbb16, 0xef91d864, 0xe9b9dde1, 0xf1fade18, -0xe306f50b, 0xeb5253aa, 0x30010729, 0xb4169d72, -0x3320e4f1, 0x9c6946e1, 0xdee63588, 0x4b2967be, -0x167720ed, 0x6f27e397, 0x83419fdc, 0xac4386f3, -0x0ac58383, 0x55c0dd4e, 0x62b4a145, 0x91d64a01, -0x0e8acdb5, 0x40de995a, 0xc850ada1, 0xaa95a50a, -0x14516378, 0x294a976e, 0x544fa118, 0x904c471c, -0x8a5896d3, 0xb1486188, 0x237498dc, 0x1a1980b3, -0xd339968f, 0xe735a8b1, 0xc5ee31e3, 0x35c64060, -0x79cd8f43, 0xa2bb1974, 0x00189576, 0xf7bd74be, -0xdd52d07c, 0xa20b9c8b, 0x98dadf9d, 0xf75c05be, -0x476ac3a5, 0x6fb2bf82, 0x914c23c7, 0xd91c35e8, -0x709ef212, 0x3d8f3ca6, 0x14c20046, 0x7015482e, -0xb3fa2331, 0x78933f36, 0xc73c72b5, 0x645b4476, -0x299fa727, 0x701d7717, 0xf6c4bfed, 0x3213dc65, -0xfe66e1b4, 0x8040904c, 0xc536845b, 0xd1764a8d, -0xdeb49b88, 0xdaf26115, 0x8160aa13, 0x206d4929, -0x92fdb80a, 0x4f1aaab2, 0xfbbac21f, 0x2dc479da, -0xd2ce1eab, 0xa7da6602, 0xa9fbe019, 0xdd58fac1, -0x747ab469, 0x946a3b93, 0xc7b9cbe7, 0xc6f74040, -0x8a8bee87, 0x07f65d07, 0xe79eb820, 0x64ef2fc1, -0x72b1eccf, 0xc71f601b, 0x2812ab18, 0x48415edf, -0x45a80c6d, 0x7f616640, 0xfeaa98d0, 0x1024f1e8, -0x37b3735c, 0xc136f513, 0x5df10182, 0x1bd2ec03, -0x07f04b3c, 0x59beeff2, 0xea0388f8, 0x2f6addc8, -0xe0f282e2, 0xf9772673, 0x6bd0dc01, 0x3b4d6f9b, -0x29b81515, 0x6c553377, 0x1136b69a, 0x50e03397, -0x9c483ccd, 0xb0a13c9d, 0xea8e6bd6, 0xb8129b95, -0xc085a4d1, 0x52f64f7f, 0x178aad6e, 0xe5c4d92a, -0x4c35f2de, 0x8f179df7, 0xba405091, 0xd756e10d, -0x23bfae39, 0x74015fee, 0x15dc3e64, 0xdfc05a18, -0xa51ac3a0, 0x0ad4595a, 0x801363f0, 0x3db1f0c5, -0x97a8ca8f, 0x7e74b015, 0x124d1664, 0x71b26596, -0xaf073d4e, 0xf45d87d4, 0xd73c1dd0, 0xd1ade30b, -0x8127545f, 0x4ba0585c, 0x5bb26da4, 0xd64fb76b, -0x5c9c8190, 0xc1603512, 0xf7a69779, 0x1529ac38, -0x8d9422c9, 0xac132697, 0x5f9ce586, 0x8d5ca1ce, -0xba409dbd, 0x184b0698, 0x71bc5a54, 0x294e6b1c, -0x085c38df, 0x629e955b, 0x73f5c2b8, 0x219166e4, -0x9805fea9, 0x7602d837, 0x0932604b, 0x06a1509c, -0x2afe3b47, 0x61050264, 0x0fba8fc2, 0x9f648238, -0xbf3adf84, 0xdb8d2f92, 0xba2d9b51, 0x3d4415df, -0x32811e41, 0x176a4519, 0x1ffd7d6b, 0xffe56807, -0xca7db7a3, 0x5c811c87, 0x6bf1fe24, 0xc3013434, -0x4ccc937e, 0x0a04797c, 0xca7dd4b5, 0x20ba4643, -0x2b18ed89, 0x2ccf7a54, 0xd1a9e7a8, 0x67d96e26, -0x9dd29473, 0x0f26a8f8, 0x164fb823, 0x17c5d3fc, -0x26361bf0, 0x02544619, 0x32bbe44e, 0x12fbec8d, -0x0a928412, 0x23652975, 0xe67465e7, 0xd1f49edc, -0x200ce053, 0x1276b87a, 0xf5150061, 0xf509028d, -0x4aa27234, 0x6fbc6156, 0x89e61e73, 0x612a7618, -0x20783c3e, 0x152fda0c, 0x9a5c7b17, 0xebd39bba, -0x9793ab7e, 0x053f88e4, 0xef9499c7, 0xdf5efc36, -0xa2792729, 0x068ba6d6, 0xa5c5687e, 0x3924364a, -0xa4c6c2e4, 0x45364a92, 0xda08f6ba, 0x1551c9a5, -0xb4787235, 0x73d99aae, 0x584e52ec, 0xd76c6379, -0xf852e104, 0xa335ab55, 0xd2b1013a, 0xc2c591f1, -0x91ac865d, 0xe82497be, 0x39f62b27, 0x3d6a9530, -0xb74f7711, 0xca3f54d4, 0x466e17e8, 0xe91d700d, -0xbe8197a7, 0x04218b87, 0x587e7832, 0x838c1a71, -0x39d27956, 0x36ecc542, 0x36b22957, 0x5c44fe01, -0x86ae0bfe, 0x2ffa7c08, 0x603db66a, 0x69d7eed9, -0xd96761bf, 0x44bc3358, 0x2c04707e, 0x290a0631, -0xac627cd8, 0x1dd90751, 0x41e91a35, 0xf5dc1260, -0x36564120, 0x1ac71792, 0x87e0a694, 0x063d0388, -0x4f282802, 0x026fdbfd, 0x11102f9a, 0x5932ad11, -0xc5f266d3, 0x27587435, 0x6fecaeb7, 0x191e6dda, -0x50daedc2, 0xa282f89d, 0x89ceb660, 0x4564adc8, -0x0cee73af, 0xed4f399f, 0x10085cac, 0x0d9ded47, -0xa88956dd, 0x242798ad, 0xae708815, 0xf7edf1f7, -0xb9fa65b7, 0xe8b4fcc1, 0x00fd86c4, 0x7ad67bce, -0x66e3f423, 0xee1b4874, 0xccbc4116, 0x04a72b4b, -0x39a640f0, 0xef9f5c48, 0xe8d1470d, 0xee1ef5d1, -0x90784af3, 0xbc0b3389, 0x49aac119, 0xdf65d921, -0x1023547c, 0x486b404a, 0x834d359c, 0xf5dbbd50, -0x68b5997b, 0x7aee9417, 0x42e48286, 0xa9d8ee77, -0x181a3e1e, 0x607cb99f, 0x5f53c78d, 0x5a60a6a8, -0x39cfc04c, 0xfbe6eb32, 0x84348beb, 0xa278662b, -0x398c625d, 0x3f9859e8, 0x5517ef17, 0x15856fe2, -0xba4d33c1, 0xc93d7652, 0xcf40a2aa, 0x2ac37060, -0x5efc6cab, 0xced95484, 0xf39ceed8, 0x4ecc8045, -0x13c1e742, 0xd93d87f1, 0x695cf766, 0xcb53f961, -0x15e0fc91, 0x37178627, 0x5e832076, 0x8c72db35, -0x2ce047e6, 0x11d9e791, 0x45e4d466, 0x8b7a7c71, -0xa83e9738, 0x7c54e924, 0x2ff12bda, 0x6b1ca347, -0x2957b0a8, 0x1fdb23fa, 0x91f98947, 0xe02c3f1b, -0xc42cbb06, 0xf0421ecc, 0x1716fce4, 0x1bb34813, -0xc67853bd, 0x3a27d8f1, 0x8e38f3be, 0x9e5dc781, -0x245017b1, 0x8cade69f, 0x44642f90, 0x3ef4215a, -0x879c78ad, 0x371ddad7, 0x7c629ddb, 0xe5f61d71, -0xbb3896fd, 0xcd3067f4, 0x4cfc2e12, 0xe7d69e64, -0xcd35c838, 0x6af17c65, 0x322fec99, 0x81221d8b, -0xa586497b, 0xb2cecfa9, 0xebbdaef4, 0x074fef30, -0xf825db99, 0x2f916b7b, 0xdc32f01d, 0x915eddd6, -0x96238f76, 0xf61c60df, 0x68795cf1, 0x46f1f13f, -0xc9654740, 0x63872bc0, 0x51e210b6, 0x17b5c27b, -0x7adf79d9, 0x7a823cc1, 0x02011b40, 0x6434a855, -0x56eca557, 0xa14f4132, 0x8c120524, 0x778266f4, -0x04ad9ca3, 0xccceab50, 0xecd117cc, 0xf0defcc9, -0x4f573e38, 0x5393033b, 0x88684c7b, 0x1a33f3a7, -0x898f45f0, 0x355ffa68, 0x174542c3, 0xa3dcfb8d, -0x6cd09199, 0x67339d62, 0xd29348c7, 0x37431b9f, -0x508c487c, 0xe4668bdf, 0xcbba1b72, 0x1b1b10a1, -0xcd4447c0, 0xf9ee7e83, 0x871a0f4f, 0xa94572d2, -0xac77a5c1, 0x3b84dbd4, 0xd45a09b6, 0x8e73228d, -0x59f2bb36, 0x4855a81b, 0x3fafe19b, 0x2f612920, -0xb9d216f3, 0x937e6a7e, 0xf31a2011, 0xfb7ca7fb, -0x1ca50eef, 0xd1d2baec, 0xa19d932b, 0x620d57d4, -0x086b7270, 0x5fcc7905, 0xb0dbe594, 0xf16f0a1d, -0xd47563f5, 0xe54eeb3a, 0x588766e4, 0x0280ef61, -0x8f26923d, 0x14b892bd, 0xdd11550f, 0x3e5ec618, -0xed825fca, 0x52a04ef9, 0xaad0c980, 0xdff1a4ea, -0x68f8954e, 0xc0f1664d, 0x6bc36a13, 0x5d36fbca, -0x05f7883f, 0xd2da1028, 0xe3cd0e3e, 0xa4038605, -0xb48e7f32, 0x1f5ffb16, 0x7c4899b2, 0xb3073d46, -0xe2acb6e2, 0xefe17316, 0xca66163c, 0x93d4b562, -0xa86a9d63, 0x07449ca1, 0xb499c9d4, 0x6c666b70, -0x0d8c9f9d, 0x78c926a0, 0x99e4d31f, 0xd73c49ca, -0xfd7e352a, 0xd710b7c6, 0x18100555, 0xb4e79321, -0x5efc693a, 0x703180ef, 0x9bbb238b, 0xa105a3e4, -0xdaa3ce4d, 0xff7cc846, 0x2bfbd556, 0x5f5ba34d, -0x0ef8537b, 0xb0bc4e7b, 0x224f6dbf, 0x3b9ddb96, -0xf731880a, 0x00d8d325, 0x55e4908e, 0x63bc2811, -0xafa6f5cd, 0x5219a8c7, 0x4609390d, 0xd68e7ae1, -0xc2e5e5dd, 0xf232712f, 0x1c52c242, 0x5a6cb79f, -0x26667cb4, 0x0de1b656, 0x42ca30c0, 0x4ab64de9, -0x26b0cfa4, 0x2897b6d1, 0xefc5d75e, 0x67ca7a04, -0x805a805d, 0xf2e454cc, 0x837877a1, 0x8ca7dc3b, -0x40620ce0, 0x5ac019fb, 0x6ee93d19, 0xae137f12, -0x0cedbd2f, 0xacc51979, 0xec7ae13f, 0x4537c7b6, -0xe3491fd6, 0x8e63f870, 0x1e08f6b3, 0x219dae5b, -0x8db5d524, 0x8de9f8ee, 0x04913730, 0x7a11db72, -0x6e4d0088, 0xa8713aba, 0xf2e72fd0, 0x2ba5695f, -0xe11da489, 0x6a5ecdf5, 0xc2133568, 0x994cc9f4, -0xed6825cc, 0x3d104599, 0x4d7679b6, 0x3bfe94f0, -0xc6a131db, 0x6dfcc31c, 0x9ec5c4f6, 0x3a386a48, -0x5d0b6f61, 0x059b5114, 0xd4831a86, 0x37460179, -0x02f23600, 0x1c04bd2e, 0xbf689d81, 0x2bf0be1c, -0xd8d5974c, 0x0d9d0709, 0x5dcade38, 0x167df39e, -0x96942861, 0xf1e6a09c, 0x16ac7082, 0x5037af19, -0x69c40dbb, 0x10728698, 0x71d52ed0, 0xa77036b8, -0xa050ea5f, 0xa7ca5494, 0xa25b4acd, 0x7f8ceb12, -0x8f03bc78, 0x6b7ee0f3, 0xa97d44b3, 0xeda32377, -0x852c4597, 0x3f81aa95, 0xf148a2da, 0x770e5cb6, -0x90fe1806, 0x50620299, 0xd7f4042b, 0x0d356595, -0x5596e5dd, 0x6c797c13, 0x500c0ee5, 0x7e5ae4c5, -0xecf3ac43, 0xae09d902, 0x95b72b10, 0x7597d441, -0x8d719da8, 0x151b5d1c, 0x1f6790f9, 0x1147be9f, -0xee857fb4, 0x6f34c63c, 0xb5211613, 0x831687d1, -0x80e19a47, 0x1bb032f0, 0x5341a6f2, 0xc9a32ec1, -0xad2521c2, 0x359e67d5, 0xeb4fa538, 0x1cc294ee, -0xab08e4ee, 0x491c2562, 0xe1e38431, 0x039787ad, -0xa3cc1cd4, 0x3ff47385, 0x0f442100, 0xd40d9c3e, -0xcd033c28, 0x400eaf93, 0x5017c05d, 0x98554fb3, -0x3de23fb4, 0xaa7d549c, 0x6be71942, 0x78577be6, -0x47aa0dd7, 0xa1226946, 0xcb703f76, 0x023e8ff2, -0x649fd255, 0xa927f029, 0xe2cfa7b3, 0x03a6ce51, -0xf674945b, 0x77f3c516, 0x41eb2b88, 0x5be10c42, -0x88a250be, 0xc30b371b, 0x8711bcb0, 0xaba1efe7, -0x0446f6d0, 0xe7ff87ba, 0x879b4aa6, 0xb033052e, -0xa388c8ab, 0x3344d7ab, 0xa81b3a68, 0x895fb4ff, -0xe4efddc9, 0x7c69bba5, 0xbd7226cf, 0xca2e3b74, -0xba316a72, 0x087b68ba, 0xa0234a53, 0x51f6447a, -0x1c6c1312, 0x52e597e7, 0xc50f49ee, 0x064ce0c7, -0x70f67efe, 0xcaf13ee0, 0xd68fc906, 0xa5a173a8, -0xde41697f, 0xc8b09415, 0x8a08cd8f, 0x2ac8a7ed, -0xac323499, 0xf55a3c3e, 0xd487d5c3, 0xb8940642, -0x73cd4073, 0xfb15c814, 0x775f4fe8, 0x2b42622c, -0xa53339a1, 0x305c5717, 0xcdae12bf, 0x8facff91, -0x86728c4f, 0xde5967a7, 0xaefa7393, 0x60fc32e4, -0x4ddd7ad9, 0x020ac80d, 0xd87b74e7, 0x7ffcdc79, -0x6e7ebe24, 0x561f95a0, 0x2523a129, 0xd40136d7, -0xd253e4db, 0x8339b140, 0x71f6d4cf, 0x9bbfd0df, -0xc54f7b50, 0x6c13a6fd, 0x09e9596d, 0xa71eaa48, -0x5b8a7c0a, 0x5cf679df, 0xcab512b5, 0x61623502, -0xe002bd96, 0x5e7b9889, 0xb029fae3, 0x85ae825e, -0x0cb81cf4, 0x7b8d598e, 0x1b1b4c43, 0x723f793e, -0xc2d0120d, 0xfa704e12, 0x0529301e, 0x6d7c1536, -0xe4008061, 0x319c2fce, 0x4dbb7c85, 0x989ae3e5, -0x877539d3, 0x9d77a472, 0x75e0ec43, 0x5243baa3, -0x7866e10c, 0xd71618ac, 0xc87934bd, 0xe96101d1, -0x55d1976c, 0x471c8505, 0x7a36d839, 0x5d62a9ee, -0xf3c54a8a, 0xa2be15d9, 0x244087c9, 0x042c8037, -0x23224689, 0x281c5d73, 0x2139ecfc, 0xffb8bc8a, -0x834fdd11, 0x9cd5a5bd, 0xa3368319, 0x7e5bef0c, -0x4ae2dbda, 0x86d90089, 0x6675dfce, 0x48876262, -0xcec72538, 0x11dc5c80, 0x86a730f9, 0x313565c9, -0xe3e5be11, 0x106d7cce, 0x752b8be2, 0x3d00a5bc, -0xe6f70e95, 0x44447ac8, 0x600df30c, 0x8335ac3b, -0x8816ddee, 0x700982fe, 0xee495741, 0x48c7e81c, -0xa3d55da2, 0xb0172982, 0x70ab2158, 0xd4460621, -0x3a9e528b, 0x59b18a7b, 0xf4dabc4c, 0xa8454763, -0x70877bb6, 0x66005c97, 0xaf292c06, 0x7b843db1, -0xf343b59b, 0x25cdc7b5, 0xa41da617, 0x9e9d895e, -0xc936f475, 0x7270925a, 0x30024230, 0x8e72f53d, -0x2b6c1b6f, 0x1a69732c, 0x7ed5aff5, 0xfc18a2a3, -0xaf377cc1, 0xbff09a78, 0x4b4e0814, 0x95a0b2c1, -0x270398de, 0x201fca94, 0x2a032a4f, 0x131542b4, -0x0d7306da, 0x2d1c3496, 0xcc3c6d8d, 0xa814ddc9, -0xa3b3a991, 0x17ee60c2, 0x852c0b8d, 0x11e5853a, -0x762002a7, 0x92c5311d, 0x0d4bf7e1, 0xfffec870, -0xe3d35e5b, 0xff6ecfb9, 0xdedae6ff, 0x0111a772, -0x9808e780, 0x29c336e8, 0xe9bc05df, 0x5bedde11, -0x945565af, 0xaff808fe, 0x87e3423d, 0x4de6f98f, -0x93b4adef, 0xbf704fa4, 0x09120e91, 0xd54f3692, -0xdf8eab1e, 0xfabbf59c, 0xe74318be, 0xaab87ffc, -0x29fa791c, 0xe3915552, 0xa652cb9b, 0xa1252e74, -0xb35b723b, 0x542aa28b, 0x12fcc5b0, 0x3941f962, -0x82bcc6cc, 0x47b11974, 0xb821611f, 0x78b34250, -0xf1be5659, 0x561b9e61, 0x6f3bd501, 0x584e6f5c, -0xd54ed547, 0xacebcd21, 0x7b5ff816, 0xb64ad233, -0x9f2f330d, 0x69fb1ece, 0xac8710dd, 0x58dc6c60, -0x9bee6139, 0xbb10ad0e, 0xbd8cd5dd, 0xebc0ce9d, -0xa733274f, 0x884d9b55, 0x42b08b63, 0xafa54a74, -0x1c7ccf64, 0x93a20191, 0xaaa3132e, 0xc69831d1, -0x54634889, 0xfbfe3efc, 0xd3cf68d4, 0x302e3117, -0xf5693131, 0xc3ce8c6c, 0x1f03cd89, 0x6243334c, -0xf16bc80f, 0xdca5f130, 0xcb2cd956, 0x4c1bb421, -0xe8de533c, 0x7f86703a, 0x29aa897e, 0xdd54acad, -0x76b2f2ae, 0x7ef82b71, 0x2e30970b, 0xba402597, -0x9a653ab4, 0xd68fcf53, 0x2d9f0d15, 0x7f9efd1c, -0x2363d147, 0x5327289a, 0xe89229f3, 0xd63a535c, -0x7efe9273, 0x64f2e3a3, 0x9bdf65a7, 0x26b6edfb, -0x1b9c7bfe, 0x5d14b3de, 0x54d575fb, 0x6d65db4c, -0x95648b7f, 0xa8a3b8f0, 0x7cc7ad46, 0xe20e6dbb, -0x8488a45f, 0x8ebc2932, 0xd4767316, 0x3e8c4b8a, -0xbab7402c, 0xfc1e217e, 0xe5c5bf82, 0x6928fe2e, -0xc88528e9, 0x4b2e4e8f, 0xdd938b86, 0x0c964f98, -0xfc88d480, 0x35fcaf9e, 0xdd7bbe9d, 0x197d005a, -0x4d40b3b3, 0xcf203155, 0x0d2fa621, 0x752d2c58, -0xb12bac12, 0x1e7e8c23, 0x94215d54, 0x9854a71c, -0x4de63c64, 0x7a012529, 0x9c171f8d, 0x9e71def7, -0x3bd17d50, 0x11f175d9, 0xec78abf3, 0x7b529eee, -0xd3a69fc3, 0x5b718676, 0x58214d29, 0xa8bd2c34, -0x41ea00ab, 0xa03f64d6, 0x4ee342b0, 0x32b1e444, -0x1c1801a4, 0xc8424702, 0x334a7e35, 0x50cf1543, -0x3b22b495, 0x88683776, 0x8e2e0154, 0x6155c033, -0x4e2fa6ac, 0x42ace700, 0x8d64f97c, 0xaf9ced17, -0xb2a5cb92, 0xa558582d, 0x88705de7, 0x9e528d59, -0x84bd45e4, 0x5cb680c0, 0xcd48fa5c, 0x2722bfa2, -0x10462123, 0x30080f7d, 0xb346cd81, 0x0049c396, -0x4e24165f, 0xa7c66809, 0x2e60bdcf, 0xaad70a08, -0xa73ea713, 0xe28f97a7, 0x283a9eab, 0xd4366489, -0xe776f963, 0x64ffa8ae, 0xde717b50, 0xbd2ca2b5, -0x3bae5f6d, 0x8d2bbef1, 0x7e9181e6, 0xf06aa121, -0xd06b2d20, 0xa83ea826, 0xef935e4f, 0xdfd27456, -0xa3451468, 0xc6820a63, 0x43463105, 0x787697aa, -0xcba5543d, 0xdf7e1e2d, 0x6998a8af, 0x98ce6c08, -0x89de731a, 0x943a3510, 0xb36ead85, 0xd5258d4b, -0x1cd6df61, 0x82a5c59d, 0xd078e7a4, 0xa33d4317, -0x24dc45f8, 0x3f3daf27, 0x0478bc6f, 0x92dfa16c, -0x952a872e, 0x7a34e03f, 0x0f088084, 0xa40937fe, -0x38fc7749, 0xa157e8a4, 0xbce94344, 0x7045ff7b, -0xf3e1ab66, 0xe62a6058, 0x5564ff10, 0x38198f1e, -0xf326f0f1, 0xe262bc0c, 0x2f0b851a, 0xc7bcbe11, -0xe79f1d1a, 0xc2f93c29, 0x54f3ea9f, 0x8f8f9141, -0x9f45e13c, 0x7a5b86bd, 0xa764efd8, 0x35f04729, -0xdd8c4b54, 0x5fa12e51, 0xa5824af9, 0xad328f71, -0x0f11fbb9, 0x9048e950, 0x04d7a900, 0x02538d1f, -0x99f745b7, 0xe31f63bb, 0x2c4e3d78, 0x7cdb9245, -0xa3966ee7, 0x27c4433a, 0xe1d79f3e, 0xe640fa06, -0x79ce31eb, 0xf25634fa, 0xdd9ce5cb, 0xb7fab8d2, -0x2f1f0ff2, 0x2acb625c, 0xa0494989, 0x206d7f11, -0xf268b8ca, 0x292bbf9f, 0x763bd7d0, 0xea4b14fc, -0x9d3d6aeb, 0x64cca57e, 0x6fc3e29e, 0x3e7bf4bf, -0x90efc7e3, 0x08e39173, 0xd05bee2c, 0x5b3c8f37, -0x0921ec6f, 0x3371b715, 0xb324e114, 0xe3abc53f, -0x576b18f8, 0xc4469024, 0xb2ded6c6, 0xe7783782, -0xc0a1fd5d, 0xcf324bde, 0x97527c8e, 0x19f8f48c, -0x3e806a5d, 0x96cff225, 0xe3b9d04a, 0x0e5856ae, -0x781372f6, 0x9645f2b7, 0x95a743ed, 0xd0c7eded, -0x86ca3cd9, 0xbab94db0, 0x43a1233a, 0x89c55554, -0xee776239, 0x34aa0098, 0x66a6e1d4, 0xae0e233e, -0x717e7b29, 0xb403a4c1, 0x36eb96c5, 0x42140832, -0x04250936, 0xda375dca, 0x524cb2e6, 0x86deaa0c, -0x400dc9d1, 0x12c00364, 0xe3ca7cf5, 0x87f20da7, -0xf57df9ef, 0x580dbdfc, 0x0b3e0369, 0x014d27fd, -0x4afaf6a1, 0xd1f4ca09, 0x77abc831, 0x30e49729, -0xec61cd2c, 0x159c1e92, 0xb61b40b1, 0x17c66fd6, -0xde11c061, 0x79d7f792, 0xc709cbfa, 0x94201c89, -0xbe65137d, 0x18aea1b4, 0xf248bbc3, 0x465f957d, -0xcf4a9672, 0xbf293fd2, 0x2c5e31c9, 0xc2c73011, -0xfb29cbf2, 0x576f7f0b, 0x74de1745, 0xa76e172b, -0x99b96223, 0x14ce1502, 0x231013fb, 0x1d4df40a, -0x951b0c16, 0xab173e66, 0x4ff65f74, 0xc4a87a47, -0x09cc3370, 0x66385490, 0x73e09118, 0x4ee96432, -0x0164d347, 0x205069b5, 0x158dd226, 0xc932c238, -0xe9048fa2, 0x100b626a, 0x86ee08cd, 0xed87cb1c, -0x6353ec37, 0xa36edcc3, 0x8a16dd6b, 0xd28a4198, -0xebea1127, 0xca0b761a, 0x61c31acf, 0xced5ff4f, -0xbf4dbd8f, 0xd969d8a7, 0xb6e4e9e8, 0x8421c402, -0x809d7222, 0xabfd1d2f, 0xc1857ce5, 0x23958fd7, -0x3226f1d3, 0xd822b4cc, 0x2f1cc3aa, 0x501fe01e, -0xe36f8c94, 0x7ad27716, 0x3321308b, 0xa85b957b, -0x38cfdf6e, 0xc7497dd5, 0x2462090c, 0x8f9e42e7, -0xdf97684a, 0xac8af621, 0xd5224866, 0xc5f64e50, -0x9724f297, 0xc386097b, 0x48c6f98a, 0xe1478b1a, -0x2dd23fd8, 0x716b2d85, 0xa5c3789b, 0x53625e80, -0x9b8b312c, 0xce482165, 0x66161e35, 0x64ecb56a, -0x9981c46a, 0xe6cb6bb3, 0xe1983186, 0x75ed470f, -0x4adcbd27, 0x3efeda68, 0x4d193a2a, 0xbfdb3cd4, -0x7c6167b6, 0xdbddea68, 0x4b0d2d62, 0x00ba3860, -0x49ec2544, 0xa68698c9, 0x2ce7be1b, 0xf5afc9fc, -0x1cebf9c3, 0x350f8f5b, 0x893eefb8, 0x77414f6f, -0xe46f26fa, 0x67bf6398, 0xd6858f5d, 0xac73db2a, -0x58e20acc, 0x750dd76a, 0xb7930e80, 0x8a8796c0, -0x44c86997, 0xb1807742, 0x3c827dc1, 0x381aaa3c, -0x83ac76f3, 0x57f0a2d6, 0x18261009, 0xe107138f, -0x85711c22, 0x2e1d982f, 0x7062179a, 0xaedfa298, -0x62e438f2, 0x6d325a9a, 0x99b489d3, 0x1bf77b3a, -0x28ca20e8, 0x502d1b21, 0x74a833c0, 0xbeb91634, -0xf56ffef9, 0x05401164, 0xe5dbab51, 0x0a2b460d, -0x2f0d9c22, 0xc74472f9, 0x12da5199, 0x68b2d628, -0x9a118f9a, 0x9035d200, 0xcda0221f, 0x12430cde, -0x79a43fbb, 0x5bb5e1b7, 0xeab5ed62, 0xe6a11e32, -0x3118b0fa, 0xedbcfb64, 0xd2285490, 0x824023c6, -0x30311fb1, 0xa0a4a475, 0xbfa8ac55, 0xb8c8fbda, -0xdf3cab63, 0x8d805566, 0xf52c1b1a, 0xa3471090, -0x02328a4a, 0x5d1dce57, 0x196aea39, 0xcd0f640b, -0x2fa01c27, 0x6175f783, 0xb2b6a0e4, 0x02fe6171, -0x2d3cb20b, 0x25f331e6, 0xacfa8085, 0x46a09a58, -0x27bbfb9e, 0x3914f970, 0x73e35206, 0x8bb87194, -0xdb58fc4b, 0x62fd53ff, 0x2c942c7c, 0x3f4681ba, -0xeada1780, 0x5dfbb960, 0x8473948a, 0x80787902, -0x049c20ba, 0x9e95a4fc, 0x8526d8ac, 0x3dcdcd2d, -0xb9562f16, 0xc9c8eb08, 0x533ed0a2, 0xa34d5d73, -0x3e579c8e, 0x235bb378, 0x36576983, 0xc71f11b2, -0x035eae76, 0xbec23972, 0x8613e5e9, 0x3982899a, -0xe5a55d62, 0x3c45a7e9, 0xbd4d6def, 0x17ae0a5f, -0xf0f53bb8, 0xa3dd1e29, 0x36f9520b, 0x72cbd950, -0x4d762d12, 0xe03cb7a8, 0xf8c8c1fe, 0xa4ff17a1, -0xcc779472, 0x83f9b379, 0xa2fc038c, 0xdd3b8104, -0x95936bb0, 0xf36c9705, 0x93939e08, 0xc98576ac, -0xec9196d1, 0xc8bce622, 0xb48e1075, 0x98dbd77d, -0xd1b04c3d, 0x85d1d422, 0x20765885, 0xc6a17eb5, -0x8e913cdc, 0x3f7a6758, 0x08176f48, 0xba2ea15f, -0x3638114d, 0xf08cb49b, 0xb8b6d9ce, 0x4e55891a, -0x2775c022, 0xc8d45982, 0x529c2eb3, 0xde080e24, -0xdac9c028, 0xeec68934, 0x8eaace11, 0xe82e05aa, -0x00033a20, 0x4ec94b5e, 0x445f5562, 0xa5c58462, -0xb6942526, 0x44631607, 0x5065644c, 0x14946f9c, -0xa9cb0e63, 0x53dff50a, 0x3f18fa24, 0x20b3b811, -0x95c1e57b, 0x1523d301, 0xc4e24932, 0x41a9be80, -0x24fc45b0, 0xccff2cbc, 0x996af6a1, 0xe3f201c3, -0x0917ea23, 0xbf4a1ac3, 0xbb0db6f1, 0xd15772df, -0xb1465383, 0x61400275, 0x571f6b1d, 0x0a4407f7, -0x916cfbce, 0x114f042a, 0x1cb9b3a6, 0x1b34c85a, -0xe36acc8d, 0xab109469, 0x5af9a63a, 0xccd4defc, -0xb758adfd, 0xbd8ddecf, 0x5ffe8424, 0xd73e2a4b, -0xb41cb99e, 0x01a52553, 0xba70e749, 0xf81d7557, -0x2b4f0847, 0xa22e281f, 0x5c653c31, 0x89bdb546, -0xa596e592, 0xbca4cbf4, 0xc3d1dfe3, 0x64a21c2e, -0x159aa4b7, 0xed90f2d6, 0xb1164cb0, 0x86de0088, -0xfd4e49e6, 0x70702b0d, 0x946b532b, 0x03a0144e, -0x71fb19ed, 0x07c41763, 0x63312ce9, 0x0e2f5ee4, -0xc6501661, 0x09599e4e, 0x544fd5cc, 0x054d842c, -0x902bb57d, 0xdf82a365, 0xb7ae9427, 0xa6750881, -0xeee3c9cd, 0x6cbe0f45, 0x7f72d3f9, 0x430b786f, -0x162b6004, 0xbfcd440b, 0xdc4f5c81, 0x82249f6b, -0x98d1cdca, 0x2cc2692e, 0xf977f83a, 0x570c1e1f, -0x24ed6461, 0xcae5afea, 0x9cf06576, 0x9199d69c, -0x883febfe, 0x0f254c42, 0x6eb50978, 0xf91fade4, -0x9cfe5488, 0xfe3bf66b, 0x86ea94e3, 0x1bed23f5, -0x0bded397, 0x0cde064b, 0x7abd7a81, 0x8efb798e, -0x9a78e5f2, 0x7c46d76f, 0xcb3ae1ea, 0xc33e7ab1, -0x0c3993f0, 0x5b2d8de7, 0x24948ba8, 0xffce06e6, -0x0d3c2dc2, 0x3ae09142, 0x7e6b932e, 0xb3e22558, -0x9f7c425e, 0x8fa1329b, 0x24aa5012, 0xb9e49bc7, -0x787dd5a6, 0xf68c8171, 0x440d2146, 0x9734857f, -0x8c30c31a, 0xcb3352a1, 0x46b04f38, 0x72572ef8, -0xc90c56df, 0xe8103fa8, 0x04057577, 0xd1c250d9, -0x5cb390a9, 0xbdba74b9, 0x80012fa3, 0x408216c2, -0xadca83bc, 0x3c39bcdf, 0xf0da9459, 0x421d5a3d, -0xc5cf55c9, 0x2dcfa63d, 0xd852066b, 0x606b2204, -0x4d5e9576, 0xe8d6475f, 0xe46ec6b0, 0xf4e3c2c6, -0x1bfe1bb0, 0xc2803818, 0x2a3e4809, 0x947e50a1, -0x3a10e713, 0xc9e070cc, 0xa4244fe4, 0xa7f5d2e7, -0x194f77ee, 0x76754ab4, 0x75ed4e5f, 0x92ffdbaa, -0x1f5bce6a, 0x14aeeec7, 0x366fbb47, 0x44ecec7b, -0xbc31e911, 0xee6c224f, 0x0a6f7376, 0xbe79fce3, -0x53a18077, 0x6f6ad5fe, 0x945938bd, 0x61bb760c, -0xed26220f, 0x9f492f0a, 0xaf0f2d80, 0x265f5449, -0xae1f2dc3, 0xd235910c, 0x44a0f4a0, 0x36fcc004, -0x1e8fa223, 0xe7440ed0, 0xa8535548, 0x6d7e7029, -0x2e1b7968, 0xf3baa61d, 0xf447ef12, 0x701d62d6, -0x2da5dcf4, 0x44828196, 0x41af9c9a, 0xab210662, -0xa5ee18f2, 0xd45eb369, 0x947814fe, 0xeb62eb49, -0x30c555c6, 0xdc06ccbd, 0x786705d2, 0xd50c80d3, -0x266d8313, 0x68f63164, 0x1e3e4322, 0xfc23834e, -0xe879261f, 0x28992a8f, 0xab86dac9, 0x19f88d1a, -0x5110c867, 0x3c050155, 0xf9b1b3f5, 0x98909489, -0xfa0ee6bc, 0x038fb4ce, 0xbe1c9e33, 0x18f96bcd, -0xa1635c9a, 0xff3e9374, 0x5b033171, 0x0b84bfd9, -0x3c091bae, 0x6da61a4e, 0x07d81b5d, 0x3904ea3c, -0x75f4e7f1, 0x3e70c12e, 0x9c70d835, 0x9a1ea5a6, -0x4b99b705, 0x08f6ab89, 0x7649901c, 0xee3e7687, -0xa3deb48c, 0xd74e8c78, 0xe8e120c3, 0x425d3d96, -0x16f136bd, 0x0c7a32ef, 0x37a0ff53, 0x77b035e4, -0xba8808c1, 0x1d3d8330, 0x8d224cce, 0xed789fed, -0x550a8352, 0xe2715912, 0x185f62d1, 0xe301002a, -0xbe2ed99b, 0xbb1dfd60, 0x9d22d8f9, 0xcbfa36d5, -0xad7e92e0, 0xd2db61d4, 0x1df386f5, 0x92b5797c, -0x00ac8ed1, 0x2f7470b1, 0x674e258b, 0x6689df79, -0x135c5c1a, 0x87abbc50, 0x19ac082b, 0xe7f7d64c, -0x24fd4922, 0x7eeadc29, 0xa0910eaa, 0x763231d6, -0x23597ccb, 0x332f33c3, 0x93992b6a, 0x19c8937c, -0x75d6a9f4, 0x221395e1, 0x662914d0, 0x997d7860, -0xd196adeb, 0xa5402fd9, 0x8bd6f12f, 0xc31d97e0, -0x304dd9dc, 0x72f35c72, 0x8ced870e, 0x1eef8a14, -0x323321fa, 0xf193079f, 0x18026b1c, 0x5a1107a5, -0x54979f4b, 0x6afee492, 0x04c012e6, 0x3446250c, -0x25a691a8, 0xc19a76ea, 0x66bd5b14, 0x6250bd2d, -0xc6c082d9, 0x67ea1d78, 0xbe68a7ef, 0x03f50dc8, -0xd8f76566, 0xb6681752, 0x00e2b087, 0x7ed2e598, -0x8c9cbc83, 0x103b03f5, 0xee4d2723, 0x67b3903f, -0x1e057dec, 0xc5703ba6, 0xae0615f9, 0x1bce0df2, -0xfd041279, 0xc874a2c3, 0x0a91d2fa, 0xac098457, -0xc1efc5f9, 0xd48208eb, 0x72e9baa8, 0x184dc658, -0x3d26b8b4, 0x90e2469d, 0x6d07f351, 0x3f6898a7, -0x21e4de0b, 0x0fd04a43, 0x2c99cd2b, 0x44b28cdd, -0xaf5483a5, 0xe50b9a12, 0xd98fe031, 0x9d6e8f08, -0xf385ba19, 0x5e531cb0, 0xc545867a, 0x65f5ebf5, -0x9f27ad5a, 0x2de11f0d, 0xef6f0970, 0x973b11f2, -0x72228c07, 0xe13fdb84, 0xd2a7b46f, 0xc85a38db, -0x331a9807, 0x3be38ebc, 0x3e7bf15d, 0xa82a1e68, -0x4b42b5bc, 0x9871203e, 0x7d1e1e24, 0x12f57b6b, -0xf5403ec8, 0x28746c33, 0xae20522f, 0xf6042fba, -0x66bada5d, 0xbefe376f, 0xfd3773a5, 0xbb5fc6e8, -0x34c0433d, 0x3cfc83e9, 0xd096736a, 0xa53be016, -0xeba3dd6c, 0x2c626561, 0x3c160c8d, 0x8506c719, -0x802e7b47, 0x16079396, 0x6d29b175, 0x4e91abb4, -0xe350ce95, 0x0d481aa5, 0x94e95371, 0x10dc4dec, -0xbfeb3735, 0x3ce3cb4d, 0x32ff742a, 0xac5ad3cb, diff --git a/usr/src/cmd/varpd/Makefile b/usr/src/cmd/varpd/Makefile new file mode 100644 index 0000000000..ea37ac6f71 --- /dev/null +++ b/usr/src/cmd/varpd/Makefile @@ -0,0 +1,75 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2018 Joyent, Inc. +# + +PROG= varpd +OBJS = varpd.o +SRCS = $(OBJS:%.o=../%.c) +MANIFEST = varpd.xml +ROOTLIBVARPD = $(ROOTLIB)/varpd +ROOTLIBVARPDPROG= $(PROG:%=$(ROOTLIBVARPD)/%) + + +include ../Makefile.cmd +include ../Makefile.ctf + +ROOTMANIFESTDIR= $(ROOTSVCNETWORK) + +CLEANFILES += $(OBJS) +CPPFLAGS += -D_REENTRANT +CFLAGS += $(CCVERBOSE) +LDLIBS += -lvarpd -lumem -lscf +$(NOT_RELEASE_BUILD)CPPFLAGS += -DDEBUG + +# +# Our debug only umem related functions cause lint to get confused. +# +LINTFLAGS += -erroff=E_NAME_DEF_NOT_USED2 + +C99MODE= -xc99=%all +C99LMODE= -Xc99=%all + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) + +clean: + -$(RM) $(CLEANFILES) + +lint: lint_PROG + +%.o: ../%.c + $(COMPILE.c) $< + $(POST_PROCESS_O) + +check: $(CHKMANIFEST) + +clobber: clean + $(RM) $(PROG) + +install: $(PROG) $(ROOTLIBVARPDPROG) $(ROOTMANIFEST) + +$(ROOTLIBVARPD): + $(INS.dir) + +$(ROOTLIBVARPD)/%: % $(ROOTLIBVARPD) + $(INS.file) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/cmd/varpd/varpd.c b/usr/src/cmd/varpd/varpd.c new file mode 100644 index 0000000000..896f39733a --- /dev/null +++ b/usr/src/cmd/varpd/varpd.c @@ -0,0 +1,526 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2018 Joyent, Inc. + */ + +/* + * virtual arp daemon -- varpd + * + * The virtual arp daemon is the user land counterpart to the overlay driver. To + * truly understand its purpose and how it fits into things, you should read the + * overlay big theory statement in uts/common/io/overlay/overlay.c. + * + * varod's purpose it to provide a means for looking up the destination on the + * underlay network for a host on an overlay network and to also be a door + * server such that dladm(1M) via libdladm can configure and get useful status + * information. The heavy lifting is all done by libvarpd and the various lookup + * plugins. + * + * When varpd first starts up, we take of chdiring into /var/run/varpd, which is + * also where we create /var/run/varpd.door, our door server. After that we + * daemonize and only after we daemonize do we go ahead and load plugins. The + * reason that we don't load plugins before daemonizing is that they could very + * well be creating threads and thus lose them all. In general, we want to make + * things easier on our children and not require them to be fork safe. + * + * Once it's spun up, the main varpd thread sits in sigsuspend and really just + * hangs out waiting for something, libvarpd handles everything else. + */ + +#include <libvarpd.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <libgen.h> +#include <stdarg.h> +#include <stdlib.h> +#include <paths.h> +#include <limits.h> +#include <sys/corectl.h> +#include <signal.h> +#include <strings.h> +#include <sys/wait.h> +#include <unistd.h> +#include <thread.h> +#include <priv.h> +#include <libscf.h> + +#define VARPD_EXIT_REQUESTED SMF_EXIT_OK +#define VARPD_EXIT_FATAL SMF_EXIT_ERR_FATAL +#define VARPD_EXIT_USAGE SMF_EXIT_ERR_CONFIG + +#define VARPD_RUNDIR "/var/run/varpd" +#define VARPD_DEFAULT_DOOR "/var/run/varpd/varpd.door" + +#define VARPD_PG "varpd" +#define VARPD_PROP_INC "include_path" + +static varpd_handle_t *varpd_handle; +static const char *varpd_pname; +static volatile boolean_t varpd_exit = B_FALSE; + +/* + * Debug builds are automatically wired up for umem debugging. + */ +#ifdef DEBUG +const char * +_umem_debug_init() +{ + return ("default,verbose"); +} + +const char * +_umem_logging_init(void) +{ + return ("fail,contents"); +} +#endif /* DEBUG */ + +static void +varpd_vwarn(FILE *out, const char *fmt, va_list ap) +{ + int error = errno; + + (void) fprintf(out, "%s: ", varpd_pname); + (void) vfprintf(out, fmt, ap); + + if (fmt[strlen(fmt) - 1] != '\n') + (void) fprintf(out, ": %s\n", strerror(error)); +} + +static void +varpd_fatal(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + varpd_vwarn(stderr, fmt, ap); + va_end(ap); + + exit(VARPD_EXIT_FATAL); +} + +static void +varpd_dfatal(int dfd, const char *fmt, ...) +{ + int status = VARPD_EXIT_FATAL; + va_list ap; + + va_start(ap, fmt); + varpd_vwarn(stdout, fmt, ap); + va_end(ap); + + /* Take a single shot at this */ + (void) write(dfd, &status, sizeof (status)); + exit(status); +} + +/* ARGSUSED */ +static int +varpd_plugin_walk_cb(varpd_handle_t *vph, const char *name, void *unused) +{ + (void) printf("loaded %s!\n", name); + return (0); +} + +static int +varpd_dir_setup(void) +{ + int fd; + + if (mkdir(VARPD_RUNDIR, 0700) != 0) { + if (errno != EEXIST) + varpd_fatal("failed to create %s: %s", VARPD_RUNDIR, + strerror(errno)); + } + + fd = open(VARPD_RUNDIR, O_RDONLY); + if (fd < 0) + varpd_fatal("failed to open %s: %s", VARPD_RUNDIR, + strerror(errno)); + + if (fchown(fd, UID_NETADM, GID_NETADM) != 0) + varpd_fatal("failed to chown %s: %s\n", VARPD_RUNDIR, + strerror(errno)); + + return (fd); +} + +/* + * Because varpd is generally run under SMF, we opt to keep its stdout and + * stderr to be whatever our parent set them up to be. + */ +static void +varpd_fd_setup(void) +{ + int dupfd; + + closefrom(STDERR_FILENO + 1); + dupfd = open(_PATH_DEVNULL, O_RDONLY); + if (dupfd < 0) + varpd_fatal("failed to open %s: %s", _PATH_DEVNULL, + strerror(errno)); + if (dup2(dupfd, STDIN_FILENO) == -1) + varpd_fatal("failed to dup out stdin: %s", strerror(errno)); +} + +/* + * We borrow fmd's daemonization style. Basically, the parent waits for the + * child to successfully set up a door and recover all of the old configurations + * before we say that we're good to go. + */ +static int +varpd_daemonize(int dirfd) +{ + char path[PATH_MAX]; + struct rlimit rlim; + sigset_t set, oset; + int estatus, pfds[2]; + pid_t child; + priv_set_t *pset; + + /* + * Set a per-process core path to be inside of /var/run/varpd. Make sure + * that we aren't limited in our dump size. + */ + (void) snprintf(path, sizeof (path), + "/var/run/varpd/core.%s.%%p", varpd_pname); + (void) core_set_process_path(path, strlen(path) + 1, getpid()); + + rlim.rlim_cur = RLIM_INFINITY; + rlim.rlim_max = RLIM_INFINITY; + (void) setrlimit(RLIMIT_CORE, &rlim); + + /* + * Claim as many file descriptors as the system will let us. + */ + if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) { + rlim.rlim_cur = rlim.rlim_max; + (void) setrlimit(RLIMIT_NOFILE, &rlim); + } + + /* + * chdir /var/run/varpd + */ + if (fchdir(dirfd) != 0) + varpd_fatal("failed to chdir to %s", VARPD_RUNDIR); + + + /* + * At this point block all signals going in so we don't have the parent + * mistakingly exit when the child is running, but never block SIGABRT. + */ + if (sigfillset(&set) != 0) + abort(); + if (sigdelset(&set, SIGABRT) != 0) + abort(); + if (sigprocmask(SIG_BLOCK, &set, &oset) != 0) + abort(); + + /* + * Do the fork+setsid dance. + */ + if (pipe(pfds) != 0) + varpd_fatal("failed to create pipe for daemonizing"); + + if ((child = fork()) == -1) + varpd_fatal("failed to fork for daemonizing"); + + if (child != 0) { + /* We'll be exiting shortly, so allow for silent failure */ + (void) close(pfds[1]); + if (read(pfds[0], &estatus, sizeof (estatus)) == + sizeof (estatus)) + _exit(estatus); + + if (waitpid(child, &estatus, 0) == child && WIFEXITED(estatus)) + _exit(WEXITSTATUS(estatus)); + + _exit(VARPD_EXIT_FATAL); + } + + /* + * Drop privileges here. + * + * We should make sure we keep around PRIV_NET_PRIVADDR and + * PRIV_SYS_DLCONFIG, but drop everything else; however, keep basic + * privs and have our child drop them. + * + * We should also run as netadm:netadm and drop all of our groups. + */ + if (setgroups(0, NULL) != 0) + abort(); + if (setgid(GID_NETADM) == -1 || seteuid(UID_NETADM) == -1) + abort(); + if ((pset = priv_allocset()) == NULL) + abort(); + priv_basicset(pset); + if (priv_delset(pset, PRIV_PROC_EXEC) == -1 || + priv_delset(pset, PRIV_PROC_INFO) == -1 || + priv_delset(pset, PRIV_PROC_FORK) == -1 || + priv_delset(pset, PRIV_PROC_SESSION) == -1 || + priv_delset(pset, PRIV_FILE_LINK_ANY) == -1 || + priv_addset(pset, PRIV_SYS_DL_CONFIG) == -1 || + priv_addset(pset, PRIV_NET_PRIVADDR) == -1) { + abort(); + } + /* + * Remove privs from the permitted set. That will cause them to be + * removed from the effective set. We want to make sure that in the case + * of a vulnerability, something can't get back in here and wreak more + * havoc. But if we want non-basic privs in the effective set, we have + * to request them explicitly. + */ + if (setppriv(PRIV_SET, PRIV_PERMITTED, pset) == -1) + abort(); + if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pset) == -1) + abort(); + + priv_freeset(pset); + + if (close(pfds[0]) != 0) + abort(); + if (setsid() == -1) + abort(); + if (sigprocmask(SIG_SETMASK, &oset, NULL) != 0) + abort(); + (void) umask(0022); + + return (pfds[1]); +} + +static int +varpd_setup_lookup_threads(void) +{ + int ret; + long i, ncpus = sysconf(_SC_NPROCESSORS_ONLN) * 2 + 1; + + if (ncpus <= 0) + abort(); + for (i = 0; i < ncpus; i++) { + thread_t thr; + + ret = thr_create(NULL, 0, + (void *(*)(void *))libvarpd_overlay_lookup_run, + varpd_handle, THR_DETACHED | THR_DAEMON, &thr); + if (ret != 0) + return (ret); + } + + return (0); +} + +static void +varpd_cleanup(void) +{ + varpd_exit = B_TRUE; +} + +/* + * Load default information from SMF and apply any of if necessary. We recognize + * the following properties: + * + * varpd/include_path Treat these as a series of -i options. + * + * If we're not under SMF, just move on. + */ +static void +varpd_load_smf(int dfd) +{ + char *fmri, *inc; + scf_simple_prop_t *prop; + + if ((fmri = getenv("SMF_FMRI")) == NULL) + return; + + if ((prop = scf_simple_prop_get(NULL, fmri, VARPD_PG, + VARPD_PROP_INC)) == NULL) + return; + + while ((inc = scf_simple_prop_next_astring(prop)) != NULL) { + int err = libvarpd_plugin_load(varpd_handle, inc); + if (err != 0) { + varpd_dfatal(dfd, "failed to load from %s: %s\n", + inc, strerror(err)); + } + } + + scf_simple_prop_free(prop); +} + +/* + * There are a bunch of things we need to do to be a proper daemon here. + * + * o Ensure that /var/run/varpd exists or create it + * o make stdin /dev/null (stdout?) + * o Ensure any other fds that we somehow inherited are closed, eg. + * closefrom() + * o Properly daemonize + * o Mask all signals except sigabrt before creating our first door -- all + * other doors will inherit from that. + * o Have the main thread sigsuspend looking for most things that are + * actionable... + */ +int +main(int argc, char *argv[]) +{ + int err, c, dirfd, dfd, i; + const char *doorpath = VARPD_DEFAULT_DOOR; + sigset_t set; + struct sigaction act; + int nincpath = 0, nextincpath = 0; + char **incpath = NULL; + + varpd_pname = basename(argv[0]); + + /* + * We want to clean up our file descriptors before we do anything else + * as we can't assume that libvarpd won't open file descriptors, etc. + */ + varpd_fd_setup(); + + if ((err = libvarpd_create(&varpd_handle)) != 0) { + varpd_fatal("failed to open a libvarpd handle"); + return (1); + } + + while ((c = getopt(argc, argv, ":i:d:")) != -1) { + switch (c) { + case 'i': + if (nextincpath == nincpath) { + if (nincpath == 0) + nincpath = 16; + else + nincpath *= 2; + incpath = realloc(incpath, sizeof (char *) * + nincpath); + if (incpath == NULL) { + (void) fprintf(stderr, "failed to " + "allocate memory for the %dth " + "-I option: %s\n", nextincpath + 1, + strerror(errno)); + } + + } + incpath[nextincpath] = optarg; + nextincpath++; + break; + case 'd': + doorpath = optarg; + break; + default: + (void) fprintf(stderr, "unknown option: %c\n", c); + return (1); + } + } + + dirfd = varpd_dir_setup(); + + (void) libvarpd_plugin_walk(varpd_handle, varpd_plugin_walk_cb, NULL); + + dfd = varpd_daemonize(dirfd); + + /* + * Now that we're in the child, go ahead and load all of our plug-ins. + * We do this, in part, because these plug-ins may need threads of their + * own and fork won't preserve those and we'd rather the plug-ins don't + * have to learn about fork-handlers. + */ + for (i = 0; i < nextincpath; i++) { + err = libvarpd_plugin_load(varpd_handle, incpath[i]); + if (err != 0) { + varpd_dfatal(dfd, "failed to load from %s: %s\n", + incpath[i], strerror(err)); + } + } + + varpd_load_smf(dfd); + + if ((err = libvarpd_persist_enable(varpd_handle, VARPD_RUNDIR)) != 0) + varpd_dfatal(dfd, "failed to enable varpd persistence: %s\n", + strerror(err)); + + if ((err = libvarpd_persist_restore(varpd_handle)) != 0) + varpd_dfatal(dfd, "failed to enable varpd persistence: %s\n", + strerror(err)); + + /* + * The ur-door thread will inherit from this signal mask. So set it to + * what we want before doing anything else. In addition, so will our + * threads that handle varpd lookups. + */ + if (sigfillset(&set) != 0) + varpd_dfatal(dfd, "failed to fill a signal set..."); + + if (sigdelset(&set, SIGABRT) != 0) + varpd_dfatal(dfd, "failed to unmask SIGABRT"); + + if (sigprocmask(SIG_BLOCK, &set, NULL) != 0) + varpd_dfatal(dfd, "failed to set our door signal mask"); + + if ((err = varpd_setup_lookup_threads()) != 0) + varpd_dfatal(dfd, "failed to create lookup threads: %s\n", + strerror(err)); + + if ((err = libvarpd_door_server_create(varpd_handle, doorpath)) != 0) + varpd_dfatal(dfd, "failed to create door server at %s: %s\n", + doorpath, strerror(err)); + + /* + * At this point, finish up signal intialization and finally go ahead, + * notify the parent that we're okay, and enter the sigsuspend loop. + */ + bzero(&act, sizeof (struct sigaction)); + act.sa_handler = varpd_cleanup; + if (sigfillset(&act.sa_mask) != 0) + varpd_dfatal(dfd, "failed to fill sigaction mask"); + act.sa_flags = 0; + if (sigaction(SIGHUP, &act, NULL) != 0) + varpd_dfatal(dfd, "failed to register HUP handler"); + if (sigdelset(&set, SIGHUP) != 0) + varpd_dfatal(dfd, "failed to remove HUP from mask"); + if (sigaction(SIGQUIT, &act, NULL) != 0) + varpd_dfatal(dfd, "failed to register QUIT handler"); + if (sigdelset(&set, SIGQUIT) != 0) + varpd_dfatal(dfd, "failed to remove QUIT from mask"); + if (sigaction(SIGINT, &act, NULL) != 0) + varpd_dfatal(dfd, "failed to register INT handler"); + if (sigdelset(&set, SIGINT) != 0) + varpd_dfatal(dfd, "failed to remove INT from mask"); + if (sigaction(SIGTERM, &act, NULL) != 0) + varpd_dfatal(dfd, "failed to register TERM handler"); + if (sigdelset(&set, SIGTERM) != 0) + varpd_dfatal(dfd, "failed to remove TERM from mask"); + + err = 0; + (void) write(dfd, &err, sizeof (err)); + (void) close(dfd); + + for (;;) { + if (sigsuspend(&set) == -1) + if (errno == EFAULT) + abort(); + if (varpd_exit == B_TRUE) + break; + } + + libvarpd_door_server_destroy(varpd_handle); + libvarpd_destroy(varpd_handle); + + return (VARPD_EXIT_REQUESTED); +} diff --git a/usr/src/cmd/varpd/varpd.xml b/usr/src/cmd/varpd/varpd.xml new file mode 100644 index 0000000000..df7015a3d6 --- /dev/null +++ b/usr/src/cmd/varpd/varpd.xml @@ -0,0 +1,67 @@ +<?xml version="1.0"?> +<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> +<!-- +This file and its contents are supplied under the terms of the +Common Development and Distribution License ("CDDL"), version 1.0. +You may only use this file in accordance with the terms of version +1.0 of the CDDL. + +A full copy of the text of the CDDL should have accompanied this +source. A copy of the CDDL is also available via the Internet at +http://www.illumos.org/license/CDDL. + +Copyright 2018, Joyent, Inc. +--> + +<service_bundle type="manifest" name="illumos:varpd" > + + <service name="network/varpd" type="service" version="1" > + + <create_default_instance enabled="true" /> + + <single_instance/> + + <dependency name="varpd-network-physical" + grouping="require_all" + restart_on="none" + type="service"> + <service_fmri value="svc:/network/physical:default" /> + </dependency> + + <dependency name="varpd-device-local" + grouping="require_all" + restart_on="none" + type="service"> + <service_fmri value="svc:/system/device/local:default" /> + </dependency> + + <exec_method + type="method" + name="start" + exec="/usr/lib/varpd/varpd" + timeout_seconds="60" /> + + <exec_method + type="method" + name="stop" + exec=":kill" + timeout_seconds="10" /> + + <property_group name='varpd' type='application'> + <property name='include_path' type='astring'> + <astring_list> + <value_node value='/usr/lib/varpd'/> + </astring_list> + </property> + </property_group> + + <stability value='Unstable' /> + + <template> + <common_name> + <loctext xml:lang="C">virtual ARP daemon + </loctext> + </common_name> + </template> + </service> +</service_bundle> diff --git a/usr/src/cmd/vi/port/Makefile b/usr/src/cmd/vi/port/Makefile index c74e8cbdbc..56cb0ca527 100644 --- a/usr/src/cmd/vi/port/Makefile +++ b/usr/src/cmd/vi/port/Makefile @@ -79,6 +79,9 @@ $(XPG6) := CFLAGS += -DXPG4 -DXPG6 -I$(SRC)/lib/libc/inc CPPFLAGS += -DUSG -DSTDIO -DVMUNIX -DTABS=8 -DSINGLE -DTAG_STACK +# vi intentionally uses foo[-1] as a sentinal value to q*column() +$(__GNUC4)CERRWARN += -_gcc=-Wno-array-bounds + # vi maintains its own versions of various routines from libc and libcurses, # so localize all symbols to avoid name space collisions. LDFLAGS += $(MAPFILE.NGB:%=-M%) diff --git a/usr/src/cmd/vi/port/ex_cmdsub.c b/usr/src/cmd/vi/port/ex_cmdsub.c index 9004ac7271..7e2cd4740d 100644 --- a/usr/src/cmd/vi/port/ex_cmdsub.c +++ b/usr/src/cmd/vi/port/ex_cmdsub.c @@ -1740,7 +1740,7 @@ char *prompt; /* In ex mode, let the system hassle with setting no echo */ if (!inopen) - return (unsigned char *)getpass(prompt); + return (unsigned char *)getpass((const char *)prompt); viprintf("%s", prompt); flush(); for (p=pbuf; (c = getkey())!='\n' && c!=EOF && c!='\r';) { if (p < &pbuf[8]) diff --git a/usr/src/cmd/vndadm/Makefile b/usr/src/cmd/vndadm/Makefile new file mode 100644 index 0000000000..2b9ca6c3c1 --- /dev/null +++ b/usr/src/cmd/vndadm/Makefile @@ -0,0 +1,67 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2018 Joyent, Inc. All rights reserved. +# + +PROG= vndadm +OBJS = vndadm.o +SRCS = $(OBJS:%.o=../%.c) + + +include ../Makefile.cmd +include ../Makefile.ctf + +CLEANFILES += $(OBJS) +CFLAGS += $(CCVERBOSE) +LDLIBS += -lvnd +LINTFLAGS += -xerroff=E_NAME_DEF_NOT_USED2 +C99MODE= -xc99=%all +C99LMODE= -Xc99=%all + +all := TARGET += all +clean := TARGET += clean +clobber := TARGET += clobber +install := TARGET += install +lint := TARGET += lint + +SUBDIRS = test + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) + +clean: $(SUBDIRS) + -$(RM) $(CLEANFILES) + +lint: lint_PROG $(SUBDIRS) + +%.o: ../%.c + $(COMPILE.c) $< + $(POST_PROCESS_O) + +clobber: clean $(SUBDIRS) + $(RM) $(PROG) + +install: $(PROG) $(ROOTUSRSBINPROG) $(SUBDIRS) + + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/cmd/vndadm/test/Makefile b/usr/src/cmd/vndadm/test/Makefile new file mode 100644 index 0000000000..12ef2c3a3c --- /dev/null +++ b/usr/src/cmd/vndadm/test/Makefile @@ -0,0 +1,19 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +SUBDIRS = scripts tst + +include Makefile.subdirs +include Makefile.com diff --git a/usr/src/cmd/vndadm/test/Makefile.com b/usr/src/cmd/vndadm/test/Makefile.com new file mode 100644 index 0000000000..cb096952ca --- /dev/null +++ b/usr/src/cmd/vndadm/test/Makefile.com @@ -0,0 +1,43 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +include $(SRC)/Makefile.master +include $(SRC)/cmd/Makefile.cmd + +# +# Force c99 for everything +# +C99MODE= -xc99=%all +C99LMODE= -Xc99=%all + +# +# Deal with odd lint bits. +# +LINTFLAGS += -xerroff=E_NAME_DEF_NOT_USED2 + +# +# Install related definitions +# +ROOTOPTPKG = $(ROOT)/opt/vndtest +ROOTBIN = $(ROOTOPTPKG)/bin +ROOTTST = $(ROOTOPTPKG)/tst +ROOTTSTDIR = $(ROOTTST)/$(TSTDIR) +ROOTTSTEXES = $(EXETESTS:%=$(ROOTTSTDIR)/%) +ROOTTSTSH = $(SHTESTS:%=$(ROOTTSTDIR)/%) +ROOTOUT = $(OUTFILES:%=$(ROOTTSTDIR)/%) +ROOTTESTS = $(ROOTTSTEXES) $(ROOTTSTSH) $(ROOTOUT) +FILEMODE = 0555 +LDLIBS = $(LDLIBS.cmd) +LINTEXE = $(EXETESTS:%.exe=%.exe.ln) diff --git a/usr/src/cmd/vndadm/test/Makefile.subdirs b/usr/src/cmd/vndadm/test/Makefile.subdirs new file mode 100644 index 0000000000..957448c23b --- /dev/null +++ b/usr/src/cmd/vndadm/test/Makefile.subdirs @@ -0,0 +1,29 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +.KEEP_STATE: + +all := TARGET += all +clean := TARGET += clean +clobber := TARGET += clobber +install := TARGET += install +lint := TARGET += lint + +all clean clobber install lint: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/cmd/vndadm/test/Makefile.targ b/usr/src/cmd/vndadm/test/Makefile.targ new file mode 100644 index 0000000000..bcbd3c8f35 --- /dev/null +++ b/usr/src/cmd/vndadm/test/Makefile.targ @@ -0,0 +1,59 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +$(ROOTOPTPKG): + $(INS.dir) + +$(ROOTBIN): $(ROOTOPTPKG) + $(INS.dir) + +$(ROOTBIN)/%: %.ksh $(ROOTBIN) + $(INS.rename) + +$(ROOTTST): $(ROOTOPTPKG) + $(INS.dir) + +$(ROOTTSTDIR): $(ROOTTST) + $(INS.dir) + +$(ROOTTSTDIR)/%.ksh: %.ksh $(ROOTTSTDIR) + $(INS.file) + +$(ROOTTSTDIR)/%.out: %.out $(ROOTTSTDIR) + $(INS.file) + +%.o: %.c + $(COMPILE.c) $< + $(POST_PROCESS_O) + +%.exe: %.o $(SUPOBJS) + $(LINK.c) -o $@ $< $(SUPOBJS) $(LDLIBS) + $(POST_PROCESS) + +$(ROOTTSTDIR)/%.exe: %.exe $(ROOTTSTDIR) + $(INS.file) + +all: install + +%.exe.ln: %.c $(SUPOBJS) + $(LINT.c) $< $(LDLIBS) + +lint: $(LINTEXE) + +clean: + -$(RM) *.o $(CLEANFILES) + +clobber: clean + -$(RM) $(CLOBBERFILES) diff --git a/usr/src/cmd/vndadm/test/scripts/Makefile b/usr/src/cmd/vndadm/test/scripts/Makefile new file mode 100644 index 0000000000..d0f58918f9 --- /dev/null +++ b/usr/src/cmd/vndadm/test/scripts/Makefile @@ -0,0 +1,28 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +include ../Makefile.com + +SRCS = vndtest +SCRIPTS = $(SRCS:%=$(ROOTBIN)/%) + +SCRIPTS := FILEMODE = 0555 +CLOBBERFILES = $(SCRIPTS) + +install: $(SCRIPTS) + +lint: + +include ../Makefile.targ diff --git a/usr/src/cmd/vndadm/test/scripts/vndtest.ksh b/usr/src/cmd/vndadm/test/scripts/vndtest.ksh new file mode 100755 index 0000000000..1167a64802 --- /dev/null +++ b/usr/src/cmd/vndadm/test/scripts/vndtest.ksh @@ -0,0 +1,300 @@ +#!/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014, Joyent, Inc. +# + +# +# vnd test suite driver +# +unalias -a + +vt_arg0=$(basename $0) +vt_root="$(dirname $0)/.." +vt_ksh="/usr/bin/ksh" +vt_outdir= +vt_keep= +vt_all= +vt_tests= +vt_stub= +vt_vnics="vndtest1 vndtest2 vndtest3 vndtest4 vndtest5" +vt_tnum=0 +vt_tfail=0 +vt_tsuc=0 + +function usage +{ + typeset msg="$*" + [[ -z "$msg" ]] || echo "$msg" 2>&1 + cat <<USAGE >&2 +Usage: $vt_arg0 [ -o dir ] [ -k ] [ -a | test ... ] + + -o dir Sets 'dir' as the output directory + -a Runs all tests, ignores tests passed in + -k Keep output from all tests, not just failures + -m mdb binary to test +USAGE + exit 2 +} + +function fatal +{ + typeset msg="$*" + [[ -z "$msg" ]] && msg="failed" + echo "$vt_arg0: $msg" >&2 + exit 1 +} + +function setup_outdir +{ + vt_outdir="$vt_outdir/$vt_arg0.$$" + mkdir -p $vt_outdir || fatal "failed to make output dir $vt_outdir" +} + +function setup_etherstub +{ + vt_ether="vndstub$$" + + dladm create-etherstub -t $vt_ether || \ + fatal "failed to create etherstub" +} + +function cleanup_vnd +{ + typeset over=$1 + typeset vnddevs vn + + vnddevs=$(vndadm list -p -d: -o datalink,name) + [[ $? -eq 0 ]] || fatal "failed to list vnics" + for v in $vnddevs; do + vn=$(echo $v | awk 'BEGIN{ FS=":"} + { if ($1 == targ) { print $2 } }' targ=$over) + [[ -z "$vn" ]] && continue + vndadm destroy $vn || fatal "failed to destroy $vn" + done +} + +function create_vnics +{ + for n in $vt_vnics; do + dladm create-vnic -t -l $vt_ether $n || fatal \ + "failed to create vnic $n over $vt_ether" + done +} + +function cleanup_vnics +{ + typeset nics vn + + nics=$(dladm show-vnic -p -o over,link) + [[ $? -eq 0 ]] || fatal "failed to list vnics" + for n in $nics; do + vn=$(echo $n | awk 'BEGIN{ FS=":"} + { if ($1 == targ) { print $2 } }' targ=$vt_ether ) + [[ -z "$vn" ]] && continue + cleanup_vnd $vn + # + # There may or may not be an IP device on our nics... + # + ifconfig $vn down unplumb 2>/dev/null || /bin/true + dladm delete-vnic $vn || fatal "failed to delete vnic $n" + done + +} + +function cleanup_etherstub +{ + cleanup_vnics + dladm delete-etherstub -t $vt_ether || \ + fatal "failed to delete etherstub" +} + +function run_single +{ + typeset name=$1 + typeset expect base ext exe command odir res reason + typeset iserr + + [[ -z "$name" ]] && fail "missing test to run" + base=${name##*/} + ext=${base##*.} + expect=${base%%.*} + odir="$vt_outdir/current" + [[ -z "$ext" ]] && fatal "found test without ext: $name" + [[ -z "$expect" ]] && fatal "found test without prefix: $name" + + [[ "$expect" == "create" || "$expect" == "ecreate" ]] && create_vnics + if [[ "$expect" == "err" || "$expect" == "ecreate" ]]; then + iserr="yup" + else + iserr="" + fi + + case "$ext" in + "ksh") + command="$vt_ksh ./$base" + ;; + "exe") + command="./$base" + ;; + "out") + # + # This is the file format for checking output against. + # + return 0 + ;; + *) + echo "skipping test $name (unknown extensino)" + return 0 + ;; + esac + + echo "Executing test $name ... \c" + mkdir -p "$odir" >/dev/null || fatal "can't make output directory" + cd $(dirname $name) || fatal "failed to enter test directory" + $command $vt_vnics > "$odir/stdout" 2>"$odir/stderr" + res=$? + cd - > /dev/null || fatal "failed to leave test directory" + + if [[ -f "$name.out" ]] && \ + ! diff "$name.out" "$odir/stdout" >/dev/null; then + cp $name.out $odir/$base.out + reason="stdout mismatch" + elif [[ -n "$iserr" && $res -eq 0 ]]; then + reason="test exited $res, not non-zero" + elif [[ -z "$iserr" && $res -ne 0 ]]; then + reason="test exited $res, not zero" + fi + + if [[ -n "$reason" ]]; then + echo "$reason" + ((vt_tfail++)) + mv "$odir" "$vt_outdir/failure.$vt_tfail" || fatal \ + "failed to move test output directory" + cp "$name" "$vt_outdir/failure.$vt_tfail/$(basename $name)" || \ + fatal "failed to copy test into output directory" + else + echo "passed" + ((vt_tsuc++)) + mv "$odir" "$vt_outdir/success.$vt_tsuc" || fatal \ + "failed to move test directory" + fi + + [[ "$expect" == "create" || "$expect" == "ecreate" ]] && cleanup_vnics + + ((vt_tnum++)) +} + +function run_all +{ + typeset tests t dir + + cd $vt_root || fatal "failed to enter root test directory" + tests=$(ls -1 */*/@(ecreate|create|tst|err).*.@(ksh|exe)) + cd - > /dev/null + for t in $tests; do + run_single $t + done +} + +function welcome +{ + cat <<WELCOME +Starting tests... +output directory: $vt_outdir +WELCOME +} + +function cleanup +{ + [[ -n "$vt_keep" ]] && return + rm -rf "$vt_outdir"/success.* || fatal \ + "failed to remove successful test cases" + if [[ $vt_tfail -eq 0 ]]; then + rmdir "$vt_outdir" || fatal \ + "failed to remove test output directory" + fi +} + +function goodbye +{ + cat <<EOF + +------------- +Results +------------- + +Tests passed: $vt_tsuc +Tests failed: $vt_tfail +Tests ran: $vt_tnum + +EOF + if [[ $vt_tfail -eq 0 ]]; then + echo "Congrats, vnd isn't completely broken, the tests pass". + else + echo "Some tests failed, you have some work to do." + fi +} + +while getopts ":ahko:m:" c $@; do + case "$c" in + a) + vt_all="y" + ;; + k) + vt_keep="y" + ;; + o) + vt_outdir="$OPTARG" + ;; + h) + usage + ;; + :) + usage "option requires an argument -- $OPTARG" + ;; + *) + usage "invalid option -- $OPTARG" + ;; + esac +done + +shift $((OPTIND-1)) + +[[ $(zonename) != "global" ]] && fatal "vndtest only runs in the global zone" + +[[ -z "$vt_all" && $# == 0 ]] && usage "no tests to run" + +[[ -z "$vt_outdir" ]] && vt_outdir="$PWD" + +setup_outdir +setup_etherstub +welcome + +if [[ ! -z "$vt_all" ]]; then + run_all +else + for t in $@; do + [[ -f $t ]] || fatal "cannot find test $t" + run_single $t + done +fi + +cleanup_etherstub +goodbye +cleanup + +# +# Exit 1 if we have tests that return non-zero +# +[[ $vt_tfai -eq 0 ]] diff --git a/usr/src/cmd/vndadm/test/tst/Makefile b/usr/src/cmd/vndadm/test/tst/Makefile new file mode 100644 index 0000000000..9b1ba29429 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/Makefile @@ -0,0 +1,18 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +SUBDIRS = cmd dld ioctl lib + +include ../Makefile.subdirs diff --git a/usr/src/cmd/vndadm/test/tst/cmd/Makefile b/usr/src/cmd/vndadm/test/tst/cmd/Makefile new file mode 100644 index 0000000000..1ca20bf749 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/Makefile @@ -0,0 +1,34 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +TSTDIR = cmd +COMMONSH = cmd.common.ksh +SHTESTS = $(COMMONSH) \ + create.list.ksh \ + create.sdev.ksh \ + create.setbuf.ksh \ + ecreate.destroy.ksh \ + ecreate.setbadprop.ksh \ + ecreate.setbadvalue.ksh \ + ecreate.setbuftoobig.ksh \ + ecreate.setrdonlyprop.ksh + +OUTFILES = create.list.ksh.out + +include ../../Makefile.com + +install: $(ROOTTESTS) + +include ../../Makefile.targ diff --git a/usr/src/cmd/vndadm/test/tst/cmd/cmd.common.ksh b/usr/src/cmd/vndadm/test/tst/cmd/cmd.common.ksh new file mode 100644 index 0000000000..31e4e8bf5c --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/cmd.common.ksh @@ -0,0 +1,33 @@ +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Common ksh-based utilities +# + +vt_arg0=$(basename $0) + +function fatal +{ + typeset msg="$*" + [[ -z "$msg" ]] && msg="failed" + echo "$vt_arg0: $msg" >&2 + exit 1 +} + +[[ -z "$1" ]] && fatal "missing required vnic" +[[ -z "$2" ]] && fatal "missing required vnic" +[[ -z "$3" ]] && fatal "missing required vnic" diff --git a/usr/src/cmd/vndadm/test/tst/cmd/create.list.ksh b/usr/src/cmd/vndadm/test/tst/cmd/create.list.ksh new file mode 100644 index 0000000000..fdec9a85be --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/create.list.ksh @@ -0,0 +1,30 @@ +#!/usr/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Basic device listing +# + +. ./cmd.common.ksh + +# +# Use what we hope is a relatively unique name +# +cl_name="triforceofcourage0" +vndadm create -l $1 $cl_name || fatal "failed to create vnd device" +vndadm list -p -o name,zone $cl_name +vndadm list -p -d: -o zone,name $cl_name +vndadm destroy $cl_name || fatal "failed to destroy vnd device" diff --git a/usr/src/cmd/vndadm/test/tst/cmd/create.list.ksh.out b/usr/src/cmd/vndadm/test/tst/cmd/create.list.ksh.out new file mode 100644 index 0000000000..d208b38aab --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/create.list.ksh.out @@ -0,0 +1,2 @@ +triforceofcourage0 global +global:triforceofcourage0 diff --git a/usr/src/cmd/vndadm/test/tst/cmd/create.sdev.ksh b/usr/src/cmd/vndadm/test/tst/cmd/create.sdev.ksh new file mode 100644 index 0000000000..b816ade1de --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/create.sdev.ksh @@ -0,0 +1,25 @@ +#!/usr/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Verify that our sdev links exist +# + +. ./cmd.common.ksh + +vndadm create $1 || fatal "failed to bring up vnd" +[[ -c /dev/vnd/$1 ]] || fatal "missing link" +[[ -c /dev/vnd/zone/$(zonename)/$1 ]] || fatal "missing per-zone link" diff --git a/usr/src/cmd/vndadm/test/tst/cmd/create.setbuf.ksh b/usr/src/cmd/vndadm/test/tst/cmd/create.setbuf.ksh new file mode 100644 index 0000000000..d50edbead4 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/create.setbuf.ksh @@ -0,0 +1,34 @@ +#!/usr/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Set and validate the buffer size properties. Valiate that we can set +# the value using the various number analogues, eg. 1024K, etc. +# +set -o pipefail + +. ./cmd.common.ksh + +vndadm create $1 || fatal "failed to bring up vnd device" +vndadm set $1 rxbuf=1M +cur=$(vndadm get -p $1 rxbuf | nawk '{ print $4 }') +[[ $? -eq 0 ]] || fatal "failed to get rxbuf" +[[ $cur -eq 1048576 ]] || fatal "rxbuf is $cur, not 1M" + +vndadm set $1 txbuf=1024K +cur=$(vndadm get -p $1 rxbuf | nawk '{ print $4 }') +[[ $? -eq 0 ]] || fatal "failed to get txbuf" +[[ $cur -eq 1048576 ]] || fatal "txbuf is $cur, not 1M" diff --git a/usr/src/cmd/vndadm/test/tst/cmd/ecreate.destroy.ksh b/usr/src/cmd/vndadm/test/tst/cmd/ecreate.destroy.ksh new file mode 100644 index 0000000000..e3c4931018 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/ecreate.destroy.ksh @@ -0,0 +1,25 @@ +#!/usr/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Make sure that destroy on a previously destroyed link fails +# + +. ./cmd.common.ksh + +vndadm create $1 || fatal "failed to bring up vnd device" +vndadm destroy $1 || fatal "failed to destroy vnd device" +vndadm destroy $1 diff --git a/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setbadprop.ksh b/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setbadprop.ksh new file mode 100644 index 0000000000..30c27575b1 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setbadprop.ksh @@ -0,0 +1,24 @@ +#!/usr/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Make sure that we can't set a non-existant proprety +# + +. ./cmd.common.ksh + +vndadm create $1 || fatal "failed to bring up vnd device" +vndadm set $1 ganon=ganondorf diff --git a/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setbadvalue.ksh b/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setbadvalue.ksh new file mode 100644 index 0000000000..056b24a817 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setbadvalue.ksh @@ -0,0 +1,24 @@ +#!/usr/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Make sure that we can't set something to a garbage value +# + +. ./cmd.common.ksh + +vndadm create $1 || fatal "failed to bring up vnd device" +vndadm set $1 rxbuf=hello diff --git a/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setbuftoobig.ksh b/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setbuftoobig.ksh new file mode 100644 index 0000000000..551e20461c --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setbuftoobig.ksh @@ -0,0 +1,24 @@ +#!/usr/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Make sure that we can't set a buffer value to a ridiculous size +# + +. ./cmd.common.ksh + +vndadm create $1 || fatal "failed to bring up vnd device" +vndadm set $1 rxsize=1T diff --git a/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setrdonlyprop.ksh b/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setrdonlyprop.ksh new file mode 100644 index 0000000000..4beb53e227 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/cmd/ecreate.setrdonlyprop.ksh @@ -0,0 +1,24 @@ +#!/usr/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Make sure that we can't set a read only property. +# + +. ./cmd.common.ksh + +vndadm create $1 || fatal "failed to bring up vnd device" +vndadm set $1 mintu=100 diff --git a/usr/src/cmd/vndadm/test/tst/dld/Makefile b/usr/src/cmd/vndadm/test/tst/dld/Makefile new file mode 100644 index 0000000000..3088812630 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/dld/Makefile @@ -0,0 +1,27 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +TSTDIR = dld +COMMONSH = dld.common.ksh +SHTESTS = $(COMMONSH) \ + ecreate.ipfirst.ksh \ + ecreate.vndfirst.ksh \ + create.reuse.ksh + +include ../../Makefile.com + +install: $(ROOTTESTS) + +include ../../Makefile.targ diff --git a/usr/src/cmd/vndadm/test/tst/dld/create.reuse.ksh b/usr/src/cmd/vndadm/test/tst/dld/create.reuse.ksh new file mode 100644 index 0000000000..bc2ffde7f6 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/dld/create.reuse.ksh @@ -0,0 +1,31 @@ +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Make sure that we can reuse a data link +# + +. ./dld.common.ksh + +dld_nic=$1 +[[ -z "$1" ]] && fatal "missing required vnic" + +vndadm create $dld_nic || fatal "failed to bring up vnd" +vndadm destroy $dld_nic || fatal "failed to bring down vnd" +ifconfig $dld_nic plumb up || fatal "failed to bring up IP" +ifconfig $dld_nic down unplumb || fatal "failed to bring down IP" +vndadm create $dld_nic || fatal "failed to bring up vnd" +vndadm destroy $dld_nic || fatal "failed to bring down vnd" diff --git a/usr/src/cmd/vndadm/test/tst/dld/dld.common.ksh b/usr/src/cmd/vndadm/test/tst/dld/dld.common.ksh new file mode 100644 index 0000000000..7a2e0a8e2b --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/dld/dld.common.ksh @@ -0,0 +1,29 @@ +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Common ksh-based utilities +# + +vt_arg0=$(basename $0) + +function fatal +{ + typeset msg="$*" + [[ -z "$msg" ]] && msg="failed" + echo "$vt_arg0: $msg" >&2 + exit 1 +} diff --git a/usr/src/cmd/vndadm/test/tst/dld/ecreate.ipfirst.ksh b/usr/src/cmd/vndadm/test/tst/dld/ecreate.ipfirst.ksh new file mode 100644 index 0000000000..e6409781cb --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/dld/ecreate.ipfirst.ksh @@ -0,0 +1,27 @@ +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Make sure vnd fails to come up when IP is up +# + +. ./dld.common.ksh + +dld_nic=$1 +[[ -z "$1" ]] && fatal "missing required vnic" + +ifconfig $dld_nic plumb up || fatal "failed to bring up IP" +vndadm create $dld_nic diff --git a/usr/src/cmd/vndadm/test/tst/dld/ecreate.vndfirst.ksh b/usr/src/cmd/vndadm/test/tst/dld/ecreate.vndfirst.ksh new file mode 100644 index 0000000000..ee7a13c09c --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/dld/ecreate.vndfirst.ksh @@ -0,0 +1,27 @@ +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Make sure IP fails to come up when vnd is up +# + +. ./dld.common.ksh + +dld_nic=$1 +[[ -z "$1" ]] && fatal "missing required vnic" + +vndadm create $dld_nic || fatal "failed to bring up vnd" +ifconfig $dld_nic plumb up diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/Makefile b/usr/src/cmd/vndadm/test/tst/ioctl/Makefile new file mode 100644 index 0000000000..fe074f32b0 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/Makefile @@ -0,0 +1,49 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +TSTDIR = ioctl +EXETESTS = \ + create.attach.exe \ + create.attachnolink.exe \ + create.badlinkname.exe \ + create.doublelink.exe \ + create.gioctlattach.exe \ + create.link.exe \ + create.linkexists.exe \ + create.ngioctlfault.exe \ + create.nopriv1.exe \ + create.nopriv2.exe \ + create.nopriv3.exe \ + create.nopriv4.exe \ + create.olink.exe \ + create.olinknopriv.exe \ + create.rmenolink.exe \ + tst.attachrdonly.exe \ + tst.basicopenctl.exe \ + tst.badioctl.exe \ + tst.gioctlfault.exe \ + tst.gioctlnattach.exe \ + tst.openctlbadflags.exe +SHTESTS = \ + tst.iocsize.ksh +SUPBOBJS = + +CLOBBERFILES = $(EXETESTS) + +include ../../Makefile.com + +install: $(ROOTTESTS) + +include ../../Makefile.targ diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.attach.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.attach.c new file mode 100644 index 0000000000..d7bca5cce3 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.attach.c @@ -0,0 +1,63 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Simply attach a nic + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + vnd_ioc_attach_t via; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.attachnolink.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.attachnolink.c new file mode 100644 index 0000000000..43c6c99af5 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.attachnolink.c @@ -0,0 +1,67 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Try to attach to a non-existant vnic + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + vnd_ioc_attach_t via; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + + /* + * All datalink names have numbers, so we can pick a datalink which + * doesn't exist by not using numbers... + */ + (void) strlcpy(via.via_name, "enolink", VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == -1); + assert(via.via_errno == VND_E_NODATALINK); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.badlinkname.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.badlinkname.c new file mode 100644 index 0000000000..e3a067d5ce --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.badlinkname.c @@ -0,0 +1,119 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Test that we can't link a nic with invalid names + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +static const char *names[] = { + /* Reserved names */ + "ctl", + "zone", + /* Invalid characters */ + "The fight of the century", + "Link/Ganon", + "happens@7pm", + "#testing", + "asdf!!", + "power&courage&wisdom", + "over9000?", + "you're", + "100$", + "(function", + "x)", + "2^128", + "1++", + "No.", + "99%", + "*****", + "r|m", + "=0", + "`p0", + "goodbye~", + "however;", + "\"hesaid", + "shesaid\'", + /* emoji pile of poo */ + "\xF0\x9F\x92\xA9", + NULL +}; + +int +main(int argc, const char *argv[]) +{ + int fd, ret, i; + vnd_ioc_attach_t via; + vnd_ioc_link_t vil; + vnd_ioc_unlink_t viu; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + for (i = 0; names[i] != NULL; i++) { + (void) strlcpy(vil.vil_name, names[i], VND_NAMELEN); + (void) fprintf(stderr, "Trying to create [%s]\n", names[i]); + vil.vil_errno = 0; + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(ret == -1); + assert(vil.vil_errno == VND_E_BADNAME); + } + + /* Finally, the missing null terminator */ + for (i = 0; i < VND_NAMELEN; i++) + vil.vil_name[i] = 'a'; + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(ret == -1); + assert(vil.vil_errno == VND_E_BADNAME); + + viu.viu_errno = 0; + ret = ioctl(fd, VND_IOC_UNLINK, &viu); + assert(ret == -1); + assert(viu.viu_errno == VND_E_NOTLINKED); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.doublelink.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.doublelink.c new file mode 100644 index 0000000000..dcf4f311e9 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.doublelink.c @@ -0,0 +1,82 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Link a nic, first should work, second will fail. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + vnd_ioc_attach_t via; + vnd_ioc_link_t vil; + vnd_ioc_unlink_t viu; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + (void) strlcpy(vil.vil_name, argv[1], VND_NAMELEN); + vil.vil_errno = 0; + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(ret == 0); + assert(vil.vil_errno == 0); + + (void) strlcpy(vil.vil_name, "dup", VND_NAMELEN); + vil.vil_errno = 0; + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(ret == -1); + assert(vil.vil_errno == VND_E_LINKED); + viu.viu_errno = 0; + + ret = ioctl(fd, VND_IOC_UNLINK, &viu); + assert(ret == 0); + assert(viu.viu_errno == 0); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.gioctlattach.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.gioctlattach.c new file mode 100644 index 0000000000..3d6f43377b --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.gioctlattach.c @@ -0,0 +1,69 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Ensure that we can't run global ioctls on an attached handle + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + vnd_ioc_attach_t via; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + via.via_name[0] = 'a'; + via.via_name[1] = '\0'; + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == -1); + assert(via.via_errno == VND_E_ATTACHED); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.link.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.link.c new file mode 100644 index 0000000000..16569d58cd --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.link.c @@ -0,0 +1,76 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Link a nic + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + vnd_ioc_attach_t via; + vnd_ioc_link_t vil; + vnd_ioc_unlink_t viu; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + (void) strlcpy(vil.vil_name, argv[1], VND_NAMELEN); + vil.vil_errno = 0; + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(ret == 0); + assert(vil.vil_errno == 0); + + viu.viu_errno = 0; + ret = ioctl(fd, VND_IOC_UNLINK, &viu); + assert(ret == 0); + assert(viu.viu_errno == 0); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.linkexists.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.linkexists.c new file mode 100644 index 0000000000..4e3be0db5d --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.linkexists.c @@ -0,0 +1,90 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Try to create two devices with the same link name. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, fd2, ret; + vnd_ioc_attach_t via; + vnd_ioc_link_t vil; + vnd_ioc_unlink_t viu; + + if (argc < 3) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + fd2 = open(VND_PATH, O_RDWR); + assert(fd2 > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + (void) strlcpy(via.via_name, argv[2], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + ret = ioctl(fd2, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + (void) strlcpy(vil.vil_name, "dup", VND_NAMELEN); + vil.vil_errno = 0; + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(ret == 0); + assert(vil.vil_errno == 0); + + (void) strlcpy(vil.vil_name, "dup", VND_NAMELEN); + vil.vil_errno = 0; + ret = ioctl(fd2, VND_IOC_LINK, &vil); + assert(ret == -1); + assert(vil.vil_errno == VND_E_LINKEXISTS); + + viu.viu_errno = 0; + ret = ioctl(fd, VND_IOC_UNLINK, &viu); + assert(ret == 0); + assert(viu.viu_errno == 0); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.ngioctlfault.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.ngioctlfault.c new file mode 100644 index 0000000000..bf174f1a8f --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.ngioctlfault.c @@ -0,0 +1,96 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Pass bad addresses to all of our non-global ioctls + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +static int requests[] = { + VND_IOC_LINK, + VND_IOC_UNLINK, + VND_IOC_GETRXBUF, + VND_IOC_SETRXBUF, + VND_IOC_GETTXBUF, + VND_IOC_SETTXBUF, + VND_IOC_GETMINTU, + VND_IOC_GETMAXTU, + VND_IOC_GETMAXBUF, + -1 +}; + +int +main(int argc, const char *argv[]) +{ + int fd, ret, i; + vnd_ioc_attach_t via; + vnd_ioc_link_t vil; + vnd_ioc_unlink_t viu; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + (void) strlcpy(vil.vil_name, argv[1], VND_NAMELEN); + vil.vil_errno = 0; + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(ret == 0); + assert(vil.vil_errno == 0); + + for (i = 0; requests[i] != -1; i++) { + ret = ioctl(fd, requests[i], (void *)(uintptr_t)i); + assert(ret == -1); + assert(errno == EFAULT); + } + + + viu.viu_errno = 0; + ret = ioctl(fd, VND_IOC_UNLINK, &viu); + assert(ret == 0); + assert(viu.viu_errno == 0); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv1.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv1.c new file mode 100644 index 0000000000..6d5ad0eec2 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv1.c @@ -0,0 +1,69 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Fail to attach a device without PRIV_NET_CONFIG + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <assert.h> +#include <priv.h> +#include <string.h> +#include <unistd.h> +#include <stropts.h> +#include <stdio.h> +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + priv_set_t *ps; + vnd_ioc_attach_t via; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + ps = priv_allocset(); + assert(ps != NULL); + assert(priv_addset(ps, PRIV_SYS_NET_CONFIG) == 0); + assert(setppriv(PRIV_OFF, PRIV_PERMITTED, ps) == 0); + + fd = open(VND_PATH, O_RDWR); + assert(fd >= 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == -1); + assert(errno == EPERM); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv2.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv2.c new file mode 100644 index 0000000000..6b38f159a0 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv2.c @@ -0,0 +1,69 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Fail to attach a device without PRIV_NET_RAWACCESS + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <assert.h> +#include <priv.h> +#include <unistd.h> +#include <stropts.h> +#include <string.h> +#include <stdio.h> +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + priv_set_t *ps; + vnd_ioc_attach_t via; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + ps = priv_allocset(); + assert(ps != NULL); + assert(priv_addset(ps, PRIV_NET_RAWACCESS) == 0); + assert(setppriv(PRIV_OFF, PRIV_PERMITTED, ps) == 0); + + fd = open(VND_PATH, O_RDWR); + assert(fd >= 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == -1); + assert(errno == EPERM); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv3.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv3.c new file mode 100644 index 0000000000..a8c43fc46d --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv3.c @@ -0,0 +1,70 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Fail to attach a device without PRIV_NET_CONFIG and PRIV_NET_RAWACCESS + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <assert.h> +#include <priv.h> +#include <unistd.h> +#include <stropts.h> +#include <string.h> +#include <stdio.h> +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + priv_set_t *ps; + vnd_ioc_attach_t via; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + ps = priv_allocset(); + assert(ps != NULL); + assert(priv_addset(ps, PRIV_SYS_NET_CONFIG) == 0); + assert(priv_addset(ps, PRIV_NET_RAWACCESS) == 0); + assert(setppriv(PRIV_OFF, PRIV_PERMITTED, ps) == 0); + + fd = open(VND_PATH, O_RDWR); + assert(fd >= 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == -1); + assert(errno == EPERM); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv4.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv4.c new file mode 100644 index 0000000000..aed0204544 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv4.c @@ -0,0 +1,75 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Fail to link a device without PRIV_NET_CONFIG + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <assert.h> +#include <priv.h> +#include <unistd.h> +#include <stropts.h> +#include <string.h> +#include <stdio.h> +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + priv_set_t *ps; + vnd_ioc_attach_t via; + vnd_ioc_link_t vil; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd >= 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + + ps = priv_allocset(); + assert(ps != NULL); + assert(priv_addset(ps, PRIV_SYS_NET_CONFIG) == 0); + assert(setppriv(PRIV_OFF, PRIV_PERMITTED, ps) == 0); + + (void) strlcpy(vil.vil_name, argv[1], VND_NAMELEN); + vil.vil_errno = 0; + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(ret == -1); + assert(errno == EPERM); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv5.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv5.c new file mode 100644 index 0000000000..2db8ecc95f --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.nopriv5.c @@ -0,0 +1,77 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Fail to open a device without PRIV_NET_RAWACCESS + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <assert.h> +#include <priv.h> +#include <unistd.h> +#include <stropts.h> +#include <string.h> +#include <stdio.h> +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, fd2, ret; + priv_set_t *ps; + char *path; + vnd_ioc_attach_t via; + vnd_ioc_link_t vil; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd >= 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + + ps = priv_allocset(); + assert(ps != NULL); + assert(priv_addset(ps, PRIV_SYS_NET_RAWACCESS) == 0); + assert(setppriv(PRIV_OFF, PRIV_PERMITTED, ps) == 0); + + (void) asprintf(&path, "/dev/vnd/%s", argv[1]); + assert(path != NULL); + fd2 = open(path, O_RDWR); + assert(fd2 == -1); + assert(errno == EPERM); + + free(path); + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.olink.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.olink.c new file mode 100644 index 0000000000..0f9292bbae --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.olink.c @@ -0,0 +1,77 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Open a /dev/vnd/%s link + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + char *path; + vnd_ioc_attach_t via; + vnd_ioc_link_t vil; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + (void) strlcpy(vil.vil_name, argv[1], VND_NAMELEN); + vil.vil_errno = 0; + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(ret == 0); + assert(vil.vil_errno == 0); + + ret = asprintf(&path, "/dev/vnd/%s", argv[1]); + assert(ret != -1); + + ret = open(path, O_RDONLY); + assert(ret > 0); + assert(close(ret) == 0); + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.olinknopriv.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.olinknopriv.c new file mode 100644 index 0000000000..338218e751 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.olinknopriv.c @@ -0,0 +1,83 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Fail to open a /dev/vnd/%s without PRIV_NET_RAWACCESS + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> +#include <priv.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + char *path; + priv_set_t *ps; + vnd_ioc_attach_t via; + vnd_ioc_link_t vil; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + (void) strlcpy(vil.vil_name, argv[1], VND_NAMELEN); + vil.vil_errno = 0; + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(ret == 0); + assert(vil.vil_errno == 0); + + ret = asprintf(&path, "/dev/vnd/%s", argv[1]); + assert(ret != -1); + + ps = priv_allocset(); + assert(ps != NULL); + assert(priv_addset(ps, PRIV_NET_RAWACCESS) == 0); + assert(setppriv(PRIV_OFF, PRIV_PERMITTED, ps) == 0); + + ret = open(path, O_RDWR); + assert(ret == -1); + assert(errno == EPERM); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/create.rmenolink.c b/usr/src/cmd/vndadm/test/tst/ioctl/create.rmenolink.c new file mode 100644 index 0000000000..d44e6512a7 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/create.rmenolink.c @@ -0,0 +1,69 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Verify that unlink fails when we're not linked. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + vnd_ioc_attach_t via; + vnd_ioc_unlink_t viu; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + assert(fd > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == 0); + assert(via.via_errno == 0); + + viu.viu_errno = 0; + ret = ioctl(fd, VND_IOC_UNLINK, &viu); + assert(ret == -1); + assert(viu.viu_errno == VND_E_NOTLINKED); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/tst.attachrdonly.c b/usr/src/cmd/vndadm/test/tst/ioctl/tst.attachrdonly.c new file mode 100644 index 0000000000..29def6182d --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/tst.attachrdonly.c @@ -0,0 +1,63 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Fail to attach when /dev/vnd/ctl is opened read only. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <strings.h> +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(int argc, const char *argv[]) +{ + int fd, ret; + vnd_ioc_attach_t via; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= VND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open(VND_PATH, O_RDONLY); + assert(fd > 0); + + (void) strlcpy(via.via_name, argv[1], VND_NAMELEN); + via.via_zoneid = 0; + via.via_errno = 0; + + ret = ioctl(fd, VND_IOC_ATTACH, &via); + assert(ret == -1); + assert(errno == EBADF); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/tst.badioctl.c b/usr/src/cmd/vndadm/test/tst/ioctl/tst.badioctl.c new file mode 100644 index 0000000000..f26722f035 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/tst.badioctl.c @@ -0,0 +1,79 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Throw a bunch of bad ioctls at us and make sure that we get ENOTTY. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <strings.h> +#include <unistd.h> +#include <stropts.h> +#include <limits.h> +#include <assert.h> + +/* + * We're including a bunch of bad header files that have ioctl numbers that we + * know we shouldn't. + */ +#include <sys/ipd.h> +#include <sys/dtrace.h> + +#define VND_PATH "/dev/vnd/ctl" + +/* + * A series of bad requests + */ +static int requests[] = { + 0, + 1, + 42, + 169, + 4096, + INT_MAX, + IPDIOC_CORRUPT, + IPDIOC_REMOVE, + DTRACEIOC_CONF, + DTRACEIOC_REPLICATE, + -1 +}; + +int +main(void) +{ + int fd, i; + + fd = open(VND_PATH, O_RDONLY); + if (fd < 0) { + (void) fprintf(stderr, "failed to open %s read only: %s\n", + VND_PATH, strerror(errno)); + return (1); + } + + for (i = 0; requests[i] != -1; i++) { + int ret; + ret = ioctl(fd, requests[i], NULL); + assert(ret == -1); + assert(errno == ENOTTY); + } + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/tst.basicopenctl.c b/usr/src/cmd/vndadm/test/tst/ioctl/tst.basicopenctl.c new file mode 100644 index 0000000000..852ad5550f --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/tst.basicopenctl.c @@ -0,0 +1,76 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Ensure that we can do a basic open of the device for read, write, and + * read/write. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <strings.h> +#include <unistd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(void) +{ + int fd; + + fd = open(VND_PATH, O_RDONLY); + if (fd < 0) { + (void) fprintf(stderr, "failed to open %s read only: %s\n", + VND_PATH, strerror(errno)); + return (1); + } + + if (close(fd) != 0) { + (void) fprintf(stderr, "failed to close vnd fd: %s\n", + strerror(errno)); + return (1); + } + + fd = open(VND_PATH, O_RDWR); + if (fd < 0) { + (void) fprintf(stderr, "failed to open %s read/write: %s\n", + VND_PATH, strerror(errno)); + return (1); + } + + if (close(fd) != 0) { + (void) fprintf(stderr, "failed to close vnd fd: %s\n", + strerror(errno)); + return (1); + } + + fd = open(VND_PATH, O_WRONLY); + if (fd < 0) { + (void) fprintf(stderr, "failed to open %s write only: %s\n", + VND_PATH, strerror(errno)); + return (1); + } + + if (close(fd) != 0) { + (void) fprintf(stderr, "failed to close vnd fd: %s\n", + strerror(errno)); + return (1); + } + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/tst.gioctlfault.c b/usr/src/cmd/vndadm/test/tst/ioctl/tst.gioctlfault.c new file mode 100644 index 0000000000..b581b5dd4c --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/tst.gioctlfault.c @@ -0,0 +1,78 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Pass pointers to arbitrary addresses and make sure we properly get EFAULT for + * all the global ioctls. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <strings.h> +#include <unistd.h> +#include <stropts.h> +#include <limits.h> +#include <assert.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(void) +{ + int fd, ret; + vnd_ioc_attach_t *via; + vnd_ioc_list_t *vil; + vnd_ioc_buf_t *vib; + + fd = open(VND_PATH, O_RDWR); + if (fd < 0) { + (void) fprintf(stderr, "failed to open %s r/w: %s\n", VND_PATH, + strerror(errno)); + return (1); + } + + via = (vnd_ioc_attach_t *)(uintptr_t)23; + vil = (vnd_ioc_list_t *)(uintptr_t)42; + vib = (vnd_ioc_buf_t *)(uintptr_t)169; + + ret = ioctl(fd, VND_IOC_ATTACH, NULL); + assert(ret == -1); + assert(errno == EFAULT); + ret = ioctl(fd, VND_IOC_LIST, NULL); + assert(ret == -1); + assert(errno == EFAULT); + ret = ioctl(fd, VND_IOC_GETMAXBUF, NULL); + assert(ret == -1); + assert(errno == EFAULT); + + ret = ioctl(fd, VND_IOC_ATTACH, via); + assert(ret == -1); + assert(errno == EFAULT); + ret = ioctl(fd, VND_IOC_LIST, vil); + assert(ret == -1); + assert(errno == EFAULT); + ret = ioctl(fd, VND_IOC_GETMAXBUF, vib); + assert(ret == -1); + assert(errno == EFAULT); + + assert(close(fd) == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/tst.gioctlnattach.c b/usr/src/cmd/vndadm/test/tst/ioctl/tst.gioctlnattach.c new file mode 100644 index 0000000000..98acffa194 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/tst.gioctlnattach.c @@ -0,0 +1,100 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Here we test that all the ioctls which require us to be on a local device + * fail to work. Specifically, the errno should be VND_E_NOTATTACHED + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> +#include <strings.h> +#include <unistd.h> +#include <stropts.h> +#include <limits.h> +#include <assert.h> +#include <stdlib.h> + +#include <sys/vnd.h> + +#define VND_PATH "/dev/vnd/ctl" + +static int vib_ioc[] = { + VND_IOC_GETRXBUF, + VND_IOC_SETRXBUF, + VND_IOC_GETTXBUF, + VND_IOC_SETTXBUF, + VND_IOC_GETMINTU, + VND_IOC_GETMAXTU, + -1 +}; + +int +main(void) +{ + int fd, ret, i; + vnd_ioc_link_t vil; + vnd_ioc_unlink_t viu; + vnd_ioc_buf_t vib; + frameio_t *fio; + char buf[1]; + + fd = open(VND_PATH, O_RDWR); + if (fd < 0) { + (void) fprintf(stderr, "failed to open %s r/w: %s\n", VND_PATH, + strerror(errno)); + return (1); + } + + bzero(&vil, sizeof (vnd_ioc_link_t)); + vil.vil_name[0] = 'a'; + bzero(&viu, sizeof (vnd_ioc_unlink_t)); + bzero(&vib, sizeof (vnd_ioc_buf_t)); + fio = malloc(sizeof (frameio_t) + sizeof (framevec_t)); + assert(fio != NULL); + fio->fio_version = FRAMEIO_CURRENT_VERSION; + fio->fio_nvpf = 1; + fio->fio_nvecs = 1; + fio->fio_vecs[0].fv_buf = buf; + fio->fio_vecs[0].fv_buflen = 1; + + ret = ioctl(fd, VND_IOC_LINK, &vil); + assert(vil.vil_errno == VND_E_NOTATTACHED); + ret = ioctl(fd, VND_IOC_UNLINK, &viu); + assert(viu.viu_errno == VND_E_NOTLINKED); + + for (i = 0; vib_ioc[i] != -1; i++) { + bzero(&vib, sizeof (vib)); + ret = ioctl(fd, vib_ioc[i], &vib); + assert(vib.vib_errno == VND_E_NOTATTACHED); + } + + /* The frameio ioctls only use standard errnos */ + ret = ioctl(fd, VND_IOC_FRAMEIO_READ, fio); + assert(ret == -1); + assert(errno == ENXIO); + ret = ioctl(fd, VND_IOC_FRAMEIO_WRITE, fio); + assert(ret == -1); + assert(errno == ENXIO); + + free(fio); + assert(close(fd) == 0); + + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/tst.iocsize.ksh b/usr/src/cmd/vndadm/test/tst/ioctl/tst.iocsize.ksh new file mode 100644 index 0000000000..9b30043d47 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/tst.iocsize.ksh @@ -0,0 +1,54 @@ +# +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +# +# Ensure structure sizes for both ILP32 and LP64 are the same +# + +vt_arg0=$(basename $0) +vt_structs="vnd_ioc_attach_t vnd_ioc_link_t vnd_ioc_unlink_t" +vt_structs="$vt_structs vnd_ioc_nonblock_t vnd_ioc_buf_t vnd_ioc_info_t" + +vt_t32="/tmp/vnd.iocsize.32.$$" +vt_t64="/tmp/vnd.iocsize.64.$$" + +function fatal +{ + typeset msg="$*" + [[ -z "$msg" ]] && msg="failed" + echo "$vt_arg0: $msg" >&2 + exit 1 +} + +function dump_types +{ + typeset file=$1 + typeset lib=$2 + typeset t + + for t in $vn_structs; do + mdb -e \'::print -at $t\' $lib >> $file || fatal \ + "failed to dump type $t from $lib" + done +} + +rm -f $vt_t32 $vt_t64 || fatal "failed to cleanup old temp files" +touch $vt_t32 $vt_t64 || fatal "failed to create temp files" + +dump_types $vt_t32 /usr/lib/libvnd.so.1 +dump_types $vt_t64 /usr/lib/64/libvnd.so.1 + +diff $vt_t32 $vt_t64 diff --git a/usr/src/cmd/vndadm/test/tst/ioctl/tst.openctlbadflags.c b/usr/src/cmd/vndadm/test/tst/ioctl/tst.openctlbadflags.c new file mode 100644 index 0000000000..65e48029b7 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/ioctl/tst.openctlbadflags.c @@ -0,0 +1,88 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Make sure that we can't open the vnd control device with invalid flags. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <stdio.h> + +#define VND_PATH "/dev/vnd/ctl" + +int +main(void) +{ + int fd; + + fd = open(VND_PATH, O_RDONLY | O_EXCL); + if (fd != -1) { + (void) fprintf(stderr, "somehow opened vnd O_EXCL!"); + return (1); + } + + fd = open(VND_PATH, O_RDWR | O_EXCL); + if (fd != -1) { + (void) fprintf(stderr, "somehow opened vnd O_EXCL!"); + return (1); + } + + fd = open(VND_PATH, O_WRONLY | O_EXCL); + if (fd != -1) { + (void) fprintf(stderr, "somehow opened vnd O_EXCL!"); + return (1); + } + + fd = open(VND_PATH, O_RDONLY | O_NDELAY); + if (fd != -1) { + (void) fprintf(stderr, "somehow opened vnd O_NDELAY!"); + return (1); + } + + fd = open(VND_PATH, O_RDWR | O_NDELAY); + if (fd != -1) { + (void) fprintf(stderr, "somehow opened vnd O_NDELAY!"); + return (1); + } + + fd = open(VND_PATH, O_WRONLY | O_NDELAY); + if (fd != -1) { + (void) fprintf(stderr, "somehow opened vnd O_NDELAY!"); + return (1); + } + + fd = open(VND_PATH, O_RDONLY | O_NDELAY | O_EXCL); + if (fd != -1) { + (void) fprintf(stderr, "somehow opened vnd O_NDELAY | O_EXCL!"); + return (1); + } + + fd = open(VND_PATH, O_RDWR | O_NDELAY | O_EXCL); + if (fd != -1) { + (void) fprintf(stderr, "somehow opened vnd O_NDELAY | O_EXCL!"); + return (1); + } + + fd = open(VND_PATH, O_WRONLY | O_NDELAY | O_EXCL); + if (fd != -1) { + (void) fprintf(stderr, "somehow opened vnd O_NDELAY | O_EXCL!"); + return (1); + } + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/Makefile b/usr/src/cmd/vndadm/test/tst/lib/Makefile new file mode 100644 index 0000000000..d7a1ed8fa5 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/Makefile @@ -0,0 +1,44 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +TSTDIR = lib +EXETESTS = \ + create.basic.exe \ + create.badlink.exe \ + create.badpropid.exe \ + create.badpropsize.exe \ + create.badzone.exe \ + create.enomem.exe \ + create.frameioeagain.exe \ + create.open.exe \ + create.propiter.exe \ + create.proprdonly.exe \ + err.badclose.exe \ + tst.badopen.exe \ + tst.strerror.exe \ + tst.strsyserror.exe +OUTFILES = tst.strerror.exe.out +SHTESTS = +SUPBOBJS = + +CLOBBERFILES = $(EXETESTS) + +include ../../Makefile.com + +LDLIBS += -lvnd + +install: $(ROOTTESTS) + +include ../../Makefile.targ diff --git a/usr/src/cmd/vndadm/test/tst/lib/create.badlink.c b/usr/src/cmd/vndadm/test/tst/lib/create.badlink.c new file mode 100644 index 0000000000..aefec3ed44 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/create.badlink.c @@ -0,0 +1,39 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Make sure that we can't create something in the context of a datalink that + * doesn't exist. + */ + +#include <assert.h> +#include <stdio.h> +#include <libvnd.h> + +int +main(void) +{ + int syserr; + vnd_errno_t vnderr; + vnd_handle_t *vhp; + + vhp = vnd_create(NULL, "foobar", "foobar", &vnderr, &syserr); + (void) printf("%d, %d\n", vnderr, syserr); + assert(vhp == NULL); + assert(vnderr == VND_E_NODATALINK); + assert(syserr == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/create.badpropid.c b/usr/src/cmd/vndadm/test/tst/lib/create.badpropid.c new file mode 100644 index 0000000000..15334fa31c --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/create.badpropid.c @@ -0,0 +1,76 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Make sure that we can't get and set nonexisting properties. + */ + +#include <stdio.h> +#include <strings.h> +#include <assert.h> +#include <libvnd.h> + +int +main(int argc, const char *argv[]) +{ + int syserr, ret; + vnd_errno_t vnderr; + vnd_handle_t *vhp; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= LIBVND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + vhp = vnd_create(NULL, argv[1], argv[1], &vnderr, &syserr); + assert(vhp != NULL); + assert(vnderr == 0); + assert(syserr == 0); + + ret = vnd_prop_get(vhp, VND_PROP_MAX, NULL, 0); + assert(ret == -1); + assert(vnd_errno(vhp) == VND_E_BADPROP); + assert(vnd_syserrno(vhp) == 0); + + ret = vnd_prop_get(vhp, VND_PROP_MAX + 5, NULL, 0); + assert(ret == -1); + assert(vnd_errno(vhp) == VND_E_BADPROP); + assert(vnd_syserrno(vhp) == 0); + + ret = vnd_prop_set(vhp, VND_PROP_MAX, NULL, 0); + assert(ret == -1); + assert(vnd_errno(vhp) == VND_E_BADPROP); + assert(vnd_syserrno(vhp) == 0); + + ret = vnd_prop_set(vhp, VND_PROP_MAX + 5, NULL, 0); + assert(ret == -1); + assert(vnd_errno(vhp) == VND_E_BADPROP); + assert(vnd_syserrno(vhp) == 0); + + ret = vnd_prop_writeable(VND_PROP_MAX, NULL); + assert(ret == -1); + + ret = vnd_prop_writeable(VND_PROP_MAX + 5, NULL); + assert(ret == -1); + + vnd_close(vhp); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/create.badpropsize.c b/usr/src/cmd/vndadm/test/tst/lib/create.badpropsize.c new file mode 100644 index 0000000000..d5fefd3764 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/create.badpropsize.c @@ -0,0 +1,63 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Validate that we can't set properties with bogus sizes. + */ + +#include <stdio.h> +#include <strings.h> +#include <assert.h> +#include <limits.h> +#include <libvnd.h> + +int +main(int argc, const char *argv[]) +{ + int syserr, ret, i; + vnd_errno_t vnderr; + vnd_handle_t *vhp; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= LIBVND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + vhp = vnd_create(NULL, argv[1], argv[1], &vnderr, &syserr); + assert(vhp != NULL); + assert(vnderr == 0); + assert(syserr == 0); + + for (i = 0; i < VND_PROP_MAX; i++) { + ret = vnd_prop_get(vhp, i, NULL, INT32_MAX); + assert(ret == -1); + assert(vnd_errno(vhp) == VND_E_BADPROPSIZE); + assert(vnd_syserrno(vhp) == 0); + + ret = vnd_prop_set(vhp, i, NULL, INT32_MAX); + assert(ret == -1); + assert(vnd_errno(vhp) == VND_E_BADPROPSIZE); + assert(vnd_syserrno(vhp) == 0); + } + + vnd_close(vhp); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/create.badzone.c b/usr/src/cmd/vndadm/test/tst/lib/create.badzone.c new file mode 100644 index 0000000000..30f9612963 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/create.badzone.c @@ -0,0 +1,43 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Make sure that we can't create something in the context of a zone that + * doesn't exist. + */ + +#include <assert.h> +#include <sys/zone.h> +#include <string.h> +#include <libvnd.h> + +int +main(void) +{ + int syserr; + vnd_errno_t vnderr; + char zname[ZONENAME_MAX+4]; + vnd_handle_t *vhp; + + (void) memset(zname, 'a', sizeof (zname)); + zname[ZONENAME_MAX+3] = '\0'; + + vhp = vnd_create(zname, "foobar", "foobar", &vnderr, &syserr); + assert(vhp == NULL); + assert(vnderr == VND_E_NOZONE); + assert(syserr == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/create.basic.c b/usr/src/cmd/vndadm/test/tst/lib/create.basic.c new file mode 100644 index 0000000000..5335f8cbb4 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/create.basic.c @@ -0,0 +1,49 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Simple create and destroy. + */ + +#include <stdio.h> +#include <strings.h> +#include <assert.h> +#include <libvnd.h> + +int +main(int argc, const char *argv[]) +{ + int syserr; + vnd_errno_t vnderr; + vnd_handle_t *vhp; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= LIBVND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + vhp = vnd_create(NULL, argv[1], argv[1], &vnderr, &syserr); + assert(vhp != NULL); + assert(vnderr == 0); + assert(syserr == 0); + vnd_close(vhp); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/create.enomem.c b/usr/src/cmd/vndadm/test/tst/lib/create.enomem.c new file mode 100644 index 0000000000..9203e369ae --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/create.enomem.c @@ -0,0 +1,91 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Verify that we can't allocate a handle when in an ENOMEM situation. + */ + +#include <procfs.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/sysmacros.h> +#include <assert.h> +#include <strings.h> + +#include <libvnd.h> + +int +main(int argc, const char *argv[]) +{ + int fd; + int syserr; + vnd_errno_t vnderr; + vnd_handle_t *vhp; + pstatus_t status; + void *addr; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= LIBVND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + fd = open("/proc/self/status", O_RDONLY); + if (fd < 0) + exit(1); + if (read(fd, &status, sizeof (status)) != sizeof (status)) + exit(1); + + addr = mmap((caddr_t)P2ROUNDUP(status.pr_brkbase + + status.pr_brksize, 0x1000), 0x1000, + PROT_READ, MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0); + if (addr == (void *)-1) { + perror("mmap"); + exit(1); + } + + /* malloc an approximate size of the vnd_handle_t */ + for (;;) { + void *buf; + + buf = malloc(8); + if (buf == NULL) + break; + } + + for (;;) { + void *buf; + + buf = malloc(4); + if (buf == NULL) + break; + } + + vhp = vnd_create(NULL, argv[1], argv[1], &vnderr, &syserr); + assert(vhp == NULL); + assert(vnderr == VND_E_NOMEM); + assert(syserr == 0); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/create.frameioeagain.c b/usr/src/cmd/vndadm/test/tst/lib/create.frameioeagain.c new file mode 100644 index 0000000000..6cb14fb7df --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/create.frameioeagain.c @@ -0,0 +1,80 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Create a datalink, set it to non-blocking mode and ensure that we get EAGAIN + * from frame I/O calls. Note that if this test is not plumbed up over an + * etherstub, then it is likely that other traffic will appear on the device and + * this will fail. Note that the test suite always creates these devices over an + * etherstub. + */ + +#include <stdio.h> +#include <strings.h> +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <libvnd.h> + +int +main(int argc, const char *argv[]) +{ + int syserr, ret, fd; + vnd_errno_t vnderr; + vnd_handle_t *vhp; + frameio_t *fio; + char buf[1520]; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= LIBVND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + vhp = vnd_create(NULL, argv[1], argv[1], &vnderr, &syserr); + assert(vhp != NULL); + assert(vnderr == 0); + assert(syserr == 0); + + fd = vnd_pollfd(vhp); + ret = fcntl(fd, F_SETFL, O_NONBLOCK); + assert(ret == 0); + + fio = malloc(sizeof (frameio_t) + + sizeof (framevec_t)); + assert(fio != NULL); + fio->fio_version = FRAMEIO_CURRENT_VERSION; + fio->fio_nvpf = 1; + fio->fio_nvecs = 1; + + fio->fio_vecs[0].fv_buf = buf; + fio->fio_vecs[0].fv_buflen = sizeof (buf); + + ret = vnd_frameio_read(vhp, fio); + (void) printf("%d, %d\n", ret, errno); + assert(ret == -1); + assert(errno == EAGAIN); + + vnd_close(vhp); + free(fio); + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/create.open.c b/usr/src/cmd/vndadm/test/tst/lib/create.open.c new file mode 100644 index 0000000000..9cb1d7e40e --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/create.open.c @@ -0,0 +1,56 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Make sure we can open a created datalink. + */ + +#include <stdio.h> +#include <strings.h> +#include <assert.h> +#include <libvnd.h> + +int +main(int argc, const char *argv[]) +{ + int syserr; + vnd_errno_t vnderr; + vnd_handle_t *vhp, *vhp2; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= LIBVND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + vhp = vnd_create(NULL, argv[1], argv[1], &vnderr, &syserr); + assert(vhp != NULL); + assert(vnderr == 0); + assert(syserr == 0); + + vhp2 = vnd_open(NULL, argv[1], &vnderr, &syserr); + assert(vhp2 != NULL); + assert(vnderr == 0); + assert(syserr == 0); + + vnd_close(vhp2); + vnd_close(vhp); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/create.propiter.c b/usr/src/cmd/vndadm/test/tst/lib/create.propiter.c new file mode 100644 index 0000000000..a0b46180f7 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/create.propiter.c @@ -0,0 +1,79 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Ensure that vnd_prop_iter sees all props; + */ + +#include <stdio.h> +#include <strings.h> +#include <stdlib.h> +#include <assert.h> +#include <libvnd.h> + +static boolean_t *g_props; + +/* ARGSUSED */ +static int +prop_cb(vnd_handle_t *vhp, vnd_prop_t prop, void *unused) +{ + assert(prop < VND_PROP_MAX); + g_props[prop] = B_TRUE; + + return (0); +} + +int +main(int argc, const char *argv[]) +{ + int syserr, i, ret; + vnd_errno_t vnderr; + vnd_handle_t *vhp; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= LIBVND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + g_props = malloc(sizeof (boolean_t) * VND_PROP_MAX); + if (g_props == NULL) { + (void) fprintf(stderr, "failed to alloc memory for %d " + "boolean_t\n", VND_PROP_MAX); + return (1); + } + for (i = 0; i < VND_PROP_MAX; i++) + g_props[i] = B_FALSE; + + vhp = vnd_create(NULL, argv[1], argv[1], &vnderr, &syserr); + assert(vhp != NULL); + assert(vnderr == 0); + assert(syserr == 0); + + ret = vnd_prop_iter(vhp, prop_cb, NULL); + assert(ret == 0); + + for (i = 0; i < VND_PROP_MAX; i++) + assert(g_props[i] == B_TRUE); + + free(g_props); + vnd_close(vhp); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/create.proprdonly.c b/usr/src/cmd/vndadm/test/tst/lib/create.proprdonly.c new file mode 100644 index 0000000000..18b1f7d58d --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/create.proprdonly.c @@ -0,0 +1,63 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Validate that we can't set read only properties + */ + +#include <errno.h> +#include <stdio.h> +#include <strings.h> +#include <assert.h> +#include <limits.h> +#include <libvnd.h> + +int +main(int argc, const char *argv[]) +{ + int syserr, ret; + vnd_errno_t vnderr; + vnd_handle_t *vhp; + vnd_prop_buf_t vpb; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= LIBVND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + vhp = vnd_create(NULL, argv[1], argv[1], &vnderr, &syserr); + assert(vhp != NULL); + assert(vnderr == 0); + assert(syserr == 0); + + ret = vnd_prop_get(vhp, VND_PROP_MINTU, &vpb, + sizeof (vnd_prop_buf_t)); + assert(ret == 0); + + ret = vnd_prop_set(vhp, VND_PROP_MINTU, &vpb, + sizeof (vnd_prop_buf_t)); + assert(ret == -1); + assert(vnd_errno(vhp) == VND_E_PROPRDONLY); + assert(vnd_syserrno(vhp) == 0); + + vnd_close(vhp); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/err.badclose.c b/usr/src/cmd/vndadm/test/tst/lib/err.badclose.c new file mode 100644 index 0000000000..8c832506a0 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/err.badclose.c @@ -0,0 +1,33 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * This program should segfault. + */ + +#include <errno.h> +#include <stdio.h> +#include <strings.h> +#include <assert.h> +#include <libvnd.h> + +int +main(void) +{ + vnd_handle_t *vhp = (void *)0x42; + vnd_close(vhp); + /* This should not be reached */ + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/tst.badopen.c b/usr/src/cmd/vndadm/test/tst/lib/tst.badopen.c new file mode 100644 index 0000000000..4f67ce79ed --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/tst.badopen.c @@ -0,0 +1,49 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Make sure we can't open a vnd device that doesn't exist + */ + +#include <errno.h> +#include <stdio.h> +#include <strings.h> +#include <assert.h> +#include <libvnd.h> + +int +main(int argc, const char *argv[]) +{ + int syserr; + vnd_errno_t vnderr; + vnd_handle_t *vhp; + + if (argc < 2) { + (void) fprintf(stderr, "missing arguments...\n"); + return (1); + } + + if (strlen(argv[1]) >= LIBVND_NAMELEN) { + (void) fprintf(stderr, "vnic name too long...\n"); + return (1); + } + + vhp = vnd_open(NULL, argv[1], &vnderr, &syserr); + assert(vhp == NULL); + assert(vnderr == VND_E_SYS); + assert(syserr == ENOENT); + + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/tst.strerror.c b/usr/src/cmd/vndadm/test/tst/lib/tst.strerror.c new file mode 100644 index 0000000000..a99a9ecbf6 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/tst.strerror.c @@ -0,0 +1,30 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Verify that all the error strings we care about match what we expect. + */ + +#include <stdio.h> +#include <libvnd.h> + +int +main(void) +{ + int i; + for (i = 0; i <= VND_E_UNKNOWN + 1; i++) + (void) printf("[%s]\n", vnd_strerror(i)); + return (0); +} diff --git a/usr/src/cmd/vndadm/test/tst/lib/tst.strerror.exe.out b/usr/src/cmd/vndadm/test/tst/lib/tst.strerror.exe.out new file mode 100644 index 0000000000..83dbcdfdb4 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/tst.strerror.exe.out @@ -0,0 +1,37 @@ +[no error] +[not enough memory available] +[no such datalink] +[datalink not of type DL_ETHER] +[unknown dlpi failure] +[DL_ATTACH_REQ failed] +[DL_BIND_REQ failed] +[DL_PROMISCON_REQ failed] +[DLD_CAPAB_DIRECT enable failed] +[bad datalink capability] +[bad datalink subcapability] +[bad dld version] +[failed to create kstats] +[no such vnd link] +[netstack doesn't exist] +[device already associated] +[device already attached] +[device already linked] +[invalid name] +[permission denied] +[no such zone] +[failed to initialize vnd stream module] +[device not attached] +[device not linked] +[another device has the same link name] +[failed to create minor node] +[requested buffer size is too large] +[requested buffer size is too small] +[unable to obtain exclusive access to dlpi link, link busy] +[DLD direct capability not supported over data link] +[invalid property size] +[invalid property] +[property is read only] +[unexpected system error] +[capabilities invalid, pass-through module detected] +[unknown error] +[unknown error] diff --git a/usr/src/cmd/vndadm/test/tst/lib/tst.strsyserror.c b/usr/src/cmd/vndadm/test/tst/lib/tst.strsyserror.c new file mode 100644 index 0000000000..b95e6372e4 --- /dev/null +++ b/usr/src/cmd/vndadm/test/tst/lib/tst.strsyserror.c @@ -0,0 +1,50 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +/* + * Verify that the error message from libvnd's strsyserrno is the same as the + * underlying strerror function's. It should be. We'll just check an assortment + * of errnos. + */ + +#include <stdio.h> +#include <string.h> +#include <libvnd.h> + +int +main(void) +{ + int i; + const char *vnd, *libc; + for (i = 0; i < 42; i++) { + vnd = vnd_strsyserror(i); + libc = strerror(i); + if ((vnd != NULL && libc == NULL) || + (vnd == NULL && libc != NULL)) { + (void) fprintf(stderr, "errno %d, vnd: %p, libc: %p", + i, (void *)vnd, (void *)libc); + return (1); + } + if (vnd != NULL && strcmp(vnd, libc) != 0) { + (void) fprintf(stderr, + "errno %d: libc and vnd disagree.\n", i); + (void) fprintf(stderr, "vnd: %s\n", vnd); + (void) fprintf(stderr, "libc: %s\n", libc); + return (1); + } + } + + return (0); +} diff --git a/usr/src/cmd/vndadm/vndadm.c b/usr/src/cmd/vndadm/vndadm.c new file mode 100644 index 0000000000..6811663696 --- /dev/null +++ b/usr/src/cmd/vndadm/vndadm.c @@ -0,0 +1,872 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014 Joyent, Inc. All rights reserved. + */ + +#include <errno.h> +#include <sys/types.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <assert.h> +#include <libgen.h> +#include <stdlib.h> +#include <unistd.h> +#include <zone.h> + +#include <libvnd.h> + +typedef int (*vndadm_print_t)(vnd_handle_t *, vnd_prop_t); +typedef int (*vndadm_parse_t)(char *, void **, size_t *); + +typedef struct vndadm_proptbl { + const char *vp_name; + vndadm_print_t vp_print; + vndadm_parse_t vp_parse; +} vndadm_proptbl_t; + +/* + * Forwards + */ +static int usage(const char *, ...); +static int vndadm_print_size(vnd_handle_t *, vnd_prop_t); +static int vndadm_print_number(vnd_handle_t *, vnd_prop_t); +static int vndadm_parse_size(char *, void **, size_t *); + +/* + * Globals + */ +static char *vnd_pname; + +static void +vnd_vwarn(vnd_errno_t verr, int syserr, const char *format, va_list alist) +{ + (void) fprintf(stderr, "%s: ", vnd_pname); + (void) vfprintf(stderr, format, alist); + if (strchr(format, '\n') == NULL) { + (void) fprintf(stderr, ": %s\n", verr != VND_E_SYS ? + vnd_strerror(verr) : vnd_strsyserror(syserr)); + } +} + +static void +vnd_libwarn(vnd_errno_t verr, int syserr, const char *format, ...) +{ + va_list alist; + + va_start(alist, format); + vnd_vwarn(verr, syserr, format, alist); + va_end(alist); +} + +static void +vnd_warn(const char *format, ...) +{ + va_list alist; + + va_start(alist, format); + vnd_vwarn(0, 0, format, alist); + va_end(alist); +} + +static vndadm_proptbl_t vndadm_propname_tbl[] = { + { "rxbuf", vndadm_print_size, + vndadm_parse_size }, /* VND_PROP_RXBUF */ + { "txbuf", vndadm_print_size, + vndadm_parse_size }, /* VND_PROP_TXBUF */ + { "maxsize", vndadm_print_size, NULL }, /* VND_PROP_MAXBUF */ + { "mintu", vndadm_print_number, NULL }, /* VND_PROP_MINTU */ + { "maxtu", vndadm_print_number, NULL }, /* VND_PROP_MAXTU */ + NULL /* VND_PROP_MAX */ +}; + +static const char * +vndadm_prop_to_name(vnd_prop_t prop) +{ + if (prop > VND_PROP_MAX) + return (NULL); + + return (vndadm_propname_tbl[prop].vp_name); +} + +static vnd_prop_t +vndadm_name_to_prop(const char *name) +{ + int i; + + for (i = 0; i < VND_PROP_MAX; i++) { + if (strcmp(name, vndadm_propname_tbl[i].vp_name) == 0) + return (i); + } + + return (VND_PROP_MAX); +} + +static int +vndadm_print_size(vnd_handle_t *vhp, vnd_prop_t prop) +{ + vnd_prop_buf_t buf; + + if (vnd_prop_get(vhp, prop, &buf, sizeof (buf)) != 0) { + vnd_libwarn(vnd_errno(vhp), vnd_syserrno(vhp), + "failed to get property %s", vndadm_prop_to_name(prop)); + return (1); + } + + (void) printf("%lld", buf.vpb_size); + return (0); +} + +static int +vndadm_print_number(vnd_handle_t *vhp, vnd_prop_t prop) +{ + vnd_prop_buf_t buf; + + if (vnd_prop_get(vhp, prop, &buf, sizeof (buf)) != 0) { + vnd_libwarn(vnd_errno(vhp), vnd_syserrno(vhp), + "failed to get property %s", vndadm_prop_to_name(prop)); + return (1); + } + + (void) printf("%lld", buf.vpb_size); + return (0); +} + +static int +vndadm_parse_size(char *str, void **bufp, size_t *sizep) +{ + char *end; + unsigned long long val, orig; + vnd_prop_buf_t *buf; + + errno = 0; + val = strtoull(str, &end, 10); + if (errno != 0) { + vnd_warn("%s: not a number\n", str); + return (1); + } + + orig = val; + switch (*end) { + case 'g': + case 'G': + val *= 1024; + if (val < orig) + goto overflow; + /*FALLTHRU*/ + case 'm': + case 'M': + val *= 1024; + if (val < orig) + goto overflow; + /*FALLTHRU*/ + case 'k': + case 'K': + val *= 1024; + if (val < orig) + goto overflow; + end++; + break; + default: + break; + } + + if (*end == 'b' || *end == 'B') + end++; + if (*end != '\0') { + vnd_warn("%s: not a number", str); + return (1); + } + + buf = malloc(sizeof (vnd_prop_buf_t)); + if (buf == NULL) { + vnd_warn("failed to allocate memory for setting a property"); + return (1); + } + + buf->vpb_size = val; + *bufp = buf; + *sizep = sizeof (vnd_prop_buf_t); + + return (0); + +overflow: + vnd_warn("value overflowed: %s\n", str); + return (1); +} + +static void +vndadm_create_usage(FILE *out) +{ + (void) fprintf(out, "\tcreate:\t\t[-z zonename] -l datalink name\n"); +} + +static int +vndadm_create(int argc, char *argv[]) +{ + int c, syserr; + vnd_errno_t vnderr; + const char *datalink = NULL; + const char *linkname = NULL; + const char *zonename = NULL; + vnd_handle_t *vhp; + + optind = 0; + while ((c = getopt(argc, argv, ":z:l:")) != -1) { + switch (c) { + case 'l': + datalink = optarg; + break; + case 'z': + zonename = optarg; + break; + case ':': + return (usage("-%c requires an operand\n", optopt)); + case '?': + return (usage("unknown option: -%c\n", optopt)); + default: + abort(); + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) { + return (usage("missing required link name\n")); + } else if (argc > 1) { + return (usage("create: too many arguments for link name, " + "pick one\n")); + } + linkname = argv[0]; + if (datalink == NULL) + datalink = linkname; + + vhp = vnd_create(zonename, datalink, linkname, &vnderr, &syserr); + if (vhp == NULL) { + vnd_libwarn(vnderr, syserr, + "failed to create datapath link %s", linkname); + return (1); + } + + vnd_close(vhp); + return (0); +} + +static void +vndadm_destroy_usage(FILE *out) +{ + (void) fprintf(out, "\tdestroy:\t[-z zonename] [link]...\n"); +} + +static int +vndadm_destroy(int argc, char *argv[]) +{ + vnd_handle_t *vhp; + int c, syserr; + vnd_errno_t vnderr; + const char *zonename = NULL; + + optind = 0; + while ((c = getopt(argc, argv, ":z:")) != -1) { + switch (c) { + case 'z': + zonename = optarg; + break; + case ':': + return (usage("-%c requires an operand\n", optopt)); + case '?': + return (usage("unknown option: -%c\n", optopt)); + default: + abort(); + } + } + + argc -= optind; + argv += optind; + + if (argc != 1) { + return (usage("extraneous arguments\n")); + } + + vhp = vnd_open(zonename, argv[0], &vnderr, &syserr); + if (vhp == NULL) { + vnd_libwarn(vnderr, syserr, "failed to open link: %s", argv[0]); + return (1); + } + + if (vnd_unlink(vhp) != 0) { + vnd_libwarn(vnd_errno(vhp), vnd_syserrno(vhp), + "failed to destroy link %s", argv[0]); + return (1); + } + + vnd_close(vhp); + return (0); +} + +static void +vndadm_list_usage(FILE *out) +{ + (void) fprintf(out, "\tlist:\t\t[-p] [-d delim] [-o field,...] " + "[-z zonename] [link]...\n"); +} + +#define VNDADM_LIST_NFIELDS 3 + +typedef struct vndadm_list_cb { + int vsc_argc; + char **vsc_argv; + int vsc_found; + boolean_t vsc_parse; + const char *vsc_delim; + int vsc_order[VNDADM_LIST_NFIELDS]; + int vsc_last; + zoneid_t vsc_zid; +} vndadm_list_cb_t; + +typedef struct vndadm_list_field { + const char *vlf_name; + const char *vlf_header; + int vlf_size; + void (*vlf_print)(struct vndadm_list_field *, vnd_info_t *, boolean_t); + void (*vlf_parse)(struct vndadm_list_field *, vnd_info_t *, boolean_t); +} vndadm_list_field_t; + +static void +vlf_print_link(vndadm_list_field_t *vlfp, vnd_info_t *viip, + boolean_t last) +{ + if (last == B_TRUE) { + (void) printf("%s", viip->vi_name); + } else { + (void) printf("%-*s", vlfp->vlf_size, viip->vi_name); + } +} + +/* ARGSUSED */ +static void +vlf_parse_link(vndadm_list_field_t *vlfp, vnd_info_t *viip, + boolean_t last) +{ + (void) printf("%s", viip->vi_name); +} + +static void +vlf_print_datalink(vndadm_list_field_t *vlfp, vnd_info_t *viip, + boolean_t last) +{ + if (last == B_TRUE) { + (void) printf("%s", viip->vi_datalink); + } else { + (void) printf("%-*s", vlfp->vlf_size, viip->vi_datalink); + } +} + +/* ARGSUSED */ +static void +vlf_parse_datalink(vndadm_list_field_t *vlfp, vnd_info_t *viip, + boolean_t last) +{ + (void) printf("%s", viip->vi_datalink); +} + +static void +vlf_print_zone(vndadm_list_field_t *vlfp, vnd_info_t *viip, + boolean_t last) +{ + char buf[ZONENAME_MAX]; + + if (getzonenamebyid(viip->vi_zone, buf, sizeof (buf)) <= 0) + (void) strlcpy(buf, "<unknown>", sizeof (buf)); + + if (last == B_TRUE) { + (void) printf("%s", buf); + } else { + (void) printf("%-*s", vlfp->vlf_size, buf); + } +} + +/* ARGSUSED */ +static void +vlf_parse_zone(vndadm_list_field_t *vlfp, vnd_info_t *viip, + boolean_t last) +{ + char buf[ZONENAME_MAX]; + + if (getzonenamebyid(viip->vi_zone, buf, sizeof (buf)) <= 0) + (void) strlcpy(buf, "<unknown>", sizeof (buf)); + + (void) printf("%s", buf); +} + +static vndadm_list_field_t vlf_tbl[] = { + { "name", "NAME", 16, vlf_print_link, vlf_parse_link }, + { "datalink", "DATALINK", 16, vlf_print_datalink, vlf_parse_datalink }, + { "zone", "ZONENAME", 32, vlf_print_zone, vlf_parse_zone }, + { NULL } +}; + + +static int +vndadm_list_f(vnd_info_t *viip, void *arg) +{ + int i; + boolean_t found; + vndadm_list_cb_t *vscp = arg; + + if (vscp->vsc_zid != ALL_ZONES && vscp->vsc_zid != viip->vi_zone) + return (0); + + if (vscp->vsc_argc != 0) { + found = B_FALSE; + for (i = 0; i < vscp->vsc_argc; i++) { + if (strcmp(viip->vi_name, vscp->vsc_argv[i]) == 0) { + found = B_TRUE; + break; + } + } + if (found == B_FALSE) + return (0); + vscp->vsc_found++; + } + + for (i = 0; i < VNDADM_LIST_NFIELDS && vscp->vsc_order[i] != -1; i++) { + boolean_t last = i == vscp->vsc_last; + if (vscp->vsc_parse == B_TRUE) + vlf_tbl[vscp->vsc_order[i]].vlf_parse( + &vlf_tbl[vscp->vsc_order[i]], viip, last); + else + vlf_tbl[vscp->vsc_order[i]].vlf_print( + &vlf_tbl[vscp->vsc_order[i]], viip, last); + + if (last == B_FALSE) + (void) printf("%s", vscp->vsc_delim); + } + (void) printf("\n"); + + return (0); +} + +static int +vndadm_list(int argc, char *argv[]) +{ + int c, i, syserr; + vnd_errno_t vnderr; + boolean_t parse = B_FALSE; + const char *zonename = NULL, *delim = NULL; + char *fields = NULL; + vndadm_list_cb_t vsc; + + optind = 0; + while ((c = getopt(argc, argv, ":pd:o:z:")) != -1) { + switch (c) { + case 'p': + parse = B_TRUE; + break; + case 'd': + delim = optarg; + break; + case 'o': + fields = optarg; + break; + case 'z': + zonename = optarg; + break; + case ':': + return (usage("-%c requires an operand\n", optopt)); + case '?': + return (usage("unknown option: -%c\n", optopt)); + default: + abort(); + } + } + + argc -= optind; + argv += optind; + + vsc.vsc_argc = argc; + vsc.vsc_argv = argv; + vsc.vsc_found = 0; + if (zonename != NULL) { + vsc.vsc_zid = getzoneidbyname(zonename); + if (vsc.vsc_zid == -1) { + vnd_warn("no such zone: %s\n", zonename); + return (1); + } + } else { + vsc.vsc_zid = ALL_ZONES; + } + + /* Sanity check parseable related stuff */ + if (delim != NULL && parse == B_FALSE) { + return (usage("-d cannot be used without -p\n")); + } + + if (parse == B_TRUE && fields == NULL) { + return (usage("-p cannot be used without -o\n")); + } + + /* validate our fields, if any */ + if (fields != NULL) { + char *c, *n; + int floc = 0; + + c = fields; + for (;;) { + if (floc >= VNDADM_LIST_NFIELDS) { + return (usage("too many fields specified " + "for -o\n")); + } + + n = strchr(c, ','); + if (n != NULL) + *n = '\0'; + + for (i = 0; i < VNDADM_LIST_NFIELDS; i++) { + if (strcasecmp(c, vlf_tbl[i].vlf_name) == 0) + break; + } + if (i == VNDADM_LIST_NFIELDS) { + vnd_warn("invalid field for -o: %s\nvalid " + "fields are:", c); + for (i = 0; i < VNDADM_LIST_NFIELDS; i++) + vnd_warn(" %s", vlf_tbl[i].vlf_name); + vnd_warn("\n"); + return (usage(NULL)); + } + vsc.vsc_order[floc] = i; + floc++; + + if (n == NULL) + break; + c = n + 1; + } + + vsc.vsc_last = floc - 1; + while (floc < VNDADM_LIST_NFIELDS) + vsc.vsc_order[floc++] = -1; + } else { + vsc.vsc_order[0] = 0; + vsc.vsc_order[1] = 1; + vsc.vsc_order[2] = 2; + } + + vsc.vsc_parse = parse; + vsc.vsc_delim = delim; + if (vsc.vsc_delim == NULL) + vsc.vsc_delim = " "; + + if (vsc.vsc_parse != B_TRUE) { + for (i = 0; i < VNDADM_LIST_NFIELDS && vsc.vsc_order[i] != -1; + i++) { + if (i + 1 == VNDADM_LIST_NFIELDS) { + (void) printf("%s\n", + vlf_tbl[vsc.vsc_order[i]].vlf_header); + continue; + } + (void) printf("%-*s ", + vlf_tbl[vsc.vsc_order[i]].vlf_size, + vlf_tbl[vsc.vsc_order[i]].vlf_header); + } + } + + if (vnd_walk(vndadm_list_f, &vsc, &vnderr, &syserr) != 0) { + vnd_libwarn(vnderr, syserr, "failed to walk vnd links"); + return (1); + } + + if (argc > 0 && vsc.vsc_found == 0) { + vnd_warn("no links matched requested names\n"); + return (1); + } + + return (0); +} + +typedef struct vndadm_get { + boolean_t vg_parse; + const char *vg_delim; + const char *vg_link; + int vg_argc; + char **vg_argv; +} vndadm_get_t; + +static int +vndadm_get_cb(vnd_handle_t *vhp, vnd_prop_t prop, void *arg) +{ + boolean_t writeable; + const char *perm; + vndadm_get_t *vgp = arg; + const char *name = vndadm_prop_to_name(prop); + + /* Verify if this is a prop we're supposed to print */ + if (vgp->vg_argc > 0) { + int i; + boolean_t found = B_FALSE; + for (i = 0; i < vgp->vg_argc; i++) { + if (strcmp(name, vgp->vg_argv[i]) == 0) { + found = B_TRUE; + break; + } + } + if (found == B_FALSE) + return (0); + } + + if (vnd_prop_writeable(prop, &writeable) != 0) + abort(); + + perm = writeable ? "rw" : "r-"; + + if (vgp->vg_parse == B_TRUE) { + (void) printf("%s%s%s%s%s%s", vgp->vg_link, vgp->vg_delim, + name, vgp->vg_delim, perm, vgp->vg_delim); + } else { + (void) printf("%-13s %-16s %-5s ", vgp->vg_link, name, perm); + } + + if (vndadm_propname_tbl[prop].vp_print != NULL) { + if (vndadm_propname_tbl[prop].vp_print(vhp, prop) != 0) + return (1); + } else { + (void) printf("-"); + } + (void) printf("\n"); + return (0); +} + +static int +vndadm_get(int argc, char *argv[]) +{ + vnd_handle_t *vhp; + boolean_t parse = B_FALSE; + vndadm_get_t vg; + int c, syserr; + vnd_errno_t vnderr; + const char *zonename = NULL, *delim = NULL; + + if (argc <= 0) { + return (usage("get requires a link name\n")); + } + + optind = 0; + while ((c = getopt(argc, argv, ":pd:z:")) != -1) { + switch (c) { + case 'p': + parse = B_TRUE; + break; + case 'd': + delim = optarg; + break; + case 'z': + zonename = optarg; + break; + case ':': + return (usage("-%c requires an operand\n", optopt)); + case '?': + return (usage("unknown option: -%c\n", optopt)); + default: + abort(); + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) { + return (usage("missing required link\n")); + } + + vhp = vnd_open(zonename, argv[0], &vnderr, &syserr); + if (vhp == NULL) { + vnd_libwarn(vnderr, syserr, "failed to open link: %s", argv[0]); + return (1); + } + + vg.vg_argc = argc - 1; + vg.vg_argv = argv + 1; + vg.vg_link = argv[0]; + vg.vg_parse = parse; + vg.vg_delim = delim != NULL ? delim : " "; + if (vg.vg_parse == B_FALSE) + (void) printf("%-13s %-16s %-5s %s\n", "LINK", "PROPERTY", + "PERM", "VALUE"); + + if (vnd_prop_iter(vhp, vndadm_get_cb, &vg) != 0) + return (1); + + return (0); +} + +static void +vndadm_get_usage(FILE *out) +{ + (void) fprintf(out, + "\tget:\t\t[-p] [-d delim] [-z zonename] link [prop]...\n"); +} + +static int +vndadm_set(int argc, char *argv[]) +{ + vnd_handle_t *vhp; + int c, i, syserr; + vnd_errno_t vnderr; + const char *zonename = NULL; + + optind = 0; + while ((c = getopt(argc, argv, ":z:")) != -1) { + switch (c) { + case 'z': + zonename = optarg; + break; + case ':': + return (usage("-%c requires an operand\n", optopt)); + case '?': + return (usage("unknown option: -%c\n", optopt)); + default: + abort(); + } + } + + argc -= optind; + argv += optind; + + if (argc < 2) { + return (usage("missing arguments to set\n")); + } + + vhp = vnd_open(zonename, argv[0], &vnderr, &syserr); + if (vhp == NULL) { + vnd_libwarn(vnderr, syserr, "failed to open link: %s", argv[0]); + return (1); + } + + for (i = 1; i < argc; i++) { + char *eq, *key, *value; + boolean_t writeable; + vnd_prop_t prop; + void *buf; + size_t psize; + int ret; + + key = argv[i]; + eq = strchr(key, '='); + if (eq == NULL) { + vnd_warn("invalid property name=value: %s\n", key); + return (1); + } + *eq = '\0'; + value = eq + 1; + if (*value == '\0') { + vnd_warn("property value required for %s\n", key); + return (1); + } + prop = vndadm_name_to_prop(key); + if (prop == VND_PROP_MAX) { + vnd_warn("unknown property: %s\n", key); + return (1); + } + + if (vnd_prop_writeable(prop, &writeable) != 0) + abort(); + if (writeable != B_TRUE) { + vnd_warn("property %s is read-only\n", key); + return (1); + } + assert(vndadm_propname_tbl[prop].vp_parse != NULL); + + /* + * vp_parse functions should say what explicitly is invalid. We + * should indicate that the property failed. + */ + ret = vndadm_propname_tbl[prop].vp_parse(value, &buf, &psize); + if (ret != 0) { + vnd_warn("failed to set property %s\n", key); + return (1); + } + + ret = vnd_prop_set(vhp, prop, buf, psize); + free(buf); + if (ret != 0) { + vnd_libwarn(vnd_errno(vhp), vnd_syserrno(vhp), + "failed to set property %s", key); + return (1); + } + } + + return (0); +} + +static void +vndadm_set_usage(FILE *out) +{ + (void) fprintf(out, "\tset:\t\t[-z zonename] link prop=val...\n"); +} + +typedef struct vnd_cmdtab { + const char *vc_name; + int (*vc_op)(int, char *[]); + void (*vc_usage)(FILE *); +} vnd_cmdtab_t; + +static vnd_cmdtab_t vnd_tab[] = { + { "create", vndadm_create, vndadm_create_usage }, + { "destroy", vndadm_destroy, vndadm_destroy_usage }, + { "list", vndadm_list, vndadm_list_usage }, + { "get", vndadm_get, vndadm_get_usage }, + { "set", vndadm_set, vndadm_set_usage }, + { NULL, NULL } +}; + +static int +usage(const char *format, ...) +{ + vnd_cmdtab_t *tab; + const char *help = "usage: %s <subcommand> <args> ...\n"; + + if (format != NULL) { + va_list alist; + + va_start(alist, format); + (void) fprintf(stderr, "%s: ", vnd_pname); + (void) vfprintf(stderr, format, alist); + va_end(alist); + } + (void) fprintf(stderr, help, vnd_pname); + for (tab = vnd_tab; tab->vc_name != NULL; tab++) + tab->vc_usage(stderr); + + return (2); +} + +int +main(int argc, char *argv[]) +{ + vnd_cmdtab_t *tab; + + vnd_pname = basename(argv[0]); + if (argc < 2) { + return (usage(NULL)); + } + + for (tab = vnd_tab; tab->vc_name != NULL; tab++) { + if (strcmp(argv[1], tab->vc_name) == 0) { + argc -= 2; argv += 2; + assert(argc >= 0); + return (tab->vc_op(argc, argv)); + } + } + + return (usage("unknown sub-command '%s'\n", argv[1])); +} diff --git a/usr/src/cmd/vndstat/Makefile b/usr/src/cmd/vndstat/Makefile new file mode 100644 index 0000000000..c77eef3887 --- /dev/null +++ b/usr/src/cmd/vndstat/Makefile @@ -0,0 +1,33 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2014 Joyent, Inc. All rights reserved. +# + +PROG= vndstat + +include ../Makefile.cmd + +LDLIBS += -lkstat + +.KEEP_STATE: + +all: $(PROG) + +install: all $(ROOTPROG) + +clean: + $(RM) $(PROG) + +lint: lint_PROG + +include ../Makefile.targ diff --git a/usr/src/cmd/vndstat/vndstat.c b/usr/src/cmd/vndstat/vndstat.c new file mode 100644 index 0000000000..6f6c76fc12 --- /dev/null +++ b/usr/src/cmd/vndstat/vndstat.c @@ -0,0 +1,542 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2014, Joyent, Inc. All rights reserved. + */ + +#include <sys/kstat.h> +#include <kstat.h> +#include <stdlib.h> +#include <unistd.h> +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <alloca.h> +#include <signal.h> +#include <sys/varargs.h> +#include <sys/int_limits.h> +#include <sys/sysmacros.h> + +#define KSTAT_FIELD_USEINSTANCE 0x01 +#define KSTAT_FIELD_NODELTA 0x02 +#define KSTAT_FIELD_FILLER 0x04 +#define KSTAT_FIELD_STRING 0x08 +#define KSTAT_FIELD_UNIT 0x10 +#define KSTAT_FIELD_LJUST 0x20 + +typedef struct kstat_field { + char *ksf_header; /* header for field */ + char *ksf_name; /* name of stat, if any */ + int ksf_width; /* width for field in output line */ + uint32_t ksf_flags; /* flags for this field, if any */ + char *ksf_suffix; /* optional suffix for units */ + int ksf_hint; /* index hint for field in kstat */ +} kstat_field_t; + +typedef struct kstat_instance { + char ksi_name[KSTAT_STRLEN]; /* name of the underlying kstat */ + int ksi_instance; /* instance identifer of this kstat */ + kstat_t *ksi_ksp; /* pointer to the kstat */ + uint64_t *ksi_data[2]; /* pointer to two generations of data */ + hrtime_t ksi_snaptime[2]; /* hrtime for data generations */ + int ksi_gen; /* current generation */ + struct kstat_instance *ksi_next; /* next in instance list */ +} kstat_instance_t; + +const char *g_cmd = "vndstat"; + +static void +kstat_nicenum(uint64_t num, char *buf, size_t buflen) +{ + uint64_t n = num; + int index = 0; + char u; + + while (n >= 1024) { + n /= 1024; + index++; + } + + u = " KMGTPE"[index]; + + if (index == 0) { + (void) snprintf(buf, buflen, "%llu", n); + } else if ((num & ((1ULL << 10 * index) - 1)) == 0) { + /* + * If this is an even multiple of the base, always display + * without any decimal precision. + */ + (void) snprintf(buf, buflen, "%llu%c", n, u); + } else { + /* + * We want to choose a precision that reflects the best choice + * for fitting in 5 characters. This can get rather tricky when + * we have numbers that are very close to an order of magnitude. + * For example, when displaying 10239 (which is really 9.999K), + * we want only a single place of precision for 10.0K. We could + * develop some complex heuristics for this, but it's much + * easier just to try each combination in turn. + */ + int i; + for (i = 2; i >= 0; i--) { + if (snprintf(buf, buflen, "%.*f%c", i, + (double)num / (1ULL << 10 * index), u) <= 5) + break; + } + } +} + +static void +fatal(char *fmt, ...) +{ + va_list ap; + int error = errno; + + va_start(ap, fmt); + + (void) fprintf(stderr, "%s: ", g_cmd); + /*LINTED*/ + (void) vfprintf(stderr, fmt, ap); + + if (fmt[strlen(fmt) - 1] != '\n') + (void) fprintf(stderr, ": %s\n", strerror(error)); + + exit(EXIT_FAILURE); +} + +int +kstat_field_hint(kstat_t *ksp, kstat_field_t *field) +{ + kstat_named_t *nm = KSTAT_NAMED_PTR(ksp); + int i; + + assert(ksp->ks_type == KSTAT_TYPE_NAMED); + + for (i = 0; i < ksp->ks_ndata; i++) { + if (strcmp(field->ksf_name, nm[i].name) == 0) + return (field->ksf_hint = i); + } + + fatal("could not find field '%s' in %s:%d\n", + field->ksf_name, ksp->ks_name, ksp->ks_instance); + + return (0); +} + +int +kstat_instances_compare(const void *lhs, const void *rhs) +{ + kstat_instance_t *l = *((kstat_instance_t **)lhs); + kstat_instance_t *r = *((kstat_instance_t **)rhs); + int rval; + + if ((rval = strcmp(l->ksi_name, r->ksi_name)) != 0) + return (rval); + + if (l->ksi_instance < r->ksi_instance) + return (-1); + + if (l->ksi_instance > r->ksi_instance) + return (1); + + return (0); +} + +void +kstat_instances_update(kstat_ctl_t *kcp, kstat_instance_t **head, + boolean_t (*interested)(kstat_t *)) +{ + int ninstances = 0, i; + kstat_instance_t **sorted, *ksi, *next; + kstat_t *ksp; + kid_t kid; + + if ((kid = kstat_chain_update(kcp)) == 0 && *head != NULL) + return; + + if (kid == -1) + fatal("failed to update kstat chain"); + + for (ksi = *head; ksi != NULL; ksi = ksi->ksi_next) + ksi->ksi_ksp = NULL; + + for (ksp = kcp->kc_chain; ksp != NULL; ksp = ksp->ks_next) { + kstat_instance_t *last = NULL; + + if (!interested(ksp)) + continue; + + /* + * Now look to see if we have this instance and name. (Yes, + * this is a linear search; we're assuming that this list is + * modest in size.) + */ + for (ksi = *head; ksi != NULL; ksi = ksi->ksi_next) { + last = ksi; + + if (ksi->ksi_instance != ksp->ks_instance) + continue; + + if (strcmp(ksi->ksi_name, ksp->ks_name) != 0) + continue; + + ksi->ksi_ksp = ksp; + ninstances++; + break; + } + + if (ksi != NULL) + continue; + + if ((ksi = malloc(sizeof (kstat_instance_t))) == NULL) + fatal("could not allocate memory for stat instance"); + + bzero(ksi, sizeof (kstat_instance_t)); + (void) strlcpy(ksi->ksi_name, ksp->ks_name, KSTAT_STRLEN); + ksi->ksi_instance = ksp->ks_instance; + ksi->ksi_ksp = ksp; + ksi->ksi_next = NULL; + + if (last == NULL) { + assert(*head == NULL); + *head = ksi; + } else { + last->ksi_next = ksi; + } + + ninstances++; + } + + /* + * Now we know how many instances we have; iterate back over them, + * pruning the stale ones and adding the active ones to a holding + * array in which to sort them. + */ + sorted = (void *)alloca(ninstances * sizeof (kstat_instance_t *)); + ninstances = 0; + + for (ksi = *head; ksi != NULL; ksi = next) { + next = ksi->ksi_next; + + if (ksi->ksi_ksp == NULL) { + free(ksi); + } else { + sorted[ninstances++] = ksi; + } + } + + if (ninstances == 0) { + *head = NULL; + return; + } + + qsort(sorted, ninstances, sizeof (kstat_instance_t *), + kstat_instances_compare); + + *head = sorted[0]; + + for (i = 0; i < ninstances; i++) { + ksi = sorted[i]; + ksi->ksi_next = i < ninstances - 1 ? sorted[i + 1] : NULL; + } +} + +void +kstat_instances_read(kstat_ctl_t *kcp, kstat_instance_t *instances, + kstat_field_t *fields) +{ + kstat_instance_t *ksi; + int i, nfields; + + for (nfields = 0; fields[nfields].ksf_header != NULL; nfields++) + continue; + + for (ksi = instances; ksi != NULL; ksi = ksi->ksi_next) { + kstat_t *ksp = ksi->ksi_ksp; + + if (ksp == NULL) + continue; + + if (kstat_read(kcp, ksp, NULL) == -1) { + if (errno == ENXIO) { + /* + * Our kstat has been removed since the update; + * NULL it out to prevent us from trying to read + * it again (and to indicate that it should not + * be displayed) and drive on. + */ + ksi->ksi_ksp = NULL; + continue; + } + + fatal("failed to read kstat %s:%d", + ksi->ksi_name, ksi->ksi_instance); + } + + if (ksp->ks_type != KSTAT_TYPE_NAMED) { + fatal("%s:%d is not a named kstat", ksi->ksi_name, + ksi->ksi_instance); + } + + if (ksi->ksi_data[0] == NULL) { + size_t size = nfields * sizeof (uint64_t) * 2; + uint64_t *data; + + if ((data = malloc(size)) == NULL) + fatal("could not allocate memory"); + + bzero(data, size); + ksi->ksi_data[0] = data; + ksi->ksi_data[1] = &data[nfields]; + } + + for (i = 0; i < nfields; i++) { + kstat_named_t *nm = KSTAT_NAMED_PTR(ksp); + kstat_field_t *field = &fields[i]; + int hint = field->ksf_hint; + + if (field->ksf_name == NULL) + continue; + + if (hint < 0 || hint >= ksp->ks_ndata || + strcmp(field->ksf_name, nm[hint].name) != 0) { + hint = kstat_field_hint(ksp, field); + } + + if (field->ksf_flags & KSTAT_FIELD_STRING) + ksi->ksi_data[ksi->ksi_gen][i] = + (uint64_t)(uintptr_t) + nm[hint].value.str.addr.ptr; + else + ksi->ksi_data[ksi->ksi_gen][i] = + nm[hint].value.ui64; + } + + ksi->ksi_snaptime[ksi->ksi_gen] = ksp->ks_snaptime; + ksi->ksi_gen ^= 1; + } +} + +uint64_t +kstat_instances_delta(kstat_instance_t *ksi, int i) +{ + int gen = ksi->ksi_gen; + uint64_t delta = ksi->ksi_data[gen ^ 1][i] - ksi->ksi_data[gen][i]; + uint64_t tdelta = ksi->ksi_snaptime[gen ^ 1] - ksi->ksi_snaptime[gen]; + + return (((delta * (uint64_t)NANOSEC) + (tdelta / 2)) / tdelta); +} + +void +kstat_instances_print(kstat_instance_t *instances, kstat_field_t *fields, + boolean_t header) +{ + kstat_instance_t *ksi = instances; + int i, nfields; + + for (nfields = 0; fields[nfields].ksf_header != NULL; nfields++) + continue; + + if (header) { + for (i = 0; i < nfields; i++) { + if (fields[i].ksf_flags & KSTAT_FIELD_LJUST) { + (void) printf("%s%c", fields[i].ksf_header, + i < nfields - 1 ? ' ' : '\n'); + continue; + } + (void) printf("%*s%c", fields[i].ksf_width, + fields[i].ksf_header, i < nfields - 1 ? ' ' : '\n'); + } + } + + for (ksi = instances; ksi != NULL; ksi = ksi->ksi_next) { + if (ksi->ksi_snaptime[1] == 0 || ksi->ksi_ksp == NULL) + continue; + + for (i = 0; i < nfields; i++) { + char trailer = i < nfields - 1 ? ' ' : '\n'; + + if (fields[i].ksf_flags & KSTAT_FIELD_FILLER) { + (void) printf("%*s%c", fields[i].ksf_width, + fields[i].ksf_header, trailer); + continue; + } + + if (fields[i].ksf_flags & KSTAT_FIELD_STRING) { + (void) printf("%*s%c", fields[i].ksf_width, + (char *)(uintptr_t)ksi->ksi_data[ + ksi->ksi_gen ^ 1][i], + trailer); + continue; + } + + if (fields[i].ksf_flags & KSTAT_FIELD_UNIT) { + char buf[128]; + size_t flen = fields[i].ksf_width + 1; + const char *suffix = ""; + + if (fields[i].ksf_suffix != NULL) { + suffix = fields[i].ksf_suffix; + flen -= strlen(fields[i].ksf_suffix); + } + + kstat_nicenum(fields[i].ksf_flags & + KSTAT_FIELD_NODELTA ? + ksi->ksi_data[ksi->ksi_gen ^ 1][i] : + kstat_instances_delta(ksi, i), buf, + MIN(sizeof (buf), flen)); + (void) printf("%*s%s%c", flen - 1, buf, + suffix, trailer); + continue; + } + + (void) printf("%*lld%c", fields[i].ksf_width, + fields[i].ksf_flags & KSTAT_FIELD_USEINSTANCE ? + ksi->ksi_instance : + fields[i].ksf_flags & KSTAT_FIELD_NODELTA ? + ksi->ksi_data[ksi->ksi_gen ^ 1][i] : + kstat_instances_delta(ksi, i), trailer); + } + } +} + +static boolean_t +interested(kstat_t *ksp) +{ + const char *module = "vnd"; + const char *class = "net"; + + if (strcmp(ksp->ks_module, module) != 0) + return (B_FALSE); + + if (strcmp(ksp->ks_class, class) != 0) + return (B_FALSE); + + return (B_TRUE); +} + +/* BEGIN CSTYLED */ +char *g_usage = "Usage: vndstat [interval [count]]\n" + "\n" + " Displays statistics for active vnd devices, with one line per device.\n" + " All statistics are reported as per-second rates.\n" + "\n" + " The columns are as follows:\n" + "\n" + " zone => name of the zone with the device\n" + " name => name of the vnd device\n" + " rx => bytes received\n" + " tx => bytes transmitted\n" + " drops => number of dropped packets\n" + " txfc => number of transmit flow control events\n" + "\n"; +/* END CSTYLED */ + +void +usage() +{ + (void) fprintf(stderr, "%s", g_usage); + exit(EXIT_FAILURE); +} + +/*ARGSUSED*/ +void +intr(int sig) +{} + +/*ARGSUSED*/ +int +main(int argc, char **argv) +{ + kstat_ctl_t *kcp; + kstat_instance_t *instances = NULL; + int i = 0; + int interval = 1; + int count = INT32_MAX; + struct itimerval itimer; + struct sigaction act; + sigset_t set; + char *endp; + + kstat_field_t fields[] = { + { "name", "linkname", 6, KSTAT_FIELD_STRING }, + { "|", NULL, 1, KSTAT_FIELD_FILLER }, + { "rx B/s", "rbytes", 8, KSTAT_FIELD_UNIT, "B/s" }, + { "|", NULL, 1, KSTAT_FIELD_FILLER }, + { "tx B/s", "obytes", 8, KSTAT_FIELD_UNIT, "B/s" }, + { "|", NULL, 1, KSTAT_FIELD_FILLER }, + { "drops", "total_drops", 5 }, + { "txfc", "flowcontrol_events", 4 }, + { "|", NULL, 1, KSTAT_FIELD_FILLER }, + { "zone", "zonename", 36, + KSTAT_FIELD_STRING | KSTAT_FIELD_LJUST }, + { NULL } + }; + + if (argc > 1) { + interval = strtol(argv[1], &endp, 10); + + if (*endp != '\0' || interval <= 0) + usage(); + } + + if (argc > 2) { + count = strtol(argv[2], &endp, 10); + + if (*endp != '\0' || count <= 0) + usage(); + } + + if ((kcp = kstat_open()) == NULL) + fatal("could not open /dev/kstat"); + + (void) sigemptyset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = intr; + (void) sigaction(SIGALRM, &act, NULL); + + (void) sigemptyset(&set); + (void) sigaddset(&set, SIGALRM); + (void) sigprocmask(SIG_BLOCK, &set, NULL); + + bzero(&itimer, sizeof (itimer)); + itimer.it_value.tv_sec = interval; + itimer.it_interval.tv_sec = interval; + + if (setitimer(ITIMER_REAL, &itimer, NULL) != 0) { + fatal("could not set timer to %d second%s", interval, + interval == 1 ? "" : "s"); + } + + (void) sigemptyset(&set); + + for (;;) { + kstat_instances_update(kcp, &instances, interested); + kstat_instances_read(kcp, instances, fields); + + if (i++ > 0) { + kstat_instances_print(instances, fields, + instances != NULL && instances->ksi_next == NULL ? + (((i - 2) % 20) == 0) : B_TRUE); + } + + if (i > count) + break; + + (void) sigsuspend(&set); + } + + /*NOTREACHED*/ + return (0); +} diff --git a/usr/src/cmd/zdb/zdb.c b/usr/src/cmd/zdb/zdb.c index 3d0490b73e..be07c5aa7d 100644 --- a/usr/src/cmd/zdb/zdb.c +++ b/usr/src/cmd/zdb/zdb.c @@ -907,7 +907,7 @@ dump_metaslab(metaslab_t *msp) if (dump_opt['m'] > 2 && !dump_opt['L']) { mutex_enter(&msp->ms_lock); - VERIFY0(metaslab_load(msp)); + VERIFY0(metaslab_load(msp, 0)); range_tree_stat_verify(msp->ms_allocatable); dump_metaslab_stats(msp); metaslab_unload(msp); diff --git a/usr/src/cmd/zfs/zfs_main.c b/usr/src/cmd/zfs/zfs_main.c index ca11041cba..993d98ea12 100644 --- a/usr/src/cmd/zfs/zfs_main.c +++ b/usr/src/cmd/zfs/zfs_main.c @@ -239,7 +239,7 @@ get_usage(zfs_help_t idx) "<filesystem|volume>@<snap>[%<snap>][,...]\n" "\tdestroy <filesystem|volume>#<bookmark>\n")); case HELP_GET: - return (gettext("\tget [-rHp] [-d max] " + return (gettext("\tget [-crHp] [-d max] " "[-o \"all\" | field[,...]]\n" "\t [-t type[,...]] [-s source[,...]]\n" "\t <\"all\" | property[,...]> " @@ -625,7 +625,7 @@ should_auto_mount(zfs_handle_t *zhp) } /* - * zfs clone [-p] [-o prop=value] ... <snap> <fs | vol> + * zfs clone [-Fp] [-o prop=value] ... <snap> <fs | vol> * * Given an existing dataset, create a writable copy whose initial contents * are the same as the source. The newly created dataset maintains a @@ -633,12 +633,18 @@ should_auto_mount(zfs_handle_t *zhp) * the clone exists. * * The '-p' flag creates all the non-existing ancestors of the target first. + * + * The '-F' flag retries the zfs_mount() operation as long as zfs_mount() is + * still returning EBUSY. Any callers which specify -F should be careful to + * ensure that no other process has a persistent hold on the mountpoint's + * directory. */ static int zfs_do_clone(int argc, char **argv) { zfs_handle_t *zhp = NULL; boolean_t parents = B_FALSE; + boolean_t keeptrying = B_FALSE; nvlist_t *props; int ret = 0; int c; @@ -647,8 +653,11 @@ zfs_do_clone(int argc, char **argv) nomem(); /* check options */ - while ((c = getopt(argc, argv, "o:p")) != -1) { + while ((c = getopt(argc, argv, "Fo:p")) != -1) { switch (c) { + case 'F': + keeptrying = B_TRUE; + break; case 'o': if (parseprop(props, optarg) != 0) return (1); @@ -715,11 +724,16 @@ zfs_do_clone(int argc, char **argv) * step. */ if (should_auto_mount(clone)) { - if ((ret = zfs_mount(clone, NULL, 0)) != 0) { - (void) fprintf(stderr, gettext("clone " - "successfully created, " - "but not mounted\n")); - } else if ((ret = zfs_share(clone)) != 0) { + while ((ret = zfs_mount(clone, NULL, 0)) != 0) { + if (!keeptrying || errno != EBUSY) { + (void) fprintf(stderr, + gettext("clone " + "successfully created, " + "but not mounted\n")); + break; + } + } + if (ret == 0 && (ret = zfs_share(clone)) != 0) { (void) fprintf(stderr, gettext("clone " "successfully created, " "but not shared\n")); @@ -945,12 +959,13 @@ badusage: } /* - * zfs destroy [-rRf] <fs, vol> + * zfs destroy [-rRfF] <fs, vol> * zfs destroy [-rRd] <snap> * * -r Recursively destroy all children * -R Recursively destroy all dependents, including clones * -f Force unmounting of any dependents + * -F Continue retrying on seeing EBUSY * -d If we can't destroy now, mark for deferred destruction * * Destroys the given dataset. By default, it will unmount any filesystems, @@ -960,6 +975,7 @@ badusage: typedef struct destroy_cbdata { boolean_t cb_first; boolean_t cb_force; + boolean_t cb_wait; boolean_t cb_recurse; boolean_t cb_error; boolean_t cb_doclones; @@ -1043,13 +1059,18 @@ out: static int destroy_callback(zfs_handle_t *zhp, void *data) { - destroy_cbdata_t *cb = data; + destroy_cbdata_t *cbp = data; + struct timespec ts; + int err = 0; + + ts.tv_sec = 0; + ts.tv_nsec = 500 * (NANOSEC / MILLISEC); const char *name = zfs_get_name(zhp); - if (cb->cb_verbose) { - if (cb->cb_parsable) { + if (cbp->cb_verbose) { + if (cbp->cb_parsable) { (void) printf("destroy\t%s\n", name); - } else if (cb->cb_dryrun) { + } else if (cbp->cb_dryrun) { (void) printf(gettext("would destroy %s\n"), name); } else { @@ -1064,13 +1085,10 @@ destroy_callback(zfs_handle_t *zhp, void *data) */ if (strchr(zfs_get_name(zhp), '/') == NULL && zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) { - zfs_close(zhp); - return (0); - } - if (cb->cb_dryrun) { - zfs_close(zhp); - return (0); + goto out; } + if (cbp->cb_dryrun) + goto out; /* * We batch up all contiguous snapshots (even of different @@ -1079,23 +1097,66 @@ destroy_callback(zfs_handle_t *zhp, void *data) * because we must delete a clone before its origin. */ if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) { - fnvlist_add_boolean(cb->cb_batchedsnaps, name); - } else { - int error = zfs_destroy_snaps_nvl(g_zfs, - cb->cb_batchedsnaps, B_FALSE); - fnvlist_free(cb->cb_batchedsnaps); - cb->cb_batchedsnaps = fnvlist_alloc(); - - if (error != 0 || - zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 || - zfs_destroy(zhp, cb->cb_defer_destroy) != 0) { - zfs_close(zhp); - return (-1); + fnvlist_add_boolean(cbp->cb_batchedsnaps, name); + goto out; + } + + if (cbp->cb_wait) + libzfs_print_on_error(g_zfs, B_FALSE); + + /* + * Unless instructed to retry on EBUSY, bail out on the first error. + * When retrying, try every 500ms until either succeeding or seeing a + * non-EBUSY error code. + */ + while ((err = zfs_destroy_snaps_nvl(g_zfs, + cbp->cb_batchedsnaps, B_FALSE)) != 0) { + if (cbp->cb_wait && libzfs_errno(g_zfs) == EZFS_BUSY) { + nanosleep(&ts, NULL); + continue; } + (void) fprintf(stderr, "%s: %s\n", + libzfs_error_action(g_zfs), + libzfs_error_description(g_zfs)); + break; + } + + fnvlist_free(cbp->cb_batchedsnaps); + cbp->cb_batchedsnaps = fnvlist_alloc(); + + if (err != 0) + goto out; + + while ((err = zfs_unmount(zhp, NULL, + cbp->cb_force ? MS_FORCE : 0)) != 0) { + if (cbp->cb_wait && libzfs_errno(g_zfs) == EZFS_BUSY) { + (void) nanosleep(&ts, NULL); + continue; + } + (void) fprintf(stderr, "%s: %s\n", + libzfs_error_action(g_zfs), + libzfs_error_description(g_zfs)); + break; + } + + if (err != 0) + goto out; + + while ((err = zfs_destroy(zhp, cbp->cb_defer_destroy)) != 0) { + if (cbp->cb_wait && libzfs_errno(g_zfs) == EZFS_BUSY) { + (void) nanosleep(&ts, NULL); + continue; + } + (void) fprintf(stderr, "%s: %s\n", + libzfs_error_action(g_zfs), + libzfs_error_description(g_zfs)); + break; } +out: + libzfs_print_on_error(g_zfs, B_TRUE); zfs_close(zhp); - return (0); + return (err); } static int @@ -1251,7 +1312,7 @@ zfs_do_destroy(int argc, char **argv) zfs_type_t type = ZFS_TYPE_DATASET; /* check options */ - while ((c = getopt(argc, argv, "vpndfrR")) != -1) { + while ((c = getopt(argc, argv, "vpndfFrR")) != -1) { switch (c) { case 'v': cb.cb_verbose = B_TRUE; @@ -1270,6 +1331,9 @@ zfs_do_destroy(int argc, char **argv) case 'f': cb.cb_force = B_TRUE; break; + case 'F': + cb.cb_wait = B_TRUE; + break; case 'r': cb.cb_recurse = B_TRUE; break; @@ -1640,8 +1704,11 @@ zfs_do_get(int argc, char **argv) cb.cb_type = ZFS_TYPE_DATASET; /* check options */ - while ((c = getopt(argc, argv, ":d:o:s:rt:Hp")) != -1) { + while ((c = getopt(argc, argv, ":d:o:s:rt:Hcp")) != -1) { switch (c) { + case 'c': + libzfs_set_cachedprops(g_zfs, B_TRUE); + break; case 'p': cb.cb_literal = B_TRUE; break; @@ -3079,6 +3146,7 @@ zfs_do_list(int argc, char **argv) int types = ZFS_TYPE_DATASET; boolean_t types_specified = B_FALSE; char *fields = NULL; + zprop_list_t *pl; list_cbdata_t cb = { 0 }; char *value; int limit = 0; @@ -3197,6 +3265,18 @@ zfs_do_list(int argc, char **argv) != 0) usage(B_FALSE); + /* + * The default set of properties contains only properties which can be + * retrieved from the set of cached properties. If any user-specfied + * properties cannot be retrieved from that set, unset the cachedprops + * flags on the ZFS handle. + */ + libzfs_set_cachedprops(g_zfs, B_TRUE); + for (pl = cb.cb_proplist; pl != NULL; pl = pl->pl_next) { + if (zfs_prop_cacheable(pl->pl_prop)) + libzfs_set_cachedprops(g_zfs, B_FALSE); + } + cb.cb_first = B_TRUE; ret = zfs_for_each(argc, argv, flags, types, sortcol, &cb.cb_proplist, diff --git a/usr/src/cmd/zlogin/zlogin.c b/usr/src/cmd/zlogin/zlogin.c index 296c32be01..1934ba2595 100644 --- a/usr/src/cmd/zlogin/zlogin.c +++ b/usr/src/cmd/zlogin/zlogin.c @@ -22,11 +22,12 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2013 DEY Storage Systems, Inc. * Copyright (c) 2014 Gary Mills + * Copyright 2016 Joyent, Inc. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ /* - * zlogin provides three types of login which allow users in the global + * zlogin provides five types of login which allow users in the global * zone to access non-global zones. * * - "interactive login" is similar to rlogin(1); for example, the user could @@ -42,12 +43,22 @@ * In this mode, zlogin sets up pipes as the communication channel, and * 'su' is used to do the login setup work. * + * - "interactive command" is a combination of the above two modes where + * a command is provide like the non-interactive case, but the -i option is + * also provided to make things interactive. For example, the user could + * issue 'zlogin -i my-zone /bin/sh'. In this mode neither 'login -c' nor + * 'su root -c' is prepended to the command invocation. Because of this + * there will be no wtmpx login record within the zone. + * * - "console login" is the equivalent to accessing the tip line for a * zone. For example, the user can issue 'zlogin -C my-zone'. * In this mode, zlogin contacts the zoneadmd process via unix domain * socket. If zoneadmd is not running, it starts it. This allows the * console to be available anytime the zone is installed, regardless of * whether it is running. + * + * - "standalone-processs interactive" is specified with -I and connects to + * the zone's stdin, stdout and stderr zfd(7D) devices. */ #include <sys/socket.h> @@ -92,7 +103,8 @@ #include <auth_attr.h> #include <secdb.h> -static int masterfd; +static int masterfd = -1; +static int ctlfd = -1; static struct termios save_termios; static struct termios effective_termios; static int save_fd; @@ -101,12 +113,13 @@ static volatile int dead; static volatile pid_t child_pid = -1; static int interactive = 0; static priv_set_t *dropprivs; +static unsigned int connect_flags = 0; static int nocmdchar = 0; static int failsafe = 0; -static int disconnect = 0; static char cmdchar = '~'; static int quiet = 0; +static char zonebrand[MAXNAMELEN]; static int pollerr = 0; @@ -123,10 +136,14 @@ static boolean_t forced_login = B_FALSE; #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */ #endif -#define SUPATH "/usr/bin/su" +#define SUPATH1 "/usr/bin/su" +#define SUPATH2 "/bin/su" #define FAILSAFESHELL "/sbin/sh" #define DEFAULTSHELL "/sbin/sh" #define DEF_PATH "/usr/sbin:/usr/bin" +#define LX_DEF_PATH "/bin:/usr/sbin:/usr/bin" + +#define MAX_RETRY 30 #define CLUSTER_BRAND_NAME "cluster" @@ -153,7 +170,7 @@ static boolean_t forced_login = B_FALSE; static void usage(void) { - (void) fprintf(stderr, gettext("usage: %s [ -dnQCES ] [ -e cmdchar ] " + (void) fprintf(stderr, gettext("usage: %s [-dinCEINQS] [-e cmdchar] " "[-l user] zonename [command [args ...] ]\n"), pname); exit(2); } @@ -248,57 +265,60 @@ postfork_dropprivs() } } -/* - * Create the unix domain socket and call the zoneadmd server; handshake - * with it to determine whether it will allow us to connect. - */ static int -get_console_master(const char *zname) +connect_zone_sock(const char *zname, const char *suffix, boolean_t verbose) { int sockfd = -1; struct sockaddr_un servaddr; - char clientid[MAXPATHLEN]; - char handshake[MAXPATHLEN], c; - int msglen; - int i = 0, err = 0; if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - zperror(gettext("could not create socket")); + if (verbose) + zperror(gettext("could not create socket")); return (-1); } bzero(&servaddr, sizeof (servaddr)); servaddr.sun_family = AF_UNIX; (void) snprintf(servaddr.sun_path, sizeof (servaddr.sun_path), - "%s/%s.console_sock", ZONES_TMPDIR, zname); - + "%s/%s.%s", ZONES_TMPDIR, zname, suffix); if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof (servaddr)) == -1) { - zperror(gettext("Could not connect to zone console")); - goto bad; + if (verbose) + zperror(gettext("Could not connect to zone")); + close(sockfd); + return (-1); } - masterfd = sockfd; + return (sockfd); +} - msglen = snprintf(clientid, sizeof (clientid), "IDENT %lu %s %d\n", - getpid(), setlocale(LC_MESSAGES, NULL), disconnect); + +static int +handshake_zone_sock(int sockfd, unsigned int flags) +{ + char clientid[MAXPATHLEN]; + char handshake[MAXPATHLEN], c; + int msglen; + int i = 0, err = 0; + + msglen = snprintf(clientid, sizeof (clientid), "IDENT %s %u\n", + setlocale(LC_MESSAGES, NULL), flags); if (msglen >= sizeof (clientid) || msglen < 0) { zerror("protocol error"); - goto bad; + return (-1); } - if (write(masterfd, clientid, msglen) != msglen) { + if (write(sockfd, clientid, msglen) != msglen) { zerror("protocol error"); - goto bad; + return (-1); } - bzero(handshake, sizeof (handshake)); - /* * Take care not to accumulate more than our fill, and leave room for * the NUL at the end. */ - while ((err = read(masterfd, &c, 1)) == 1) { + bzero(handshake, sizeof (handshake)); + while ((err = read(sockfd, &c, 1)) == 1) { if (i >= (sizeof (handshake) - 1)) break; if (c == '\n') @@ -308,26 +328,48 @@ get_console_master(const char *zname) } /* - * If something went wrong during the handshake we bail; perhaps - * the server died off. + * If something went wrong during the handshake we bail. + * Perhaps the server died off. */ if (err == -1) { - zperror(gettext("Could not connect to zone console")); - goto bad; + zperror(gettext("Could not connect to zone")); + return (-1); } - if (strncmp(handshake, "OK", sizeof (handshake)) == 0) - return (0); + if (strncmp(handshake, "OK", sizeof (handshake)) != 0) { + zerror(gettext("Zone is already in use by process ID %s."), + handshake); + return (-1); + } - zerror(gettext("Console is already in use by process ID %s."), - handshake); -bad: - (void) close(sockfd); - masterfd = -1; - return (-1); + return (0); } - +static int +send_ctl_sock(const char *buf, size_t len) +{ + char rbuf[BUFSIZ]; + int i; + if (ctlfd == -1) { + return (-1); + } + if (write(ctlfd, buf, len) != len) { + return (-1); + } + /* read the response */ + for (i = 0; i < (BUFSIZ - 1); i++) { + char c; + if (read(ctlfd, &c, 1) != 1 || c == '\n' || c == '\0') { + break; + } + rbuf[i] = c; + } + rbuf[i+1] = '\0'; + if (strncmp("OK", rbuf, BUFSIZ) != 0) { + return (-1); + } + return (0); +} /* * Routines to handle pty creation upon zone entry and to shuttle I/O back * and forth between the two terminals. We also compute and store the @@ -516,8 +558,32 @@ sigwinch(int s) { struct winsize ws; - if (ioctl(0, TIOCGWINSZ, &ws) == 0) - (void) ioctl(masterfd, TIOCSWINSZ, &ws); + if (ioctl(0, TIOCGWINSZ, &ws) == 0) { + if (ctlfd != -1) { + char buf[BUFSIZ]; + snprintf(buf, sizeof (buf), "TIOCSWINSZ %hu %hu\n", + ws.ws_row, ws.ws_col); + (void) send_ctl_sock(buf, strlen(buf)); + } else { + (void) ioctl(masterfd, TIOCSWINSZ, &ws); + } + } +} + +/* + * Toggle zfd EOF mode and notify zoneadmd + */ +/*ARGSUSED*/ +static void +sigusr1(int s) +{ + connect_flags ^= ZLOGIN_ZFD_EOF; + if (ctlfd != -1) { + char buf[BUFSIZ]; + snprintf(buf, sizeof (buf), "SETFLAGS %u\n", + connect_flags); + (void) send_ctl_sock(buf, strlen(buf)); + } } static volatile int close_on_sig = -1; @@ -862,28 +928,28 @@ doio(int stdin_fd, int appin_fd, int stdout_fd, int stderr_fd, int sig_fd, break; } - /* event from master side stdout */ - if (pollfds[0].revents) { - if (pollfds[0].revents & + /* event from master side stderr */ + if (pollfds[1].revents) { + if (pollfds[1].revents & (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { - if (process_output(stdout_fd, STDOUT_FILENO) + if (process_output(stderr_fd, STDERR_FILENO) != 0) break; } else { - pollerr = pollfds[0].revents; + pollerr = pollfds[1].revents; break; } } - /* event from master side stderr */ - if (pollfds[1].revents) { - if (pollfds[1].revents & + /* event from master side stdout */ + if (pollfds[0].revents) { + if (pollfds[0].revents & (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { - if (process_output(stderr_fd, STDERR_FILENO) + if (process_output(stdout_fd, STDOUT_FILENO) != 0) break; } else { - pollerr = pollfds[1].revents; + pollerr = pollfds[0].revents; break; } } @@ -1053,7 +1119,7 @@ zone_login_cmd(brand_handle_t bh, const char *login) * but we're going to be very simplistic about it and break stuff * up based on spaces. We're not even going to support any kind * of quoting or escape characters. It's truly amazing that - * there is no library function in OpenSolaris to do this for us. + * there is no library function in Illumos to do this for us. */ /* @@ -1092,69 +1158,155 @@ zone_login_cmd(brand_handle_t bh, const char *login) } /* - * Prepare argv array for exec'd process; if we're passing commands to the - * new process, then use su(1M) to do the invocation. Otherwise, use + * Prepare argv array for exec'd process. If commands are passed to the new + * process and su(1M) is avalable, use it for the invocation. Otherwise, use * 'login -z <from_zonename> -f' (-z is an undocumented option which tells * login that we're coming from another zone, and to disregard its CONSOLE * checks). */ static char ** -prep_args(brand_handle_t bh, const char *login, char **argv) +prep_args(brand_handle_t bh, char *zonename, const char *login, char **argv) { - int argc = 0, a = 0, i, n = -1; - char **new_argv; + int argc = 0, i; + size_t subshell_len = 1; + char *subshell = NULL, *supath = NULL; + char **new_argv = NULL; - if (argv != NULL) { - size_t subshell_len = 1; - char *subshell; + if (argv == NULL) { + if (failsafe) { + if ((new_argv = malloc(sizeof (char *) * 2)) == NULL) + return (NULL); + new_argv[0] = FAILSAFESHELL; + new_argv[1] = NULL; + } else { + new_argv = zone_login_cmd(bh, login); + } + return (new_argv); + } - while (argv[argc] != NULL) - argc++; + /* + * Attempt to locate a 'su' binary if not using the failsafe shell. + */ + if (!failsafe) { + struct stat sb; + char zonepath[MAXPATHLEN]; + char supath_check[MAXPATHLEN]; + + if (zone_get_zonepath(zonename, zonepath, + sizeof (zonepath)) != Z_OK) { + zerror(gettext("unable to determine zone " + "path")); + return (NULL); + } - for (i = 0; i < argc; i++) { - subshell_len += strlen(argv[i]) + 1; + (void) snprintf(supath_check, sizeof (supath), "%s/root/%s", + zonepath, SUPATH1); + if (stat(supath_check, &sb) == 0) { + supath = SUPATH1; + } else { + (void) snprintf(supath_check, sizeof (supath_check), + "%s/root/%s", zonepath, SUPATH2); + if (stat(supath_check, &sb) == 0) { + supath = SUPATH2; + } } - if ((subshell = calloc(1, subshell_len)) == NULL) + } + + /* + * With no failsafe shell or supath to wrap the incoming command, the + * arguments are passed straight through. + */ + if (!failsafe && supath == NULL) { + /* + * Such an outcome is not acceptable, however, if the caller + * expressed a desire to switch users. + */ + if (strcmp(login, "root") != 0) { + zerror(gettext("unable to find 'su' command")); return (NULL); + } + return (argv); + } - for (i = 0; i < argc; i++) { - (void) strcat(subshell, argv[i]); + /* + * Inventory arguments and allocate a buffer to escape them for the + * subshell. + */ + while (argv[argc] != NULL) { + /* + * Allocate enough space for the delimiter and 2 + * quotes which might be needed. + */ + subshell_len += strlen(argv[argc]) + 3; + argc++; + } + if ((subshell = calloc(1, subshell_len)) == NULL) { + return (NULL); + } + + /* + * The handling of quotes in the following block may seem unusual, but + * it is done this way for backward compatibility. + * When running a command, zlogin is documented as: + * zlogin zonename command args + * However, some code has come to depend on the following usage: + * zlogin zonename 'command args' + * This relied on the fact that the single argument would be re-parsed + * within the zone and excuted as a command with an argument. To remain + * compatible with this (incorrect) usage, if there is only a single + * argument, it is not quoted, even if it has embedded spaces. + * + * Here are two examples which both need to work: + * 1) zlogin foo 'echo hello' + * This has a single argv member with a space in it but will not be + * quoted on the command passed into the zone. + * 2) zlogin foo bash -c 'echo hello' + * This has 3 argv members. The 3rd arg has a space and must be + * quoted on the command passed into the zone. + */ + for (i = 0; i < argc; i++) { + if (i > 0) (void) strcat(subshell, " "); + + if (argc > 1 && (strchr(argv[i], ' ') != NULL || + strchr(argv[i], '\t') != NULL)) { + (void) strcat(subshell, "'"); + (void) strcat(subshell, argv[i]); + (void) strcat(subshell, "'"); + } else { + (void) strcat(subshell, argv[i]); } + } - if (failsafe) { - n = 4; - if ((new_argv = malloc(sizeof (char *) * n)) == NULL) - return (NULL); + if (failsafe) { + int a = 0, n = 4; - new_argv[a++] = FAILSAFESHELL; - } else { - n = 5; - if ((new_argv = malloc(sizeof (char *) * n)) == NULL) - return (NULL); + if ((new_argv = malloc(sizeof (char *) * n)) == NULL) + return (NULL); - new_argv[a++] = SUPATH; - if (strcmp(login, "root") != 0) { - new_argv[a++] = "-"; - n++; - } - new_argv[a++] = (char *)login; - } + new_argv[a++] = FAILSAFESHELL; new_argv[a++] = "-c"; new_argv[a++] = subshell; new_argv[a++] = NULL; assert(a == n); } else { - if (failsafe) { - n = 2; - if ((new_argv = malloc(sizeof (char *) * n)) == NULL) - return (NULL); - new_argv[a++] = FAILSAFESHELL; - new_argv[a++] = NULL; - assert(n == a); + int a = 0, n = 6; + + assert(supath != NULL); + if ((new_argv = malloc(sizeof (char *) * n)) == NULL) + return (NULL); + + new_argv[a++] = supath; + if (strcmp(login, "root") != 0) { + new_argv[a++] = "-"; } else { - new_argv = zone_login_cmd(bh, login); + n--; } + new_argv[a++] = (char *)login; + new_argv[a++] = "-c"; + new_argv[a++] = subshell; + new_argv[a++] = NULL; + assert(a == n); } return (new_argv); @@ -1185,6 +1337,7 @@ prep_env() int e = 0, size = 1; char **new_env, *estr; char *term = getenv("TERM"); + char *path; size++; /* for $PATH */ if (term != NULL) @@ -1201,7 +1354,12 @@ prep_env() if ((new_env = malloc(sizeof (char *) * size)) == NULL) return (NULL); - if ((estr = add_env("PATH", DEF_PATH)) == NULL) + if (strcmp(zonebrand, "lx") == 0) + path = LX_DEF_PATH; + else + path = DEF_PATH; + + if ((estr = add_env("PATH", path)) == NULL) return (NULL); new_env[e++] = estr; @@ -1723,24 +1881,61 @@ get_username() return (nptr->pw_name); } +static boolean_t +zlog_mode_logging(char *zonename, boolean_t *found) +{ + boolean_t lm = B_FALSE; + zone_dochandle_t handle; + struct zone_attrtab attr; + + *found = B_FALSE; + if ((handle = zonecfg_init_handle()) == NULL) + return (lm); + + if (zonecfg_get_handle(zonename, handle) != Z_OK) + goto done; + + if (zonecfg_setattrent(handle) != Z_OK) + goto done; + while (zonecfg_getattrent(handle, &attr) == Z_OK) { + if (strcmp("zlog-mode", attr.zone_attr_name) == 0) { + int len = strlen(attr.zone_attr_value); + + *found = B_TRUE; + if (strncmp("log", attr.zone_attr_value, 3) == 0 || + strncmp("nolog", attr.zone_attr_value, 5) == 0 || + (len >= 3 && attr.zone_attr_value[len - 2] == '-')) + lm = B_TRUE; + break; + } + } + (void) zonecfg_endattrent(handle); + +done: + zonecfg_fini_handle(handle); + return (lm); +} + int main(int argc, char **argv) { - int arg, console = 0; + int arg, console = 0, imode = 0; + int estatus = 0; zoneid_t zoneid; zone_state_t st; char *login = "root"; + int iflag = 0; int lflag = 0; int nflag = 0; char *zonename = NULL; char **proc_args = NULL; char **new_args, **new_env; sigset_t block_cld; + siginfo_t si; char devroot[MAXPATHLEN]; char *slavename, slaveshortname[MAXPATHLEN]; priv_set_t *privset; int tmpl_fd; - char zonebrand[MAXNAMELEN]; char default_brand[MAXNAMELEN]; struct stat sb; char kernzone[ZONENAME_MAX]; @@ -1754,7 +1949,7 @@ main(int argc, char **argv) (void) getpname(argv[0]); username = get_username(); - while ((arg = getopt(argc, argv, "dnECR:Se:l:Q")) != EOF) { + while ((arg = getopt(argc, argv, "diNnECIR:Se:l:Q")) != EOF) { switch (arg) { case 'C': console = 1; @@ -1762,6 +1957,16 @@ main(int argc, char **argv) case 'E': nocmdchar = 1; break; + case 'I': + /* + * interactive mode is just a slight variation on the + * console mode. + */ + console = 1; + imode = 1; + /* The default is HUP, disconnect on EOF */ + connect_flags ^= ZLOGIN_ZFD_EOF; + break; case 'R': /* undocumented */ if (*optarg != '/') { zerror(gettext("root path must be absolute.")); @@ -1781,15 +1986,22 @@ main(int argc, char **argv) failsafe = 1; break; case 'd': - disconnect = 1; + connect_flags |= ZLOGIN_DISCONNECT; break; case 'e': set_cmdchar(optarg); break; + case 'i': + iflag = 1; + break; case 'l': login = optarg; lflag = 1; break; + case 'N': + /* NOHUP - do not send EOF */ + connect_flags ^= ZLOGIN_ZFD_EOF; + break; case 'n': nflag = 1; break; @@ -1800,6 +2012,12 @@ main(int argc, char **argv) if (console != 0) { + /* + * The only connect option in console mode is ZLOGIN_DISCONNECT + */ + if (imode == 0) + connect_flags &= ZLOGIN_DISCONNECT; + if (lflag != 0) { zerror(gettext( "-l may not be specified for console login")); @@ -1826,17 +2044,27 @@ main(int argc, char **argv) } + if (iflag != 0 && nflag != 0) { + zerror(gettext("-i and -n flags are incompatible")); + usage(); + } + if (failsafe != 0 && lflag != 0) { zerror(gettext("-l may not be specified for failsafe login")); usage(); } - if (!console && disconnect != 0) { + if (!console && (connect_flags & ZLOGIN_DISCONNECT) != 0) { zerror(gettext( "-d may only be specified with console login")); usage(); } + if (imode == 0 && (connect_flags & ZLOGIN_ZFD_EOF) != 0) { + zerror(gettext("-N may only be specified with -I")); + usage(); + } + if (optind == (argc - 1)) { /* * zone name, no process name; this should be an interactive @@ -1859,7 +2087,8 @@ main(int argc, char **argv) /* zone name and process name, and possibly some args */ zonename = argv[optind]; proc_args = &argv[optind + 1]; - interactive = 0; + if (iflag && isatty(STDIN_FILENO)) + interactive = 1; } else { usage(); } @@ -1945,10 +2174,31 @@ main(int argc, char **argv) } /* - * The console is a separate case from the rest of the code; handle - * it first. + * The console (or standalong interactive mode) is a separate case from + * the rest of the code; handle it first. */ if (console) { + int gz_stderr_fd = -1; + int retry; + boolean_t set_raw = B_TRUE; + + if (imode) { + boolean_t has_zfd_config; + + if (zlog_mode_logging(zonename, &has_zfd_config)) + set_raw = B_FALSE; + + /* + * Asked for standalone interactive mode but the + * zlog-mode attribute is not configured on the zone. + */ + if (!has_zfd_config) { + zerror(gettext("'%s' is not configured on " + "the zone"), "zlog-mode"); + return (1); + } + } + /* * Ensure that zoneadmd for this zone is running. */ @@ -1957,16 +2207,56 @@ main(int argc, char **argv) /* * Make contact with zoneadmd. + * + * Handshake with the control socket first. We handle retries + * here since the relevant thread in zoneadmd might not have + * finished setting up yet. */ - if (get_console_master(zonename) == -1) + for (retry = 0; retry < MAX_RETRY; retry++) { + masterfd = connect_zone_sock(zonename, + (imode ? "server_ctl" : "console_sock"), B_FALSE); + if (masterfd != -1) + break; + sleep(1); + } + + if (retry == MAX_RETRY) { + zerror(gettext("unable to connect for %d seconds"), + MAX_RETRY); return (1); + } - if (!quiet) - (void) printf( - gettext("[Connected to zone '%s' console]\n"), - zonename); + if (handshake_zone_sock(masterfd, connect_flags) != 0) { + (void) close(masterfd); + return (1); + } + + if (imode) { + ctlfd = masterfd; + + /* Now open the io-related sockets */ + masterfd = connect_zone_sock(zonename, "server_out", + B_TRUE); + gz_stderr_fd = connect_zone_sock(zonename, + "server_err", B_TRUE); + if (masterfd == -1 || gz_stderr_fd == -1) { + (void) close(ctlfd); + (void) close(masterfd); + (void) close(gz_stderr_fd); + return (1); + } + } - if (set_tty_rawmode(STDIN_FILENO) == -1) { + if (!quiet) { + if (imode) + (void) printf(gettext("[Connected to zone '%s' " + "interactively]\n"), zonename); + else + (void) printf(gettext("[Connected to zone '%s' " + "console]\n"), zonename); + } + + if (set_raw && set_tty_rawmode(STDIN_FILENO) == -1) { reset_tty(); zperror(gettext("failed to set stdin pty to raw mode")); return (1); @@ -1975,15 +2265,25 @@ main(int argc, char **argv) (void) sigset(SIGWINCH, sigwinch); (void) sigwinch(0); + if (imode) { + /* Allow EOF mode toggling via SIGUSR1 */ + (void) sigset(SIGUSR1, sigusr1); + } + /* * Run the I/O loop until we get disconnected. */ - doio(masterfd, -1, masterfd, -1, -1, B_FALSE); + doio(masterfd, -1, masterfd, gz_stderr_fd, -1, B_FALSE); reset_tty(); - if (!quiet) - (void) printf( - gettext("\n[Connection to zone '%s' console " - "closed]\n"), zonename); + if (!quiet) { + if (imode) + (void) printf(gettext("\n[Interactive " + "connection to zone '%s' closed]\n"), + zonename); + else + (void) printf(gettext("\n[Connection to zone " + "'%s' console closed]\n"), zonename); + } return (0); } @@ -2051,11 +2351,23 @@ main(int argc, char **argv) return (1); } - if ((new_args = prep_args(bh, login, proc_args)) == NULL) { - zperror(gettext("could not assemble new arguments")); - brand_close(bh); - return (1); + /* + * The 'interactive' parameter (-i option) indicates that we're running + * a command interactively. In this case we skip prep_args so that we + * don't prepend the 'su root -c' preamble to the command invocation + * since the 'su' command typically will execute a setpgrp which will + * disassociate the actual command from the controlling terminal that + * we (zlogin) setup. + */ + if (!iflag) { + if ((new_args = prep_args(bh, zonename, login, proc_args)) + == NULL) { + zperror(gettext("could not assemble new arguments")); + brand_close(bh); + return (1); + } } + /* * Get the brand specific user_cmd. This command is used to get * a passwd(4) entry for login. @@ -2201,6 +2513,8 @@ main(int argc, char **argv) return (1); } + /* Note: we're now inside the zone, can't use gettext anymore */ + if (slavefd != STDERR_FILENO) (void) close(STDERR_FILENO); @@ -2242,8 +2556,18 @@ main(int argc, char **argv) /* * In failsafe mode, we don't use login(1), so don't try * setting up a utmpx entry. + * + * A branded zone may have very different utmpx semantics. + * At the moment, we only have two brand types: + * Illumos-like (native, sn1) and Linux. In the Illumos + * case, we know exactly how to do the necessary utmpx + * setup. Fortunately for us, the Linux /bin/login is + * prepared to deal with a non-initialized utmpx entry, so + * we can simply skip it. If future brands don't fall into + * either category, we'll have to add a per-brand utmpx + * setup hook. */ - if (!failsafe) + if (!failsafe && (strcmp(zonebrand, "lx") != 0)) if (setup_utmpx(slaveshortname) == -1) return (1); @@ -2252,13 +2576,17 @@ main(int argc, char **argv) * execute the brand's login program. */ if (setuid(0) == -1) { - zperror(gettext("insufficient privilege")); + zperror("insufficient privilege"); return (1); } - (void) execve(new_args[0], new_args, new_env); - zperror(gettext("exec failure")); - return (1); + if (iflag) { + (void) execve(proc_args[0], proc_args, new_env); + } else { + (void) execve(new_args[0], new_args, new_env); + } + zperror("exec failure"); + return (ENOEXEC); } (void) ct_tmpl_clear(tmpl_fd); @@ -2283,8 +2611,19 @@ main(int argc, char **argv) if (pollerr != 0) { (void) fprintf(stderr, gettext("Error: connection closed due " "to unexpected pollevents=0x%x.\n"), pollerr); - return (1); + return (EPIPE); } - return (0); + /* reap child and get its status */ + if (waitid(P_PID, child_pid, &si, WEXITED | WNOHANG) == -1) { + estatus = errno; + } else if (si.si_pid == 0) { + estatus = ECHILD; + } else if (si.si_code == CLD_EXITED) { + estatus = si.si_status; + } else { + estatus = ECONNABORTED; + } + + return (estatus); } diff --git a/usr/src/cmd/zoneadm/Makefile b/usr/src/cmd/zoneadm/Makefile index 2b01078aec..fba7809c71 100644 --- a/usr/src/cmd/zoneadm/Makefile +++ b/usr/src/cmd/zoneadm/Makefile @@ -21,14 +21,18 @@ # # Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, Joyent, Inc. All rights reserved. # PROG= zoneadm +SCRIPTS= MANIFEST= zones.xml resource-mgmt.xml SVCMETHOD= svc-zones svc-resource-mgmt include ../Makefile.cmd +include ../Makefile.ctf +ROOTUSRSBINSCRIPTS= $(SCRIPTS:%=$(ROOTUSRSBIN)/%) ROOTMANIFESTDIR= $(ROOTSVCSYSTEM) OBJS= zoneadm.o zfs.o @@ -42,13 +46,14 @@ CERRWARN += -_gcc=-Wno-uninitialized .KEEP_STATE: -all: $(PROG) +all: $(PROG) $(SCRIPTS) $(PROG): $(OBJS) $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(POST_PROCESS) -install: all $(ROOTUSRSBINPROG) $(ROOTMANIFEST) $(ROOTSVCMETHOD) +install: all $(ROOTUSRSBINPROG) $(ROOTUSRSBINSCRIPTS) $(ROOTMANIFEST) \ + $(ROOTSVCMETHOD) check: $(PROG).c $(CHKMANIFEST) $(CSTYLE) -pP $(SRCS:%=%) @@ -58,7 +63,7 @@ $(POFILE): $(POFILES) $(CAT) $(POFILES) > $@ clean: - $(RM) $(OBJS) $(POFILES) + $(RM) $(OBJS) $(POFILES) $(SCRIPTS) lint: lint_SRCS diff --git a/usr/src/cmd/zoneadm/svc-zones b/usr/src/cmd/zoneadm/svc-zones index 9d307835bd..30d54f5272 100644 --- a/usr/src/cmd/zoneadm/svc-zones +++ b/usr/src/cmd/zoneadm/svc-zones @@ -32,7 +32,7 @@ shutdown_zones() { zoneadm list -p | nawk -F: '{ - if ($2 != "global") { + if (($5 != "lx") && ($2 != "global")) { print $2 } }' diff --git a/usr/src/cmd/zoneadm/zfs.c b/usr/src/cmd/zoneadm/zfs.c index 15be33ddab..214340d0ce 100644 --- a/usr/src/cmd/zoneadm/zfs.c +++ b/usr/src/cmd/zoneadm/zfs.c @@ -21,8 +21,8 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012, 2015 by Delphix. All rights reserved. - * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2016 Martin Matuska. All rights reserved. */ @@ -968,6 +968,7 @@ create_zfs_zonepath(char *zonepath) zfs_handle_t *zhp; char zfs_name[MAXPATHLEN]; nvlist_t *props = NULL; + int i; if (path2name(zonepath, zfs_name, sizeof (zfs_name)) != Z_OK) return; @@ -1003,9 +1004,20 @@ create_zfs_zonepath(char *zonepath) nvlist_free(props); - if (zfs_mount(zhp, NULL, 0) != 0) { + /* + * A monitoring tool might race with us and touch the mountpoint just + * as we're trying to mount, blocking the mount. We wait and retry a + * few times to workaround this race. + */ + for (i = 0; i < 5; i++) { + if (zfs_mount(zhp, NULL, 0) == 0) + break; (void) fprintf(stderr, gettext("cannot mount ZFS dataset %s: " "%s\n"), zfs_name, libzfs_error_description(g_zfs)); + (void) sleep(1); + } + + if (i >= 5) { (void) zfs_destroy(zhp, B_FALSE); } else { if (chmod(zonepath, S_IRWXU) != 0) { diff --git a/usr/src/cmd/zoneadm/zoneadm.c b/usr/src/cmd/zoneadm/zoneadm.c index 21bc9248f4..312159cabd 100644 --- a/usr/src/cmd/zoneadm/zoneadm.c +++ b/usr/src/cmd/zoneadm/zoneadm.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2015, Joyent Inc. All rights reserved. * Copyright (c) 2015 by Delphix. All rights reserved. */ @@ -101,13 +102,11 @@ typedef struct zone_entry { char zroot[MAXPATHLEN]; char zuuid[UUID_PRINTABLE_STRING_LENGTH]; zone_iptype_t ziptype; + zoneid_t zdid; } zone_entry_t; #define CLUSTER_BRAND_NAME "cluster" -static zone_entry_t *zents; -static size_t nzents; - #define LOOPBACK_IF "lo0" #define SOCKET_AF(af) (((af) == AF_UNSPEC) ? AF_INET : (af)) @@ -406,19 +405,6 @@ zerror(const char *fmt, ...) va_end(alist); } -static void * -safe_calloc(size_t nelem, size_t elsize) -{ - void *r = calloc(nelem, elsize); - - if (r == NULL) { - zerror(gettext("failed to allocate %lu bytes: %s"), - (ulong_t)nelem * elsize, strerror(errno)); - exit(Z_ERR); - } - return (r); -} - static void zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable) { @@ -443,6 +429,7 @@ zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable) } if (!verbose) { char *cp, *clim; + char zdid[80]; if (!parsable) { (void) printf("%s\n", zent->zname); @@ -458,8 +445,12 @@ zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable) (void) printf("%.*s\\:", clim - cp, cp); cp = clim + 1; } - (void) printf("%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand, - ip_type_str); + if (zent->zdid == -1) + zdid[0] = '\0'; + else + (void) snprintf(zdid, sizeof (zdid), "%d", zent->zdid); + (void) printf("%s:%s:%s:%s:%s\n", cp, zent->zuuid, zent->zbrand, + ip_type_str, zdid); return; } if (zent->zstate_str != NULL) { @@ -485,6 +476,9 @@ lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent) (void) strlcpy(zent->zbrand, "???", sizeof (zent->zbrand)); zent->zstate_str = "???"; + if (strcmp(zone_name, GLOBAL_ZONENAME) == 0) + zid = zent->zdid = GLOBAL_ZONEID; + zent->zid = zid; if (zonecfg_get_uuid(zone_name, uuid) == Z_OK && @@ -529,8 +523,8 @@ lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent) zent->zstate_str = zone_state_str(zent->zstate_num); /* - * A zone's brand is only available in the .xml file describing it, - * which is only visible to the global zone. This causes + * A zone's brand might only be available in the .xml file describing + * it, which is only visible to the global zone. This causes * zone_get_brand() to fail when called from within a non-global * zone. Fortunately we only do this on labeled systems, where we * know all zones are native. @@ -554,6 +548,22 @@ lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent) return (Z_OK); } + if ((handle = zonecfg_init_handle()) == NULL) { + zperror2(zent->zname, gettext("could not init handle")); + return (Z_ERR); + } + if ((err = zonecfg_get_handle(zent->zname, handle)) != Z_OK) { + zperror2(zent->zname, gettext("could not get handle")); + zonecfg_fini_handle(handle); + return (Z_ERR); + } + + if ((err = zonecfg_get_iptype(handle, &zent->ziptype)) != Z_OK) { + zperror2(zent->zname, gettext("could not get ip-type")); + zonecfg_fini_handle(handle); + return (Z_ERR); + } + /* * There is a race condition where the zone could boot while * we're walking the index file. In this case the zone state @@ -574,189 +584,73 @@ lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent) zent->ziptype = ZS_EXCLUSIVE; else zent->ziptype = ZS_SHARED; - return (Z_OK); } } - if ((handle = zonecfg_init_handle()) == NULL) { - zperror2(zent->zname, gettext("could not init handle")); - return (Z_ERR); - } - if ((err = zonecfg_get_handle(zent->zname, handle)) != Z_OK) { - zperror2(zent->zname, gettext("could not get handle")); - zonecfg_fini_handle(handle); - return (Z_ERR); - } + zent->zdid = zonecfg_get_did(handle); - if ((err = zonecfg_get_iptype(handle, &zent->ziptype)) != Z_OK) { - zperror2(zent->zname, gettext("could not get ip-type")); - zonecfg_fini_handle(handle); - return (Z_ERR); - } zonecfg_fini_handle(handle); return (Z_OK); } -/* - * fetch_zents() calls zone_list(2) to find out how many zones are running - * (which is stored in the global nzents), then calls zone_list(2) again - * to fetch the list of running zones (stored in the global zents). This - * function may be called multiple times, so if zents is already set, we - * return immediately to save work. - * - * Note that the data about running zones can change while this function - * is running, so its possible that the list of zones will have empty slots - * at the end. - */ - -static int -fetch_zents(void) -{ - zoneid_t *zids = NULL; - uint_t nzents_saved; - int i, retv; - FILE *fp; - boolean_t inaltroot; - zone_entry_t *zentp; - const char *altroot; - - if (nzents > 0) - return (Z_OK); - - if (zone_list(NULL, &nzents) != 0) { - zperror(gettext("failed to get zoneid list"), B_FALSE); - return (Z_ERR); - } - -again: - if (nzents == 0) - return (Z_OK); - - zids = safe_calloc(nzents, sizeof (zoneid_t)); - nzents_saved = nzents; - - if (zone_list(zids, &nzents) != 0) { - zperror(gettext("failed to get zone list"), B_FALSE); - free(zids); - return (Z_ERR); - } - if (nzents != nzents_saved) { - /* list changed, try again */ - free(zids); - goto again; - } - - zents = safe_calloc(nzents, sizeof (zone_entry_t)); - - inaltroot = zonecfg_in_alt_root(); - if (inaltroot) { - fp = zonecfg_open_scratch("", B_FALSE); - altroot = zonecfg_get_root(); - } else { - fp = NULL; - } - zentp = zents; - retv = Z_OK; - for (i = 0; i < nzents; i++) { - char name[ZONENAME_MAX]; - char altname[ZONENAME_MAX]; - char rev_altroot[MAXPATHLEN]; - - if (getzonenamebyid(zids[i], name, sizeof (name)) < 0) { - /* - * There is a race condition where the zone may have - * shutdown since we retrieved the number of running - * zones above. This is not an error, there will be - * an empty slot at the end of the list. - */ - continue; - } - if (zonecfg_is_scratch(name)) { - /* Ignore scratch zones by default */ - if (!inaltroot) - continue; - if (fp == NULL || - zonecfg_reverse_scratch(fp, name, altname, - sizeof (altname), rev_altroot, - sizeof (rev_altroot)) == -1) { - zerror(gettext("could not resolve scratch " - "zone %s"), name); - retv = Z_ERR; - continue; - } - /* Ignore zones in other alternate roots */ - if (strcmp(rev_altroot, altroot) != 0) - continue; - (void) strcpy(name, altname); - } else { - /* Ignore non-scratch when in an alternate root */ - if (inaltroot && strcmp(name, GLOBAL_ZONENAME) != 0) - continue; - } - if (lookup_zone_info(name, zids[i], zentp) != Z_OK) { - /* - * There is a race condition where the zone may have - * shutdown since we retrieved the number of running - * zones above. This is not an error, there will be - * an empty slot at the end of the list. - */ - continue; - } - zentp++; - } - nzents = zentp - zents; - if (fp != NULL) - zonecfg_close_scratch(fp); - - free(zids); - return (retv); -} - static int zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable) { - int i; zone_entry_t zent; FILE *cookie; - char *name; + struct zoneent *ze; /* - * First get the list of running zones from the kernel and print them. - * If that is all we need, then return. - */ - if ((i = fetch_zents()) != Z_OK) { - /* - * No need for error messages; fetch_zents() has already taken - * care of this. - */ - return (i); - } - for (i = 0; i < nzents; i++) - zone_print(&zents[i], verbose, parsable); - if (min_state >= ZONE_STATE_RUNNING) - return (Z_OK); - /* - * Next, get the full list of zones from the configuration, skipping - * any we have already printed. + * Get the full list of zones from the configuration. */ cookie = setzoneent(); - while ((name = getzoneent(cookie)) != NULL) { - for (i = 0; i < nzents; i++) { - if (strcmp(zents[i].zname, name) == 0) - break; - } - if (i < nzents) { - free(name); - continue; - } - if (lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) { - free(name); - continue; + while ((ze = getzoneent_private(cookie)) != NULL) { + char *name = ze->zone_name; + zoneid_t zid; + + zid = getzoneidbyname(name); + + if (ze->zone_brand[0] == '\0') { + /* old, incomplete index entry */ + if (lookup_zone_info(name, zid, &zent) != Z_OK) { + free(ze); + continue; + } + } else { + /* new, full index entry */ + (void) strlcpy(zent.zname, name, sizeof (zent.zname)); + (void) strlcpy(zent.zroot, ze->zone_path, + sizeof (zent.zroot)); + uuid_unparse(ze->zone_uuid, zent.zuuid); + (void) strlcpy(zent.zbrand, ze->zone_brand, + sizeof (zent.zbrand)); + zent.ziptype = ze->zone_iptype; + zent.zdid = ze->zone_did; + zent.zid = zid; + + if (zid != -1) { + int err; + + err = zone_get_state(name, + (zone_state_t *)&ze->zone_state); + if (err != Z_OK) { + errno = err; + zperror2(name, gettext("could not get " + "state")); + free(ze); + continue; + } + } + + zent.zstate_num = ze->zone_state; + zent.zstate_str = zone_state_str(zent.zstate_num); } - free(name); + if (zent.zstate_num >= min_state) zone_print(&zent, verbose, parsable); + + free(ze); } endzoneent(cookie); return (Z_OK); @@ -766,18 +660,22 @@ zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable) * Retrieve a zone entry by name. Returns NULL if no such zone exists. */ static zone_entry_t * -lookup_running_zone(const char *str) +lookup_running_zone(const char *name) { - int i; + zoneid_t zid; + zone_entry_t *zent; + + if ((zid = getzoneidbyname(name)) == -1) + return (NULL); - if (fetch_zents() != Z_OK) + if ((zent = malloc(sizeof (zone_entry_t))) == NULL) return (NULL); - for (i = 0; i < nzents; i++) { - if (strcmp(str, zents[i].zname) == 0) - return (&zents[i]); + if (lookup_zone_info(name, zid, zent) != Z_OK) { + free(zent); + return (NULL); } - return (NULL); + return (zent); } /* @@ -1013,8 +911,12 @@ validate_zonepath(char *path, int cmd_num) (void) printf(gettext("WARNING: %s is on a temporary " "file system.\n"), rpath); } - if (crosscheck_zonepaths(rpath) != Z_OK) - return (Z_ERR); + if (cmd_num != CMD_BOOT && cmd_num != CMD_REBOOT && + cmd_num != CMD_READY) { + /* we checked when we installed, no need to check each boot */ + if (crosscheck_zonepaths(rpath) != Z_OK) + return (Z_ERR); + } /* * Try to collect and report as many minor errors as possible * before returning, so the user can learn everything that needs @@ -1201,6 +1103,7 @@ static int ready_func(int argc, char *argv[]) { zone_cmd_arg_t zarg; + boolean_t debug = B_FALSE; int arg; if (zonecfg_in_alt_root()) { @@ -1209,11 +1112,14 @@ ready_func(int argc, char *argv[]) } optind = 0; - if ((arg = getopt(argc, argv, "?")) != EOF) { + if ((arg = getopt(argc, argv, "?X")) != EOF) { switch (arg) { case '?': sub_usage(SHELP_READY, CMD_READY); return (optopt == '?' ? Z_OK : Z_USAGE); + case 'X': + debug = B_TRUE; + break; default: sub_usage(SHELP_READY, CMD_READY); return (Z_USAGE); @@ -1230,6 +1136,7 @@ ready_func(int argc, char *argv[]) return (Z_ERR); zarg.cmd = Z_READY; + zarg.debug = debug; if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) { zerror(gettext("call to %s failed"), "zoneadmd"); return (Z_ERR); @@ -1242,6 +1149,7 @@ boot_func(int argc, char *argv[]) { zone_cmd_arg_t zarg; boolean_t force = B_FALSE; + boolean_t debug = B_FALSE; int arg; if (zonecfg_in_alt_root()) { @@ -1268,7 +1176,7 @@ boot_func(int argc, char *argv[]) * zoneadm -z myzone boot -- -s -v -m verbose. */ optind = 0; - while ((arg = getopt(argc, argv, "?fs")) != EOF) { + while ((arg = getopt(argc, argv, "?fsX")) != EOF) { switch (arg) { case '?': sub_usage(SHELP_BOOT, CMD_BOOT); @@ -1280,6 +1188,9 @@ boot_func(int argc, char *argv[]) case 'f': force = B_TRUE; break; + case 'X': + debug = B_TRUE; + break; default: sub_usage(SHELP_BOOT, CMD_BOOT); return (Z_USAGE); @@ -1305,6 +1216,7 @@ boot_func(int argc, char *argv[]) if (verify_details(CMD_BOOT, argv) != Z_OK) return (Z_ERR); zarg.cmd = force ? Z_FORCEBOOT : Z_BOOT; + zarg.debug = debug; if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) { zerror(gettext("call to %s failed"), "zoneadmd"); return (Z_ERR); @@ -1614,10 +1526,10 @@ auth_check(char *user, char *zone, int cmd_num) * not already running (or ready). */ static int -sanity_check(char *zone, int cmd_num, boolean_t running, +sanity_check(char *zone, int cmd_num, boolean_t need_running, boolean_t unsafe_when_running, boolean_t force) { - zone_entry_t *zent; + boolean_t is_running = B_FALSE; priv_set_t *privset; zone_state_t state, min_state; char kernzone[ZONENAME_MAX]; @@ -1688,51 +1600,54 @@ sanity_check(char *zone, int cmd_num, boolean_t running, } if (!zonecfg_in_alt_root()) { - zent = lookup_running_zone(zone); - } else if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) { - zent = NULL; - } else { - if (zonecfg_find_scratch(fp, zone, zonecfg_get_root(), - kernzone, sizeof (kernzone)) == 0) - zent = lookup_running_zone(kernzone); - else - zent = NULL; + /* Avoid the xml read overhead of lookup_running_zone */ + if (getzoneidbyname(zone) != -1) + is_running = B_TRUE; + + } else if ((fp = zonecfg_open_scratch("", B_FALSE)) != NULL) { + if (zonecfg_find_scratch(fp, zone, zonecfg_get_root(), kernzone, + sizeof (kernzone)) == 0 && getzoneidbyname(kernzone) != -1) + is_running = B_TRUE; + zonecfg_close_scratch(fp); } /* * Look up from the kernel for 'running' zones. */ - if (running && !force) { - if (zent == NULL) { + if (need_running && !force) { + if (!is_running) { zerror(gettext("not running")); return (Z_ERR); } } else { int err; - if (unsafe_when_running && zent != NULL) { + err = zone_get_state(zone, &state); + + if (unsafe_when_running && is_running) { /* check whether the zone is ready or running */ - if ((err = zone_get_state(zent->zname, - &zent->zstate_num)) != Z_OK) { + char *zstate_str; + + if (err != Z_OK) { errno = err; - zperror2(zent->zname, - gettext("could not get state")); + zperror2(zone, gettext("could not get state")); /* can't tell, so hedge */ - zent->zstate_str = "ready/running"; + zstate_str = "ready/running"; } else { - zent->zstate_str = - zone_state_str(zent->zstate_num); + zstate_str = zone_state_str(state); } zerror(gettext("%s operation is invalid for %s zones."), - cmd_to_str(cmd_num), zent->zstate_str); + cmd_to_str(cmd_num), zstate_str); return (Z_ERR); } - if ((err = zone_get_state(zone, &state)) != Z_OK) { + + if (err != Z_OK) { errno = err; zperror2(zone, gettext("could not get state")); return (Z_ERR); } + switch (cmd_num) { case CMD_UNINSTALL: if (state == ZONE_STATE_CONFIGURED) { @@ -1820,6 +1735,7 @@ static int halt_func(int argc, char *argv[]) { zone_cmd_arg_t zarg; + boolean_t debug = B_FALSE; int arg; if (zonecfg_in_alt_root()) { @@ -1828,11 +1744,14 @@ halt_func(int argc, char *argv[]) } optind = 0; - if ((arg = getopt(argc, argv, "?")) != EOF) { + if ((arg = getopt(argc, argv, "?X")) != EOF) { switch (arg) { case '?': sub_usage(SHELP_HALT, CMD_HALT); return (optopt == '?' ? Z_OK : Z_USAGE); + case 'X': + debug = B_TRUE; + break; default: sub_usage(SHELP_HALT, CMD_HALT); return (Z_USAGE); @@ -1858,6 +1777,7 @@ halt_func(int argc, char *argv[]) return (Z_ERR); zarg.cmd = Z_HALT; + zarg.debug = debug; return ((zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) == 0) ? Z_OK : Z_ERR); } @@ -1935,6 +1855,7 @@ static int reboot_func(int argc, char *argv[]) { zone_cmd_arg_t zarg; + boolean_t debug = B_FALSE; int arg; if (zonecfg_in_alt_root()) { @@ -1943,11 +1864,14 @@ reboot_func(int argc, char *argv[]) } optind = 0; - if ((arg = getopt(argc, argv, "?")) != EOF) { + if ((arg = getopt(argc, argv, "?X")) != EOF) { switch (arg) { case '?': sub_usage(SHELP_REBOOT, CMD_REBOOT); return (optopt == '?' ? Z_OK : Z_USAGE); + case 'X': + debug = B_TRUE; + break; default: sub_usage(SHELP_REBOOT, CMD_REBOOT); return (Z_USAGE); @@ -1982,6 +1906,7 @@ reboot_func(int argc, char *argv[]) return (Z_ERR); zarg.cmd = Z_REBOOT; + zarg.debug = debug; return ((zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) == 0) ? Z_OK : Z_ERR); } @@ -2209,6 +2134,10 @@ verify_fs_special(struct zone_fstab *fstab) if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0) return (verify_fs_zfs(fstab)); + if (strcmp(fstab->zone_fs_type, MNTTYPE_HYPRLOFS) == 0 && + strcmp(fstab->zone_fs_special, "swap") == 0) + return (Z_OK); + if (stat64(fstab->zone_fs_special, &st) != 0) { (void) fprintf(stderr, gettext("could not verify fs " "%s: could not access %s: %s\n"), fstab->zone_fs_dir, @@ -2612,7 +2541,6 @@ verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[]) dladm_handle_t dh; dladm_status_t status; datalink_id_t linkid; - char errmsg[DLADM_STRSIZE]; in_alt_root = zonecfg_in_alt_root(); if (in_alt_root) @@ -2695,11 +2623,6 @@ verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[]) dladm_close(dh); } if (status != DLADM_STATUS_OK) { - (void) fprintf(stderr, - gettext("WARNING: skipping network " - "interface '%s': %s\n"), - nwiftab.zone_nwif_physical, - dladm_status2str(status, errmsg)); break; } dl_owner_zid = ALL_ZONES; @@ -2783,6 +2706,74 @@ no_net: return (return_code); } +/* + * Called when readying or booting a zone. We double check that the zone's + * debug ID is set and is unique. This covers the case of pre-existing zones + * with no ID. Also, its possible that a zone was migrated to this host + * and as a result it has a duplicate ID. In this case we preserve the ID + * of the first zone we match on in the index file (since it was there before + * the current zone) and we assign a new unique ID to the current zone. + * Return true if we assigned a new ID, indicating that the zone configuration + * needs to be saved. + */ +static boolean_t +verify_fix_did(zone_dochandle_t handle) +{ + zoneid_t mydid; + struct zoneent *ze; + FILE *cookie; + boolean_t fix = B_FALSE; + + mydid = zonecfg_get_did(handle); + if (mydid == -1) { + zonecfg_set_did(handle); + return (B_TRUE); + } + + /* Get the full list of zones from the configuration. */ + cookie = setzoneent(); + while ((ze = getzoneent_private(cookie)) != NULL) { + char *name; + zoneid_t did; + + name = ze->zone_name; + if (strcmp(name, GLOBAL_ZONENAME) == 0 || + strcmp(name, target_zone) == 0) { + free(ze); + continue; + } + + if (ze->zone_brand[0] == '\0') { + /* old, incomplete index entry */ + zone_entry_t zent; + + if (lookup_zone_info(name, ZONE_ID_UNDEFINED, + &zent) != Z_OK) { + free(ze); + continue; + } + did = zent.zdid; + } else { + /* new, full index entry */ + did = ze->zone_did; + } + free(ze); + + if (did == mydid) { + fix = B_TRUE; + break; + } + } + endzoneent(cookie); + + if (fix) { + zonecfg_set_did(handle); + return (B_TRUE); + } + + return (B_FALSE); +} + static int verify_details(int cmd_num, char *argv[]) { @@ -2842,6 +2833,18 @@ verify_details(int cmd_num, char *argv[]) if (verify_handle(cmd_num, handle, argv) != Z_OK) return_code = Z_ERR; + if (cmd_num == CMD_READY || cmd_num == CMD_BOOT) { + int vcommit = 0, obscommit = 0; + + vcommit = verify_fix_did(handle); + obscommit = zonecfg_fix_obsolete(handle); + + if (vcommit || obscommit) + if (zonecfg_save(handle) != Z_OK) + (void) fprintf(stderr, gettext("Could not save " + "updated configuration.\n")); + } + zonecfg_fini_handle(handle); if (return_code == Z_ERR) (void) fprintf(stderr, @@ -2927,6 +2930,7 @@ install_func(int argc, char *argv[]) int status; boolean_t do_postinstall = B_FALSE; boolean_t brand_help = B_FALSE; + boolean_t do_dataset = B_TRUE; char opts[128]; if (target_zone == NULL) { @@ -3002,6 +3006,12 @@ install_func(int argc, char *argv[]) } /* Ignore unknown options - may be brand specific. */ break; + case 'x': + if (strcmp(optarg, "nodataset") == 0) { + do_dataset = B_FALSE; + continue; /* internal arg, don't pass thru */ + } + break; default: /* Ignore unknown options - may be brand specific. */ break; @@ -3054,7 +3064,8 @@ install_func(int argc, char *argv[]) goto done; } - create_zfs_zonepath(zonepath); + if (do_dataset) + create_zfs_zonepath(zonepath); } status = do_subproc(cmdbuf); @@ -3865,10 +3876,10 @@ cleanup_zonepath(char *zonepath, boolean_t all) * exist if the zone was force-attached after a * migration. */ - char *std_entries[] = {"dev", "lu", "root", - "SUNWattached.xml", NULL}; - /* (MAXPATHLEN * 3) is for the 3 std_entries dirs */ - char cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 3) + 64]; + char *std_entries[] = {"dev", "lastexited", "logs", "lu", + "root", "SUNWattached.xml", NULL}; + /* (MAXPATHLEN * 5) is for the 5 std_entries dirs */ + char cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 5) + 64]; /* * We shouldn't need these checks but lets be paranoid since we @@ -5018,6 +5029,7 @@ uninstall_func(int argc, char *argv[]) if (zonecfg_ping_zoneadmd(target_zone) == Z_OK) { zone_cmd_arg_t zarg; zarg.cmd = Z_NOTE_UNINSTALLING; + zarg.debug = B_FALSE; /* we don't care too much if this fails, just plow on */ (void) zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE); @@ -5133,6 +5145,7 @@ mount_func(int argc, char *argv[]) return (Z_ERR); zarg.cmd = force ? Z_FORCEMOUNT : Z_MOUNT; + zarg.debug = B_FALSE; zarg.bootbuf[0] = '\0'; if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) { zerror(gettext("call to %s failed"), "zoneadmd"); @@ -5154,6 +5167,7 @@ unmount_func(int argc, char *argv[]) return (Z_ERR); zarg.cmd = Z_UNMOUNT; + zarg.debug = B_FALSE; if (zonecfg_call_zoneadmd(target_zone, &zarg, locale, B_TRUE) != 0) { zerror(gettext("call to %s failed"), "zoneadmd"); return (Z_ERR); @@ -5375,7 +5389,7 @@ apply_func(int argc, char *argv[]) priv_set_t *privset; zoneid_t zoneid; zone_dochandle_t handle; - struct zone_mcaptab mcap; + uint64_t mcap; char pool_err[128]; zoneid = getzoneid(); @@ -5466,19 +5480,12 @@ apply_func(int argc, char *argv[]) } /* - * If a memory cap is configured, set the cap in the kernel using - * zone_setattr() and make sure the rcapd SMF service is enabled. + * If a memory cap is configured, make sure the rcapd SMF service is + * enabled. */ - if (zonecfg_getmcapent(handle, &mcap) == Z_OK) { - uint64_t num; + if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, &mcap) == Z_OK) { char smf_err[128]; - num = (uint64_t)strtoll(mcap.zone_physmem_cap, NULL, 10); - if (zone_setattr(zoneid, ZONE_ATTR_PHYS_MCAP, &num, 0) == -1) { - zerror(gettext("could not set zone memory cap")); - res = Z_ERR; - } - if (zonecfg_enable_rcapd(smf_err, sizeof (smf_err)) != Z_OK) { zerror(gettext("enabling system/rcap service failed: " "%s"), smf_err); diff --git a/usr/src/cmd/zoneadm/zones.xml b/usr/src/cmd/zoneadm/zones.xml index 9c8e305f89..b094bc660b 100644 --- a/usr/src/cmd/zoneadm/zones.xml +++ b/usr/src/cmd/zoneadm/zones.xml @@ -54,11 +54,32 @@ <service_fmri value='svc:/milestone/multi-user-server' /> </dependency> + <!-- + Until overlay device creation is moved out of the zone + state-change script, zones must be dependent on varpd's + successful launch. + --> + <dependency + name='varpd' + type='service' + grouping='require_all' + restart_on='none'> + <service_fmri value='svc:/network/varpd' /> + </dependency> + + <dependency + name='metadata' + type='service' + grouping='require_all' + restart_on='none'> + <service_fmri value='svc:/system/smartdc/metadata' /> + </dependency> + <exec_method type='method' name='start' exec='/lib/svc/method/svc-zones %m' - timeout_seconds='60'> + timeout_seconds='0'> </exec_method> <!-- diff --git a/usr/src/cmd/zoneadmd/Makefile b/usr/src/cmd/zoneadmd/Makefile index 8324f7fefa..e81e4631aa 100644 --- a/usr/src/cmd/zoneadmd/Makefile +++ b/usr/src/cmd/zoneadmd/Makefile @@ -18,57 +18,54 @@ # # CDDL HEADER END - -# - # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2014 Nexenta Systems, Inc. All rights reserved. +# Copyright (c) 2011, Joyent, Inc. All rights reserved. # PROG= zoneadmd include ../Makefile.cmd +include ../Makefile.ctf -ROOTCMDDIR= $(ROOTLIB)/zones - -OBJS= zoneadmd.o zcons.o vplat.o -SRCS = $(OBJS:.o=.c) -POFILE=zoneadmd_all.po -POFILES= $(OBJS:%.o=%.po) +$(64ONLY)SUBDIRS= $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) -CFLAGS += $(CCVERBOSE) -CERRWARN += -_gcc=-Wno-switch -CERRWARN += -_gcc=-Wno-parentheses -CERRWARN += -_gcc=-Wno-uninitialized +all := TARGET = all +install := TARGET = install +clean := TARGET = clean +clobber := TARGET = clobber +lint := TARGET = lint -LDLIBS += -lsocket -lzonecfg -lnsl -ldevinfo -ldevice -lnvpair \ - -lgen -lbsm -lcontract -lzfs -luuid -lbrand -ldladm -ltsnet -ltsol \ - -linetutil -lscf XGETFLAGS += -a -x zoneadmd.xcl +ROOTUSRLIBZONES = $(ROOT)/usr/lib/zones + .KEEP_STATE: .PARALLEL: -all: $(PROG) +all: $(SUBDIRS) $(PROG): $(OBJS) $(LINK.c) -o $@ $(OBJS) $(LDLIBS) $(POST_PROCESS) -install: all $(ROOTCMD) - -$(POFILE): $(POFILES) - $(RM) $@ - $(CAT) $(POFILES) > $@ +install: $(SUBDIRS) + -$(RM) $(ROOTUSRLIBZONES)/$(PROG) + -$(LN) $(ISAEXEC) $(ROOTUSRLIBZONES)/$(PROG) -clean: - $(RM) $(OBJS) +$(POFILE): -lint: lint_SRCS +clean clobebr lint: $(SUBDIRS) check: - $(CSTYLE) -p -P $(SRCS:%=%) + $(CSTYLE) -p -P *.c + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: include ../Makefile.targ diff --git a/usr/src/cmd/zoneadmd/Makefile.com b/usr/src/cmd/zoneadmd/Makefile.com new file mode 100644 index 0000000000..6312c00ad5 --- /dev/null +++ b/usr/src/cmd/zoneadmd/Makefile.com @@ -0,0 +1,72 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END + +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2018 Joyent, Inc. +# + +PROG= zoneadmd + +include ../../Makefile.cmd +include ../../Makefile.ctf + +ROOTCMDDIR= $(ROOTLIB)/zones + +OBJS= zoneadmd.o zcons.o zfd.o vplat.o log.o + +CFLAGS += $(CCVERBOSE) +LDLIBS += -lsocket -lzonecfg -lnsl -ldevinfo -ldevice -lnvpair \ + -lgen -lbsm -lcontract -lzfs -luuid -lbrand -ldladm -ltsnet -ltsol \ + -linetutil -lproc -lscf -lppt + +CSTD= $(CSTD_GNU99) + +.KEEP_STATE: + +%.o: ../%.c + $(COMPILE.c) $< + $(POST_PROCESS_O) + +ROOTUSRLIBZONES = $(ROOT)/usr/lib/zones +ROOTUSRLIBZONES32 = $(ROOTUSRLIBZONES)/$(MACH32) +ROOTUSRLIBZONES64 = $(ROOTUSRLIBZONES)/$(MACH64) +ROOTUSRLIBZONESPROG32 = $(ROOTUSRLIBZONES32)/$(PROG) +ROOTUSRLIBZONESPROG64 = $(ROOTUSRLIBZONES64)/$(PROG) +$(ROOTUSRLIBZONES32)/%: $(ROOTUSRLIBZONES32) % + $(INS.file) +$(ROOTUSRLIBZONES64)/%: $(ROOTUSRLIBZONES64) % + $(INS.file) +$(ROOTUSRLIBZONES32): + $(INS.dir) + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) + +clean: + $(RM) $(OBJS) + +lint: + $(LINT.c) ../*.c $(LDLIBS) + +include ../../Makefile.targ diff --git a/usr/src/cmd/zoneadmd/amd64/Makefile b/usr/src/cmd/zoneadmd/amd64/Makefile new file mode 100644 index 0000000000..75ac51db32 --- /dev/null +++ b/usr/src/cmd/zoneadmd/amd64/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2011, Joyent, Inc. All rights reserved. +# + +.KEEP_STATE: + +include ../Makefile.com +include ../../Makefile.cmd.64 + +install: all $(ROOTUSRLIBZONES64) $(ROOTUSRLIBZONESPROG64) diff --git a/usr/src/cmd/zoneadmd/i386/Makefile b/usr/src/cmd/zoneadmd/i386/Makefile new file mode 100644 index 0000000000..a8764e0638 --- /dev/null +++ b/usr/src/cmd/zoneadmd/i386/Makefile @@ -0,0 +1,30 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2011, Joyent, Inc. All rights reserved. +# + +.KEEP_STATE: + +include ../Makefile.com + +install: all $(ROOTUSRLIBZONES32) $(ROOTUSRLIBZONESPROG32) diff --git a/usr/src/cmd/zoneadmd/log.c b/usr/src/cmd/zoneadmd/log.c new file mode 100644 index 0000000000..f08f0288ec --- /dev/null +++ b/usr/src/cmd/zoneadmd/log.c @@ -0,0 +1,958 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019 Joyent, Inc. + */ + +/* + * zoneadmd logging + * + * zoneadmd logs to log files under <zonepath>/logs. Each log entry is a json + * structure of the form: + * + * { + * "log": "some message\n", + * "stream": "stderr", + * "time": "2018-03-28T13:25:02.670423000Z" + * } + * + * Unlike the example above, the entries in the log file are not pretty-printed. + * Messages are processed so that they have the proper json escapes for + * problematic characters. Excessively long messages may be truncated. + * + * To use these interfaces: + * + * int logid; + * + * logstream_init(zlogp); + * + * logid = logstream_open("stdio.log", "stdout", flags); + * ... + * logstream_write(logid, buf, len); + * ... + * logstream_close(logid); + * + * logstream_init() needs to be called only once. + * + * logstream_open() opens a log file (if not already open) and associates the + * specified stream with it. + * + * The following flag is supported: + * + * LS_LINE_BUFFERED Buffer writes until a newline is encountered or the + * buffer fills. This should only be used with streams + * that are written to by a single thread. The timestamp + * on log messages are the time that the log entry was + * written to the log file. This means the timestamp is + * the time when the console user hits enter, not the time + * that the prompt was printed. + * + * Line buffering is particularly useful for bhyve console logging because + * bhyve's UART emulation causes read() calls in zcons.c to return far fewer + * than 10 characters at a time. Without line buffering, a small number of + * logged characters are accompanied by about 64 characters of timestamp and + * other overhead. Line buffering saves quite a lot of space and makes the log + * much easier to read. + * + * + * Log rotation + * + * Two attributes, zlog-max-size and zlog-keep-rotated are used for automatic + * log rotation. zlog-max-size is the approximate maximum size of a log before + * it is automatically rotated. Rotated logs are renamed as + * <log>.<iso-8601-stamp>. If zlog-keep-rotated is specified and is an integer + * greater than zero, only that number of rotated logs will be retained. + * + * If zlog-max-size is not specified, log rotation will not happen + * automatically. An external log rotation program may rename the log file(s), + * then send SIGHUP to zoneadmd. + * + * Log rotation can be forced with SIGUSR1. In this case, the log will be + * rotated as though it hit the maximum size and will be subject to retention + * rules described above. + * + * + * Locking strategy + * + * Callers need not worry about locking. In the interest of simplicity, a + * single global lock is used to protect the state of the log files and the + * associated streams. Locking is necessary because reboots and log rotations + * can cause various state changes. Without locking, races could cause log + * entries to be directed to the wrong file descriptors. + * + * The simplistic global lock complicates error reporting within logging + * routines. zerror() must not be called while holding logging_lock. Rather, + * logstream_err() should be used to log via syslog. + */ + +#include <assert.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <glob.h> +#include <signal.h> +#include <stdarg.h> +#include <stdio.h> +#include <strings.h> +#include <synch.h> +#include <syslog.h> +#include <time.h> +#include <thread.h> +#include <unistd.h> + +#include <sys/debug.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> +#include <sys/time.h> +#include <sys/types.h> +#include <sys/varargs.h> + +#include "zoneadmd.h" + +/* + * Currently we only expect stdout, stderr, zoneadmd, and console. Increase + * MAX_ZLOG_STREAMS if more streams are added. If the count increases + * significantly, logfile_t and logstream_t elements should be dynamically + * allocated and the algorithms associated with opening and closing them should + * become more efficient. + */ +#define MAX_LOG_STREAMS 4 + +#define ZLOG_MAXSZ "zlog-max-size" /* zonecfg attr */ +#define ZLOG_MAXSZ_MIN (1024 * 1024) /* min size for autorotate */ +#define ZLOG_KEEP "zlog-keep-rotated" /* zonecfg attr */ +#define ZLOG_KEEP_MAX 1000 /* number of log files */ + +typedef struct logfile { + char lf_path[MAXPATHLEN]; /* log file name (absolute path) */ + char lf_name[MAXNAMELEN]; /* tail of log file name */ + int lf_fd; /* file descriptor */ + size_t lf_size; /* Current size */ + boolean_t lf_write_err; /* Avoid spamming console via logsys */ + boolean_t lf_closing; /* Avoid rotation recursion */ +} logfile_t; + +typedef struct logstream { + char ls_stream[MAXNAMELEN]; /* stdout, stderr, etc. */ + char ls_buf[BUFSIZ * 2]; /* Not-yet written data, json */ + int ls_buflen; + logstream_flags_t ls_flags; + logfile_t *ls_logfile; /* N streams per log file */ +} logstream_t; + +typedef struct jsonpair { + const char *jp_key; + const char *jp_val; +} jsonpair_t; + +boolean_t logging_poisoned = B_FALSE; + +/* + * MAX_LOG_STREAMS is a small number so we allocate in the simplest way. + */ +static logstream_t streams[MAX_LOG_STREAMS]; +static logfile_t logfiles[MAX_LOG_STREAMS]; + +static boolean_t logging_initialized = B_FALSE; +static uint64_t logging_rot_size; /* See ZLOG_MAXSZ */ +static uint64_t logging_rot_keep; /* See ZLOG_KEEP */ +static int logging_pending_sig = 0; /* Signal recvd while logging */ +static mutex_t logging_lock; /* The global logging lock */ + +static void logstream_flush_all(logfile_t *); +static void logstream_sighandler(int); +static void rotate_log(logfile_t *); +static size_t make_json(jsonpair_t *, int, char *, size_t); +static void logfile_write(logfile_t *, const char *, size_t); + +/* + * If errors are encountered while logging_lock is held, we can't use zerror(). + */ +static void +logstream_err(boolean_t use_strerror, const char *fmt, ...) +{ + va_list alist; + char buf[MAXPATHLEN * 2]; + char *bp; + int saved_errno = errno; + + (void) snprintf(buf, sizeof (buf), "[zone %s] ", zone_name); + + bp = &buf[strlen(buf)]; + + va_start(alist, fmt); + (void) vsnprintf(bp, sizeof (buf) - (bp - buf), fmt, alist); + va_end(alist); + + if (use_strerror) { + bp = &buf[strlen(buf)]; + (void) snprintf(bp, sizeof (buf) - (bp - buf), ": %s", + strerror(saved_errno)); + } + syslog(LOG_ERR, "%s", buf); + + errno = saved_errno; +} + +static void +logstream_lock(void) +{ + int ret; + + assert(logging_initialized && !logging_poisoned); + + ret = mutex_lock(&logging_lock); + assert(ret == 0); +} + +static void +logstream_unlock(void) +{ + int ret; + int err = errno; + int sig = logging_pending_sig; + + logging_pending_sig = 0; + ret = mutex_unlock(&logging_lock); + assert(ret == 0); + + /* + * If a signal arrived while this thread was holding the lock, call the + * handler. + */ + if (sig != 0) { + logstream_sighandler(sig); + } + + errno = err; +} + +static void +logfile_write_event(logfile_t *lfp, const char *stream, const char *event) +{ + char buf[BUFSIZ]; + size_t len; + jsonpair_t pairs[] = { + { "event", event }, + { "stream", stream } + }; + + len = make_json(pairs, ARRAY_SIZE(pairs), buf, sizeof (buf)); + if (len >= sizeof (buf)) { + logstream_err(B_FALSE, "%s: buffer too small. Need %llu bytes, " + "have %llu bytes", __func__, len + 1, sizeof (buf)); + return; + } + + logfile_write(lfp, buf, len); +} + +static void +close_log(logfile_t *lfp, const char *why, boolean_t ign_err) +{ + int err; + + assert(MUTEX_HELD(&logging_lock)); + + /* + * Something may have gone wrong during log rotation, leading to a + * zombie log. + */ + if (lfp->lf_fd == -1) { + return; + } + + lfp->lf_closing = B_TRUE; + + logstream_flush_all(lfp); + + logfile_write_event(lfp, "logfile", why); + + err = close(lfp->lf_fd); + if (!ign_err) + assert(err == 0); + + lfp->lf_size = 0; + lfp->lf_fd = -1; +} + +static void +open_log(logfile_t *lfp, const char *why) +{ + struct stat64 sb; + int err; + + assert(MUTEX_HELD(&logging_lock)); + assert(lfp->lf_fd == -1); + + lfp->lf_fd = open(lfp->lf_path, + O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC, 0600); + if (lfp->lf_fd == -1) { + logstream_err(B_TRUE, "Cannot open log file %s", + lfp->lf_path); + lfp->lf_write_err = B_TRUE; + return; + } + + err = fstat64(lfp->lf_fd, &sb); + assert(err == 0); + lfp->lf_size = sb.st_size; + lfp->lf_write_err = B_FALSE; + lfp->lf_closing = B_FALSE; + + logfile_write_event(lfp, "logfile", why); +} + +static void +logstream_sighandler(int sig) +{ + int i; + + /* + * Protect against recursive mutex enters when a signal comes during + * logging. This will cause this function to be called again just after + * this thread drops the lock. + */ + if (MUTEX_HELD(&logging_lock)) { + logging_pending_sig = sig; + return; + } + + logstream_lock(); + if (logging_poisoned) { + logstream_unlock(); + return; + } + + for (i = 0; i < ARRAY_SIZE(logfiles); i++) { + /* Inactive logfile slot */ + if (logfiles[i].lf_name[0] == '\0') { + continue; + } + + switch (sig) { + case SIGHUP: + close_log(&logfiles[i], "close-rotate", B_FALSE); + open_log(&logfiles[i], "open-rotate"); + break; + case SIGUSR1: + rotate_log(&logfiles[i]); + break; + default: + logstream_err(B_FALSE, "unhandled signal %d", sig); + } + } + + logstream_unlock(); +} + +static void +get_attr_uint64(zlog_t *zlogp, zone_dochandle_t handle, const char *name, + uint64_t max, uint64_t *valp) +{ + struct zone_attrtab tab = { 0 }; + char *p; + uint64_t val; + + ASSERT(!MUTEX_HELD(&logging_lock)); + + (void) strlcpy(tab.zone_attr_name, name, sizeof (tab.zone_attr_name)); + if (zonecfg_lookup_attr(handle, &tab) != Z_OK) { + return; + } + + errno = 0; + val = strtol(tab.zone_attr_value, &p, 10); + if (errno != 0 && *p == '\0') { + zerror(zlogp, errno != 0, "Bad value '%s' for 'attr name=%s'", + tab.zone_attr_value, tab.zone_attr_name); + return; + } + if (val > max) { + zerror(zlogp, B_FALSE, "Value of attr '%s' is too large. " + "Reducing to %llu", name, max); + val = max; + } + + *valp = val; +} + +static void +logstream_atfork_prepare(void) +{ + logstream_lock(); +} + +static void +logstream_atfork_parent(void) +{ + logstream_unlock(); +} + +/* + * logstream_*() should never be called in a child process, so we make sure this + * code is never called there. + * + * zerror() in a child process is still safe: it knows to check for poisoning, + * and in such a case will redirect its output to stderr on the presumption it + * is a pipe to the parent. + */ +static void +logstream_atfork_child(void) +{ + logging_poisoned = B_TRUE; + logging_pending_sig = 0; + logstream_unlock(); +} + +void +logstream_init(zlog_t *zlogp) +{ + zone_dochandle_t handle; + int err; + int i; + + assert(!logging_initialized); + + err = mutex_init(&logging_lock, USYNC_THREAD | LOCK_ERRORCHECK, 0); + assert(err == 0); + + for (i = 0; i < ARRAY_SIZE(logfiles); i++) { + logfiles[i].lf_fd = -1; + } + + err = pthread_atfork(logstream_atfork_prepare, + logstream_atfork_parent, logstream_atfork_child); + assert(err == 0); + + logging_initialized = B_TRUE; + + /* Now it is safe to use zlogp */ + + if ((handle = zonecfg_init_handle()) == NULL || + zonecfg_get_handle(zone_name, handle) != Z_OK) { + zerror(zlogp, B_FALSE, "failed to open zone configuration " + "while initializing logging"); + } else { + get_attr_uint64(zlogp, handle, ZLOG_MAXSZ, UINT64_MAX, + &logging_rot_size); + if (logging_rot_size != 0 && + logging_rot_size < ZLOG_MAXSZ_MIN) { + zerror(zlogp, B_FALSE, "%s value %llu is too small. " + "Setting to %d", ZLOG_MAXSZ, logging_rot_size, + ZLOG_MAXSZ_MIN); + logging_rot_size = ZLOG_MAXSZ_MIN; + } + get_attr_uint64(zlogp, handle, ZLOG_KEEP, ZLOG_KEEP_MAX, + &logging_rot_keep); + } + + zonecfg_fini_handle(handle); + + /* + * This thread should receive SIGHUP so that it can close the log + * file and reopen it during log rotation. SIGUSR1 can be used to force + * a log rotation. + */ + sigset(SIGHUP, logstream_sighandler); + sigset(SIGUSR1, logstream_sighandler); +} + +/* + * Rotate a single log file. The global lock must be held while this is called. + */ +static void +rotate_log(logfile_t *lfp) +{ + time_t t; + struct tm gtm; + char path[MAXPATHLEN]; + int64_t i; + size_t len; + glob_t glb = { 0 }; + int err; + + assert(MUTEX_HELD(&logging_lock)); + + if (lfp->lf_closing) { + return; + } + + if ((t = time(NULL)) == (time_t)-1 || gmtime_r(&t, >m) == NULL) { + logstream_err(B_TRUE, "failed to format time"); + return; + } + + (void) snprintf(path, sizeof (path), "%s.%04d%02d%02dT%02d%02d%02dZ", + lfp->lf_path, gtm.tm_year + 1900, gtm.tm_mon + 1, gtm.tm_mday, + gtm.tm_hour, gtm.tm_min, gtm.tm_sec); + + if (rename(lfp->lf_path, path) != 0) { + logstream_err(B_TRUE, "failed to rotate log file " + "'%s' to '%s'", lfp->lf_path, path); + } + + close_log(lfp, "close-rotate", B_FALSE); + open_log(lfp, "open-rotate"); + + if (logging_rot_keep == 0) { + return; + } + + /* + * Remove old logs. + */ + len = snprintf(path, sizeof (path), + /* <lf_path>.YYYYmmdd */ + "%s.[12][0-9][0-9][0-9][01][0-9][0-3][0-9]" + /* THHMMSSZ */ + "T[012][0-9][0-5][0-9][0-6][0-9]Z", lfp->lf_path); + if (len >= sizeof (path)) { + logstream_err(B_FALSE, "log rotation glob too long"); + return; + } + + if ((err = glob(path, GLOB_LIMIT, NULL, &glb)) != 0) { + if (err != GLOB_NOMATCH) { + logstream_err(B_TRUE, "glob terminated with error %d", + err); + } + globfree(&glb); + return; + } + + if (glb.gl_pathc <= logging_rot_keep) { + globfree(&glb); + return; + } + + for (i = glb.gl_pathc - logging_rot_keep - 1; i >= 0; i--) { + if (unlink(glb.gl_pathv[i]) != 0) { + logstream_err(B_TRUE, "log rotation could not remove " + "%s", glb.gl_pathv[i]); + } + } + globfree(&glb); +} + +/* + * Modify the input string with json escapes. Since the destination can thus + * be larger than the source, multiple calls may be required to fully convert + * sbuf to json. + * + * sbuf, slen Source buffer and the number of bytes in it to process + * dbuf, dlen Destination buffer and its size. On return, the result + * is always null terminated. + * scntp On return, *scntp stores number of scnt bytes consumed + * dcntp On return, *dcntp stores number of bytes stored in dcnt, + * excluding trailing nul. + * flushp If non-NULL, line-buffered mode is enabled. Processing + * will stop at the first newline or when obuf is full and + * *flushp will be set to B_TRUE. + * + * This function makes no attempt to handle wide characters properly because + * the messages that come in may be using any character encoding. Since + * characters other than 7-bit ASCII are not directly readable in the log + * anyway, it is better to log the raw data and leave it to specialized log + * readers to interpret non-ASCII data. + */ +static void +escape_json(const char *sbuf, int slen, char *dbuf, int dlen, int *scntp, + int *dcntp, boolean_t *flushp) +{ + int i; + char c; + const char *save_sbuf = sbuf; + const char *sbuf_end = sbuf + slen - 1; + char append_buf[7]; /* "\\u0000\0" */ + const char *append; + int len; + + if (flushp != NULL) { + *flushp = B_FALSE; + } + + i = 0; + while (i < (dlen - 1) && sbuf <= sbuf_end) { + c = sbuf[0]; + + switch (c) { + case '\\': + append = "\\\\"; + break; + + case '"': + append = "\\\""; + break; + + case '\b': + append = "\\b"; + break; + + case '\f': + append = "\\f"; + break; + + case '\n': + append = "\\n"; + if (flushp != NULL) { + *flushp = B_TRUE; + } + break; + + case '\r': + append = "\\r"; + break; + + case '\t': + append = "\\t"; + break; + + default: + if (c >= 0x20 && c < 0x7f) { + append_buf[0] = c; + append_buf[1] = '\0'; + } else { + len = snprintf(append_buf, sizeof (append_buf), + "\\u%04x", (int)(0xff & c)); + assert(len < sizeof (append_buf)); + } + append = append_buf; + break; + } + + len = strlcpy(&dbuf[i], append, dlen - i); + if (len >= dlen - i) { + if (flushp != NULL) { + *flushp = B_TRUE; + } + break; + } else { + sbuf++; + i += len; + } + if (flushp != NULL && *flushp) { + break; + } + } + + dbuf[i] = '\0'; + + *dcntp = i; + *scntp = sbuf - save_sbuf; + + assert(*dcntp < dlen); + assert(*scntp <= slen); + + /* Buffer is too full to append "\\n". Force a flush. */ + if (flushp != NULL && i >= dlen - 2) { + *flushp = B_TRUE; + } +} + +/* + * Like write(2), but to a logfile_t and with retries on short writes. + */ +static void +logfile_write(logfile_t *lfp, const char *buf, size_t buflen) +{ + ssize_t wlen; + size_t wanted = buflen; + + while (buflen > 0) { + wlen = write(lfp->lf_fd, buf, buflen); + if (wlen == -1) { + if (lfp->lf_write_err) { + lfp->lf_write_err = B_TRUE; + logstream_err(B_TRUE, "log file fd %d '%s': " + "failed to write %llu of %llu bytes", + lfp->lf_fd, lfp->lf_path, buflen, wanted); + } + return; + } + buf += wlen; + buflen -= wlen; + lfp->lf_size += wlen; + + lfp->lf_write_err = B_FALSE; + } + + if (logging_rot_size != 0 && lfp->lf_size > logging_rot_size) { + rotate_log(lfp); + } +} + +/* + * Convert the json pairs into a json object. A "time" element is added to + * every object. Returns the number of bytes that would have been written to + * buf if bufsz had buf been sufficiently large (excluding the terminating null + * byte). Like snprintf(). + */ +static size_t +make_json(jsonpair_t *pairs, int npairs, char *buf, size_t bufsz) +{ + struct tm gtm; + struct timeval tv; + char ts[32]; + size_t len = 0; + int i; + const char *key, *val, *start, *end; + + assert(npairs > 0); + + if (gettimeofday(&tv, NULL) != 0 || + gmtime_r(&tv.tv_sec, >m) == NULL) { + logstream_err(B_TRUE, "failed to get time of day"); + abort(); + } + + if (snprintf(ts, sizeof (ts), "%04d-%02d-%02dT%02d:%02d:%02d.%09ldZ", + gtm.tm_year + 1900, gtm.tm_mon + 1, gtm.tm_mday, + gtm.tm_hour, gtm.tm_min, gtm.tm_sec, tv.tv_usec * 1000) >= + sizeof (ts)) { + logstream_err(B_FALSE, "timestamp buffer too small"); + abort(); + } + + start = "{"; + end = ""; + for (i = 0; i <= npairs; i++) { + if (i < npairs) { + key = pairs[i].jp_key; + val = pairs[i].jp_val; + } else { + key = "time"; + val = ts; + end = "}\n"; + } + + len += snprintf(bufsz > len ? buf + len : NULL, + bufsz > len ? bufsz - len : 0, "%s\"%s\":\"%s\"%s", + start, key, val, end); + + start = ","; + } + + return (len); +} + +static void +logstream_write_json(logstream_t *lsp) +{ + char obuf[sizeof (lsp->ls_buf) + sizeof (lsp->ls_stream) + 64]; + size_t len; + jsonpair_t pairs[] = { + { "log", lsp->ls_buf }, + { "stream", lsp->ls_stream }, + }; + + if (lsp->ls_buflen == 0) { + return; + } + + len = make_json(pairs, ARRAY_SIZE(pairs), obuf, sizeof (obuf)); + lsp->ls_buflen = 0; + if (len >= sizeof (obuf)) { + logstream_err(B_FALSE, "%s: buffer too small. Need %llu bytes, " + "have %llu bytes", __func__, len + 1, sizeof (obuf)); + return; + } + + logfile_write(lsp->ls_logfile, obuf, len); +} + +/* + * We output to the log file as json. + * ex. for string 'msg\n' on the zone's stdout: + * {"log":"msg\n","stream":"stdout","time":"2014-10-24T20:12:11.101973117Z"} + * + * We use ns in the last field of the timestamp for compatibility. + * + * We keep track of the size of the log file and rotate it when we exceed + * the log size limit (if one is set). + */ +void +logstream_write(int ls, char *buf, int len) +{ + logstream_t *lsp; + int scnt, dcnt; + boolean_t newline; + boolean_t buffered; + + if (ls == -1 || len == 0) { + return; + } + assert(ls >= 0 && ls < ARRAY_SIZE(streams)); + + logstream_lock(); + + lsp = &streams[ls]; + if (lsp->ls_stream[0] == '\0' || lsp->ls_logfile == NULL) { + logstream_unlock(); + return; + } + + buffered = !!(lsp->ls_flags & LS_LINE_BUFFERED); + + do { + escape_json(buf, len, lsp->ls_buf + lsp->ls_buflen, + sizeof (lsp->ls_buf) - lsp->ls_buflen, + &scnt, &dcnt, buffered ? &newline : NULL); + + lsp->ls_buflen += dcnt; + buf += scnt; + len -= scnt; + + if (!buffered || newline) { + logstream_write_json(lsp); + } + } while (len > 0 && (!buffered || newline)); + + logstream_unlock(); +} + +static void +logstream_flush(int ls) +{ + logstream_t *lsp; + + assert(MUTEX_HELD(&logging_lock)); + + lsp = &streams[ls]; + if (lsp->ls_stream[0] == '\0' || lsp->ls_logfile == NULL) { + return; + } + logstream_write_json(lsp); +} + +static void +logstream_flush_all(logfile_t *lfp) +{ + int i; + + assert(MUTEX_HELD(&logging_lock)); + + for (i = 0; i < ARRAY_SIZE(streams); i++) { + if (streams[i].ls_logfile == lfp) { + logstream_flush(i); + } + } +} + +int +logstream_open(const char *logname, const char *stream, logstream_flags_t flags) +{ + int ls = -1; + int i; + logstream_t *lsp; + logfile_t *lfp = NULL; + + assert(strlen(logname) < sizeof (lfp->lf_name)); + assert(strlen(stream) < sizeof (lsp->ls_stream)); + + logstream_lock(); + + /* + * Find an empty logstream_t and verify that the stream is not already + * open. + */ + for (i = 0; i < ARRAY_SIZE(streams); i++) { + if (ls == -1 && streams[i].ls_stream[0] == '\0') { + assert(streams[i].ls_logfile == NULL); + ls = i; + continue; + } + if (strcmp(stream, streams[i].ls_stream) == 0) { + logstream_unlock(); + logstream_err(B_FALSE, "log stream %s already open", + stream); + return (-1); + } + } + assert(ls != -1); + + /* Find an existing or available logfile_t */ + for (i = 0; i < ARRAY_SIZE(logfiles); i++) { + if (lfp == NULL && logfiles[i].lf_name[0] == '\0') { + lfp = &logfiles[i]; + } + if (strcmp(logname, logfiles[i].lf_name) == 0) { + lfp = &logfiles[i]; + break; + } + } + if (lfp->lf_name[0] == '\0') { + (void) strlcpy(lfp->lf_name, logname, sizeof (lfp->lf_name)); + (void) snprintf(lfp->lf_path, sizeof (lfp->lf_path), "%s/logs", + zonepath); + (void) mkdir(lfp->lf_path, 0700); + + (void) snprintf(lfp->lf_path, sizeof (lfp->lf_path), + "%s/logs/%s", zonepath, logname); + + open_log(lfp, "open"); + if (lfp->lf_fd == -1) { + logstream_unlock(); + return (-1); + } + } + + lsp = &streams[ls]; + (void) strlcpy(lsp->ls_stream, stream, sizeof (lsp->ls_stream)); + + lsp->ls_flags = flags; + lsp->ls_logfile = lfp; + + logstream_unlock(); + + return (ls); +} + +void +logstream_close(int ls, boolean_t abrupt) +{ + logstream_t *lsp; + logfile_t *lfp; + int i; + + if (ls == -1) { + return; + } + assert(ls >= 0 && ls < ARRAY_SIZE(streams)); + + logstream_lock(); + logstream_flush(ls); + + lsp = &streams[ls]; + lfp = lsp->ls_logfile; + + assert(lsp->ls_stream[0] != '\0'); + assert(lfp != NULL); + + (void) memset(lsp, 0, sizeof (*lsp)); + + for (i = 0; i < ARRAY_SIZE(streams); i++) { + if (streams[i].ls_logfile == lfp) { + logstream_unlock(); + return; + } + } + + /* No more streams using this log file so return to initial state */ + + close_log(lfp, "close", abrupt); + + (void) memset(lfp, 0, sizeof (*lfp)); + lfp->lf_fd = -1; + + logstream_unlock(); +} diff --git a/usr/src/cmd/zoneadmd/vplat.c b/usr/src/cmd/zoneadmd/vplat.c index 4a2d94605b..01332d43e8 100644 --- a/usr/src/cmd/zoneadmd/vplat.c +++ b/usr/src/cmd/zoneadmd/vplat.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2013, Joyent Inc. All rights reserved. + * Copyright 2018, Joyent Inc. * Copyright (c) 2015, 2016 by Delphix. All rights reserved. * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. */ @@ -79,10 +79,12 @@ #include <sys/conf.h> #include <sys/systeminfo.h> #include <sys/secflags.h> +#include <sys/vnic.h> #include <libdlpi.h> #include <libdllink.h> #include <libdlvlan.h> +#include <libdlvnic.h> #include <inet/tcp.h> #include <arpa/inet.h> @@ -138,6 +140,9 @@ #define DFSTYPES "/etc/dfs/fstypes" #define MAXTNZLEN 2048 +/* Number of times to retry unmounting if it fails */ +#define UMOUNT_RETRIES 30 + #define ALT_MOUNT(mount_cmd) ((mount_cmd) != Z_MNT_BOOT) /* a reasonable estimate for the number of lwps per process */ @@ -163,11 +168,25 @@ static priv_set_t *zprivs = NULL; static const char *DFLT_FS_ALLOWED = "hsfs,smbfs,nfs,nfs3,nfs4,nfsdyn"; +typedef struct zone_proj_rctl_map { + char *zpr_zone_rctl; + char *zpr_project_rctl; +} zone_proj_rctl_map_t; + +static zone_proj_rctl_map_t zone_proj_rctl_map[] = { + {"zone.max-msg-ids", "project.max-msg-ids"}, + {"zone.max-sem-ids", "project.max-sem-ids"}, + {"zone.max-shm-ids", "project.max-shm-ids"}, + {"zone.max-shm-memory", "project.max-shm-memory"}, + {NULL, NULL} +}; + /* from libsocket, not in any header file */ extern int getnetmaskbyaddr(struct in_addr, struct in_addr *); /* from zoneadmd */ extern char query_hook[]; +extern char post_statechg_hook[]; /* * For each "net" resource configured in zonecfg, we track a zone_addr_list_t @@ -204,7 +223,7 @@ autofs_cleanup(zoneid_t zoneid) /* * Ask autofs to unmount all trigger nodes in the given zone. */ - return (_autofssys(AUTOFS_UNMOUNTALL, (void *)zoneid)); + return (_autofssys(AUTOFS_UNMOUNTALL, (void *)((uintptr_t)zoneid))); } static void @@ -595,6 +614,24 @@ root_to_lu(zlog_t *zlogp, char *zroot, size_t zrootlen, boolean_t isresolved) } /* + * Perform brand-specific cleanup if we are unable to unmount a FS. + */ +static void +brand_umount_cleanup(zlog_t *zlogp, char *path) +{ + char cmdbuf[2 * MAXPATHLEN]; + + if (post_statechg_hook[0] == '\0') + return; + + if (snprintf(cmdbuf, sizeof (cmdbuf), "%s %d %d %s", post_statechg_hook, + ZONE_STATE_DOWN, Z_UNMOUNT, path) > sizeof (cmdbuf)) + return; + + (void) do_subproc(zlogp, cmdbuf, NULL, B_FALSE); +} + +/* * The general strategy for unmounting filesystems is as follows: * * - Remote filesystems may be dead, and attempting to contact them as @@ -627,6 +664,7 @@ static int unmount_filesystems(zlog_t *zlogp, zoneid_t zoneid, boolean_t unmount_cmd) { int error = 0; + int fail = 0; FILE *mnttab; struct mnttab *mnts; uint_t nmnt; @@ -714,18 +752,39 @@ unmount_filesystems(zlog_t *zlogp, zoneid_t zoneid, boolean_t unmount_cmd) if (umount2(path, MS_FORCE) == 0) { unmounted = B_TRUE; stuck = B_FALSE; + fail = 0; } else { /* - * The first failure indicates a - * mount we won't be able to get - * rid of automatically, so we - * bail. + * We may hit a failure here if there + * is an app in the GZ with an open + * pipe into the zone (commonly into + * the zone's /var/run). This type + * of app will notice the closed + * connection and cleanup, but it may + * take a while and we have no easy + * way to notice that. To deal with + * this case, we will wait and retry + * a few times before we give up. */ - error++; - zerror(zlogp, B_FALSE, - "unable to unmount '%s'", path); - free_mnttable(mnts, nmnt); - goto out; + fail++; + if (fail < (UMOUNT_RETRIES - 1)) { + zerror(zlogp, B_FALSE, + "unable to unmount '%s', " + "retrying in 2 seconds", + path); + (void) sleep(2); + } else if (fail > UMOUNT_RETRIES) { + error++; + zerror(zlogp, B_FALSE, + "unmount of '%s' failed", + path); + free_mnttable(mnts, nmnt); + goto out; + } else { + /* Try the hook 2 times */ + brand_umount_cleanup(zlogp, + path); + } } } /* @@ -1063,23 +1122,10 @@ mount_one_dev_symlink_cb(void *arg, const char *source, const char *target) int vplat_get_iptype(zlog_t *zlogp, zone_iptype_t *iptypep) { - zone_dochandle_t handle; - - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, "getting zone configuration handle"); - return (-1); - } - if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { - zerror(zlogp, B_FALSE, "invalid configuration"); - zonecfg_fini_handle(handle); - return (-1); - } - if (zonecfg_get_iptype(handle, iptypep) != Z_OK) { + if (zonecfg_get_iptype(snap_hndl, iptypep) != Z_OK) { zerror(zlogp, B_FALSE, "invalid ip-type configuration"); - zonecfg_fini_handle(handle); return (-1); } - zonecfg_fini_handle(handle); return (0); } @@ -1092,14 +1138,13 @@ static int mount_one_dev(zlog_t *zlogp, char *devpath, zone_mnt_t mount_cmd) { char brand[MAXNAMELEN]; - zone_dochandle_t handle = NULL; brand_handle_t bh = NULL; struct zone_devtab ztab; di_prof_t prof = NULL; int err; int retval = -1; zone_iptype_t iptype; - const char *curr_iptype; + const char *curr_iptype = NULL; if (di_prof_init(devpath, &prof)) { zerror(zlogp, B_TRUE, "failed to initialize profile"); @@ -1134,6 +1179,8 @@ mount_one_dev(zlog_t *zlogp, char *devpath, zone_mnt_t mount_cmd) curr_iptype = "exclusive"; break; } + if (curr_iptype == NULL) + abort(); if (brand_platform_iter_devices(bh, zone_name, mount_one_dev_device_cb, prof, curr_iptype) != 0) { @@ -1148,28 +1195,25 @@ mount_one_dev(zlog_t *zlogp, char *devpath, zone_mnt_t mount_cmd) } /* Add user-specified devices and directories */ - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_FALSE, "can't initialize zone handle"); - goto cleanup; - } - if (err = zonecfg_get_handle(zone_name, handle)) { - zerror(zlogp, B_FALSE, "can't get handle for zone " - "%s: %s", zone_name, zonecfg_strerror(err)); - goto cleanup; - } - if (err = zonecfg_setdevent(handle)) { + if ((err = zonecfg_setdevent(snap_hndl)) != 0) { zerror(zlogp, B_FALSE, "%s: %s", zone_name, zonecfg_strerror(err)); goto cleanup; } - while (zonecfg_getdevent(handle, &ztab) == Z_OK) { - if (di_prof_add_dev(prof, ztab.zone_dev_match)) { + while (zonecfg_getdevent(snap_hndl, &ztab) == Z_OK) { + char path[MAXPATHLEN]; + + if ((err = resolve_device_match(zlogp, &ztab, + path, sizeof (path))) != Z_OK) + goto cleanup; + + if (di_prof_add_dev(prof, path)) { zerror(zlogp, B_TRUE, "failed to add " - "user-specified device"); + "user-specified device '%s'", path); goto cleanup; } } - (void) zonecfg_enddevent(handle); + (void) zonecfg_enddevent(snap_hndl); /* Send profile to kernel */ if (di_prof_commit(prof)) { @@ -1182,8 +1226,6 @@ mount_one_dev(zlog_t *zlogp, char *devpath, zone_mnt_t mount_cmd) cleanup: if (bh != NULL) brand_close(bh); - if (handle != NULL) - zonecfg_fini_handle(handle); if (prof) di_prof_fini(prof); return (retval); @@ -1674,12 +1716,10 @@ static int mount_filesystems(zlog_t *zlogp, zone_mnt_t mount_cmd) { char rootpath[MAXPATHLEN]; - char zonepath[MAXPATHLEN]; char brand[MAXNAMELEN]; char luroot[MAXPATHLEN]; int i, num_fs = 0; struct zone_fstab *fs_ptr = NULL; - zone_dochandle_t handle = NULL; zone_state_t zstate; brand_handle_t bh; plat_gmount_cb_data_t cb; @@ -1693,22 +1733,12 @@ mount_filesystems(zlog_t *zlogp, zone_mnt_t mount_cmd) goto bad; } - if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) { - zerror(zlogp, B_TRUE, "unable to determine zone path"); - goto bad; - } - if (zone_get_rootpath(zone_name, rootpath, sizeof (rootpath)) != Z_OK) { zerror(zlogp, B_TRUE, "unable to determine zone root"); goto bad; } - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, "getting zone configuration handle"); - goto bad; - } - if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK || - zonecfg_setfsent(handle) != Z_OK) { + if (zonecfg_setfsent(snap_hndl) != Z_OK) { zerror(zlogp, B_FALSE, "invalid configuration"); goto bad; } @@ -1726,7 +1756,6 @@ mount_filesystems(zlog_t *zlogp, zone_mnt_t mount_cmd) /* Get a handle to the brand info for this zone */ if ((bh = brand_open(brand)) == NULL) { zerror(zlogp, B_FALSE, "unable to determine zone brand"); - zonecfg_fini_handle(handle); return (-1); } @@ -1741,7 +1770,6 @@ mount_filesystems(zlog_t *zlogp, zone_mnt_t mount_cmd) plat_gmount_cb, &cb) != 0) { zerror(zlogp, B_FALSE, "unable to mount filesystems"); brand_close(bh); - zonecfg_fini_handle(handle); return (-1); } brand_close(bh); @@ -1752,13 +1780,10 @@ mount_filesystems(zlog_t *zlogp, zone_mnt_t mount_cmd) * higher level directories (e.g., /usr) get mounted before * any beneath them (e.g., /usr/local). */ - if (mount_filesystems_fsent(handle, zlogp, &fs_ptr, &num_fs, + if (mount_filesystems_fsent(snap_hndl, zlogp, &fs_ptr, &num_fs, mount_cmd) != 0) goto bad; - zonecfg_fini_handle(handle); - handle = NULL; - /* * Normally when we mount a zone all the zone filesystems * get mounted relative to rootpath, which is usually @@ -1798,23 +1823,40 @@ mount_filesystems(zlog_t *zlogp, zone_mnt_t mount_cmd) qsort(fs_ptr, num_fs, sizeof (*fs_ptr), fs_compare); for (i = 0; i < num_fs; i++) { - if (ALT_MOUNT(mount_cmd) && - strcmp(fs_ptr[i].zone_fs_dir, "/dev") == 0) { - size_t slen = strlen(rootpath) - 2; + if (ALT_MOUNT(mount_cmd)) { + if (strcmp(fs_ptr[i].zone_fs_dir, "/dev") == 0) { + size_t slen = strlen(rootpath) - 2; - /* - * By default we'll try to mount /dev as /a/dev - * but /dev is special and always goes at the top - * so strip the trailing '/a' from the rootpath. - */ - assert(strcmp(&rootpath[slen], "/a") == 0); - rootpath[slen] = '\0'; - if (mount_one(zlogp, &fs_ptr[i], rootpath, mount_cmd) - != 0) - goto bad; - rootpath[slen] = '/'; - continue; + /* + * By default we'll try to mount /dev + * as /a/dev but /dev is special and + * always goes at the top so strip the + * trailing '/a' from the rootpath. + */ + assert(strcmp(&rootpath[slen], "/a") == 0); + rootpath[slen] = '\0'; + if (mount_one(zlogp, &fs_ptr[i], rootpath, + mount_cmd) != 0) + goto bad; + rootpath[slen] = '/'; + continue; + } else if (strcmp(brand_name, default_brand) != 0) { + /* + * If mounting non-native brand, skip + * mounting global mounts and + * filesystem entries since they are + * only needed for native pkg upgrade + * tools. + * + * The only exception right now is + * /dev (handled above), which is + * needed in the luroot in order to + * zlogin -S into the zone. + */ + continue; + } } + if (mount_one(zlogp, &fs_ptr[i], rootpath, mount_cmd) != 0) goto bad; } @@ -1837,8 +1879,6 @@ mount_filesystems(zlog_t *zlogp, zone_mnt_t mount_cmd) return (0); bad: - if (handle != NULL) - zonecfg_fini_handle(handle); free_fs_data(fs_ptr, num_fs); return (-1); } @@ -2194,13 +2234,7 @@ configure_one_interface(zlog_t *zlogp, zoneid_t zone_id, if (ioctl(s, SIOCLIFADDIF, (caddr_t)&lifr) < 0) { /* * Here, we know that the interface can't be brought up. - * A similar warning message was already printed out to - * the console by zoneadm(1M) so instead we log the - * message to syslog and continue. */ - zerror(&logsys, B_TRUE, "WARNING: skipping network interface " - "'%s' which may not be present/plumbed in the " - "global zone.", lifr.lifr_name); (void) close(s); return (Z_OK); } @@ -2413,7 +2447,6 @@ bad: static int configure_shared_network_interfaces(zlog_t *zlogp) { - zone_dochandle_t handle; struct zone_nwiftab nwiftab, loopback_iftab; zoneid_t zoneid; @@ -2422,29 +2455,19 @@ configure_shared_network_interfaces(zlog_t *zlogp) return (-1); } - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, "getting zone configuration handle"); - return (-1); - } - if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { - zerror(zlogp, B_FALSE, "invalid configuration"); - zonecfg_fini_handle(handle); - return (-1); - } - if (zonecfg_setnwifent(handle) == Z_OK) { + if (zonecfg_setnwifent(snap_hndl) == Z_OK) { for (;;) { - if (zonecfg_getnwifent(handle, &nwiftab) != Z_OK) + if (zonecfg_getnwifent(snap_hndl, &nwiftab) != Z_OK) break; + nwifent_free_attrs(&nwiftab); if (configure_one_interface(zlogp, zoneid, &nwiftab) != Z_OK) { - (void) zonecfg_endnwifent(handle); - zonecfg_fini_handle(handle); + (void) zonecfg_endnwifent(snap_hndl); return (-1); } } - (void) zonecfg_endnwifent(handle); + (void) zonecfg_endnwifent(snap_hndl); } - zonecfg_fini_handle(handle); if (is_system_labeled()) { /* * Labeled zones share the loopback interface @@ -2898,7 +2921,6 @@ free_ip_interface(zone_addr_list_t *zalist) static int configure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid) { - zone_dochandle_t handle; struct zone_nwiftab nwiftab; char rootpath[MAXPATHLEN]; char path[MAXPATHLEN]; @@ -2907,30 +2929,18 @@ configure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid) boolean_t added = B_FALSE; zone_addr_list_t *zalist = NULL, *new; - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, "getting zone configuration handle"); - return (-1); - } - if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { - zerror(zlogp, B_FALSE, "invalid configuration"); - zonecfg_fini_handle(handle); - return (-1); - } - - if (zonecfg_setnwifent(handle) != Z_OK) { - zonecfg_fini_handle(handle); + if (zonecfg_setnwifent(snap_hndl) != Z_OK) return (0); - } for (;;) { - if (zonecfg_getnwifent(handle, &nwiftab) != Z_OK) + if (zonecfg_getnwifent(snap_hndl, &nwiftab) != Z_OK) break; + nwifent_free_attrs(&nwiftab); if (prof == NULL) { if (zone_get_devroot(zone_name, rootpath, sizeof (rootpath)) != Z_OK) { - (void) zonecfg_endnwifent(handle); - zonecfg_fini_handle(handle); + (void) zonecfg_endnwifent(snap_hndl); zerror(zlogp, B_TRUE, "unable to determine dev root"); return (-1); @@ -2938,8 +2948,7 @@ configure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid) (void) snprintf(path, sizeof (path), "%s%s", rootpath, "/dev"); if (di_prof_init(path, &prof) != 0) { - (void) zonecfg_endnwifent(handle); - zonecfg_fini_handle(handle); + (void) zonecfg_endnwifent(snap_hndl); zerror(zlogp, B_TRUE, "failed to initialize profile"); return (-1); @@ -2963,17 +2972,17 @@ configure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid) nwiftab.zone_nwif_physical) == 0) { added = B_TRUE; } else { - (void) zonecfg_endnwifent(handle); - zonecfg_fini_handle(handle); - zerror(zlogp, B_TRUE, "failed to add network device"); - return (-1); + /* + * Failed to add network device, but the brand hook + * might be doing this for us, so keep silent. + */ + continue; } /* set up the new IP interface, and add them all later */ new = malloc(sizeof (*new)); if (new == NULL) { zerror(zlogp, B_TRUE, "no memory for %s", nwiftab.zone_nwif_physical); - zonecfg_fini_handle(handle); free_ip_interface(zalist); } bzero(new, sizeof (*new)); @@ -2983,16 +2992,14 @@ configure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid) } if (zalist != NULL) { if ((errno = add_net(zlogp, zoneid, zalist)) != 0) { - (void) zonecfg_endnwifent(handle); - zonecfg_fini_handle(handle); + (void) zonecfg_endnwifent(snap_hndl); zerror(zlogp, B_TRUE, "failed to add address"); free_ip_interface(zalist); return (-1); } free_ip_interface(zalist); } - (void) zonecfg_endnwifent(handle); - zonecfg_fini_handle(handle); + (void) zonecfg_endnwifent(snap_hndl); if (prof != NULL && added) { if (di_prof_commit(prof) != 0) { @@ -3128,48 +3135,23 @@ remove_datalink_protect(zlog_t *zlogp, zoneid_t zoneid) /* datalink does not belong to the GZ */ continue; } - if (dlstatus != DLADM_STATUS_OK) { + if (dlstatus != DLADM_STATUS_OK) zerror(zlogp, B_FALSE, + "clear 'protection' link property: %s", dladm_status2str(dlstatus, dlerr)); - free(dllinks); - return (-1); - } + dlstatus = dladm_set_linkprop(dld_handle, *dllink, "allowed-ips", NULL, 0, DLADM_OPT_ACTIVE); - if (dlstatus != DLADM_STATUS_OK) { + if (dlstatus != DLADM_STATUS_OK) zerror(zlogp, B_FALSE, + "clear 'allowed-ips' link property: %s", dladm_status2str(dlstatus, dlerr)); - free(dllinks); - return (-1); - } } free(dllinks); return (0); } static int -unconfigure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid) -{ - int dlnum = 0; - - /* - * The kernel shutdown callback for the dls module should have removed - * all datalinks from this zone. If any remain, then there's a - * problem. - */ - if (zone_list_datalink(zoneid, &dlnum, NULL) != 0) { - zerror(zlogp, B_TRUE, "unable to list network interfaces"); - return (-1); - } - if (dlnum != 0) { - zerror(zlogp, B_FALSE, - "datalinks remain in zone after shutdown"); - return (-1); - } - return (0); -} - -static int tcp_abort_conn(zlog_t *zlogp, zoneid_t zoneid, const struct sockaddr_storage *local, const struct sockaddr_storage *remote) { @@ -3251,26 +3233,14 @@ static int get_privset(zlog_t *zlogp, priv_set_t *privs, zone_mnt_t mount_cmd) { int error = -1; - zone_dochandle_t handle; char *privname = NULL; - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, "getting zone configuration handle"); - return (-1); - } - if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { - zerror(zlogp, B_FALSE, "invalid configuration"); - zonecfg_fini_handle(handle); - return (-1); - } - if (ALT_MOUNT(mount_cmd)) { zone_iptype_t iptype; - const char *curr_iptype; + const char *curr_iptype = NULL; - if (zonecfg_get_iptype(handle, &iptype) != Z_OK) { + if (zonecfg_get_iptype(snap_hndl, &iptype) != Z_OK) { zerror(zlogp, B_TRUE, "unable to determine ip-type"); - zonecfg_fini_handle(handle); return (-1); } @@ -3283,17 +3253,15 @@ get_privset(zlog_t *zlogp, priv_set_t *privs, zone_mnt_t mount_cmd) break; } - if (zonecfg_default_privset(privs, curr_iptype) == Z_OK) { - zonecfg_fini_handle(handle); + if (zonecfg_default_privset(privs, curr_iptype) == Z_OK) return (0); - } + zerror(zlogp, B_FALSE, "failed to determine the zone's default privilege set"); - zonecfg_fini_handle(handle); return (-1); } - switch (zonecfg_get_privset(handle, privs, &privname)) { + switch (zonecfg_get_privset(snap_hndl, privs, &privname)) { case Z_OK: error = 0; break; @@ -3316,10 +3284,22 @@ get_privset(zlog_t *zlogp, priv_set_t *privs, zone_mnt_t mount_cmd) } free(privname); - zonecfg_fini_handle(handle); return (error); } +static char * +zone_proj_rctl(const char *name) +{ + int i; + + for (i = 0; zone_proj_rctl_map[i].zpr_zone_rctl != NULL; i++) { + if (strcmp(name, zone_proj_rctl_map[i].zpr_zone_rctl) == 0) { + return (zone_proj_rctl_map[i].zpr_project_rctl); + } + } + return (NULL); +} + static int get_rctls(zlog_t *zlogp, char **bufp, size_t *bufsizep) { @@ -3329,25 +3309,15 @@ get_rctls(zlog_t *zlogp, char **bufp, size_t *bufsizep) nvlist_t **nvlv = NULL; int rctlcount = 0; int error = -1; - zone_dochandle_t handle; struct zone_rctltab rctltab; rctlblk_t *rctlblk = NULL; uint64_t maxlwps; uint64_t maxprocs; + int rproc, rlwp; *bufp = NULL; *bufsizep = 0; - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, "getting zone configuration handle"); - return (-1); - } - if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { - zerror(zlogp, B_FALSE, "invalid configuration"); - zonecfg_fini_handle(handle); - return (-1); - } - rctltab.zone_rctl_valptr = NULL; if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { zerror(zlogp, B_TRUE, "%s failed", "nvlist_alloc"); @@ -3356,22 +3326,31 @@ get_rctls(zlog_t *zlogp, char **bufp, size_t *bufsizep) /* * Allow the administrator to control both the maximum number of - * process table slots and the maximum number of lwps with just the - * max-processes property. If only the max-processes property is set, - * we add a max-lwps property with a limit derived from max-processes. + * process table slots, and the maximum number of lwps, with a single + * max-processes or max-lwps property. If only the max-processes + * property is set, we add a max-lwps property with a limit derived + * from max-processes. If only the max-lwps property is set, we add a + * max-processes property with the same limit as max-lwps. */ - if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXPROCS, &maxprocs) - == Z_OK && - zonecfg_get_aliased_rctl(handle, ALIAS_MAXLWPS, &maxlwps) - == Z_NO_ENTRY) { - if (zonecfg_set_aliased_rctl(handle, ALIAS_MAXLWPS, + rproc = zonecfg_get_aliased_rctl(snap_hndl, ALIAS_MAXPROCS, &maxprocs); + rlwp = zonecfg_get_aliased_rctl(snap_hndl, ALIAS_MAXLWPS, &maxlwps); + if (rproc == Z_OK && rlwp == Z_NO_ENTRY) { + if (zonecfg_set_aliased_rctl(snap_hndl, ALIAS_MAXLWPS, maxprocs * LWPS_PER_PROCESS) != Z_OK) { zerror(zlogp, B_FALSE, "unable to set max-lwps alias"); goto out; } + } else if (rlwp == Z_OK && rproc == Z_NO_ENTRY) { + /* no scaling for max-proc value */ + if (zonecfg_set_aliased_rctl(snap_hndl, ALIAS_MAXPROCS, + maxlwps) != Z_OK) { + zerror(zlogp, B_FALSE, + "unable to set max-processes alias"); + goto out; + } } - if (zonecfg_setrctlent(handle) != Z_OK) { + if (zonecfg_setrctlent(snap_hndl) != Z_OK) { zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setrctlent"); goto out; } @@ -3380,10 +3359,11 @@ get_rctls(zlog_t *zlogp, char **bufp, size_t *bufsizep) zerror(zlogp, B_TRUE, "memory allocation failed"); goto out; } - while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) { + while (zonecfg_getrctlent(snap_hndl, &rctltab) == Z_OK) { struct zone_rctlvaltab *rctlval; uint_t i, count; const char *name = rctltab.zone_rctl_name; + char *proj_nm; /* zoneadm should have already warned about unknown rctls. */ if (!zonecfg_is_rctl(name)) { @@ -3450,6 +3430,26 @@ get_rctls(zlog_t *zlogp, char **bufp, size_t *bufsizep) } zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); rctltab.zone_rctl_valptr = NULL; + + /* + * With no action on our part we will start zsched with the + * project rctl values for our (zoneadmd) current project. For + * brands running a variant of Illumos, that's not a problem + * since they will setup their own projects, but for a + * non-native brand like lx, where there are no projects, we + * want to start things up with the same project rctls as the + * corresponding zone rctls, since nothing within the zone will + * ever change the project rctls. + */ + if ((proj_nm = zone_proj_rctl(name)) != NULL) { + if (nvlist_add_nvlist_array(nvl, proj_nm, nvlv, count) + != 0) { + zerror(zlogp, B_FALSE, + "nvlist_add_nvlist_arrays failed"); + goto out; + } + } + if (nvlist_add_nvlist_array(nvl, (char *)name, nvlv, count) != 0) { zerror(zlogp, B_FALSE, "%s failed", @@ -3462,7 +3462,7 @@ get_rctls(zlog_t *zlogp, char **bufp, size_t *bufsizep) nvlv = NULL; rctlcount++; } - (void) zonecfg_endrctlent(handle); + (void) zonecfg_endrctlent(snap_hndl); if (rctlcount == 0) { error = 0; @@ -3486,8 +3486,6 @@ out: nvlist_free(nvl); if (nvlv != NULL) free(nvlv); - if (handle != NULL) - zonecfg_fini_handle(handle); return (error); } @@ -3503,7 +3501,7 @@ get_implicit_datasets(zlog_t *zlogp, char **retstr) > sizeof (cmdbuf)) return (-1); - if (do_subproc(zlogp, cmdbuf, retstr) != 0) + if (do_subproc(zlogp, cmdbuf, retstr, B_FALSE) != 0) return (-1); return (0); @@ -3512,7 +3510,6 @@ get_implicit_datasets(zlog_t *zlogp, char **retstr) static int get_datasets(zlog_t *zlogp, char **bufp, size_t *bufsizep) { - zone_dochandle_t handle; struct zone_dstab dstab; size_t total, offset, len; int error = -1; @@ -3523,30 +3520,20 @@ get_datasets(zlog_t *zlogp, char **bufp, size_t *bufsizep) *bufp = NULL; *bufsizep = 0; - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, "getting zone configuration handle"); - return (-1); - } - if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { - zerror(zlogp, B_FALSE, "invalid configuration"); - zonecfg_fini_handle(handle); - return (-1); - } - if (get_implicit_datasets(zlogp, &implicit_datasets) != 0) { zerror(zlogp, B_FALSE, "getting implicit datasets failed"); goto out; } - if (zonecfg_setdsent(handle) != Z_OK) { + if (zonecfg_setdsent(snap_hndl) != Z_OK) { zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setdsent"); goto out; } total = 0; - while (zonecfg_getdsent(handle, &dstab) == Z_OK) + while (zonecfg_getdsent(snap_hndl, &dstab) == Z_OK) total += strlen(dstab.zone_dataset_name) + 1; - (void) zonecfg_enddsent(handle); + (void) zonecfg_enddsent(snap_hndl); if (implicit_datasets != NULL) implicit_len = strlen(implicit_datasets); @@ -3563,12 +3550,12 @@ get_datasets(zlog_t *zlogp, char **bufp, size_t *bufsizep) goto out; } - if (zonecfg_setdsent(handle) != Z_OK) { + if (zonecfg_setdsent(snap_hndl) != Z_OK) { zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setdsent"); goto out; } offset = 0; - while (zonecfg_getdsent(handle, &dstab) == Z_OK) { + while (zonecfg_getdsent(snap_hndl, &dstab) == Z_OK) { len = strlen(dstab.zone_dataset_name); (void) strlcpy(str + offset, dstab.zone_dataset_name, total - offset); @@ -3576,7 +3563,7 @@ get_datasets(zlog_t *zlogp, char **bufp, size_t *bufsizep) if (offset < total - 1) str[offset++] = ','; } - (void) zonecfg_enddsent(handle); + (void) zonecfg_enddsent(snap_hndl); if (implicit_len > 0) (void) strlcpy(str + offset, implicit_datasets, total - offset); @@ -3588,8 +3575,6 @@ get_datasets(zlog_t *zlogp, char **bufp, size_t *bufsizep) out: if (error != 0 && str != NULL) free(str); - if (handle != NULL) - zonecfg_fini_handle(handle); if (implicit_datasets != NULL) free(implicit_datasets); @@ -3599,40 +3584,26 @@ out: static int validate_datasets(zlog_t *zlogp) { - zone_dochandle_t handle; struct zone_dstab dstab; zfs_handle_t *zhp; libzfs_handle_t *hdl; - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, "getting zone configuration handle"); - return (-1); - } - if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { + if (zonecfg_setdsent(snap_hndl) != Z_OK) { zerror(zlogp, B_FALSE, "invalid configuration"); - zonecfg_fini_handle(handle); - return (-1); - } - - if (zonecfg_setdsent(handle) != Z_OK) { - zerror(zlogp, B_FALSE, "invalid configuration"); - zonecfg_fini_handle(handle); return (-1); } if ((hdl = libzfs_init()) == NULL) { zerror(zlogp, B_FALSE, "opening ZFS library"); - zonecfg_fini_handle(handle); return (-1); } - while (zonecfg_getdsent(handle, &dstab) == Z_OK) { + while (zonecfg_getdsent(snap_hndl, &dstab) == Z_OK) { if ((zhp = zfs_open(hdl, dstab.zone_dataset_name, ZFS_TYPE_FILESYSTEM)) == NULL) { zerror(zlogp, B_FALSE, "cannot open ZFS dataset '%s'", dstab.zone_dataset_name); - zonecfg_fini_handle(handle); libzfs_fini(hdl); return (-1); } @@ -3647,7 +3618,6 @@ validate_datasets(zlog_t *zlogp) zerror(zlogp, B_FALSE, "cannot set 'zoned' " "property for ZFS dataset '%s'\n", dstab.zone_dataset_name); - zonecfg_fini_handle(handle); zfs_close(zhp); libzfs_fini(hdl); return (-1); @@ -3655,9 +3625,8 @@ validate_datasets(zlog_t *zlogp) zfs_close(zhp); } - (void) zonecfg_enddsent(handle); + (void) zonecfg_enddsent(snap_hndl); - zonecfg_fini_handle(handle); libzfs_fini(hdl); return (0); @@ -3711,17 +3680,11 @@ validate_rootds_label(zlog_t *zlogp, char *rootpath, m_label_t *zone_sl) zfs_handle_t *zhp; libzfs_handle_t *hdl; m_label_t ds_sl; - char zonepath[MAXPATHLEN]; char ds_hexsl[MAXNAMELEN]; if (!is_system_labeled()) return (0); - if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) { - zerror(zlogp, B_TRUE, "unable to determine zone path"); - return (-1); - } - if (!is_zonepath_zfs(zonepath)) return (0); @@ -4392,62 +4355,52 @@ duplicate_reachable_path(zlog_t *zlogp, const char *rootpath) } /* - * Set memory cap and pool info for the zone's resource management - * configuration. + * Set pool info for the zone's resource management configuration. */ static int setup_zone_rm(zlog_t *zlogp, char *zone_name, zoneid_t zoneid) { int res; uint64_t tmp; - struct zone_mcaptab mcap; char sched[MAXNAMELEN]; - zone_dochandle_t handle = NULL; char pool_err[128]; - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, "getting zone configuration handle"); - return (Z_BAD_HANDLE); - } - - if ((res = zonecfg_get_snapshot_handle(zone_name, handle)) != Z_OK) { - zerror(zlogp, B_FALSE, "invalid configuration"); - zonecfg_fini_handle(handle); - return (res); - } - - /* - * If a memory cap is configured, set the cap in the kernel using - * zone_setattr() and make sure the rcapd SMF service is enabled. - */ - if (zonecfg_getmcapent(handle, &mcap) == Z_OK) { - uint64_t num; - char smf_err[128]; - - num = (uint64_t)strtoull(mcap.zone_physmem_cap, NULL, 10); - if (zone_setattr(zoneid, ZONE_ATTR_PHYS_MCAP, &num, 0) == -1) { - zerror(zlogp, B_TRUE, "could not set zone memory cap"); - zonecfg_fini_handle(handle); - return (Z_INVAL); - } - - if (zonecfg_enable_rcapd(smf_err, sizeof (smf_err)) != Z_OK) { - zerror(zlogp, B_FALSE, "enabling system/rcap service " - "failed: %s", smf_err); - zonecfg_fini_handle(handle); - return (Z_INVAL); - } - } - /* Get the scheduling class set in the zone configuration. */ - if (zonecfg_get_sched_class(handle, sched, sizeof (sched)) == Z_OK && + if (zonecfg_get_sched_class(snap_hndl, sched, sizeof (sched)) == Z_OK && strlen(sched) > 0) { if (zone_setattr(zoneid, ZONE_ATTR_SCHED_CLASS, sched, strlen(sched)) == -1) zerror(zlogp, B_TRUE, "WARNING: unable to set the " "default scheduling class"); - } else if (zonecfg_get_aliased_rctl(handle, ALIAS_SHARES, &tmp) + if (strcmp(sched, "FX") == 0) { + /* + * When FX is specified then by default all processes + * will start at the lowest priority level (0) and + * stay there. We support an optional attr which + * indicates that all the processes should be "high + * priority". We set this on the zone so that starting + * init will set the priority high. + */ + struct zone_attrtab a; + + bzero(&a, sizeof (a)); + (void) strlcpy(a.zone_attr_name, "fixed-hi-prio", + sizeof (a.zone_attr_name)); + + if (zonecfg_lookup_attr(snap_hndl, &a) == Z_OK && + strcmp(a.zone_attr_value, "true") == 0) { + boolean_t hi = B_TRUE; + + if (zone_setattr(zoneid, + ZONE_ATTR_SCHED_FIXEDHI, (void *)hi, + sizeof (hi)) == -1) + zerror(zlogp, B_TRUE, "WARNING: unable " + "to set high priority"); + } + } + + } else if (zonecfg_get_aliased_rctl(snap_hndl, ALIAS_SHARES, &tmp) == Z_OK) { /* * If the zone has the zone.cpu-shares rctl set then we want to @@ -4458,7 +4411,7 @@ setup_zone_rm(zlog_t *zlogp, char *zone_name, zoneid_t zoneid) */ char class_name[PC_CLNMSZ]; - if (zonecfg_get_dflt_sched_class(handle, class_name, + if (zonecfg_get_dflt_sched_class(snap_hndl, class_name, sizeof (class_name)) != Z_OK) { zerror(zlogp, B_FALSE, "WARNING: unable to determine " "the zone's scheduling class"); @@ -4491,7 +4444,7 @@ setup_zone_rm(zlog_t *zlogp, char *zone_name, zoneid_t zoneid) * right thing in all cases (reuse or create) based on the current * zonecfg. */ - if ((res = zonecfg_bind_tmp_pool(handle, zoneid, pool_err, + if ((res = zonecfg_bind_tmp_pool(snap_hndl, zoneid, pool_err, sizeof (pool_err))) != Z_OK) { if (res == Z_POOL || res == Z_POOL_CREATE || res == Z_POOL_BIND) zerror(zlogp, B_FALSE, "%s: %s\ndedicated-cpu setting " @@ -4500,14 +4453,13 @@ setup_zone_rm(zlog_t *zlogp, char *zone_name, zoneid_t zoneid) else zerror(zlogp, B_FALSE, "could not bind zone to " "temporary pool: %s", zonecfg_strerror(res)); - zonecfg_fini_handle(handle); return (Z_POOL_BIND); } /* * Check if we need to warn about poold not being enabled. */ - if (zonecfg_warn_poold(handle)) { + if (zonecfg_warn_poold(snap_hndl)) { zerror(zlogp, B_FALSE, "WARNING: A range of dedicated-cpus has " "been specified\nbut the dynamic pool service is not " "enabled.\nThe system will not dynamically adjust the\n" @@ -4517,7 +4469,7 @@ setup_zone_rm(zlog_t *zlogp, char *zone_name, zoneid_t zoneid) } /* The following is a warning, not an error. */ - if ((res = zonecfg_bind_pool(handle, zoneid, pool_err, + if ((res = zonecfg_bind_pool(snap_hndl, zoneid, pool_err, sizeof (pool_err))) != Z_OK) { if (res == Z_POOL_BIND) zerror(zlogp, B_FALSE, "WARNING: unable to bind to " @@ -4531,10 +4483,9 @@ setup_zone_rm(zlog_t *zlogp, char *zone_name, zoneid_t zoneid) } /* Update saved pool name in case it has changed */ - (void) zonecfg_get_poolname(handle, zone_name, pool_name, + (void) zonecfg_get_poolname(snap_hndl, zone_name, pool_name, sizeof (pool_name)); - zonecfg_fini_handle(handle); return (Z_OK); } @@ -4725,36 +4676,31 @@ setup_zone_fs_allowed(zone_dochandle_t handle, zlog_t *zlogp, zoneid_t zoneid) } static int -setup_zone_attrs(zlog_t *zlogp, char *zone_namep, zoneid_t zoneid) +setup_zone_attrs(zlog_t *zlogp, zoneid_t zoneid) { - zone_dochandle_t handle; int res = Z_OK; - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, "getting zone configuration handle"); - return (Z_BAD_HANDLE); - } - if ((res = zonecfg_get_snapshot_handle(zone_namep, handle)) != Z_OK) { - zerror(zlogp, B_FALSE, "invalid configuration"); - goto out; - } - - if ((res = setup_zone_hostid(handle, zlogp, zoneid)) != Z_OK) + if ((res = setup_zone_hostid(snap_hndl, zlogp, zoneid)) != Z_OK) goto out; - if ((res = setup_zone_fs_allowed(handle, zlogp, zoneid)) != Z_OK) + if ((res = setup_zone_fs_allowed(snap_hndl, zlogp, zoneid)) != Z_OK) goto out; - if ((res = setup_zone_secflags(handle, zlogp, zoneid)) != Z_OK) + if ((res = setup_zone_secflags(snap_hndl, zlogp, zoneid)) != Z_OK) goto out; out: - zonecfg_fini_handle(handle); return (res); } +/* + * The zone_did is a persistent debug ID. Each zone should have a unique ID + * in the kernel. This is used for things like DTrace which want to monitor + * zones across reboots. They can't use the zoneid since that changes on + * each boot. + */ zoneid_t -vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd) +vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd, zoneid_t zone_did) { zoneid_t rval = -1; priv_set_t *privs; @@ -4770,7 +4716,7 @@ vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd) tsol_zcent_t *zcent = NULL; int match = 0; int doi = 0; - int flags; + int flags = -1; zone_iptype_t iptype; if (zone_get_rootpath(zone_name, rootpath, sizeof (rootpath)) != Z_OK) { @@ -4792,6 +4738,8 @@ vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd) flags = ZCF_NET_EXCL; break; } + if (flags == -1) + abort(); if ((privs = priv_allocset()) == NULL) { zerror(zlogp, B_TRUE, "%s failed", "priv_allocset"); @@ -4895,7 +4843,7 @@ vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd) xerr = 0; if ((zoneid = zone_create(kzone, rootpath, privs, rctlbuf, rctlbufsz, zfsbuf, zfsbufsz, &xerr, match, doi, zlabel, - flags)) == -1) { + flags, zone_did)) == -1) { if (xerr == ZE_AREMOUNTS) { if (zonecfg_find_mounts(rootpath, NULL, NULL) < 1) { zerror(zlogp, B_FALSE, @@ -4941,7 +4889,7 @@ vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd) struct brand_attr attr; char modname[MAXPATHLEN]; - if (setup_zone_attrs(zlogp, zone_name, zoneid) != Z_OK) + if (setup_zone_attrs(zlogp, zoneid) != Z_OK) goto error; if ((bh = brand_open(brand_name)) == NULL) { @@ -4999,6 +4947,8 @@ error: } if (rctlbuf != NULL) free(rctlbuf); + if (zfsbuf != NULL) + free(zfsbuf); priv_freeset(privs); if (fp != NULL) zonecfg_close_scratch(fp); @@ -5087,7 +5037,7 @@ write_index_file(zoneid_t zoneid) int vplat_bringup(zlog_t *zlogp, zone_mnt_t mount_cmd, zoneid_t zoneid) { - char zonepath[MAXPATHLEN]; + char zpath[MAXPATHLEN]; if (mount_cmd == Z_MNT_BOOT && validate_datasets(zlogp) != 0) { lofs_discard_mnttab(); @@ -5098,15 +5048,11 @@ vplat_bringup(zlog_t *zlogp, zone_mnt_t mount_cmd, zoneid_t zoneid) * Before we try to mount filesystems we need to create the * attribute backing store for /dev */ - if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) { - lofs_discard_mnttab(); - return (-1); - } - resolve_lofs(zlogp, zonepath, sizeof (zonepath)); + (void) strlcpy(zpath, zonepath, sizeof (zpath)); + resolve_lofs(zlogp, zpath, sizeof (zpath)); /* Make /dev directory owned by root, grouped sys */ - if (make_one_dir(zlogp, zonepath, "/dev", DEFAULT_DIR_MODE, - 0, 3) != 0) { + if (make_one_dir(zlogp, zpath, "/dev", DEFAULT_DIR_MODE, 0, 3) != 0) { lofs_discard_mnttab(); return (-1); } @@ -5141,6 +5087,8 @@ vplat_bringup(zlog_t *zlogp, zone_mnt_t mount_cmd, zoneid_t zoneid) return (-1); } break; + default: + abort(); } } @@ -5215,14 +5163,88 @@ unmounted: } } +/* + * Delete all transient VNICs belonging to this zone. A transient VNIC + * is one that is created and destroyed along with the lifetime of the + * zone. Non-transient VNICs, ones that are assigned from the GZ to a + * NGZ, are reassigned to the GZ in zone_shutdown() via the + * zone-specific data (zsd) callbacks. + */ +static int +delete_transient_vnics(zlog_t *zlogp, zoneid_t zoneid) +{ + dladm_status_t status; + int num_links = 0; + datalink_id_t *links, link; + uint32_t link_flags; + datalink_class_t link_class; + char link_name[MAXLINKNAMELEN]; + + if (zone_list_datalink(zoneid, &num_links, NULL) != 0) { + zerror(zlogp, B_TRUE, "unable to determine " + "number of network interfaces"); + return (-1); + } + + if (num_links == 0) + return (0); + + links = malloc(num_links * sizeof (datalink_id_t)); + + if (links == NULL) { + zerror(zlogp, B_TRUE, "failed to delete " + "network interfaces because of alloc fail"); + return (-1); + } + + if (zone_list_datalink(zoneid, &num_links, links) != 0) { + zerror(zlogp, B_TRUE, "failed to delete " + "network interfaces because of failure " + "to list them"); + return (-1); + } + + for (int i = 0; i < num_links; i++) { + char dlerr[DLADM_STRSIZE]; + link = links[i]; + + status = dladm_datalink_id2info(dld_handle, link, &link_flags, + &link_class, NULL, link_name, sizeof (link_name)); + + if (status != DLADM_STATUS_OK) { + zerror(zlogp, B_FALSE, "failed to " + "delete network interface (%u)" + "due to failure to get link info: %s", + link, + dladm_status2str(status, dlerr)); + return (-1); + } + + if (link_flags & DLADM_OPT_TRANSIENT) { + assert(link_class & DATALINK_CLASS_VNIC); + status = dladm_vnic_delete(dld_handle, link, + DLADM_OPT_ACTIVE); + + if (status != DLADM_STATUS_OK) { + zerror(zlogp, B_TRUE, "failed to delete link " + "with id %d: %s", link, + dladm_status2str(status, dlerr)); + return (-1); + } + } + } + + return (0); +} + int -vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting) +vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting, + boolean_t debug) { char *kzone; zoneid_t zoneid; int res; char pool_err[128]; - char zpath[MAXPATHLEN]; char cmdbuf[MAXPATHLEN]; brand_handle_t bh = NULL; dladm_status_t status; @@ -5255,16 +5277,12 @@ vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting) goto error; } - if (remove_datalink_pool(zlogp, zoneid) != 0) { + if (remove_datalink_pool(zlogp, zoneid) != 0) zerror(zlogp, B_FALSE, "unable clear datalink pool property"); - goto error; - } - if (remove_datalink_protect(zlogp, zoneid) != 0) { + if (remove_datalink_protect(zlogp, zoneid) != 0) zerror(zlogp, B_FALSE, "unable clear datalink protect property"); - goto error; - } /* * The datalinks assigned to the zone will be removed from the NGZ as @@ -5278,12 +5296,6 @@ vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting) goto error; } - /* Get the zonepath of this zone */ - if (zone_get_zonepath(zone_name, zpath, sizeof (zpath)) != Z_OK) { - zerror(zlogp, B_FALSE, "unable to determine zone path"); - goto error; - } - /* Get a handle to the brand info for this zone */ if ((bh = brand_open(brand_name)) == NULL) { zerror(zlogp, B_FALSE, "unable to determine zone brand"); @@ -5294,7 +5306,7 @@ vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting) * brand a chance to cleanup any custom configuration. */ (void) strcpy(cmdbuf, EXEC_PREFIX); - if (brand_get_halt(bh, zone_name, zpath, cmdbuf + EXEC_LEN, + if (brand_get_halt(bh, zone_name, zonepath, cmdbuf + EXEC_LEN, sizeof (cmdbuf) - EXEC_LEN) < 0) { brand_close(bh); zerror(zlogp, B_FALSE, "unable to determine branded zone's " @@ -5304,7 +5316,7 @@ vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting) brand_close(bh); if ((strlen(cmdbuf) > EXEC_LEN) && - (do_subproc(zlogp, cmdbuf, NULL) != Z_OK)) { + (do_subproc(zlogp, cmdbuf, NULL, debug) != Z_OK)) { zerror(zlogp, B_FALSE, "%s failed", cmdbuf); goto error; } @@ -5336,17 +5348,18 @@ vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting) } break; case ZS_EXCLUSIVE: - if (unconfigure_exclusive_network_interfaces(zlogp, - zoneid) != 0) { - zerror(zlogp, B_FALSE, "unable to unconfigure " - "network interfaces in zone"); + if (delete_transient_vnics(zlogp, zoneid) != 0) { + zerror(zlogp, B_FALSE, "unable to delete " + "transient vnics in zone"); goto error; } + status = dladm_zone_halt(dld_handle, zoneid); if (status != DLADM_STATUS_OK) { zerror(zlogp, B_FALSE, "unable to notify " "dlmgmtd of zone halt: %s", dladm_status2str(status, errmsg)); + goto error; } break; } @@ -5378,14 +5391,9 @@ vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting) if (rebooting) { struct zone_psettab pset_tab; - zone_dochandle_t handle; - if ((handle = zonecfg_init_handle()) != NULL && - zonecfg_get_handle(zone_name, handle) == Z_OK && - zonecfg_lookup_pset(handle, &pset_tab) == Z_OK) + if (zonecfg_lookup_pset(snap_hndl, &pset_tab) == Z_OK) destroy_tmp_pool = B_FALSE; - - zonecfg_fini_handle(handle); } if (destroy_tmp_pool) { diff --git a/usr/src/cmd/zoneadmd/zcons.c b/usr/src/cmd/zoneadmd/zcons.c index 5f6fc4973c..5f415b0210 100644 --- a/usr/src/cmd/zoneadmd/zcons.c +++ b/usr/src/cmd/zoneadmd/zcons.c @@ -22,7 +22,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * Copyright 2012 Joyent, Inc. All rights reserved. + * Copyright 2019 Joyent, Inc. * Copyright 2015 Nexenta Systems, Inc. All rights reserved. */ @@ -40,10 +40,10 @@ * * Global Zone | Non-Global Zone * .--------------. | - * .-----------. | zoneadmd -z | | .--------. .---------. - * | zlogin -C | | myzone | | | ttymon | | syslogd | - * `-----------' `--------------' | `--------' `---------' - * | | | | | | | + * .-----------. | zoneadmd -z |--. | .--------. .---------. + * | zlogin -C | | myzone | | | | ttymon | | syslogd | + * `-----------' `--------------' V | `--------' `---------' + * | | | | console.log | | | * User | | | | | V V * - - - - - - - - -|- - - -|- - - -|-|- - - - - - -|- - /dev/zconsole - - - * Kernel V V | | | @@ -81,6 +81,8 @@ * functions as a two-way proxy for console I/O, relaying user input * to the master side of the console, and relaying output from the * zone to the user. + * + * - Logging output to <zonepath>/logs/console.log. */ #include <sys/types.h> @@ -118,9 +120,10 @@ #define CONSOLE_SOCKPATH ZONES_TMPDIR "/%s.console_sock" +#define ZCONS_RETRY 10 + static int serverfd = -1; /* console server unix domain socket fd */ char boot_args[BOOTARGS_MAX]; -char bad_boot_arg[BOOTARGS_MAX]; /* * The eventstream is a simple one-directional flow of messages from the @@ -130,7 +133,10 @@ char bad_boot_arg[BOOTARGS_MAX]; */ static int eventstream[2]; - +/* flag used to cope with race creating master zcons devlink */ +static boolean_t master_zcons_failed = B_FALSE; +/* flag to track if we've seen a state change when there is no master zcons */ +static boolean_t state_changed = B_FALSE; int eventstream_init() @@ -322,7 +328,7 @@ destroy_console_devs(zlog_t *zlogp) * interfaces to instantiate a new zone console node. We do a lot of * sanity checking, and are careful to reuse a console if one exists. * - * Once the device is in the device tree, we kick devfsadm via di_init_devs() + * Once the device is in the device tree, we kick devfsadm via di_devlink_init() * to ensure that the appropriate symlinks (to the master and slave console * devices) are placed in /dev in the global zone. */ @@ -408,43 +414,63 @@ devlinks: * Open the master side of the console and issue the ZC_HOLDSLAVE ioctl, * which will cause the master to retain a reference to the slave. * This prevents ttymon from blowing through the slave's STREAMS anchor. + * + * In very rare cases the open returns ENOENT if devfs doesn't have + * everything setup yet due to heavy zone startup load. Wait for + * 1 sec. and retry a few times. Even if we can't setup the zone's + * console, we still go ahead and boot the zone. */ (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s", zone_name, ZCONS_MASTER_NAME); - if ((masterfd = open(conspath, O_RDWR | O_NOCTTY)) == -1) { + for (i = 0; i < ZCONS_RETRY; i++) { + masterfd = open(conspath, O_RDWR | O_NOCTTY); + if (masterfd >= 0 || errno != ENOENT) + break; + (void) sleep(1); + } + if (masterfd == -1) { zerror(zlogp, B_TRUE, "ERROR: could not open master side of " "zone console for %s to acquire slave handle", zone_name); - goto error; + master_zcons_failed = B_TRUE; } + (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s", zone_name, ZCONS_SLAVE_NAME); - if ((slavefd = open(conspath, O_RDWR | O_NOCTTY)) == -1) { + for (i = 0; i < ZCONS_RETRY; i++) { + slavefd = open(conspath, O_RDWR | O_NOCTTY); + if (slavefd >= 0 || errno != ENOENT) + break; + (void) sleep(1); + } + if (slavefd == -1) zerror(zlogp, B_TRUE, "ERROR: could not open slave side of zone" " console for %s to acquire slave handle", zone_name); - (void) close(masterfd); - goto error; - } + /* * This ioctl can occasionally return ENXIO if devfs doesn't have * everything plumbed up yet due to heavy zone startup load. Wait for * 1 sec. and retry a few times before we fail to boot the zone. */ - for (i = 0; i < 5; i++) { - if (ioctl(masterfd, ZC_HOLDSLAVE, (caddr_t)(intptr_t)slavefd) - == 0) { - rv = 0; - break; - } else if (errno != ENXIO) { - break; + if (masterfd != -1 && slavefd != -1) { + for (i = 0; i < ZCONS_RETRY; i++) { + if (ioctl(masterfd, ZC_HOLDSLAVE, + (caddr_t)(intptr_t)slavefd) == 0) { + rv = 0; + break; + } else if (errno != ENXIO) { + break; + } + (void) sleep(1); } - (void) sleep(1); + if (rv != 0) + zerror(zlogp, B_TRUE, "ERROR: error while acquiring " + "slave handle of zone console for %s", zone_name); } - if (rv != 0) - zerror(zlogp, B_TRUE, "ERROR: error while acquiring slave " - "handle of zone console for %s", zone_name); - (void) close(slavefd); - (void) close(masterfd); + if (slavefd != -1) + (void) close(slavefd); + if (masterfd != -1) + (void) close(masterfd); error: if (ddef_hdl) @@ -517,6 +543,7 @@ get_client_ident(int clifd, pid_t *pid, char *locale, size_t locale_len, size_t buflen = sizeof (buf); char c = '\0'; int i = 0, r; + ucred_t *cred = NULL; /* "eat up the ident string" case, for simplicity */ if (pid == NULL) { @@ -550,18 +577,22 @@ get_client_ident(int clifd, pid_t *pid, char *locale, size_t locale_len, break; } + if (getpeerucred(clifd, &cred) == 0) { + *pid = ucred_getpid((const ucred_t *)cred); + ucred_free(cred); + } else { + return (-1); + } + /* * Parse buffer for message of the form: - * IDENT <pid> <locale> <disconnect flag> + * IDENT <locale> <disconnect flag> */ bufp = buf; if (strncmp(bufp, "IDENT ", 6) != 0) return (-1); bufp += 6; errno = 0; - *pid = strtoll(bufp, &bufp, 10); - if (errno != 0) - return (-1); while (*bufp != '\0' && isspace(*bufp)) bufp++; @@ -667,14 +698,6 @@ event_message(int clifd, char *clilocale, zone_evt_t evt, int dflag) else str = "NOTICE: Zone boot failed"; break; - case Z_EVT_ZONE_BADARGS: - /*LINTED*/ - (void) snprintf(lmsg, sizeof (lmsg), - localize_msg(clilocale, - "WARNING: Ignoring invalid boot arguments: %s"), - bad_boot_arg); - lstr = lmsg; - break; default: return; } @@ -713,7 +736,7 @@ test_client(int clifd) * messages) can be output in the user's locale. */ static void -do_console_io(zlog_t *zlogp, int consfd, int servfd) +do_console_io(zlog_t *zlogp, int consfd, int servfd, int conslog) { struct pollfd pollfds[4]; char ibuf[BUFSIZ]; @@ -759,14 +782,21 @@ do_console_io(zlog_t *zlogp, int consfd, int servfd) (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { errno = 0; cc = read(consfd, ibuf, BUFSIZ); - if (cc <= 0 && (errno != EINTR) && - (errno != EAGAIN)) - break; - /* - * Lose I/O if no one is listening - */ - if (clifd != -1 && cc > 0) - (void) write(clifd, ibuf, cc); + if (cc <= 0) { + if (errno != EINTR && + errno != EAGAIN) { + break; + } + } else { + logstream_write(conslog, ibuf, cc); + + /* + * Lose I/O if no one is listening + */ + if (clifd != -1) { + (void) write(clifd, ibuf, cc); + } + } } else { pollerr = pollfds[0].revents; zerror(zlogp, B_FALSE, @@ -878,7 +908,6 @@ init_console(zlog_t *zlogp) if (init_console_dev(zlogp) == -1) { zerror(zlogp, B_FALSE, "console setup: device initialization failed"); - return (-1); } if ((serverfd = init_console_sock(zlogp)) == -1) { @@ -890,6 +919,17 @@ init_console(zlog_t *zlogp) } /* + * Maintain a simple flag that tracks if we have seen at least one state + * change. This is currently only used to handle the special case where we are + * running without a console device, which is what normally drives shutdown. + */ +void +zcons_statechanged() +{ + state_changed = B_TRUE; +} + +/* * serve_console() is the master loop for driving console I/O. It is also the * routine which is ultimately responsible for "pulling the plug" on zoneadmd * when it realizes that the daemon should shut down. @@ -907,6 +947,10 @@ serve_console(zlog_t *zlogp) int masterfd; zone_state_t zstate; char conspath[MAXPATHLEN]; + static boolean_t cons_warned = B_FALSE; + int conslog; + + conslog = logstream_open("console.log", "console", LS_LINE_BUFFERED); (void) snprintf(conspath, sizeof (conspath), "/dev/zcons/%s/%s", zone_name, ZCONS_MASTER_NAME); @@ -914,6 +958,46 @@ serve_console(zlog_t *zlogp) for (;;) { masterfd = open(conspath, O_RDWR|O_NONBLOCK|O_NOCTTY); if (masterfd == -1) { + if (master_zcons_failed) { + /* + * If we don't have a console and the zone is + * not shutting down, there may have been a + * race/failure with devfs while creating the + * console. In this case we want to leave the + * zone up, even without a console, so + * periodically recheck. + */ + int i; + + /* + * In the normal flow of this loop, we use + * do_console_io to give things a chance to get + * going first. However, in this case we can't + * use that, so we have to wait for at least + * one state change before checking the state. + */ + for (i = 0; i < 60; i++) { + if (state_changed) + break; + (void) sleep(1); + } + + if (i < 60 && zone_get_state(zone_name, + &zstate) == Z_OK && + (zstate == ZONE_STATE_READY || + zstate == ZONE_STATE_RUNNING)) { + if (!cons_warned) { + zerror(zlogp, B_FALSE, + "WARNING: missing zone " + "console for %s", + zone_name); + cons_warned = B_TRUE; + } + (void) sleep(ZCONS_RETRY); + continue; + } + } + zerror(zlogp, B_TRUE, "failed to open console master"); (void) mutex_lock(&lock); goto death; @@ -933,7 +1017,7 @@ serve_console(zlog_t *zlogp) goto death; } - do_console_io(zlogp, masterfd, serverfd); + do_console_io(zlogp, masterfd, serverfd, conslog); /* * We would prefer not to do this, but hostile zone processes @@ -974,4 +1058,6 @@ death: destroy_console_sock(serverfd); (void) destroy_console_devs(zlogp); + + logstream_close(conslog, B_FALSE); } diff --git a/usr/src/cmd/zoneadmd/zfd.c b/usr/src/cmd/zoneadmd/zfd.c new file mode 100644 index 0000000000..8f4307a653 --- /dev/null +++ b/usr/src/cmd/zoneadmd/zfd.c @@ -0,0 +1,1237 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * Copyright 2019 Joyent, Inc. + */ + +/* + * Zone file descriptor support is used as a mechanism for a process inside the + * zone to log messages to the GZ zoneadmd and also as a way to interact + * directly with the process (via zlogin -I). The zfd thread is modeled on + * the zcons thread so see the comment header in zcons.c for a general overview. + * Unlike with zcons, which has a single endpoint within the zone and a single + * endpoint used by zoneadmd, we setup multiple endpoints within the zone. + * + * The mode, which is controlled by the zone attribute "zlog-mode" is somewhat + * of a misnomer since its purpose has evolved. The attribute currently + * can have six values which are used to control: + * - how the zfd devices are used inside the zone + * - if the output on the device(s) is also teed into another stream within + * the zone + * - if we do logging in the GZ + * See the comment on get_mode_logmax() in this file, and the comment in + * uts/common/io/zfd.c for more details. + * + * Internally the zfd_mode_t struct holds the number of stdio devs (1 or 3), + * the number of additional devs corresponding to the zone attr value and the + * GZ logging flag. + * + * Note that although the mode indicates the number of devices needed, we always + * create all possible zfd devices for simplicity. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/termios.h> +#include <sys/zfd.h> +#include <sys/mkdev.h> + +#include <assert.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <stropts.h> +#include <thread.h> +#include <ucred.h> +#include <unistd.h> +#include <zone.h> +#include <signal.h> +#include <wchar.h> + +#include <libdevinfo.h> +#include <libdevice.h> +#include <libzonecfg.h> + +#include <syslog.h> +#include <sys/modctl.h> + +#include "zoneadmd.h" + +static int shutting_down = 0; +static thread_t logger_tid; +static char log_name[MAXNAMELEN] = "stdio.log"; + +/* + * The eventstream is a simple one-directional flow of messages implemented + * with a pipe. It is used to wake up the poller when it needs to shutdown. + */ +static int eventstream[2] = {-1, -1}; + +#define ZLOG_MODE "zlog-mode" +#define ZLOG_NAME "zlog-name" +#define ZFDNEX_DEVTREEPATH "/pseudo/zfdnex@2" +#define ZFDNEX_FILEPATH "/devices/pseudo/zfdnex@2" +#define SERVER_SOCKPATH ZONES_TMPDIR "/%s.server_%s" +#define ZTTY_RETRY 5 + +#define NUM_ZFD_DEVS 5 + +typedef struct zfd_mode { + uint_t zmode_n_stddevs; + uint_t zmode_n_addl_devs; + boolean_t zmode_gzlogging; +} zfd_mode_t; +static zfd_mode_t mode; + +/* + * cb_data is only used by destroy_cb. + */ +struct cb_data { + zlog_t *zlogp; + int killed; +}; + +/* + * destroy_zfd_devs() and its helper destroy_cb() tears down any zfd instances + * associated with this zone. If things went very wrong, we might have an + * incorrect number of instances hanging around. This routine hunts down and + * tries to remove all of them. Of course, if the fd is open, the instance will + * not detach, which is a potential issue. + */ +static int +destroy_cb(di_node_t node, void *arg) +{ + struct cb_data *cb = (struct cb_data *)arg; + char *prop_data; + char *tmp; + char devpath[MAXPATHLEN]; + devctl_hdl_t hdl; + + if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "zfd_zname", + &prop_data) == -1) + return (DI_WALK_CONTINUE); + + assert(prop_data != NULL); + if (strcmp(prop_data, zone_name) != 0) { + /* this is a zfd for a different zone */ + return (DI_WALK_CONTINUE); + } + + tmp = di_devfs_path(node); + (void) snprintf(devpath, sizeof (devpath), "/devices/%s", tmp); + di_devfs_path_free(tmp); + + if ((hdl = devctl_device_acquire(devpath, 0)) == NULL) { + zerror(cb->zlogp, B_TRUE, "WARNING: zfd %s found, " + "but it could not be controlled.", devpath); + return (DI_WALK_CONTINUE); + } + if (devctl_device_remove(hdl) == 0) { + cb->killed++; + } else { + zerror(cb->zlogp, B_TRUE, "WARNING: zfd %s found, " + "but it could not be removed.", devpath); + } + devctl_release(hdl); + return (DI_WALK_CONTINUE); +} + +static int +destroy_zfd_devs(zlog_t *zlogp) +{ + di_node_t root; + struct cb_data cb; + + bzero(&cb, sizeof (cb)); + cb.zlogp = zlogp; + + if ((root = di_init(ZFDNEX_DEVTREEPATH, DINFOCPYALL)) == DI_NODE_NIL) { + zerror(zlogp, B_TRUE, "di_init failed"); + return (-1); + } + + (void) di_walk_node(root, DI_WALK_CLDFIRST, (void *)&cb, destroy_cb); + + di_fini(root); + return (0); +} + +static void +make_tty(zlog_t *zlogp, int id) +{ + int i; + int fd = -1; + char stdpath[MAXPATHLEN]; + + /* + * Open the master side of the dev and issue the ZFD_MAKETTY ioctl, + * which will cause the the various tty-related streams modules to be + * pushed when the slave opens the device. + * + * In very rare cases the open returns ENOENT if devfs doesn't have + * everything setup yet due to heavy zone startup load. Wait for + * 1 sec. and retry a few times. Even if we can't setup tty mode + * we still move on. + */ + (void) snprintf(stdpath, sizeof (stdpath), "/dev/zfd/%s/master/%d", + zone_name, id); + + for (i = 0; !shutting_down && i < ZTTY_RETRY; i++) { + fd = open(stdpath, O_RDWR | O_NOCTTY); + if (fd >= 0 || errno != ENOENT) + break; + (void) sleep(1); + } + if (fd == -1) { + zerror(zlogp, B_TRUE, "ERROR: could not open zfd %d for " + "zone %s to set tty mode", id, zone_name); + } else { + /* + * This ioctl can occasionally return ENXIO if devfs doesn't + * have everything plumbed up yet due to heavy zone startup + * load. Wait for 1 sec. and retry a few times before we give + * up. + */ + for (i = 0; !shutting_down && i < ZTTY_RETRY; i++) { + if (ioctl(fd, ZFD_MAKETTY) == 0) { + break; + } else if (errno != ENXIO) { + break; + } + (void) sleep(1); + } + } + + if (fd != -1) + (void) close(fd); +} + +/* + * init_zfd_devs() drives the device-tree configuration of the zone fd devices. + * The general strategy is to use the libdevice (devctl) interfaces to + * instantiate all of new zone fd nodes. We do a lot of sanity checking, and + * are careful to reuse a dev if one exists. + * + * Once the devices are in the device tree, we kick devfsadm via + * di_devlink_init() to ensure that the appropriate symlinks (to the master and + * slave fd devices) are placed in /dev in the global zone. + */ +static int +init_zfd_dev(zlog_t *zlogp, devctl_hdl_t bus_hdl, int id) +{ + int rv = -1; + devctl_ddef_t ddef_hdl = NULL; + devctl_hdl_t dev_hdl = NULL; + + if ((ddef_hdl = devctl_ddef_alloc("zfd", 0)) == NULL) { + zerror(zlogp, B_TRUE, "failed to allocate ddef handle"); + goto error; + } + + /* + * Set four properties on this node; the name of the zone, the dev name + * seen inside the zone, a flag which lets pseudo know that it is OK to + * automatically allocate an instance # for this device, and the last + * one tells the device framework not to auto-detach this node - we + * need the node to still be there when we ask devfsadmd to make links, + * and when we need to open it. + */ + if (devctl_ddef_string(ddef_hdl, "zfd_zname", zone_name) == -1) { + zerror(zlogp, B_TRUE, "failed to create zfd_zname property"); + goto error; + } + if (devctl_ddef_int(ddef_hdl, "zfd_id", id) == -1) { + zerror(zlogp, B_TRUE, "failed to create zfd_id property"); + goto error; + } + if (devctl_ddef_int(ddef_hdl, "auto-assign-instance", 1) == -1) { + zerror(zlogp, B_TRUE, "failed to create auto-assign-instance " + "property"); + goto error; + } + if (devctl_ddef_int(ddef_hdl, "ddi-no-autodetach", 1) == -1) { + zerror(zlogp, B_TRUE, "failed to create ddi-no-auto-detach " + "property"); + goto error; + } + if (devctl_bus_dev_create(bus_hdl, ddef_hdl, 0, &dev_hdl) == -1) { + zerror(zlogp, B_TRUE, "failed to create zfd node"); + goto error; + } + rv = 0; + +error: + if (ddef_hdl) + devctl_ddef_free(ddef_hdl); + if (dev_hdl) + devctl_release(dev_hdl); + return (rv); +} + +static int +init_zfd_devs(zlog_t *zlogp, zfd_mode_t *mode) +{ + devctl_hdl_t bus_hdl = NULL; + di_devlink_handle_t dl = NULL; + int rv = -1; + int i; + + /* + * Time to make the devices. + */ + if ((bus_hdl = devctl_bus_acquire(ZFDNEX_FILEPATH, 0)) == NULL) { + zerror(zlogp, B_TRUE, "devctl_bus_acquire failed"); + goto error; + } + + for (i = 0; i < NUM_ZFD_DEVS; i++) { + if (init_zfd_dev(zlogp, bus_hdl, i) != 0) + goto error; + } + + if ((dl = di_devlink_init("zfd", DI_MAKE_LINK)) == NULL) { + zerror(zlogp, B_TRUE, "failed to create devlinks"); + goto error; + } + + (void) di_devlink_fini(&dl); + rv = 0; + + if (mode->zmode_n_stddevs == 1) { + /* We want the primary stream to look like a tty. */ + make_tty(zlogp, 0); + } + +error: + if (bus_hdl) + devctl_release(bus_hdl); + return (rv); +} + +static int +init_server_sock(int *servfd, char *nm) +{ + int resfd = -1; + struct sockaddr_un servaddr; + + bzero(&servaddr, sizeof (servaddr)); + servaddr.sun_family = AF_UNIX; + (void) snprintf(servaddr.sun_path, sizeof (servaddr.sun_path), + SERVER_SOCKPATH, zone_name, nm); + + if ((resfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + zerror(&logplat, B_TRUE, + "server setup: could not create socket"); + goto err; + } + (void) unlink(servaddr.sun_path); + + if (bind(resfd, (struct sockaddr *)&servaddr, sizeof (servaddr)) + == -1) { + zerror(&logplat, B_TRUE, + "server setup: could not bind to socket"); + goto err; + } + + if (listen(resfd, 4) == -1) { + zerror(&logplat, B_TRUE, + "server setup: could not listen on socket"); + goto err; + } + + *servfd = resfd; + return (0); + +err: + (void) unlink(servaddr.sun_path); + if (resfd != -1) + (void) close(resfd); + return (-1); +} + +static void +destroy_server_sock(int servfd, char *nm) +{ + char path[MAXPATHLEN]; + + (void) snprintf(path, sizeof (path), SERVER_SOCKPATH, zone_name, nm); + (void) unlink(path); + (void) shutdown(servfd, SHUT_RDWR); + (void) close(servfd); +} + +/* + * Read the "ident" string from the client's descriptor; this routine also + * tolerates being called with pid=NULL, for times when you want to "eat" + * the ident string from a client without saving it. + */ +static int +get_client_ident(int clifd, pid_t *pid, char *locale, size_t locale_len, + uint_t *flagsp) +{ + char buf[BUFSIZ], *bufp; + size_t buflen = sizeof (buf); + char c = '\0'; + int i = 0, r; + ucred_t *cred = NULL; + + /* "eat up the ident string" case, for simplicity */ + if (pid == NULL) { + assert(locale == NULL && locale_len == 0); + while (read(clifd, &c, 1) == 1) { + if (c == '\n') + return (0); + } + } + + bzero(buf, sizeof (buf)); + while ((buflen > 1) && (r = read(clifd, &c, 1)) == 1) { + buflen--; + if (c == '\n') + break; + + buf[i] = c; + i++; + } + if (r == -1) + return (-1); + + /* + * We've filled the buffer, but still haven't seen \n. Keep eating + * until we find it; we don't expect this to happen, but this is + * defensive. + */ + if (c != '\n') { + while ((r = read(clifd, &c, sizeof (c))) > 0) + if (c == '\n') + break; + } + + /* + * Parse buffer for message of the form: + * IDENT <locale> <flags> + */ + bufp = buf; + if (strncmp(bufp, "IDENT ", 6) != 0) + return (-1); + bufp += 6; + + if (getpeerucred(clifd, &cred) == 0) { + *pid = ucred_getpid((const ucred_t *)cred); + ucred_free(cred); + } else { + return (-1); + } + + while (*bufp != '\0' && isspace(*bufp)) + bufp++; + buflen = strlen(bufp) - 1; + bufp[buflen - 1] = '\0'; + (void) strlcpy(locale, bufp, locale_len); + + *flagsp = atoi(&bufp[buflen]); + + return (0); +} + +static int +accept_client(int servfd, pid_t *pid, char *locale, size_t locale_len, + uint_t *flagsp) +{ + int connfd; + struct sockaddr_un cliaddr; + socklen_t clilen; + int flags; + + clilen = sizeof (cliaddr); + connfd = accept(servfd, (struct sockaddr *)&cliaddr, &clilen); + if (connfd == -1) + return (-1); + if (pid != NULL) { + if (get_client_ident(connfd, pid, locale, locale_len, flagsp) + == -1) { + (void) shutdown(connfd, SHUT_RDWR); + (void) close(connfd); + return (-1); + } + (void) write(connfd, "OK\n", 3); + } + + flags = fcntl(connfd, F_GETFL, 0); + if (flags != -1) + (void) fcntl(connfd, F_SETFL, flags | O_NONBLOCK | FD_CLOEXEC); + + return (connfd); +} + +static void +reject_client(int servfd, pid_t clientpid) +{ + int connfd; + struct sockaddr_un cliaddr; + socklen_t clilen; + char nak[MAXPATHLEN]; + + clilen = sizeof (cliaddr); + connfd = accept(servfd, (struct sockaddr *)&cliaddr, &clilen); + + /* + * After getting its ident string, tell client to get lost. + */ + if (get_client_ident(connfd, NULL, NULL, 0, NULL) == 0) { + (void) snprintf(nak, sizeof (nak), "%lu\n", + clientpid); + (void) write(connfd, nak, strlen(nak)); + } + (void) shutdown(connfd, SHUT_RDWR); + (void) close(connfd); +} + +static int +accept_socket(int servfd, pid_t verpid) +{ + int connfd; + struct sockaddr_un cliaddr; + socklen_t clilen = sizeof (cliaddr); + ucred_t *cred = NULL; + pid_t rpid = -1; + int flags; + + connfd = accept(servfd, (struct sockaddr *)&cliaddr, &clilen); + if (connfd == -1) + return (-1); + + /* Confirm connecting process is who we expect */ + if (getpeerucred(connfd, &cred) == 0) { + rpid = ucred_getpid((const ucred_t *)cred); + ucred_free(cred); + } + if (rpid == -1 || rpid != verpid) { + (void) shutdown(connfd, SHUT_RDWR); + (void) close(connfd); + return (-1); + } + + flags = fcntl(connfd, F_GETFL, 0); + if (flags != -1) + (void) fcntl(connfd, F_SETFL, flags | O_NONBLOCK | FD_CLOEXEC); + + return (connfd); +} + +static void +ctlcmd_process(int sockfd, int stdoutfd, unsigned int *flags) +{ + char buf[BUFSIZ]; + int i; + for (i = 0; i < BUFSIZ-1; i++) { + char c; + if (read(sockfd, &c, 1) != 1 || + c == '\n' || c == '\0') { + break; + } + buf[i] = c; + } + if (i == 0) { + goto fail; + } + buf[i+1] = '\0'; + + if (strncmp(buf, "TIOCSWINSZ ", 11) == 0) { + char *next = buf + 11; + struct winsize ws; + errno = 0; + ws.ws_row = strtol(next, &next, 10); + if (errno == EINVAL) { + goto fail; + } + ws.ws_col = strtol(next + 1, &next, 10); + if (errno == EINVAL) { + goto fail; + } + if (ioctl(stdoutfd, TIOCSWINSZ, &ws) == 0) { + (void) write(sockfd, "OK\n", 3); + return; + } + } + if (strncmp(buf, "SETFLAGS ", 9) == 0) { + char *next = buf + 9; + unsigned int result; + errno = 0; + result = strtoul(next, &next, 10); + if (errno == EINVAL) { + goto fail; + } + *flags = result; + (void) write(sockfd, "OK\n", 3); + return; + } +fail: + (void) write(sockfd, "FAIL\n", 5); +} + +/* + * Check to see if the client at the other end of the socket is still alive; we + * know it is not if it throws EPIPE at us when we try to write an otherwise + * harmless 0-length message to it. + */ +static int +test_client(int clifd) +{ + if ((write(clifd, "", 0) == -1) && errno == EPIPE) + return (-1); + return (0); +} + +/* + * We want to sleep for a little while but need to be responsive if the zone is + * halting. We poll/sleep on the event stream so we can notice if we're halting. + * Return true if halting, otherwise false. + */ +static boolean_t +halt_sleep(int slptime) +{ + struct pollfd evfd[1]; + + evfd[0].fd = eventstream[1]; + evfd[0].events = POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI; + + if (poll(evfd, 1, slptime) > 0) { + /* zone halting */ + return (B_TRUE); + } + return (B_FALSE); +} + +/* + * This routine drives the logging and interactive I/O loop. It polls for + * input from the zone side of the fd (output to stdout/stderr), and from the + * client (input to the zone's stdin). Additionally, it polls on the server + * fd, and disconnects any clients that might try to hook up with the zone + * while the fd's are in use. + * + * Data from the zone's stdout and stderr is formatted in json and written to + * the log file whether an interactive client is connected or not. + * + * When the client first calls us up, it is expected to send a line giving its + * "identity"; this consists of the string 'IDENT <pid> <locale>'. This is so + * that we can report that the fd's are busy, along with some diagnostics + * about who has them busy; the locale is ignore here but kept for compatability + * with the zlogin code when running on the zone's console. + * + * We need to handle the case where there is no server within the zone (or + * the server gets stuck) and data that we're writing to the zone server's + * stdin fills the pipe. Because of the way the zfd device works writes can + * flow into the stream and simply be dropped, if there is no server, or writes + * could return -1 with EAGAIN if the server is stuck. Since we ignore errors + * on the write to stdin, we won't get blocked in that case but we'd like to + * avoid dropping initial input if the server within the zone hasn't started + * yet. To handle this we wait to read initial input until we detect that there + * is a server inside the zone. We have to poll for this so that we can + * re-run the ioctl to notice when a server shows up. This poll/wait is handled + * by halt_sleep() so that we can be responsive if the zone wants to halt. + * We only do this check to avoid dropping initial input so it is possible for + * the server within the zone to go away later. At that point zfd will just + * drop any new input flowing into the stream. + */ +static void +do_zfd_io(int gzctlfd, int gzservfd, int gzerrfd, int stdinfd, int stdoutfd, + int stderrfd, int logout, int logerr) +{ + struct pollfd pollfds[8]; + char ibuf[BUFSIZ + 1]; + int cc, ret; + int ctlfd = -1; + int clifd = -1; + int clierrfd = -1; + int pollerr = 0; + char clilocale[MAXPATHLEN]; + pid_t clipid = 0; + uint_t flags = 0; + boolean_t stdin_ready = B_FALSE; + int slptime = 250; /* initial poll sleep time in ms */ + + /* client control socket, watch for read events */ + pollfds[0].fd = ctlfd; + pollfds[0].events = POLLIN | POLLRDNORM | POLLRDBAND | + POLLPRI | POLLERR | POLLHUP | POLLNVAL; + + /* client socket, watch for read events */ + pollfds[1].fd = clifd; + pollfds[1].events = pollfds[0].events; + + /* stdout, watch for read events */ + pollfds[2].fd = stdoutfd; + pollfds[2].events = pollfds[0].events; + + /* stderr, watch for read events */ + pollfds[3].fd = stderrfd; + pollfds[3].events = pollfds[0].events; + + /* the server control socket; watch for new connections */ + pollfds[4].fd = gzctlfd; + pollfds[4].events = POLLIN | POLLRDNORM; + + /* the server stdin/out socket; watch for new connections */ + pollfds[5].fd = gzservfd; + pollfds[5].events = POLLIN | POLLRDNORM; + + /* the server stderr socket; watch for new connections */ + pollfds[6].fd = gzerrfd; + pollfds[6].events = POLLIN | POLLRDNORM; + + /* the eventstream; any input means the zone is halting */ + pollfds[7].fd = eventstream[1]; + pollfds[7].events = pollfds[0].events; + + while (!shutting_down) { + pollfds[0].revents = pollfds[1].revents = 0; + pollfds[2].revents = pollfds[3].revents = 0; + pollfds[4].revents = pollfds[5].revents = 0; + pollfds[6].revents = pollfds[7].revents = 0; + + ret = poll(pollfds, 8, -1); + if (ret == -1 && errno != EINTR) { + zerror(&logplat, B_TRUE, "poll failed"); + /* we are hosed, close connection */ + break; + } + + /* control events from client */ + if (pollfds[0].revents & + (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { + /* process control message */ + ctlcmd_process(ctlfd, stdoutfd, &flags); + } else if (pollfds[0].revents) { + /* bail if any error occurs */ + pollerr = pollfds[0].revents; + zerror(&logplat, B_FALSE, "closing connection " + "with control channel, pollerr %d\n", pollerr); + break; + } + + /* event from client side */ + if (pollfds[1].revents) { + if (stdin_ready) { + if (pollfds[1].revents & (POLLIN | + POLLRDNORM | POLLRDBAND | POLLPRI)) { + errno = 0; + cc = read(clifd, ibuf, BUFSIZ); + if (cc > 0) { + /* + * See comment for this + * function on what happens if + * there is no reader in the + * zone. EOF is handled below. + */ + (void) write(stdinfd, ibuf, cc); + } + } else if (pollfds[1].revents & (POLLERR | + POLLNVAL)) { + pollerr = pollfds[1].revents; + zerror(&logplat, B_FALSE, + "closing connection " + "with client, pollerr %d\n", + pollerr); + break; + } + + if (pollfds[1].revents & POLLHUP) { + if (flags & ZLOGIN_ZFD_EOF) { + /* + * Let the client know. We've + * already serviced any pending + * regular input. Let the + * stream clear since the EOF + * ioctl jumps to the head. + */ + (void) ioctl(stdinfd, I_FLUSH); + if (halt_sleep(250)) + break; + (void) ioctl(stdinfd, ZFD_EOF); + } + break; + } + } else { + if (ioctl(stdinfd, ZFD_HAS_SLAVE) == 0) { + stdin_ready = B_TRUE; + } else { + /* + * There is nothing in the zone to read + * our input. Presumably the user + * providing input expects something to + * show up, but that is no guarantee. + * Since we haven't serviced the pending + * input poll yet, we don't want to + * immediately loop around but we also + * need to be responsive if the zone is + * halting. + */ + if (halt_sleep(slptime)) + break; + + if (slptime < 5000) + slptime += 250; + } + } + } + + /* event from the zone's stdout */ + if (pollfds[2].revents) { + if (pollfds[2].revents & + (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { + errno = 0; + cc = read(stdoutfd, ibuf, BUFSIZ); + /* zfd is a stream, so ignore 0 length read */ + if (cc < 0 && (errno != EINTR) && + (errno != EAGAIN)) + break; + if (cc > 0) { + logstream_write(logout, ibuf, cc); + + /* + * Lose output if no one is listening, + * otherwise pass it on. + */ + if (clifd != -1) + (void) write(clifd, ibuf, cc); + } + } else { + pollerr = pollfds[2].revents; + zerror(&logplat, B_FALSE, + "closing connection with stdout zfd, " + "pollerr %d\n", pollerr); + break; + } + } + + /* event from the zone's stderr */ + if (pollfds[3].revents) { + if (pollfds[3].revents & + (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) { + errno = 0; + cc = read(stderrfd, ibuf, BUFSIZ); + /* zfd is a stream, so ignore 0 length read */ + if (cc < 0 && (errno != EINTR) && + (errno != EAGAIN)) + break; + if (cc > 0) { + logstream_write(logerr, ibuf, cc); + + /* + * Lose output if no one is listening, + * otherwise pass it on. + */ + if (clierrfd != -1) + (void) write(clierrfd, ibuf, + cc); + } + } else { + pollerr = pollfds[3].revents; + zerror(&logplat, B_FALSE, + "closing connection with stderr zfd, " + "pollerr %d\n", pollerr); + break; + } + } + + /* connect event from server control socket */ + if (pollfds[4].revents) { + if (ctlfd != -1) { + /* + * Test the client to see if it is really + * still alive. If it has died but we + * haven't yet detected that, we might + * deny a legitimate connect attempt. If it + * is dead, we break out; once we tear down + * the old connection, the new connection + * will happen. + */ + if (test_client(ctlfd) == -1) { + break; + } + /* we're already handling a client */ + reject_client(gzctlfd, clipid); + } else { + ctlfd = accept_client(gzctlfd, &clipid, + clilocale, sizeof (clilocale), &flags); + if (ctlfd != -1) { + pollfds[0].fd = ctlfd; + } else { + break; + } + } + } + + /* connect event from server stdin/out socket */ + if (pollfds[5].revents) { + if (ctlfd == -1) { + /* + * This shouldn't happen since the client is + * expected to connect on the control socket + * first. If we see this, tear everything down + * and start over. + */ + zerror(&logplat, B_FALSE, "GZ zfd stdin/stdout " + "connection attempt with no GZ control\n"); + break; + } + assert(clifd == -1); + if ((clifd = accept_socket(gzservfd, clipid)) != -1) { + /* No need to watch for other new connections */ + pollfds[5].fd = -1; + /* Client input is of interest, though */ + pollfds[1].fd = clifd; + } else { + break; + } + } + + /* connection event from server stderr socket */ + if (pollfds[6].revents) { + if (ctlfd == -1) { + /* + * Same conditions apply to stderr as stdin/out. + */ + zerror(&logplat, B_FALSE, "GZ zfd stderr " + "connection attempt with no GZ control\n"); + break; + } + assert(clierrfd == -1); + if ((clierrfd = accept_socket(gzerrfd, clipid)) != -1) { + /* No need to watch for other new connections */ + pollfds[6].fd = -1; + } else { + break; + } + } + + /* + * Watch for events on the eventstream. This is how we get + * notified of the zone halting, etc. It provides us a + * "wakeup" from poll when important things happen, which + * is good. + */ + if (pollfds[7].revents) { + break; + } + } + + if (clifd != -1) { + (void) shutdown(clifd, SHUT_RDWR); + (void) close(clifd); + } + + if (clierrfd != -1) { + (void) shutdown(clierrfd, SHUT_RDWR); + (void) close(clierrfd); + } +} + +static int +open_fd(int id, int rw) +{ + int fd; + int flag = O_NONBLOCK | O_NOCTTY | O_CLOEXEC; + int retried = 0; + char stdpath[MAXPATHLEN]; + + (void) snprintf(stdpath, sizeof (stdpath), "/dev/zfd/%s/master/%d", + zone_name, id); + flag |= rw; + + while (!shutting_down) { + if ((fd = open(stdpath, flag)) != -1) { + /* + * Setting RPROTDIS on the stream means that the + * control portion of messages received (which we don't + * care about) will be discarded by the stream head. If + * we allowed such messages, we wouldn't be able to use + * read(2), as it fails (EBADMSG) when a message with a + * control element is received. + */ + if (ioctl(fd, I_SRDOPT, RNORM|RPROTDIS) == -1) { + zerror(&logplat, B_TRUE, + "failed to set options on zfd"); + return (-1); + } + return (fd); + } + + if (retried++ > 60) + break; + + (void) sleep(1); + } + + zerror(&logplat, B_TRUE, "failed to open zfd"); + return (-1); +} + +/* + * Body of the worker thread to log the zfd's stdout and stderr to a log file + * and to perform interactive IO to the stdin, stdout and stderr zfd's. + * + * The stdin, stdout and stderr are from the perspective of the process inside + * the zone, so the zoneadmd view is opposite (i.e. we write to the stdin fd + * and read from the stdout/stderr fds). + */ +static void +srvr(void *modearg) +{ + zfd_mode_t *mode = (zfd_mode_t *)modearg; + int gzctlfd = -1; + int gzoutfd = -1; + int stdinfd = -1; + int stdoutfd = -1; + int gzerrfd = -1; + int stderrfd = -1; + int flags; + int len; + char ibuf[BUFSIZ + 1]; + int logout = -1; + int logerr = -1; + + if (!shutting_down && mode->zmode_gzlogging) { + logout = logstream_open(log_name, "stdout", 0); + logerr = logstream_open(log_name, "stderr", 0); + } + + if (!shutting_down) { + if (pipe(eventstream) != 0) { + zerror(&logplat, B_TRUE, "failed to open logger " + "control pipe"); + return; + } + } + + while (!shutting_down) { + if (init_server_sock(&gzctlfd, "ctl") == -1) { + zerror(&logplat, B_FALSE, + "server setup: control socket init failed"); + goto death; + } + if (init_server_sock(&gzoutfd, "out") == -1) { + zerror(&logplat, B_FALSE, + "server setup: stdout socket init failed"); + goto death; + } + if (init_server_sock(&gzerrfd, "err") == -1) { + zerror(&logplat, B_FALSE, + "server setup: stderr socket init failed"); + goto death; + } + + if (mode->zmode_n_stddevs == 1) { + if ((stdinfd = open_fd(0, O_RDWR)) == -1) { + goto death; + } + stdoutfd = stdinfd; + } else { + if ((stdinfd = open_fd(0, O_WRONLY)) == -1 || + (stdoutfd = open_fd(1, O_RDONLY)) == -1 || + (stderrfd = open_fd(2, O_RDONLY)) == -1) { + goto death; + } + } + + do_zfd_io(gzctlfd, gzoutfd, gzerrfd, stdinfd, stdoutfd, + stderrfd, logout, logerr); +death: + destroy_server_sock(gzctlfd, "ctl"); + destroy_server_sock(gzoutfd, "out"); + destroy_server_sock(gzerrfd, "err"); + + /* when shutting down, leave open until drained */ + if (!shutting_down) { + (void) close(stdinfd); + if (mode->zmode_n_stddevs == 3) { + (void) close(stdoutfd); + (void) close(stderrfd); + } + } + } + + /* + * Attempt to drain remaining log output from the zone prior to closing + * the file descriptors. This helps ensure that complete logs are + * captured during shutdown. + */ + flags = fcntl(stdoutfd, F_GETFL, 0); + if (fcntl(stdoutfd, F_SETFL, flags | O_NONBLOCK) != -1) { + while ((len = read(stdoutfd, ibuf, BUFSIZ)) > 0) { + logstream_write(logout, ibuf, len); + } + } + (void) close(stdoutfd); + + if (mode->zmode_n_stddevs > 1) { + (void) close(stdinfd); + flags = fcntl(stderrfd, F_GETFL, 0); + if (fcntl(stderrfd, F_SETFL, flags | O_NONBLOCK) != -1) { + while ((len = read(stderrfd, ibuf, BUFSIZ)) > 0) { + logstream_write(logerr, ibuf, len); + } + } + (void) close(stderrfd); + } + + + (void) close(eventstream[0]); + eventstream[0] = -1; + (void) close(eventstream[1]); + eventstream[1] = -1; + logstream_close(logout, B_FALSE); + logstream_close(logerr, B_FALSE); +} + +/* + * The meaning of the original legacy values for the zlog-mode evolved over + * time, to the point where the old names no longer made sense. The current + * values are simply positional letters used to indicate various capabilities. + * The following table shows the meaning of the mode values, along with the + * legacy name which we continue to support for compatability. Any future + * capability can add a letter to the left and '-' is implied for existing + * strings. + * + * zlog-mode gz log - tty - ngz log + * --------- ------ --- ------- + * gt- (int) y y n + * g-- (log) y n n + * gtn (nlint) y y y + * g-n (nolog) y n y + * -t- n y n + * --- n n n + * + * This function also obtains any custom name for stdio.log while it is reading + * the zone configuration. + */ +static void +get_mode_logmax(zfd_mode_t *mode) +{ + zone_dochandle_t handle; + struct zone_attrtab attr; + + bzero(mode, sizeof (zfd_mode_t)); + + if ((handle = zonecfg_init_handle()) == NULL) + return; + + if (zonecfg_get_handle(zone_name, handle) != Z_OK) + goto done; + + if (zonecfg_setattrent(handle) != Z_OK) + goto done; + while (zonecfg_getattrent(handle, &attr) == Z_OK) { + if (strcmp(ZLOG_MODE, attr.zone_attr_name) == 0) { + if (strcmp("g--", attr.zone_attr_value) == 0 || + strncmp("log", attr.zone_attr_value, 3) == 0) { + mode->zmode_gzlogging = B_TRUE; + mode->zmode_n_stddevs = 3; + mode->zmode_n_addl_devs = 0; + } else if (strcmp("g-n", attr.zone_attr_value) == 0 || + strncmp("nolog", attr.zone_attr_value, 5) == 0) { + mode->zmode_gzlogging = B_TRUE; + mode->zmode_n_stddevs = 3; + mode->zmode_n_addl_devs = 2; + } else if (strcmp("gt-", attr.zone_attr_value) == 0 || + strncmp("int", attr.zone_attr_value, 3) == 0) { + mode->zmode_gzlogging = B_TRUE; + mode->zmode_n_stddevs = 1; + mode->zmode_n_addl_devs = 0; + } else if (strcmp("gtn", attr.zone_attr_value) == 0 || + strncmp("nlint", attr.zone_attr_value, 5) == 0) { + mode->zmode_gzlogging = B_TRUE; + mode->zmode_n_stddevs = 1; + mode->zmode_n_addl_devs = 1; + } else if (strcmp("-t-", attr.zone_attr_value) == 0) { + mode->zmode_gzlogging = B_FALSE; + mode->zmode_n_stddevs = 1; + mode->zmode_n_addl_devs = 0; + } else if (strcmp("---", attr.zone_attr_value) == 0) { + mode->zmode_gzlogging = B_FALSE; + mode->zmode_n_stddevs = 3; + mode->zmode_n_addl_devs = 0; + } + continue; + } + + if (strcmp(ZLOG_NAME, attr.zone_attr_name) == 0) { + (void) strlcpy(log_name, attr.zone_attr_value, + sizeof (log_name)); + continue; + } + } + (void) zonecfg_endattrent(handle); + +done: + zonecfg_fini_handle(handle); +} + +void +create_log_thread(zlog_t *zlogp) +{ + int res; + + shutting_down = 0; + + get_mode_logmax(&mode); + if (mode.zmode_n_stddevs == 0) + return; + + if (init_zfd_devs(zlogp, &mode) == -1) { + zerror(zlogp, B_FALSE, + "zfd setup: device initialization failed"); + return; + } + + res = thr_create(NULL, 0, (void * (*)(void *))srvr, (void *)&mode, 0, + &logger_tid); + if (res != 0) { + zerror(zlogp, B_FALSE, "error %d creating logger thread", res); + logger_tid = 0; + } +} + +void +destroy_log_thread(zlog_t *zlogp) +{ + if (logger_tid != 0) { + int stop = 1; + + shutting_down = 1; + /* break out of poll to shutdown */ + if (eventstream[0] != -1) + (void) write(eventstream[0], &stop, sizeof (stop)); + (void) thr_join(logger_tid, NULL, NULL); + logger_tid = 0; + } + + (void) destroy_zfd_devs(zlogp); +} diff --git a/usr/src/cmd/zoneadmd/zoneadmd.c b/usr/src/cmd/zoneadmd/zoneadmd.c index 5bc26ae482..498ba4ac57 100644 --- a/usr/src/cmd/zoneadmd/zoneadmd.c +++ b/usr/src/cmd/zoneadmd/zoneadmd.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2019 Joyent, Inc. * Copyright (c) 2016 by Delphix. All rights reserved. */ @@ -69,6 +70,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/sysmacros.h> +#include <sys/time.h> #include <bsm/adt.h> #include <bsm/adt_event.h> @@ -102,6 +104,8 @@ #include <libdladm.h> #include <sys/dls_mgmt.h> #include <libscf.h> +#include <uuid/uuid.h> +#include <libppt.h> #include <libzonecfg.h> #include <zonestat_impl.h> @@ -109,6 +113,8 @@ static char *progname; char *zone_name; /* zone which we are managing */ +zone_dochandle_t snap_hndl; /* handle for snapshot created when ready */ +char zonepath[MAXNAMELEN]; char pool_name[MAXNAMELEN]; char default_brand[MAXNAMELEN]; char brand_name[MAXNAMELEN]; @@ -117,13 +123,15 @@ boolean_t zone_iscluster; boolean_t zone_islabeled; boolean_t shutdown_in_progress; static zoneid_t zone_id; +static zoneid_t zone_did = 0; dladm_handle_t dld_handle = NULL; -static char pre_statechg_hook[2 * MAXPATHLEN]; -static char post_statechg_hook[2 * MAXPATHLEN]; +char pre_statechg_hook[2 * MAXPATHLEN]; +char post_statechg_hook[2 * MAXPATHLEN]; char query_hook[2 * MAXPATHLEN]; -zlog_t logsys; +zlog_t logsys; /* log to syslog */ +zlog_t logplat; /* log to platform.log */ mutex_t lock = DEFAULTMUTEX; /* to serialize stuff */ mutex_t msglock = DEFAULTMUTEX; /* for calling setlocale() */ @@ -136,12 +144,17 @@ static int zone_door = -1; boolean_t in_death_throes = B_FALSE; /* daemon is dying */ boolean_t bringup_failure_recovery = B_FALSE; /* ignore certain failures */ +static int platloghdl = -1; /* Handle for <zonepath>/logs/platform.log */ + #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */ #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */ #endif #define DEFAULT_LOCALE "C" +#define RSRC_NET "net" +#define RSRC_DEV "device" + static const char * z_cmd_name(zone_cmd_t zcmd) { @@ -215,17 +228,14 @@ zerror(zlog_t *zlogp, boolean_t use_strerror, const char *fmt, ...) { va_list alist; char buf[MAXPATHLEN * 2]; /* enough space for err msg with a path */ - char *bp; + char *bp, *bp_nozone; int saved_errno = errno; - if (zlogp == NULL) - return; if (zlogp == &logsys) - (void) snprintf(buf, sizeof (buf), "[zone '%s'] ", - zone_name); + (void) snprintf(buf, sizeof (buf), "[zone '%s'] ", zone_name); else buf[0] = '\0'; - bp = &(buf[strlen(buf)]); + bp = bp_nozone = &(buf[strlen(buf)]); /* * In theory, the locale pointer should be set to either "C" or a @@ -242,15 +252,38 @@ zerror(zlog_t *zlogp, boolean_t use_strerror, const char *fmt, ...) if (use_strerror) (void) snprintf(bp, sizeof (buf) - (bp - buf), ": %s", strerror(saved_errno)); + + (void) strlcat(buf, "\n", sizeof (buf)); + + /* + * If we don't have the platform log, we are in a child process, and + * should log to stderr (which is a pipe) instead of the file. + */ + if (logging_poisoned) { + (void) fprintf(stderr, "%s", buf); + + if (zlogp != &logsys && zlogp->logfile == stderr) + return; + } else { + logstream_write(platloghdl, bp_nozone, strlen(bp_nozone)); + + if (zlogp == &logplat) + return; + } + if (zlogp == &logsys) { + bp = strrchr(buf, '\n'); + if (bp != NULL && bp[1] == '\0') { + *bp = '\0'; + } (void) syslog(LOG_ERR, "%s", buf); } else if (zlogp->logfile != NULL) { - (void) fprintf(zlogp->logfile, "%s\n", buf); + (void) fprintf(zlogp->logfile, "%s", buf); } else { size_t buflen; size_t copylen; - buflen = snprintf(zlogp->log, zlogp->loglen, "%s\n", buf); + buflen = snprintf(zlogp->log, zlogp->loglen, "%s", buf); copylen = MIN(buflen, zlogp->loglen); zlogp->log += copylen; zlogp->loglen -= copylen; @@ -258,34 +291,43 @@ zerror(zlog_t *zlogp, boolean_t use_strerror, const char *fmt, ...) } /* - * Emit a warning for any boot arguments which are unrecognized. Since - * Solaris boot arguments are getopt(3c) compatible (see kernel(1m)), we + * Append src to dest, modifying dest in the process. Prefix src with + * a space character if dest is a non-empty string. + */ +static void +strnappend(char *dest, size_t n, const char *src) +{ + (void) snprintf(dest, n, "%s%s%s", dest, + dest[0] == '\0' ? "" : " ", src); +} + +/* + * Since illumos boot arguments are getopt(3c) compatible (see kernel(1m)), we * put the arguments into an argv style array, use getopt to process them, - * and put the resultant argument string back into outargs. + * and put the resultant argument string back into outargs. Non-native brands + * may support alternate forms of boot arguments so we must handle that as well. * * During the filtering, we pull out any arguments which are truly "boot" * arguments, leaving only those which are to be passed intact to the * progenitor process. The one we support at the moment is -i, which * indicates to the kernel which program should be launched as 'init'. * - * A return of Z_INVAL indicates specifically that the arguments are - * not valid; this is a non-fatal error. Except for Z_OK, all other return - * values are treated as fatal. + * Except for Z_OK, all other return values are treated as fatal. */ static int filter_bootargs(zlog_t *zlogp, const char *inargs, char *outargs, - char *init_file, char *badarg) + char *init_file) { int argc = 0, argc_save; int i; - int err; + int err = Z_OK; char *arg, *lasts, **argv = NULL, **argv_save; char zonecfg_args[BOOTARGS_MAX]; char scratchargs[BOOTARGS_MAX], *sargs; + char scratchopt[3]; char c; bzero(outargs, BOOTARGS_MAX); - bzero(badarg, BOOTARGS_MAX); /* * If the user didn't specify transient boot arguments, check @@ -293,25 +335,10 @@ filter_bootargs(zlog_t *zlogp, const char *inargs, char *outargs, * and use them if applicable. */ if (inargs == NULL || inargs[0] == '\0') { - zone_dochandle_t handle; - if ((handle = zonecfg_init_handle()) == NULL) { - zerror(zlogp, B_TRUE, - "getting zone configuration handle"); - return (Z_BAD_HANDLE); - } - err = zonecfg_get_snapshot_handle(zone_name, handle); - if (err != Z_OK) { - zerror(zlogp, B_FALSE, - "invalid configuration snapshot"); - zonecfg_fini_handle(handle); - return (Z_BAD_HANDLE); - } - bzero(zonecfg_args, sizeof (zonecfg_args)); - (void) zonecfg_get_bootargs(handle, zonecfg_args, + (void) zonecfg_get_bootargs(snap_hndl, zonecfg_args, sizeof (zonecfg_args)); inargs = zonecfg_args; - zonecfg_fini_handle(handle); } if (strlen(inargs) >= BOOTARGS_MAX) { @@ -348,14 +375,22 @@ filter_bootargs(zlog_t *zlogp, const char *inargs, char *outargs, } /* - * We preserve compatibility with the Solaris system boot behavior, + * We preserve compatibility with the illumos system boot behavior, * which allows: * * # reboot kernel/unix -s -m verbose * - * In this example, kernel/unix tells the booter what file to - * boot. We don't want reboot in a zone to be gratuitously different, - * so we silently ignore the boot file, if necessary. + * In this example, kernel/unix tells the booter what file to boot. The + * original intent of this was that we didn't want reboot in a zone to + * be gratuitously different, so we would silently ignore the boot + * file, if necessary. However, this usage is archaic and has never + * been common, since it is impossible to boot a zone onto a different + * kernel. Ignoring the first argument breaks for non-native brands + * which pass boot arguments in a different style. e.g. + * systemd.log_level=debug + * Thus, for backward compatibility we only ignore the first argument + * if it appears to be in the illumos form and attempting to specify a + * kernel. */ if (argv[0] == NULL) goto done; @@ -363,7 +398,7 @@ filter_bootargs(zlog_t *zlogp, const char *inargs, char *outargs, assert(argv[0][0] != ' '); assert(argv[0][0] != '\t'); - if (argv[0][0] != '-' && argv[0][0] != '\0') { + if (strncmp(argv[0], "kernel/", 7) == 0) { argv = &argv[1]; argc--; } @@ -386,41 +421,35 @@ filter_bootargs(zlog_t *zlogp, const char *inargs, char *outargs, case 'm': case 's': /* These pass through unmolested */ - (void) snprintf(outargs, BOOTARGS_MAX, - "%s -%c %s ", outargs, c, optarg ? optarg : ""); + (void) snprintf(scratchopt, sizeof (scratchopt), + "-%c", c); + strnappend(outargs, BOOTARGS_MAX, scratchopt); + if (optarg != NULL) + strnappend(outargs, BOOTARGS_MAX, optarg); break; case '?': /* - * We warn about unknown arguments but pass them - * along anyway-- if someone wants to develop their - * own init replacement, they can pass it whatever - * args they want. + * If a brand has its own init, we need to pass along + * whatever the user provides. We use the entire + * unknown string here so that we correctly handle + * unknown long options (e.g. --debug). */ - err = Z_INVAL; - (void) snprintf(outargs, BOOTARGS_MAX, - "%s -%c", outargs, optopt); - (void) snprintf(badarg, BOOTARGS_MAX, - "%s -%c", badarg, optopt); + strnappend(outargs, BOOTARGS_MAX, argv[optind - 1]); break; } } /* - * For Solaris Zones we warn about and discard non-option arguments. - * Hence 'boot foo bar baz gub' --> 'boot'. However, to be similar - * to the kernel, we concat up all the other remaining boot args. - * and warn on them as a group. + * We need to pass along everything else since we don't know what + * the brand's init is expecting. For example, an argument list like: + * --confdir /foo --debug + * will cause the getopt parsing to stop at '/foo' but we need to pass + * that on, along with the '--debug'. This does mean that we require + * any of our known options (-ifms) to preceed the brand-specific ones. */ - if (optind < argc) { - err = Z_INVAL; - while (optind < argc) { - (void) snprintf(badarg, BOOTARGS_MAX, "%s%s%s", - badarg, strlen(badarg) > 0 ? " " : "", - argv[optind]); - optind++; - } - zerror(zlogp, B_FALSE, "WARNING: Unused or invalid boot " - "arguments `%s'.", badarg); + while (optind < argc) { + strnappend(outargs, BOOTARGS_MAX, argv[optind]); + optind++; } done: @@ -459,7 +488,7 @@ mkzonedir(zlog_t *zlogp) * Run the brand's pre-state change callback, if it exists. */ static int -brand_prestatechg(zlog_t *zlogp, int state, int cmd) +brand_prestatechg(zlog_t *zlogp, int state, int cmd, boolean_t debug) { char cmdbuf[2 * MAXPATHLEN]; const char *altroot; @@ -472,7 +501,7 @@ brand_prestatechg(zlog_t *zlogp, int state, int cmd) state, cmd, altroot) > sizeof (cmdbuf)) return (-1); - if (do_subproc(zlogp, cmdbuf, NULL) != 0) + if (do_subproc(zlogp, cmdbuf, NULL, debug) != 0) return (-1); return (0); @@ -482,7 +511,7 @@ brand_prestatechg(zlog_t *zlogp, int state, int cmd) * Run the brand's post-state change callback, if it exists. */ static int -brand_poststatechg(zlog_t *zlogp, int state, int cmd) +brand_poststatechg(zlog_t *zlogp, int state, int cmd, boolean_t debug) { char cmdbuf[2 * MAXPATHLEN]; const char *altroot; @@ -495,7 +524,7 @@ brand_poststatechg(zlog_t *zlogp, int state, int cmd) state, cmd, altroot) > sizeof (cmdbuf)) return (-1); - if (do_subproc(zlogp, cmdbuf, NULL) != 0) + if (do_subproc(zlogp, cmdbuf, NULL, debug) != 0) return (-1); return (0); @@ -532,37 +561,51 @@ notify_zonestatd(zoneid_t zoneid) * Bring a zone up to the pre-boot "ready" stage. The mount_cmd argument is * 'true' if this is being invoked as part of the processing for the "mount" * subcommand. + * + * If a scratch zone mount (ALT_MOUNT) is being performed then do not + * call the state change hooks. */ static int -zone_ready(zlog_t *zlogp, zone_mnt_t mount_cmd, int zstate) +zone_ready(zlog_t *zlogp, zone_mnt_t mount_cmd, int zstate, boolean_t debug) { int err; + boolean_t snapped = B_FALSE; - if (brand_prestatechg(zlogp, zstate, Z_READY) != 0) - return (-1); - + if ((snap_hndl = zonecfg_init_handle()) == NULL) { + zerror(zlogp, B_TRUE, "getting zone configuration handle"); + goto bad; + } if ((err = zonecfg_create_snapshot(zone_name)) != Z_OK) { zerror(zlogp, B_FALSE, "unable to create snapshot: %s", zonecfg_strerror(err)); goto bad; } + snapped = B_TRUE; - if ((zone_id = vplat_create(zlogp, mount_cmd)) == -1) { - if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK) - zerror(zlogp, B_FALSE, "destroying snapshot: %s", - zonecfg_strerror(err)); + if (zonecfg_get_snapshot_handle(zone_name, snap_hndl) != Z_OK) { + zerror(zlogp, B_FALSE, "invalid configuration snapshot"); goto bad; } + + if (zone_did == 0) + zone_did = zone_get_did(zone_name); + + if (!ALT_MOUNT(mount_cmd) && + brand_prestatechg(zlogp, zstate, Z_READY, debug) != 0) + goto bad; + + if ((zone_id = vplat_create(zlogp, mount_cmd, zone_did)) == -1) + goto bad; + if (vplat_bringup(zlogp, mount_cmd, zone_id) != 0) { bringup_failure_recovery = B_TRUE; - (void) vplat_teardown(NULL, (mount_cmd != Z_MNT_BOOT), B_FALSE); - if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK) - zerror(zlogp, B_FALSE, "destroying snapshot: %s", - zonecfg_strerror(err)); + (void) vplat_teardown(NULL, (mount_cmd != Z_MNT_BOOT), B_FALSE, + debug); goto bad; } - if (brand_poststatechg(zlogp, zstate, Z_READY) != 0) + if (!ALT_MOUNT(mount_cmd) && + brand_poststatechg(zlogp, zstate, Z_READY, debug) != 0) goto bad; return (0); @@ -572,7 +615,16 @@ bad: * If something goes wrong, we up the zones's state to the target * state, READY, and then invoke the hook as if we're halting. */ - (void) brand_poststatechg(zlogp, ZONE_STATE_READY, Z_HALT); + if (!ALT_MOUNT(mount_cmd)) + (void) brand_poststatechg(zlogp, ZONE_STATE_READY, Z_HALT, + debug); + + if (snapped) + if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK) + zerror(zlogp, B_FALSE, "destroying snapshot: %s", + zonecfg_strerror(err)); + zonecfg_fini_handle(snap_hndl); + snap_hndl = NULL; return (-1); } @@ -624,15 +676,8 @@ mount_early_fs(void *data, const char *spec, const char *dir, /* determine the zone rootpath */ if (mount_cmd) { - char zonepath[MAXPATHLEN]; char luroot[MAXPATHLEN]; - if (zone_get_zonepath(zone_name, - zonepath, sizeof (zonepath)) != Z_OK) { - zerror(zlogp, B_FALSE, "unable to determine zone path"); - return (-1); - } - (void) snprintf(luroot, sizeof (luroot), "%s/lu", zonepath); resolve_lofs(zlogp, luroot, sizeof (luroot)); (void) strlcpy(rootpath, luroot, sizeof (rootpath)); @@ -687,6 +732,8 @@ mount_early_fs(void *data, const char *spec, const char *dir, char opt_buf[MAX_MNTOPT_STR]; int optlen = 0; int mflag = MS_DATA; + int i; + int ret; (void) ct_tmpl_clear(tmpl_fd); /* @@ -714,9 +761,26 @@ mount_early_fs(void *data, const char *spec, const char *dir, optlen = MAX_MNTOPT_STR; mflag = MS_OPTIONSTR; } - if (mount(spec, dir, mflag, fstype, NULL, 0, opt, optlen) != 0) - _exit(errno); - _exit(0); + + /* + * There is an obscure race condition which can cause mount + * to return EBUSY. This happens for example on the mount + * of the zone's /etc/svc/volatile file system if there is + * a GZ process running svcs -Z, which will touch the + * mountpoint, just as we're trying to do the mount. To cope + * with this, we retry up to 3 times to let this transient + * process get out of the way. + */ + for (i = 0; i < 3; i++) { + ret = 0; + if (mount(spec, dir, mflag, fstype, NULL, 0, opt, + optlen) != 0) + ret = errno; + if (ret != EBUSY) + break; + (void) sleep(1); + } + _exit(ret); } /* parent */ @@ -740,18 +804,275 @@ mount_early_fs(void *data, const char *spec, const char *dir, } /* + * Replace characters other than [A-Za-z0-9_] with '_' so that the string is a + * valid environment variable name. + */ +static void +sanitize_env_var_name(char *var) +{ + for (char *p = var; *p != '\0'; p++) { + if (!isalnum(*p)) { + *p = '_'; + } + } +} + +/* + * env variable name format + * _ZONECFG_{resource name}_{identifying attr. name}_{property name} + * Any dashes (-) in the property names are replaced with underscore (_). + */ +static void +set_zonecfg_env(char *rsrc, char *attr, char *name, char *val) +{ + /* Enough for maximal name, rsrc + attr, & slop for ZONECFG & _'s */ + char nm[2 * MAXNAMELEN + 32]; + + if (attr == NULL) + (void) snprintf(nm, sizeof (nm), "_ZONECFG_%s_%s", rsrc, + name); + else + (void) snprintf(nm, sizeof (nm), "_ZONECFG_%s_%s_%s", rsrc, + attr, name); + + sanitize_env_var_name(nm); + + (void) setenv(nm, val, 1); +} + +/* + * Resolve a device:match value to a path. This is only different for PPT + * devices, where we expect the match property to be a /devices/... path, and + * configured for PPT already. + */ +int +resolve_device_match(zlog_t *zlogp, struct zone_devtab *dtab, + char *path, size_t len) +{ + struct zone_res_attrtab *rap; + + for (rap = dtab->zone_dev_attrp; rap != NULL; + rap = rap->zone_res_attr_next) { + if (strcmp(rap->zone_res_attr_name, "model") == 0 && + strcmp(rap->zone_res_attr_value, "passthru") == 0) + break; + } + + if (rap == NULL) { + if (strlcpy(path, dtab->zone_dev_match, len) >= len) + return (Z_INVAL); + return (Z_OK); + } + + if (strncmp(dtab->zone_dev_match, "/devices", + strlen("/devices")) != 0) { + zerror(zlogp, B_FALSE, "invalid passthru match value '%s'", + dtab->zone_dev_match); + return (Z_INVAL); + } + + if (ppt_devpath_to_dev(dtab->zone_dev_match, path, len) != 0) { + zerror(zlogp, B_TRUE, "failed to resolve passthru device %s", + dtab->zone_dev_match); + return (Z_INVAL); + } + + return (Z_OK); +} + +/* + * Export various zonecfg properties into environment for the boot and state + * change hooks. + * + * If debug is true, _ZONEADMD_brand_debug is set to 1, else it is set to an + * empty string. Brand hooks consider any non-empty string as an indication + * that debug output is requested. + * + * We could export more of the config in the future, as necessary. A better + * solution would be to make it so brand-specific behavior is handled by + * brand-specific callbacks written in C. Then the normal libzonecfg interfaces + * can be used for accessing any parts of the configuration that are needed. + * + * All of the environment variables set by this function are specific to + * SmartOS. + */ +static int +setup_subproc_env(zlog_t *zlogp, boolean_t debug) +{ + int res; + struct zone_nwiftab ntab; + struct zone_devtab dtab; + struct zone_attrtab atab; + char net_resources[MAXNAMELEN * 2]; + char dev_resources[MAXNAMELEN * 2]; + char didstr[16]; + char uuidstr[UUID_PRINTABLE_STRING_LENGTH]; + uuid_t uuid; + + /* snap_hndl is null when called through the set_brand_env code path */ + if (snap_hndl == NULL) + return (Z_OK); + + if ((res = zonecfg_get_uuid(zone_name, uuid)) != Z_OK) + return (res); + + uuid_unparse(uuid, uuidstr); + (void) setenv("_ZONECFG_uuid", uuidstr, 1); + + (void) snprintf(didstr, sizeof (didstr), "%d", zone_did); + (void) setenv("_ZONECFG_did", didstr, 1); + + /* + * "net" resources are exported because zoneadmd does not handle + * automatic configuration of vnics and so that the bhyve boot hook + * can generate the argument list for the brand's init program. At such + * a time as vnic creation is handled in zoneadmd and brand callbacks + * can be executed as part of the zoneadmd process this should be + * removed. + */ + net_resources[0] = '\0'; + if ((res = zonecfg_setnwifent(snap_hndl)) != Z_OK) + goto done; + + while (zonecfg_getnwifent(snap_hndl, &ntab) == Z_OK) { + struct zone_res_attrtab *rap; + char *phys; + + phys = ntab.zone_nwif_physical; + + (void) strlcat(net_resources, phys, sizeof (net_resources)); + (void) strlcat(net_resources, " ", sizeof (net_resources)); + + set_zonecfg_env(RSRC_NET, phys, "physical", phys); + + set_zonecfg_env(RSRC_NET, phys, "address", + ntab.zone_nwif_address); + set_zonecfg_env(RSRC_NET, phys, "allowed-address", + ntab.zone_nwif_allowed_address); + set_zonecfg_env(RSRC_NET, phys, "defrouter", + ntab.zone_nwif_defrouter); + set_zonecfg_env(RSRC_NET, phys, "global-nic", + ntab.zone_nwif_gnic); + set_zonecfg_env(RSRC_NET, phys, "mac-addr", ntab.zone_nwif_mac); + set_zonecfg_env(RSRC_NET, phys, "vlan-id", + ntab.zone_nwif_vlan_id); + + for (rap = ntab.zone_nwif_attrp; rap != NULL; + rap = rap->zone_res_attr_next) + set_zonecfg_env(RSRC_NET, phys, rap->zone_res_attr_name, + rap->zone_res_attr_value); + nwifent_free_attrs(&ntab); + } + + (void) setenv("_ZONECFG_net_resources", net_resources, 1); + + (void) zonecfg_endnwifent(snap_hndl); + + /* + * "device" resources are exported because the bhyve boot brand callback + * needs them to generate the argument list for the brand's init + * program. At such a time as brand callbacks can be executed as part + * of the zoneadmd process, this should be removed. + * + * The bhyve brand only supports disk-like and ppt devices and does not + * support regular expressions. + */ + if ((res = zonecfg_setdevent(snap_hndl)) != Z_OK) + goto done; + + dev_resources[0] = '\0'; + while (zonecfg_getdevent(snap_hndl, &dtab) == Z_OK) { + char *match = dtab.zone_dev_match; + struct zone_res_attrtab *rap; + char path[MAXPATHLEN]; + + res = resolve_device_match(zlogp, &dtab, path, sizeof (path)); + if (res != Z_OK) + goto done; + + /* + * Even if not modified, the match path will be mangled in the + * environment variable name, so we always store the value here. + */ + set_zonecfg_env(RSRC_DEV, match, "path", path); + + for (rap = dtab.zone_dev_attrp; rap != NULL; + rap = rap->zone_res_attr_next) { + set_zonecfg_env(RSRC_DEV, match, + rap->zone_res_attr_name, rap->zone_res_attr_value); + } + + /* + * _ZONECFG_device_resources will contain a space separated list + * of devices that have _ZONECFG_device_<device>* environment + * variables. So that each element of the list matches up with + * <device>, each list item needs to be sanitized in the same + * way that environment variable names are sanitized. + */ + sanitize_env_var_name(match); + (void) strlcat(dev_resources, match, sizeof (dev_resources)); + (void) strlcat(dev_resources, " ", sizeof (dev_resources)); + } + (void) zonecfg_enddevent(snap_hndl); + + (void) setenv("_ZONECFG_device_resources", dev_resources, 1); + + /* + * "attr" resources are exported because the bhyve brand's boot hook + * needs access to the "ram", "cpu", "bootrom", etc. to form the + * argument list for the brand's init program. Once the bhyve brand is + * configured via proper resources and properties, this should be + * removed. + */ + if ((res = zonecfg_setattrent(snap_hndl)) != Z_OK) + goto done; + + while (zonecfg_getattrent(snap_hndl, &atab) == Z_OK) { + set_zonecfg_env("attr", NULL, atab.zone_attr_name, + atab.zone_attr_value); + } + + (void) zonecfg_endattrent(snap_hndl); + + if (debug) + (void) setenv("_ZONEADMD_brand_debug", "1", 1); + else + (void) setenv("_ZONEADMD_brand_debug", "", 1); + + res = Z_OK; + +done: + return (res); +} + +void +nwifent_free_attrs(struct zone_nwiftab *np) +{ + struct zone_res_attrtab *rap; + + for (rap = np->zone_nwif_attrp; rap != NULL; ) { + struct zone_res_attrtab *tp = rap; + + rap = rap->zone_res_attr_next; + free(tp); + } +} + +/* * If retstr is not NULL, the output of the subproc is returned in the str, * otherwise it is output using zerror(). Any memory allocated for retstr * should be freed by the caller. */ int -do_subproc(zlog_t *zlogp, char *cmdbuf, char **retstr) +do_subproc(zlog_t *zlogp, char *cmdbuf, char **retstr, boolean_t debug) { char buf[1024]; /* arbitrary large amount */ char *inbuf; FILE *file; int status; int rd_cnt; + int fds[2]; + pid_t child; if (retstr != NULL) { if ((*retstr = malloc(1024)) == NULL) { @@ -764,31 +1085,104 @@ do_subproc(zlog_t *zlogp, char *cmdbuf, char **retstr) inbuf = buf; } - file = popen(cmdbuf, "r"); - if (file == NULL) { - zerror(zlogp, B_TRUE, "could not launch: %s", cmdbuf); + if (pipe(fds) != 0) { + zerror(zlogp, B_TRUE, "failed to create pipe for subprocess"); + return (-1); + } + + if ((child = fork()) == 0) { + int in; + + /* + * SIGINT is currently ignored. It probably shouldn't be so + * hard to kill errant children, so we revert to SIG_DFL. + * SIGHUP and SIGUSR1 are used to perform log rotation. We + * leave those as-is because we don't want a 'pkill -HUP + * zoneadmd' to kill this child process before exec(). On + * exec(), SIGHUP and SIGUSR1 will become SIG_DFL. + */ + sigset(SIGINT, SIG_DFL); + + /* + * Set up a pipe for the child to log to. + */ + if (dup2(fds[1], STDERR_FILENO) == -1) { + (void) snprintf(buf, sizeof (buf), + "subprocess failed to dup2(STDERR_FILENO): %s\n", + strerror(errno)); + (void) write(fds[1], buf, strlen(buf)); + _exit(127); + } + if (dup2(fds[1], STDOUT_FILENO) == -1) { + perror("subprocess failed to dup2(STDOUT_FILENO)"); + _exit(127); + } + /* + * Some naughty children may try to read from stdin. Be sure + * that the first file that a child opens doesn't get stdin's + * file descriptor. + */ + if ((in = open("/dev/null", O_RDONLY)) == -1 || + dup2(in, STDIN_FILENO) == -1) { + zerror(zlogp, B_TRUE, + "subprocess failed to set up STDIN_FILENO"); + _exit(127); + } + closefrom(STDERR_FILENO + 1); + + if (setup_subproc_env(zlogp, debug) != Z_OK) { + zerror(zlogp, B_FALSE, "failed to setup environment"); + _exit(127); + } + + (void) execl("/bin/sh", "sh", "-c", cmdbuf, NULL); + + zerror(zlogp, B_TRUE, "subprocess execl failed"); + _exit(127); + } else if (child == -1) { + zerror(zlogp, B_TRUE, "failed to create subprocess for '%s'", + cmdbuf); + (void) close(fds[0]); + (void) close(fds[1]); return (-1); } + (void) close(fds[1]); + + file = fdopen(fds[0], "r"); while (fgets(inbuf, 1024, file) != NULL) { if (retstr == NULL) { - if (zlogp != &logsys) + if (zlogp != &logsys) { + int last = strlen(inbuf) - 1; + + if (inbuf[last] == '\n') + inbuf[last] = '\0'; zerror(zlogp, B_FALSE, "%s", inbuf); + } } else { char *p; rd_cnt += 1024 - 1; if ((p = realloc(*retstr, rd_cnt + 1024)) == NULL) { zerror(zlogp, B_FALSE, "out of memory"); - (void) pclose(file); - return (-1); + break; } *retstr = p; inbuf = *retstr + rd_cnt; } } - status = pclose(file); + + while (fclose(file) != 0) { + assert(errno == EINTR); + } + while (waitpid(child, &status, 0) == -1) { + if (errno != EINTR) { + zerror(zlogp, B_TRUE, + "failed to get exit status of '%s'", cmdbuf); + return (-1); + } + } if (WIFSIGNALED(status)) { zerror(zlogp, B_FALSE, "%s unexpectedly terminated due to " @@ -803,24 +1197,91 @@ do_subproc(zlog_t *zlogp, char *cmdbuf, char **retstr) return (WEXITSTATUS(status)); } +/* + * Get the path for this zone's init(1M) (or equivalent) process. First look + * for a zone-specific init-name attr, then get it from the brand. + */ +static int +get_initname(brand_handle_t bh, char *initname, int len) +{ + struct zone_attrtab a; + + bzero(&a, sizeof (a)); + (void) strlcpy(a.zone_attr_name, "init-name", + sizeof (a.zone_attr_name)); + + if (zonecfg_lookup_attr(snap_hndl, &a) == Z_OK) { + (void) strlcpy(initname, a.zone_attr_value, len); + return (0); + } + + return (brand_get_initname(bh, initname, len)); +} + +/* + * Get the restart-init flag for this zone's init(1M) (or equivalent) process. + * First look for a zone-specific restart-init attr, then get it from the brand. + */ +static boolean_t +restartinit(brand_handle_t bh) +{ + struct zone_attrtab a; + + bzero(&a, sizeof (a)); + (void) strlcpy(a.zone_attr_name, "restart-init", + sizeof (a.zone_attr_name)); + + if (zonecfg_lookup_attr(snap_hndl, &a) == Z_OK) { + if (strcmp(a.zone_attr_value, "false") == 0) + return (B_FALSE); + return (B_TRUE); + } + + return (brand_restartinit(bh)); +} + +/* + * Get the app-svc-dependent flag for this zone's init process. This is a + * zone-specific attr which controls the type of contract we create for the + * zone's init. When true, the contract will include CT_PR_EV_EXIT in the fatal + * set, so that when any service which is in the same contract exits, the init + * application will be terminated. + */ +static boolean_t +is_app_svc_dep(void) +{ + struct zone_attrtab a; + + bzero(&a, sizeof (a)); + (void) strlcpy(a.zone_attr_name, "app-svc-dependent", + sizeof (a.zone_attr_name)); + + if (zonecfg_lookup_attr(snap_hndl, &a) == Z_OK && + strcmp(a.zone_attr_value, "true") == 0) { + return (B_TRUE); + } + + return (B_FALSE); +} + static int -zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate) +zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate, boolean_t debug) { zoneid_t zoneid; struct stat st; - char zpath[MAXPATHLEN], initpath[MAXPATHLEN], init_file[MAXPATHLEN]; + char rpath[MAXPATHLEN], initpath[MAXPATHLEN], init_file[MAXPATHLEN]; char nbootargs[BOOTARGS_MAX]; char cmdbuf[MAXPATHLEN]; fs_callback_t cb; brand_handle_t bh; zone_iptype_t iptype; - boolean_t links_loaded = B_FALSE; dladm_status_t status; char errmsg[DLADM_STRSIZE]; int err; boolean_t restart_init; + boolean_t app_svc_dep; - if (brand_prestatechg(zlogp, zstate, Z_BOOT) != 0) + if (brand_prestatechg(zlogp, zstate, Z_BOOT, debug) != 0) return (-1); if ((zoneid = getzoneidbyname(zone_name)) == -1) { @@ -853,13 +1314,8 @@ zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate) /* * Get the brand's boot callback if it exists. */ - if (zone_get_zonepath(zone_name, zpath, sizeof (zpath)) != Z_OK) { - zerror(zlogp, B_FALSE, "unable to determine zone path"); - brand_close(bh); - goto bad; - } (void) strcpy(cmdbuf, EXEC_PREFIX); - if (brand_get_boot(bh, zone_name, zpath, cmdbuf + EXEC_LEN, + if (brand_get_boot(bh, zone_name, zonepath, cmdbuf + EXEC_LEN, sizeof (cmdbuf) - EXEC_LEN) != 0) { zerror(zlogp, B_FALSE, "unable to determine branded zone's boot callback"); @@ -868,41 +1324,50 @@ zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate) } /* Get the path for this zone's init(1M) (or equivalent) process. */ - if (brand_get_initname(bh, init_file, MAXPATHLEN) != 0) { + if (get_initname(bh, init_file, MAXPATHLEN) != 0) { zerror(zlogp, B_FALSE, "unable to determine zone's init(1M) location"); brand_close(bh); goto bad; } - /* See if this zone's brand should restart init if it dies. */ - restart_init = brand_restartinit(bh); + /* See if we should restart init if it dies. */ + restart_init = restartinit(bh); + + /* + * See if we need to setup contract dependencies between the zone's + * primary application and any of its services. + */ + app_svc_dep = is_app_svc_dep(); brand_close(bh); - err = filter_bootargs(zlogp, bootargs, nbootargs, init_file, - bad_boot_arg); - if (err == Z_INVAL) - eventstream_write(Z_EVT_ZONE_BADARGS); - else if (err != Z_OK) + err = filter_bootargs(zlogp, bootargs, nbootargs, init_file); + if (err != Z_OK) goto bad; assert(init_file[0] != '\0'); - /* Try to anticipate possible problems: Make sure init is executable. */ - if (zone_get_rootpath(zone_name, zpath, sizeof (zpath)) != Z_OK) { + /* + * Try to anticipate possible problems: If possible, make sure init is + * executable. + */ + if (zone_get_rootpath(zone_name, rpath, sizeof (rpath)) != Z_OK) { zerror(zlogp, B_FALSE, "unable to determine zone root"); goto bad; } - (void) snprintf(initpath, sizeof (initpath), "%s%s", zpath, init_file); + (void) snprintf(initpath, sizeof (initpath), "%s%s", rpath, init_file); - if (stat(initpath, &st) == -1) { + if (lstat(initpath, &st) == -1) { zerror(zlogp, B_TRUE, "could not stat %s", initpath); goto bad; } - if ((st.st_mode & S_IXUSR) == 0) { + /* LINTED: E_NOP_IF_STMT */ + if ((st.st_mode & S_IFMT) == S_IFLNK) { + /* symlink, we'll have to wait and resolve when we boot */ + } else if ((st.st_mode & S_IXUSR) == 0) { zerror(zlogp, B_FALSE, "%s is not executable", initpath); goto bad; } @@ -920,7 +1385,6 @@ zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate) " %s", dladm_status2str(status, errmsg)); goto bad; } - links_loaded = B_TRUE; } /* @@ -929,7 +1393,7 @@ zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate) * is booted. */ if ((strlen(cmdbuf) > EXEC_LEN) && - (do_subproc(zlogp, cmdbuf, NULL) != Z_OK)) { + (do_subproc(zlogp, cmdbuf, NULL, debug) != Z_OK)) { zerror(zlogp, B_FALSE, "%s failed", cmdbuf); goto bad; } @@ -950,19 +1414,31 @@ zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate) goto bad; } + if (app_svc_dep && zone_setattr(zoneid, ZONE_ATTR_APP_SVC_CT, + (void *)B_TRUE, sizeof (boolean_t)) == -1) { + zerror(zlogp, B_TRUE, "could not set zone app-die"); + goto bad; + } + /* * Inform zonestatd of a new zone so that it can install a door for * the zone to contact it. */ notify_zonestatd(zone_id); + /* Startup a thread to perform zfd logging/tty svc for the zone. */ + create_log_thread(zlogp); + if (zone_boot(zoneid) == -1) { zerror(zlogp, B_TRUE, "unable to boot zone"); + destroy_log_thread(zlogp); goto bad; } - if (brand_poststatechg(zlogp, zstate, Z_BOOT) != 0) + if (brand_poststatechg(zlogp, zstate, Z_BOOT, debug) != 0) { + destroy_log_thread(zlogp); goto bad; + } return (0); @@ -971,32 +1447,45 @@ bad: * If something goes wrong, we up the zones's state to the target * state, RUNNING, and then invoke the hook as if we're halting. */ - (void) brand_poststatechg(zlogp, ZONE_STATE_RUNNING, Z_HALT); - if (links_loaded) - (void) dladm_zone_halt(dld_handle, zoneid); + (void) brand_poststatechg(zlogp, ZONE_STATE_RUNNING, Z_HALT, debug); + return (-1); } static int -zone_halt(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting, int zstate) +zone_halt(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting, int zstate, + boolean_t debug) { int err; - if (brand_prestatechg(zlogp, zstate, Z_HALT) != 0) + /* + * If performing a scratch zone unmount then do not call the + * state change hooks. + */ + if (unmount_cmd == B_FALSE && + brand_prestatechg(zlogp, zstate, Z_HALT, debug) != 0) return (-1); - if (vplat_teardown(zlogp, unmount_cmd, rebooting) != 0) { + if (vplat_teardown(zlogp, unmount_cmd, rebooting, debug) != 0) { if (!bringup_failure_recovery) zerror(zlogp, B_FALSE, "unable to destroy zone"); + destroy_log_thread(zlogp); return (-1); } + /* Shut down is done, stop the log thread */ + destroy_log_thread(zlogp); + + if (unmount_cmd == B_FALSE && + brand_poststatechg(zlogp, zstate, Z_HALT, debug) != 0) + return (-1); + if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK) zerror(zlogp, B_FALSE, "destroying snapshot: %s", zonecfg_strerror(err)); - if (brand_poststatechg(zlogp, zstate, Z_HALT) != 0) - return (-1); + zonecfg_fini_handle(snap_hndl); + snap_hndl = NULL; return (0); } @@ -1008,7 +1497,6 @@ zone_graceful_shutdown(zlog_t *zlogp) pid_t child; char cmdbuf[MAXPATHLEN]; brand_handle_t bh = NULL; - char zpath[MAXPATHLEN]; ctid_t ct; int tmpl_fd; int child_status; @@ -1029,18 +1517,12 @@ zone_graceful_shutdown(zlog_t *zlogp) return (-1); } - if (zone_get_zonepath(zone_name, zpath, sizeof (zpath)) != Z_OK) { - zerror(zlogp, B_FALSE, "unable to determine zone path"); - brand_close(bh); - return (-1); - } - /* * If there is a brand 'shutdown' callback, execute it now to give the * brand a chance to cleanup any custom configuration. */ (void) strcpy(cmdbuf, EXEC_PREFIX); - if (brand_get_shutdown(bh, zone_name, zpath, cmdbuf + EXEC_LEN, + if (brand_get_shutdown(bh, zone_name, zonepath, cmdbuf + EXEC_LEN, sizeof (cmdbuf) - EXEC_LEN) != 0 || strlen(cmdbuf) <= EXEC_LEN) { (void) strcat(cmdbuf, SHUTDOWN_DEFAULT); } @@ -1178,6 +1660,36 @@ audit_put_record(zlog_t *zlogp, ucred_t *uc, int return_val, } /* + * Log the exit time and status of the zone's init process into + * {zonepath}/lastexited. If the zone shutdown normally, the exit status will + * be -1, otherwise it will be the exit status as described in wait.3c. + * If the zone is configured to restart init, then nothing will be logged if + * init exits unexpectedly (the kernel will never upcall in this case). + */ +static void +log_init_exit(int status) +{ + char p[MAXPATHLEN]; + char buf[128]; + struct timeval t; + int fd; + + if (snprintf(p, sizeof (p), "%s/lastexited", zonepath) > sizeof (p)) + return; + if (gettimeofday(&t, NULL) != 0) + return; + if (snprintf(buf, sizeof (buf), "%ld.%ld %d\n", t.tv_sec, t.tv_usec, + status) > sizeof (buf)) + return; + if ((fd = open(p, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) + return; + + (void) write(fd, buf, strlen(buf)); + + (void) close(fd); +} + +/* * The main routine for the door server that deals with zone state transitions. */ /* ARGSUSED */ @@ -1190,9 +1702,11 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, zone_state_t zstate; zone_cmd_t cmd; + boolean_t debug; + int init_status; zone_cmd_arg_t *zargp; - boolean_t kernelcall; + boolean_t kernelcall = B_TRUE; int rval = -1; uint64_t uniqid; @@ -1213,6 +1727,8 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, * it is time for us to shut down zoneadmd. */ if (zargp == DOOR_UNREF_DATA) { + logstream_close(platloghdl, B_TRUE); + /* * See comment at end of main() for info on the last rites. */ @@ -1242,6 +1758,8 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, goto out; } cmd = zargp->cmd; + debug = zargp->debug; + init_status = zargp->status; if (door_ucred(&uc) != 0) { zerror(&logsys, B_TRUE, "door_ucred"); @@ -1322,7 +1840,7 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, rval = -1; goto out; } - zlogp = &logsys; /* Log errors to syslog */ + zlogp = &logplat; /* Log errors to platform.log */ } /* @@ -1348,23 +1866,25 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, case ZONE_STATE_INSTALLED: switch (cmd) { case Z_READY: - rval = zone_ready(zlogp, Z_MNT_BOOT, zstate); + rval = zone_ready(zlogp, Z_MNT_BOOT, zstate, debug); if (rval == 0) eventstream_write(Z_EVT_ZONE_READIED); + zcons_statechanged(); break; case Z_BOOT: case Z_FORCEBOOT: eventstream_write(Z_EVT_ZONE_BOOTING); - if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) - == 0) { + if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate, + debug)) == 0) { rval = zone_bootup(zlogp, zargp->bootbuf, - zstate); + zstate, debug); } audit_put_record(zlogp, uc, rval, "boot"); + zcons_statechanged(); if (rval != 0) { bringup_failure_recovery = B_TRUE; (void) zone_halt(zlogp, B_FALSE, B_FALSE, - zstate); + zstate, debug); eventstream_write(Z_EVT_ZONE_BOOTFAILED); } break; @@ -1416,7 +1936,7 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, rval = zone_ready(zlogp, strcmp(zargp->bootbuf, "-U") == 0 ? - Z_MNT_UPDATE : Z_MNT_SCRATCH, zstate); + Z_MNT_UPDATE : Z_MNT_SCRATCH, zstate, debug); if (rval != 0) break; @@ -1478,15 +1998,18 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, rval = 0; break; case Z_BOOT: + case Z_FORCEBOOT: (void) strlcpy(boot_args, zargp->bootbuf, sizeof (boot_args)); eventstream_write(Z_EVT_ZONE_BOOTING); - rval = zone_bootup(zlogp, zargp->bootbuf, zstate); + rval = zone_bootup(zlogp, zargp->bootbuf, zstate, + debug); audit_put_record(zlogp, uc, rval, "boot"); + zcons_statechanged(); if (rval != 0) { bringup_failure_recovery = B_TRUE; (void) zone_halt(zlogp, B_FALSE, B_TRUE, - zstate); + zstate, debug); eventstream_write(Z_EVT_ZONE_BOOTFAILED); } boot_args[0] = '\0'; @@ -1494,15 +2017,17 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, case Z_HALT: if (kernelcall) /* Invalid; can't happen */ abort(); - if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate)) - != 0) + if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate, + debug)) != 0) break; + zcons_statechanged(); eventstream_write(Z_EVT_ZONE_HALTED); break; case Z_SHUTDOWN: case Z_REBOOT: case Z_NOTE_UNINSTALLING: case Z_MOUNT: + case Z_FORCEMOUNT: case Z_UNMOUNT: if (kernelcall) /* Invalid; can't happen */ abort(); @@ -1519,7 +2044,7 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, case Z_UNMOUNT: if (kernelcall) /* Invalid; can't happen */ abort(); - rval = zone_halt(zlogp, B_TRUE, B_FALSE, zstate); + rval = zone_halt(zlogp, B_TRUE, B_FALSE, zstate, debug); if (rval == 0) { eventstream_write(Z_EVT_ZONE_HALTED); (void) sema_post(&scratch_sem); @@ -1541,15 +2066,18 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, case ZONE_STATE_DOWN: switch (cmd) { case Z_READY: - if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate)) - != 0) + if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate, + debug)) != 0) break; - if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) == 0) + zcons_statechanged(); + if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate, + debug)) == 0) eventstream_write(Z_EVT_ZONE_READIED); else eventstream_write(Z_EVT_ZONE_HALTED); break; case Z_BOOT: + case Z_FORCEBOOT: /* * We could have two clients racing to boot this * zone; the second client loses, but its request @@ -1560,32 +2088,40 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, rval = 0; break; case Z_HALT: - if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate)) - != 0) + if (kernelcall) { + log_init_exit(init_status); + } else { + log_init_exit(-1); + } + if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate, + debug)) != 0) break; eventstream_write(Z_EVT_ZONE_HALTED); + zcons_statechanged(); break; case Z_REBOOT: (void) strlcpy(boot_args, zargp->bootbuf, sizeof (boot_args)); eventstream_write(Z_EVT_ZONE_REBOOTING); - if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate)) - != 0) { + if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate, + debug)) != 0) { eventstream_write(Z_EVT_ZONE_BOOTFAILED); boot_args[0] = '\0'; break; } - if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) - != 0) { + zcons_statechanged(); + if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate, + debug)) != 0) { eventstream_write(Z_EVT_ZONE_BOOTFAILED); boot_args[0] = '\0'; break; } - rval = zone_bootup(zlogp, zargp->bootbuf, zstate); + rval = zone_bootup(zlogp, zargp->bootbuf, zstate, + debug); audit_put_record(zlogp, uc, rval, "reboot"); if (rval != 0) { (void) zone_halt(zlogp, B_FALSE, B_TRUE, - zstate); + zstate, debug); eventstream_write(Z_EVT_ZONE_BOOTFAILED); } boot_args[0] = '\0'; @@ -1597,6 +2133,7 @@ server(void *cookie, char *args, size_t alen, door_desc_t *dp, break; case Z_NOTE_UNINSTALLING: case Z_MOUNT: + case Z_FORCEMOUNT: case Z_UNMOUNT: zerror(zlogp, B_FALSE, "%s operation is invalid " "for zones in state '%s'", z_cmd_name(cmd), @@ -1765,6 +2302,29 @@ top: "zoneadmd does not appear to be available; " "restarted zoneadmd to recover.", zone_name, zone_state_str(zstate)); + + /* + * Startup a thread to perform the zfd logging/tty svc + * for the zone. zlogp won't be valid for much longer + * so use logplat. + */ + if (getzoneidbyname(zone_name) != -1) { + create_log_thread(&logplat); + } + + /* recover the global configuration snapshot */ + if (snap_hndl == NULL) { + if ((snap_hndl = zonecfg_init_handle()) + == NULL || + zonecfg_create_snapshot(zone_name) + != Z_OK || + zonecfg_get_snapshot_handle(zone_name, + snap_hndl) != Z_OK) { + zerror(zlogp, B_FALSE, "recovering " + "zone configuration handle"); + goto out; + } + } } (void) fdetach(zone_door_path); @@ -1778,21 +2338,62 @@ out: } /* - * Setup the brand's pre and post state change callbacks, as well as the - * query callback, if any of these exist. + * Run the query hook with the 'env' parameter. It should return a + * string of tab-delimited key-value pairs, each of which should be set + * in the environment. + * + * Because the env_vars string values become part of the environment, the + * string is static and we don't free it. + * + * This function is always called before zoneadmd forks and makes itself + * exclusive, so it is possible there could more than one instance of zoneadmd + * running in parallel at this point. Thus, we have no zonecfg snapshot and + * shouldn't take one yet (i.e. snap_hndl is NULL). Thats ok, since we don't + * need any zonecfg info to query for a brand-specific env value. */ static int -brand_callback_init(brand_handle_t bh, char *zone_name) +set_brand_env(zlog_t *zlogp) { - char zpath[MAXPATHLEN]; + int ret = 0; + static char *env_vars = NULL; + char buf[2 * MAXPATHLEN]; + + if (query_hook[0] == '\0' || env_vars != NULL) + return (0); + + if (snprintf(buf, sizeof (buf), "%s env", query_hook) > sizeof (buf)) + return (-1); - if (zone_get_zonepath(zone_name, zpath, sizeof (zpath)) != Z_OK) + if (do_subproc(zlogp, buf, &env_vars, B_FALSE) != 0) return (-1); + if (env_vars != NULL) { + char *sp; + + sp = strtok(env_vars, "\t"); + while (sp != NULL) { + if (putenv(sp) != 0) { + ret = -1; + break; + } + sp = strtok(NULL, "\t"); + } + } + + return (ret); +} + +/* + * Setup the brand's pre and post state change callbacks, as well as the + * query callback, if any of these exist. + */ +static int +brand_callback_init(brand_handle_t bh, char *zone_name) +{ (void) strlcpy(pre_statechg_hook, EXEC_PREFIX, sizeof (pre_statechg_hook)); - if (brand_get_prestatechange(bh, zone_name, zpath, + if (brand_get_prestatechange(bh, zone_name, zonepath, pre_statechg_hook + EXEC_LEN, sizeof (pre_statechg_hook) - EXEC_LEN) != 0) return (-1); @@ -1803,7 +2404,7 @@ brand_callback_init(brand_handle_t bh, char *zone_name) (void) strlcpy(post_statechg_hook, EXEC_PREFIX, sizeof (post_statechg_hook)); - if (brand_get_poststatechange(bh, zone_name, zpath, + if (brand_get_poststatechange(bh, zone_name, zonepath, post_statechg_hook + EXEC_LEN, sizeof (post_statechg_hook) - EXEC_LEN) != 0) return (-1); @@ -1814,7 +2415,7 @@ brand_callback_init(brand_handle_t bh, char *zone_name) (void) strlcpy(query_hook, EXEC_PREFIX, sizeof (query_hook)); - if (brand_get_query(bh, zone_name, zpath, query_hook + EXEC_LEN, + if (brand_get_query(bh, zone_name, zonepath, query_hook + EXEC_LEN, sizeof (query_hook) - EXEC_LEN) != 0) return (-1); @@ -1942,6 +2543,11 @@ main(int argc, char *argv[]) return (1); } + if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) { + zerror(zlogp, B_FALSE, "unable to determine zone path"); + return (-1); + } + if (zonecfg_default_brand(default_brand, sizeof (default_brand)) != Z_OK) { zerror(zlogp, B_FALSE, "unable to determine default brand"); @@ -2013,6 +2619,11 @@ main(int argc, char *argv[]) } priv_freeset(privset); + if (set_brand_env(zlogp) != 0) { + zerror(zlogp, B_FALSE, "Unable to setup brand's environment"); + return (1); + } + if (mkzonedir(zlogp) != 0) return (1); @@ -2139,6 +2750,15 @@ main(int argc, char *argv[]) openlog("zoneadmd", LOG_PID, LOG_DAEMON); /* + * Allow logging to <zonepath>/logs/<file>. + */ + logstream_init(zlogp); + platloghdl = logstream_open("platform.log", "zoneadmd", 0); + + /* logplat looks the same as logsys, but logs to platform.log */ + logplat = logsys; + + /* * The eventstream is used to publish state changes in the zone * from the door threads to the console I/O poller. */ @@ -2157,7 +2777,6 @@ main(int argc, char *argv[]) if (make_daemon_exclusive(zlogp) == -1) goto child_out; - /* * Create/join a new session; we need to be careful of what we do with * the console from now on so we don't end up being the session leader @@ -2167,9 +2786,13 @@ main(int argc, char *argv[]) /* * This thread shouldn't be receiving any signals; in particular, - * SIGCHLD should be received by the thread doing the fork(). + * SIGCHLD should be received by the thread doing the fork(). The + * exceptions are SIGHUP and SIGUSR1 for log rotation, set up by + * logstream_init(). */ (void) sigfillset(&blockset); + (void) sigdelset(&blockset, SIGHUP); + (void) sigdelset(&blockset, SIGUSR1); (void) thr_sigsetmask(SIG_BLOCK, &blockset, NULL); /* diff --git a/usr/src/cmd/zoneadmd/zoneadmd.h b/usr/src/cmd/zoneadmd/zoneadmd.h index d784a303b3..06353cbe61 100644 --- a/usr/src/cmd/zoneadmd/zoneadmd.h +++ b/usr/src/cmd/zoneadmd/zoneadmd.h @@ -22,6 +22,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2019 Joyent, Inc. */ #ifndef _ZONEADMD_H @@ -32,6 +33,9 @@ extern "C" { #endif #include <libdladm.h> +#include <libzonecfg.h> +#include <thread.h> +#include <synch.h> /* * Multi-threaded programs should avoid MT-unsafe library calls (i.e., any- @@ -69,6 +73,7 @@ extern "C" { #define DEFAULT_DIR_USER -1 /* user ID for chown: -1 means don't change */ #define DEFAULT_DIR_GROUP -1 /* grp ID for chown: -1 means don't change */ +#define ALT_MOUNT(mount_cmd) ((mount_cmd) != Z_MNT_BOOT) typedef struct zlog { FILE *logfile; /* file to log to */ @@ -83,24 +88,27 @@ typedef struct zlog { char *locale; /* locale to use for gettext() */ } zlog_t; -extern zlog_t logsys; +extern zlog_t logsys; /* syslog */ +extern zlog_t logplat; /* platform.log */ extern mutex_t lock; extern mutex_t msglock; extern boolean_t in_death_throes; extern boolean_t bringup_failure_recovery; extern char *zone_name; +extern char zonepath[MAXNAMELEN]; +extern zone_dochandle_t snap_hndl; extern char pool_name[MAXNAMELEN]; extern char brand_name[MAXNAMELEN]; extern char default_brand[MAXNAMELEN]; extern char boot_args[BOOTARGS_MAX]; -extern char bad_boot_arg[BOOTARGS_MAX]; extern boolean_t zone_isnative; extern boolean_t zone_iscluster; extern dladm_handle_t dld_handle; extern void zerror(zlog_t *, boolean_t, const char *, ...); extern char *localize_msg(char *locale, const char *msg); +extern void nwifent_free_attrs(struct zone_nwiftab *); /* * Eventstream interfaces. @@ -112,8 +120,7 @@ typedef enum { Z_EVT_ZONE_HALTED, Z_EVT_ZONE_READIED, Z_EVT_ZONE_UNINSTALLING, - Z_EVT_ZONE_BOOTFAILED, - Z_EVT_ZONE_BADARGS + Z_EVT_ZONE_BOOTFAILED } zone_evt_t; extern int eventstream_init(); @@ -135,9 +142,9 @@ typedef enum { /* * Virtual platform interfaces. */ -extern zoneid_t vplat_create(zlog_t *, zone_mnt_t); +extern zoneid_t vplat_create(zlog_t *, zone_mnt_t, zoneid_t); extern int vplat_bringup(zlog_t *, zone_mnt_t, zoneid_t); -extern int vplat_teardown(zlog_t *, boolean_t, boolean_t); +extern int vplat_teardown(zlog_t *, boolean_t, boolean_t, boolean_t); extern int vplat_get_iptype(zlog_t *, zone_iptype_t *); /* @@ -154,6 +161,23 @@ extern void resolve_lofs(zlog_t *zlogp, char *path, size_t pathlen); */ extern int init_console(zlog_t *); extern void serve_console(zlog_t *); +extern void zcons_statechanged(); + +/* + * Logging routines + */ +typedef enum { + LS_LINE_BUFFERED = 0x1 /* Write when \n found or full buffer */ +} logstream_flags_t; + +extern boolean_t logging_poisoned; + +extern void create_log_thread(zlog_t *); +extern void destroy_log_thread(zlog_t *); +extern void logstream_init(zlog_t *); +extern int logstream_open(const char *, const char *, logstream_flags_t); +extern void logstream_write(int, char *, int); +extern void logstream_close(int, boolean_t); /* * Contract handling. @@ -163,7 +187,13 @@ extern int init_template(void); /* * Routine to manage child processes. */ -extern int do_subproc(zlog_t *, char *, char **); +extern int do_subproc(zlog_t *, char *, char **, boolean_t); + +/* + * Resource handling. + */ +extern int resolve_device_match(zlog_t *, struct zone_devtab *, + char *, size_t); #ifdef __cplusplus } diff --git a/usr/src/cmd/zonecfg/Makefile b/usr/src/cmd/zonecfg/Makefile index dc4dc5a16e..4bb03aa97d 100644 --- a/usr/src/cmd/zonecfg/Makefile +++ b/usr/src/cmd/zonecfg/Makefile @@ -28,6 +28,7 @@ PROG= zonecfg OBJS= zonecfg.o zonecfg_lex.o zonecfg_grammar.tab.o include ../Makefile.cmd +include ../Makefile.ctf # zonecfg has a name clash with main() and libl.so.1. However, zonecfg must # still export a number of "yy*" (libl) interfaces. Reduce all other symbols @@ -37,7 +38,8 @@ MAPOPTS = $(MAPFILES:%=-M%) LFLAGS = -t YFLAGS = -d -b zonecfg_grammar -LDLIBS += -lzonecfg -ll -lnsl -ltecla -lzfs -lbrand -ldladm -linetutil +LDLIBS += -lzonecfg -ll -lnsl -ltecla -lzfs -lbrand -ldladm -linetutil -luuid +CFLAGS += -DYYLMAX=2048 CPPFLAGS += -I. LDFLAGS += $(MAPOPTS) CLEANFILES += zonecfg_lex.c zonecfg_grammar.tab.c zonecfg_grammar.tab.h diff --git a/usr/src/cmd/zonecfg/zonecfg.c b/usr/src/cmd/zonecfg/zonecfg.c index f6aa8678d4..512f27d1e6 100644 --- a/usr/src/cmd/zonecfg/zonecfg.c +++ b/usr/src/cmd/zonecfg/zonecfg.c @@ -23,6 +23,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2014 Nexenta Systems, Inc. All rights reserved. * Copyright 2014 Gary Mills + * Copyright 2016, Joyent Inc. */ /* @@ -80,6 +81,7 @@ #include <libinetutil.h> #include <pwd.h> #include <inet/ip.h> +#include <uuid/uuid.h> #include <libzonecfg.h> #include "zonecfg.h" @@ -127,7 +129,7 @@ extern int lex_lineno; #define SHELP_REMOVE "remove [-F] <resource-type> " \ "[ <property-name>=<property-value> ]*\n" \ "\t(global scope)\n" \ - "remove <property-name> <property-value>\n" \ + "remove [-F] <property-name> <property-value>\n" \ "\t(resource scope)" #define SHELP_REVERT "revert [-F]" #define SHELP_SELECT "select <resource-type> { <property-name>=" \ @@ -188,6 +190,8 @@ char *res_types[] = { "admin", "fs-allowed", ALIAS_MAXPROCS, + ALIAS_ZFSPRI, + "uuid", "security-flags", NULL }; @@ -236,6 +240,12 @@ char *prop_types[] = { "fs-allowed", ALIAS_MAXPROCS, "allowed-address", + ALIAS_ZFSPRI, + "mac-addr", + "vlan-id", + "global-nic", + "property", + "uuid", "default", "lower", "upper", @@ -305,6 +315,7 @@ static const char *clear_cmds[] = { "clear " ALIAS_MAXSEMIDS, "clear " ALIAS_SHARES, "clear " ALIAS_MAXPROCS, + "clear " ALIAS_ZFSPRI, NULL }; @@ -357,6 +368,8 @@ static const char *set_cmds[] = { "set hostid=", "set fs-allowed=", "set " ALIAS_MAXPROCS "=", + "set " ALIAS_ZFSPRI "=", + "set uuid=", NULL }; @@ -390,6 +403,7 @@ static const char *info_cmds[] = { "info admin", "info fs-allowed", "info max-processes", + "info uuid", NULL }; @@ -415,10 +429,20 @@ static const char *net_res_scope_cmds[] = { "exit", "help", "info", + "add property ", + "clear allowed-address", + "clear defrouter", + "clear global-nic", + "clear mac-addr", + "clear vlan-id", + "remove property ", "set address=", "set allowed-address=", - "set physical=", "set defrouter=", + "set global-nic=", + "set mac-addr=", + "set physical=", + "set vlan-id=", NULL }; @@ -428,6 +452,7 @@ static const char *device_res_scope_cmds[] = { "exit", "help", "info", + "add property ", "set match=", NULL }; @@ -545,12 +570,14 @@ static zone_dochandle_t handle; /* used all over the place */ static char zone[ZONENAME_MAX]; static char revert_zone[ZONENAME_MAX]; +static char new_uuid[UUID_PRINTABLE_STRING_LENGTH]; /* global brand operations */ static brand_handle_t brand; /* set in modifying functions, checked in read_input() */ static boolean_t need_to_commit = B_FALSE; +static boolean_t is_create = B_FALSE; boolean_t saw_error; /* set in yacc parser, checked in read_input() */ @@ -599,7 +626,6 @@ static struct zone_rctltab old_rctltab, in_progress_rctltab; static struct zone_attrtab old_attrtab, in_progress_attrtab; static struct zone_dstab old_dstab, in_progress_dstab; static struct zone_psettab old_psettab, in_progress_psettab; -static struct zone_mcaptab old_mcaptab, in_progress_mcaptab; static struct zone_admintab old_admintab, in_progress_admintab; static struct zone_secflagstab old_secflagstab, in_progress_secflagstab; @@ -1105,11 +1131,20 @@ usage(boolean_t verbose, uint_t flags) (void) fprintf(fp, gettext("Valid commands:\n")); (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), pt_to_str(PT_ADDRESS), gettext("<IP-address>")); + (void) fprintf(fp, "\t%s %s (%s=<value>,%s=<value>)\n", + cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), pt_to_str(PT_VALUE)); (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), pt_to_str(PT_ALLOWED_ADDRESS), gettext("<IP-address>")); (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), pt_to_str(PT_PHYSICAL), gettext("<interface>")); + (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), + pt_to_str(PT_MAC), gettext("<mac-address>")); + (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), + pt_to_str(PT_GNIC), gettext("<global zone NIC>")); + (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), + pt_to_str(PT_VLANID), gettext("<vlan ID>")); (void) fprintf(fp, gettext("See ifconfig(1M) for " "details of the <interface> string.\n")); (void) fprintf(fp, gettext("%s %s is valid " @@ -1117,10 +1152,12 @@ usage(boolean_t verbose, uint_t flags) "must not be set.\n"), cmd_to_str(CMD_SET), pt_to_str(PT_ADDRESS), pt_to_str(PT_IPTYPE), gettext("shared")); - (void) fprintf(fp, gettext("%s %s is valid " - "if the %s property is set to %s, otherwise it " - "must not be set.\n"), - cmd_to_str(CMD_SET), pt_to_str(PT_ALLOWED_ADDRESS), + (void) fprintf(fp, gettext("%s (%s, %s, %s, %s) are " + "valid if the %s property is set to %s, otherwise " + "they must not be set.\n"), + cmd_to_str(CMD_SET), + pt_to_str(PT_ALLOWED_ADDRESS), pt_to_str(PT_MAC), + pt_to_str(PT_VLANID), pt_to_str(PT_GNIC), pt_to_str(PT_IPTYPE), gettext("exclusive")); (void) fprintf(fp, gettext("\t%s %s=%s\n%s %s " "is valid if the %s or %s property is set, " @@ -1136,6 +1173,9 @@ usage(boolean_t verbose, uint_t flags) "used to configure a device node.\n"), rt_to_str(resource_scope)); (void) fprintf(fp, gettext("Valid commands:\n")); + (void) fprintf(fp, "\t%s %s (%s=<value>,%s=<value>)\n", + cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), pt_to_str(PT_VALUE)); (void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET), pt_to_str(PT_MATCH), gettext("<device-path>")); break; @@ -1282,10 +1322,12 @@ usage(boolean_t verbose, uint_t flags) if (flags & HELP_USAGE) { (void) fprintf(fp, "%s:\t%s %s\n", gettext("usage"), execname, cmd_to_str(CMD_HELP)); - (void) fprintf(fp, "\t%s -z <zone>\t\t\t(%s)\n", + (void) fprintf(fp, "\t%s {-z <zone>|-u <uuid>}\t\t\t(%s)\n", execname, gettext("interactive")); - (void) fprintf(fp, "\t%s -z <zone> <command>\n", execname); - (void) fprintf(fp, "\t%s -z <zone> -f <command-file>\n", + (void) fprintf(fp, "\t%s {-z <zone>|-u <uuid>} <command>\n", + execname); + (void) fprintf(fp, + "\t%s {-z <zone>|-u <uuid>} -f <command-file>\n", execname); } if (flags & HELP_SUBCMDS) { @@ -1374,15 +1416,22 @@ usage(boolean_t verbose, uint_t flags) pt_to_str(PT_MAXSEMIDS)); (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), pt_to_str(PT_SHARES)); + (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), + pt_to_str(PT_UUID)); + (void) fprintf(fp, "\t%s\t%s\n", gettext("(global)"), + pt_to_str(PT_ZFSPRI)); (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s\n", rt_to_str(RT_FS), pt_to_str(PT_DIR), pt_to_str(PT_SPECIAL), pt_to_str(PT_RAW), pt_to_str(PT_TYPE), pt_to_str(PT_OPTIONS)); - (void) fprintf(fp, "\t%s\t\t%s, %s, %s|%s\n", rt_to_str(RT_NET), + (void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s, %s, %s %s\n", + rt_to_str(RT_NET), pt_to_str(PT_ADDRESS), pt_to_str(PT_ALLOWED_ADDRESS), - pt_to_str(PT_PHYSICAL), pt_to_str(PT_DEFROUTER)); - (void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DEVICE), - pt_to_str(PT_MATCH)); + pt_to_str(PT_GNIC), pt_to_str(PT_MAC), + pt_to_str(PT_PHYSICAL), pt_to_str(PT_NPROP), + pt_to_str(PT_VLANID), pt_to_str(PT_DEFROUTER)); + (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_DEVICE), + pt_to_str(PT_MATCH), pt_to_str(PT_NPROP)); (void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_RCTL), pt_to_str(PT_NAME), pt_to_str(PT_VALUE)); (void) fprintf(fp, "\t%s\t\t%s, %s, %s\n", rt_to_str(RT_ATTR), @@ -1440,6 +1489,9 @@ initialize(boolean_t handle_expected) if (zonecfg_check_handle(handle) != Z_OK) { if ((err = zonecfg_get_handle(zone, handle)) == Z_OK) { got_handle = B_TRUE; + + (void) zonecfg_fix_obsolete(handle); + if (zonecfg_get_brand(handle, brandname, sizeof (brandname)) != Z_OK) { zerr("Zone %s is inconsistent: missing " @@ -1707,6 +1759,7 @@ create_func(cmd_t *cmd) boolean_t force = B_FALSE; boolean_t attach = B_FALSE; boolean_t arg_err = B_FALSE; + uuid_t uuid; assert(cmd != NULL); @@ -1714,7 +1767,7 @@ create_func(cmd_t *cmd) (void) strlcpy(zone_template, "SUNWdefault", sizeof (zone_template)); optind = 0; - while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?a:bFt:")) + while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "?a:bFt:X")) != EOF) { switch (arg) { case '?': @@ -1740,6 +1793,17 @@ create_func(cmd_t *cmd) (void) strlcpy(zone_template, optarg, sizeof (zone_template)); break; + case 'X': + (void) snprintf(zone_template, sizeof (zone_template), + "%s/%s.xml", ZONE_CONFIG_ROOT, zone); + err = zonecfg_get_xml_handle(zone_template, handle); + if (err != Z_OK) { + zone_perror(execname, err, B_TRUE); + exit(Z_ERR); + } + got_handle = B_TRUE; + need_to_commit = B_TRUE; + return; default: short_usage(CMD_CREATE); arg_err = B_TRUE; @@ -1793,9 +1857,14 @@ create_func(cmd_t *cmd) } need_to_commit = B_TRUE; + is_create = B_TRUE; zonecfg_fini_handle(handle); handle = tmphandle; got_handle = B_TRUE; + + /* Allocate a new uuid for this new zone */ + uuid_generate(uuid); + uuid_unparse(uuid, new_uuid); } /* @@ -1842,8 +1911,8 @@ export_func(cmd_t *cmd) struct zone_rctltab rctltab; struct zone_dstab dstab; struct zone_psettab psettab; - struct zone_mcaptab mcaptab; struct zone_rctlvaltab *valptr; + struct zone_res_attrtab *rap; struct zone_admintab admintab; struct zone_secflagstab secflagstab; int err, arg; @@ -1857,6 +1926,7 @@ export_func(cmd_t *cmd) FILE *of; boolean_t autoboot; zone_iptype_t iptype; + uuid_t uuid; boolean_t need_to_close = B_FALSE; boolean_t arg_err = B_FALSE; @@ -1967,6 +2037,14 @@ export_func(cmd_t *cmd) pt_to_str(PT_FS_ALLOWED), fsallowedp); } + if (zonecfg_get_uuid(zone, uuid) == Z_OK && !uuid_is_null(uuid)) { + char suuid[UUID_PRINTABLE_STRING_LENGTH]; + + uuid_unparse(uuid, suuid); + (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), + pt_to_str(PT_UUID), suuid); + } + if ((err = zonecfg_setfsent(handle)) != Z_OK) { zone_perror(zone, err, B_FALSE); goto done; @@ -2014,7 +2092,17 @@ export_func(cmd_t *cmd) export_prop(of, PT_ALLOWED_ADDRESS, nwiftab.zone_nwif_allowed_address); export_prop(of, PT_PHYSICAL, nwiftab.zone_nwif_physical); + export_prop(of, PT_MAC, nwiftab.zone_nwif_mac); + export_prop(of, PT_VLANID, nwiftab.zone_nwif_vlan_id); + export_prop(of, PT_GNIC, nwiftab.zone_nwif_gnic); export_prop(of, PT_DEFROUTER, nwiftab.zone_nwif_defrouter); + for (rap = nwiftab.zone_nwif_attrp; rap != NULL; + rap = rap->zone_res_attr_next) { + fprintf(of, "%s %s (%s=%s,%s=\"%s\")\n", + cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), rap->zone_res_attr_name, + pt_to_str(PT_VALUE), rap->zone_res_attr_value); + } (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); } (void) zonecfg_endnwifent(handle); @@ -2027,21 +2115,17 @@ export_func(cmd_t *cmd) (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD), rt_to_str(RT_DEVICE)); export_prop(of, PT_MATCH, devtab.zone_dev_match); + for (rap = devtab.zone_dev_attrp; rap != NULL; + rap = rap->zone_res_attr_next) { + fprintf(of, "%s %s (%s=%s,%s=\"%s\")\n", + cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), rap->zone_res_attr_name, + pt_to_str(PT_VALUE), rap->zone_res_attr_value); + } (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); } (void) zonecfg_enddevent(handle); - if (zonecfg_getmcapent(handle, &mcaptab) == Z_OK) { - char buf[128]; - - (void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD), - rt_to_str(RT_MCAP)); - bytes_to_units(mcaptab.zone_physmem_cap, buf, sizeof (buf)); - (void) fprintf(of, "%s %s=%s\n", cmd_to_str(CMD_SET), - pt_to_str(PT_PHYSICAL), buf); - (void) fprintf(of, "%s\n", cmd_to_str(CMD_END)); - } - if ((err = zonecfg_setrctlent(handle)) != Z_OK) { zone_perror(zone, err, B_FALSE); goto done; @@ -2205,7 +2289,6 @@ add_resource(cmd_t *cmd) { int type; struct zone_psettab tmp_psettab; - struct zone_mcaptab tmp_mcaptab; struct zone_secflagstab tmp_secflagstab; uint64_t tmp; uint64_t tmp_mcap; @@ -2298,9 +2381,10 @@ add_resource(cmd_t *cmd) * Make sure there isn't already a mem-cap entry or max-swap * or max-locked rctl. */ - if (zonecfg_lookup_mcap(handle, &tmp_mcaptab) == Z_OK || - zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &tmp_mcap) - == Z_OK || + if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, + &tmp_mcap) == Z_OK || + zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, + &tmp_mcap) == Z_OK || zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &tmp_mcap) == Z_OK) { zerr(gettext("The %s resource or a related resource " @@ -2313,7 +2397,6 @@ add_resource(cmd_t *cmd) "to even the root user; " "this could render the system impossible\n" "to administer. Please use caution.")); - bzero(&in_progress_mcaptab, sizeof (in_progress_mcaptab)); return; case RT_ADMIN: bzero(&in_progress_admintab, sizeof (in_progress_admintab)); @@ -2424,6 +2507,79 @@ bad: zonecfg_free_rctl_value_list(rctlvaltab); } +/* + * Resource attribute ("property" resource embedded on net or dev resource) + */ +static void +do_res_attr(struct zone_res_attrtab **headp, complex_property_ptr_t cpp) +{ + complex_property_ptr_t cp; + struct zone_res_attrtab *np; + int err; + boolean_t seen_name = B_FALSE, seen_value = B_FALSE; + + if ((np = calloc(1, sizeof (struct zone_res_attrtab))) == NULL) { + zone_perror(zone, Z_NOMEM, B_TRUE); + exit(Z_ERR); + } + + for (cp = cpp; cp != NULL; cp = cp->cp_next) { + switch (cp->cp_type) { + case PT_NAME: + if (seen_name) { + zerr(gettext("%s already specified"), + pt_to_str(PT_NAME)); + goto bad; + } + if (strlcpy(np->zone_res_attr_name, cp->cp_value, + sizeof (np->zone_res_attr_name)) >= + sizeof (np->zone_res_attr_name)) { + zerr(gettext("Input for %s is too long"), + pt_to_str(PT_NAME)); + goto bad; + } + seen_name = B_TRUE; + break; + case PT_VALUE: + if (seen_value) { + zerr(gettext("%s already specified"), + pt_to_str(PT_VALUE)); + goto bad; + } + if (strlcpy(np->zone_res_attr_value, cp->cp_value, + sizeof (np->zone_res_attr_value)) >= + sizeof (np->zone_res_attr_value)) { + zerr(gettext("Input for %s is too long"), + pt_to_str(PT_VALUE)); + goto bad; + } + + seen_value = B_TRUE; + break; + default: + zone_perror(pt_to_str(PT_NPROP), Z_NO_PROPERTY_TYPE, + B_TRUE); + long_usage(CMD_ADD, B_TRUE); + usage(B_FALSE, HELP_PROPS); + zonecfg_free_res_attr_list(np); + return; + } + } + + if (!seen_name) + zerr(gettext("%s not specified"), pt_to_str(PT_NAME)); + if (!seen_value) + zerr(gettext("%s not specified"), pt_to_str(PT_VALUE)); + + err = zonecfg_add_res_attr(headp, np); + if (err != Z_OK) + zone_perror(pt_to_str(PT_NPROP), err, B_TRUE); + return; + +bad: + zonecfg_free_res_attr_list(np); +} + static void add_property(cmd_t *cmd) { @@ -2491,6 +2647,44 @@ add_property(cmd_t *cmd) } } return; + case RT_NET: + if (prop_type != PT_NPROP) { + zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, + B_TRUE); + long_usage(CMD_ADD, B_TRUE); + usage(B_FALSE, HELP_PROPS); + return; + } + pp = cmd->cmd_property_ptr[0]; + if (pp->pv_type != PROP_VAL_COMPLEX) { + zerr(gettext("A %s value was expected here."), + pvt_to_str(PROP_VAL_COMPLEX)); + saw_error = B_TRUE; + return; + } + + do_res_attr(&(in_progress_nwiftab.zone_nwif_attrp), + pp->pv_complex); + return; + case RT_DEVICE: + if (prop_type != PT_NPROP) { + zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, + B_TRUE); + long_usage(CMD_ADD, B_TRUE); + usage(B_FALSE, HELP_PROPS); + return; + } + pp = cmd->cmd_property_ptr[0]; + if (pp->pv_type != PROP_VAL_COMPLEX) { + zerr(gettext("A %s value was expected here."), + pvt_to_str(PROP_VAL_COMPLEX)); + saw_error = B_TRUE; + return; + } + + do_res_attr(&(in_progress_devtab.zone_dev_attrp), + pp->pv_complex); + return; case RT_RCTL: if (prop_type != PT_VALUE) { zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, @@ -2535,7 +2729,7 @@ static boolean_t gz_invalid_rt_property(int type) { return (global_zone && (type == RT_ZONENAME || type == RT_ZONEPATH || - type == RT_AUTOBOOT || type == RT_LIMITPRIV || + type == RT_AUTOBOOT || type == RT_LIMITPRIV || type == RT_UUID || type == RT_BOOTARGS || type == RT_BRAND || type == RT_SCHED || type == RT_IPTYPE || type == RT_HOSTID || type == RT_FS_ALLOWED)); } @@ -2544,7 +2738,7 @@ static boolean_t gz_invalid_property(int type) { return (global_zone && (type == PT_ZONENAME || type == PT_ZONEPATH || - type == PT_AUTOBOOT || type == PT_LIMITPRIV || + type == PT_AUTOBOOT || type == PT_LIMITPRIV || type == PT_UUID || type == PT_BOOTARGS || type == PT_BRAND || type == PT_SCHED || type == PT_IPTYPE || type == PT_HOSTID || type == PT_FS_ALLOWED)); } @@ -2595,8 +2789,9 @@ add_func(cmd_t *cmd) resource_scope = cmd->cmd_res_type; end_op = CMD_ADD; add_resource(cmd); - } else + } else { add_property(cmd); + } } /* @@ -2761,6 +2956,32 @@ fill_in_fstab(cmd_t *cmd, struct zone_fstab *fstab, boolean_t fill_in_only) return (zonecfg_lookup_filesystem(handle, fstab)); } +/* + * Turn an addr that looks like f:2:0:44:5:6C into 0f:02:00:44:05:6c + * We're expecting a dst of at least MAXMACADDRLEN size here. + */ +static void +normalize_mac_addr(char *dst, const char *src, int len) +{ + char *p, *e, *sep = ""; + long n; + char buf[MAXMACADDRLEN], tmp[4]; + + *dst = '\0'; + (void) strlcpy(buf, src, sizeof (buf)); + p = strtok(buf, ":"); + while (p != NULL) { + n = strtol(p, &e, 16); + if (*e != NULL || n > 0xff) + return; + (void) snprintf(tmp, sizeof (tmp), "%s%02x", sep, n); + (void) strlcat(dst, tmp, len); + + sep = ":"; + p = strtok(NULL, ":"); + } +} + static int fill_in_nwiftab(cmd_t *cmd, struct zone_nwiftab *nwiftab, boolean_t fill_in_only) @@ -2794,6 +3015,21 @@ fill_in_nwiftab(cmd_t *cmd, struct zone_nwiftab *nwiftab, pp->pv_simple, sizeof (nwiftab->zone_nwif_physical)); break; + case PT_MAC: + normalize_mac_addr(nwiftab->zone_nwif_mac, + pp->pv_simple, + sizeof (nwiftab->zone_nwif_mac)); + break; + case PT_VLANID: + (void) strlcpy(nwiftab->zone_nwif_vlan_id, + pp->pv_simple, + sizeof (nwiftab->zone_nwif_vlan_id)); + break; + case PT_GNIC: + (void) strlcpy(nwiftab->zone_nwif_gnic, + pp->pv_simple, + sizeof (nwiftab->zone_nwif_gnic)); + break; case PT_DEFROUTER: (void) strlcpy(nwiftab->zone_nwif_defrouter, pp->pv_simple, @@ -3092,6 +3328,8 @@ prompt_remove_resource(cmd_t *cmd, char *rsrc) num = zonecfg_num_resources(handle, rsrc); if (num == 0) { + if (force) + return (B_TRUE); z_cmd_rt_perror(CMD_REMOVE, cmd->cmd_res_type, Z_NO_ENTRY, B_TRUE); return (B_FALSE); @@ -3120,7 +3358,7 @@ prompt_remove_resource(cmd_t *cmd, char *rsrc) } static void -remove_fs(cmd_t *cmd) +remove_fs(cmd_t *cmd, boolean_t force) { int err; @@ -3129,13 +3367,16 @@ remove_fs(cmd_t *cmd) struct zone_fstab fstab; if ((err = fill_in_fstab(cmd, &fstab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE); return; } - if ((err = zonecfg_delete_filesystem(handle, &fstab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE); - else + if ((err = zonecfg_delete_filesystem(handle, &fstab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_FS, err, B_TRUE); + } else { need_to_commit = B_TRUE; + } zonecfg_free_fs_option_list(fstab.zone_fs_options); return; } @@ -3154,7 +3395,7 @@ remove_fs(cmd_t *cmd) } static void -remove_net(cmd_t *cmd) +remove_net(cmd_t *cmd, boolean_t force) { int err; @@ -3163,13 +3404,18 @@ remove_net(cmd_t *cmd) struct zone_nwiftab nwiftab; if ((err = fill_in_nwiftab(cmd, &nwiftab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, + B_TRUE); return; } - if ((err = zonecfg_delete_nwif(handle, &nwiftab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, B_TRUE); - else + if ((err = zonecfg_delete_nwif(handle, &nwiftab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_NET, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } return; } @@ -3187,7 +3433,7 @@ remove_net(cmd_t *cmd) } static void -remove_device(cmd_t *cmd) +remove_device(cmd_t *cmd, boolean_t force) { int err; @@ -3196,13 +3442,18 @@ remove_device(cmd_t *cmd) struct zone_devtab devtab; if ((err = fill_in_devtab(cmd, &devtab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, + B_TRUE); return; } - if ((err = zonecfg_delete_dev(handle, &devtab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, B_TRUE); - else + if ((err = zonecfg_delete_dev(handle, &devtab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DEVICE, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } return; } @@ -3220,7 +3471,7 @@ remove_device(cmd_t *cmd) } static void -remove_attr(cmd_t *cmd) +remove_attr(cmd_t *cmd, boolean_t force) { int err; @@ -3229,13 +3480,18 @@ remove_attr(cmd_t *cmd) struct zone_attrtab attrtab; if ((err = fill_in_attrtab(cmd, &attrtab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, + B_TRUE); return; } - if ((err = zonecfg_delete_attr(handle, &attrtab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, B_TRUE); - else + if ((err = zonecfg_delete_attr(handle, &attrtab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_ATTR, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } return; } @@ -3253,7 +3509,7 @@ remove_attr(cmd_t *cmd) } static void -remove_dataset(cmd_t *cmd) +remove_dataset(cmd_t *cmd, boolean_t force) { int err; @@ -3262,13 +3518,18 @@ remove_dataset(cmd_t *cmd) struct zone_dstab dstab; if ((err = fill_in_dstab(cmd, &dstab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, + B_TRUE); return; } - if ((err = zonecfg_delete_ds(handle, &dstab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, B_TRUE); - else + if ((err = zonecfg_delete_ds(handle, &dstab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DATASET, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } return; } @@ -3286,7 +3547,7 @@ remove_dataset(cmd_t *cmd) } static void -remove_rctl(cmd_t *cmd) +remove_rctl(cmd_t *cmd, boolean_t force) { int err; @@ -3295,13 +3556,18 @@ remove_rctl(cmd_t *cmd) struct zone_rctltab rctltab; if ((err = fill_in_rctltab(cmd, &rctltab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, + B_TRUE); return; } - if ((err = zonecfg_delete_rctl(handle, &rctltab)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, B_TRUE); - else + if ((err = zonecfg_delete_rctl(handle, &rctltab)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_RCTL, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); return; } @@ -3320,72 +3586,90 @@ remove_rctl(cmd_t *cmd) } static void -remove_pset() +remove_pset(boolean_t force) { int err; struct zone_psettab psettab; if ((err = zonecfg_lookup_pset(handle, &psettab)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE); return; } - if ((err = zonecfg_delete_pset(handle)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE); - else + if ((err = zonecfg_delete_pset(handle)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_DCPU, err, B_TRUE); + } else { need_to_commit = B_TRUE; + } } static void -remove_pcap() +remove_pcap(boolean_t force) { int err; uint64_t tmp; if (zonecfg_get_aliased_rctl(handle, ALIAS_CPUCAP, &tmp) != Z_OK) { - zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), rt_to_str(RT_PCAP), - zonecfg_strerror(Z_NO_RESOURCE_TYPE)); - saw_error = B_TRUE; + if (!force) { + zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), + rt_to_str(RT_PCAP), + zonecfg_strerror(Z_NO_RESOURCE_TYPE)); + saw_error = B_TRUE; + } return; } - if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_CPUCAP)) != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_PCAP, err, B_TRUE); - else + if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_CPUCAP)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_PCAP, err, B_TRUE); + } else { need_to_commit = B_TRUE; + } } static void -remove_mcap() +remove_mcap(boolean_t force) { int err, res1, res2, res3; uint64_t tmp; - struct zone_mcaptab mcaptab; boolean_t revert = B_FALSE; - res1 = zonecfg_lookup_mcap(handle, &mcaptab); + res1 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, &tmp); res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &tmp); res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &tmp); /* if none of these exist, there is no resource to remove */ if (res1 != Z_OK && res2 != Z_OK && res3 != Z_OK) { - zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), rt_to_str(RT_MCAP), - zonecfg_strerror(Z_NO_RESOURCE_TYPE)); - saw_error = B_TRUE; + if (!force) { + zerr("%s %s: %s", cmd_to_str(CMD_REMOVE), + rt_to_str(RT_MCAP), + zonecfg_strerror(Z_NO_RESOURCE_TYPE)); + saw_error = B_TRUE; + } return; } if (res1 == Z_OK) { - if ((err = zonecfg_delete_mcap(handle)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE); - revert = B_TRUE; + if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_MAXPHYSMEM)) + != Z_OK) { + if (!force) { + z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, + B_TRUE); + revert = B_TRUE; + } } else { need_to_commit = B_TRUE; } } + if (res2 == Z_OK) { if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_MAXSWAP)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE); - revert = B_TRUE; + if (!force) { + z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, + B_TRUE); + revert = B_TRUE; + } } else { need_to_commit = B_TRUE; } @@ -3393,8 +3677,11 @@ remove_mcap() if (res3 == Z_OK) { if ((err = zonecfg_rm_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, B_TRUE); - revert = B_TRUE; + if (!force) { + z_cmd_rt_perror(CMD_REMOVE, RT_MCAP, err, + B_TRUE); + revert = B_TRUE; + } } else { need_to_commit = B_TRUE; } @@ -3405,7 +3692,7 @@ remove_mcap() } static void -remove_admin(cmd_t *cmd) +remove_admin(cmd_t *cmd, boolean_t force) { int err; @@ -3414,34 +3701,33 @@ remove_admin(cmd_t *cmd) struct zone_admintab admintab; if ((err = fill_in_admintab(cmd, &admintab, B_FALSE)) != Z_OK) { - z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, - err, B_TRUE); + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, err, + B_TRUE); return; } if ((err = zonecfg_delete_admin(handle, &admintab, - zone)) - != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, - err, B_TRUE); - else + zone)) != Z_OK) { + if (!force) + z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, err, + B_TRUE); + } else { need_to_commit = B_TRUE; + } return; - } else { - /* - * unqualified admin removal. - * remove all admins but prompt if more - * than one. - */ - if (!prompt_remove_resource(cmd, "admin")) - return; - - if ((err = zonecfg_delete_admins(handle, zone)) - != Z_OK) - z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, - err, B_TRUE); - else - need_to_commit = B_TRUE; } + + /* + * unqualified admin removal. + * remove all admins but prompt if more than one. + */ + if (!prompt_remove_resource(cmd, "admin")) + return; + + if ((err = zonecfg_delete_admins(handle, zone)) != Z_OK) + z_cmd_rt_perror(CMD_REMOVE, RT_ADMIN, err, B_TRUE); + else + need_to_commit = B_TRUE; } static void @@ -3471,6 +3757,7 @@ remove_resource(cmd_t *cmd) int type; int arg; boolean_t arg_err = B_FALSE; + boolean_t force = B_FALSE; if ((type = cmd->cmd_res_type) == RT_UNKNOWN) { long_usage(CMD_REMOVE, B_TRUE); @@ -3485,6 +3772,7 @@ remove_resource(cmd_t *cmd) arg_err = B_TRUE; break; case 'F': + force = B_TRUE; break; default: short_usage(CMD_REMOVE); @@ -3500,34 +3788,34 @@ remove_resource(cmd_t *cmd) switch (type) { case RT_FS: - remove_fs(cmd); + remove_fs(cmd, force); return; case RT_NET: - remove_net(cmd); + remove_net(cmd, force); return; case RT_DEVICE: - remove_device(cmd); + remove_device(cmd, force); return; case RT_RCTL: - remove_rctl(cmd); + remove_rctl(cmd, force); return; case RT_ATTR: - remove_attr(cmd); + remove_attr(cmd, force); return; case RT_DATASET: - remove_dataset(cmd); + remove_dataset(cmd, force); return; case RT_DCPU: - remove_pset(); + remove_pset(force); return; case RT_PCAP: - remove_pcap(); + remove_pcap(force); return; case RT_MCAP: - remove_mcap(); + remove_mcap(force); return; case RT_ADMIN: - remove_admin(cmd); + remove_admin(cmd, force); return; case RT_SECFLAGS: remove_secflags(); @@ -3547,7 +3835,27 @@ remove_property(cmd_t *cmd) int err, res_type, prop_type; property_value_ptr_t pp; struct zone_rctlvaltab *rctlvaltab; + struct zone_res_attrtab *np; complex_property_ptr_t cx; + int arg; + boolean_t force = B_FALSE; + boolean_t arg_err = B_FALSE; + + optind = 0; + while ((arg = getopt(cmd->cmd_argc, cmd->cmd_argv, "F")) != EOF) { + switch (arg) { + case 'F': + force = B_TRUE; + break; + default: + arg_err = B_TRUE; + break; + } + } + if (arg_err) { + saw_error = B_TRUE; + return; + } res_type = resource_scope; prop_type = cmd->cmd_prop_name[0]; @@ -3589,7 +3897,7 @@ remove_property(cmd_t *cmd) prop_id = pp->pv_simple; err = zonecfg_remove_fs_option(&in_progress_fstab, prop_id); - if (err != Z_OK) + if (err != Z_OK && !force) zone_perror(pt_to_str(prop_type), err, B_TRUE); } else { list_property_ptr_t list; @@ -3601,12 +3909,62 @@ remove_property(cmd_t *cmd) break; err = zonecfg_remove_fs_option( &in_progress_fstab, prop_id); - if (err != Z_OK) + if (err != Z_OK && !force) zone_perror(pt_to_str(prop_type), err, B_TRUE); } } return; + case RT_NET: /* FALLTHRU */ + case RT_DEVICE: + if (prop_type != PT_NPROP) { + zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, + B_TRUE); + long_usage(CMD_REMOVE, B_TRUE); + usage(B_FALSE, HELP_PROPS); + return; + } + pp = cmd->cmd_property_ptr[0]; + if (pp->pv_type != PROP_VAL_COMPLEX) { + zerr(gettext("A %s value was expected here."), + pvt_to_str(PROP_VAL_COMPLEX)); + saw_error = B_TRUE; + return; + } + + np = alloca(sizeof (struct zone_res_attrtab)); + for (cx = pp->pv_complex; cx != NULL; cx = cx->cp_next) { + switch (cx->cp_type) { + case PT_NAME: + (void) strlcpy(np->zone_res_attr_name, + cx->cp_value, + sizeof (np->zone_res_attr_name)); + break; + case PT_VALUE: + (void) strlcpy(np->zone_res_attr_value, + cx->cp_value, + sizeof (np->zone_res_attr_value)); + break; + default: + zone_perror(pt_to_str(prop_type), + Z_NO_PROPERTY_TYPE, B_TRUE); + long_usage(CMD_REMOVE, B_TRUE); + usage(B_FALSE, HELP_PROPS); + return; + } + } + np->zone_res_attr_next = NULL; + + if (res_type == RT_NET) { + err = zonecfg_remove_res_attr( + &(in_progress_nwiftab.zone_nwif_attrp), np); + } else { /* RT_DEVICE */ + err = zonecfg_remove_res_attr( + &(in_progress_devtab.zone_dev_attrp), np); + } + if (err != Z_OK && !force) + zone_perror(pt_to_str(prop_type), err, B_TRUE); + return; case RT_RCTL: if (prop_type != PT_VALUE) { zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, @@ -3655,22 +4013,10 @@ remove_property(cmd_t *cmd) rctlvaltab->zone_rctlval_next = NULL; err = zonecfg_remove_rctl_value(&in_progress_rctltab, rctlvaltab); - if (err != Z_OK) + if (err != Z_OK && !force) zone_perror(pt_to_str(prop_type), err, B_TRUE); zonecfg_free_rctl_value_list(rctlvaltab); return; - case RT_NET: - if (prop_type != PT_DEFROUTER) { - zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, - B_TRUE); - long_usage(CMD_REMOVE, B_TRUE); - usage(B_FALSE, HELP_PROPS); - return; - } else { - bzero(&in_progress_nwiftab.zone_nwif_defrouter, - sizeof (in_progress_nwiftab.zone_nwif_defrouter)); - return; - } default: zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE); long_usage(CMD_REMOVE, B_TRUE); @@ -3733,8 +4079,7 @@ clear_property(cmd_t *cmd) case RT_MCAP: switch (prop_type) { case PT_PHYSICAL: - in_progress_mcaptab.zone_physmem_cap[0] = '\0'; - need_to_commit = B_TRUE; + remove_aliased_rctl(PT_PHYSICAL, ALIAS_MAXPHYSMEM); return; case PT_SWAP: remove_aliased_rctl(PT_SWAP, ALIAS_MAXSWAP); @@ -3744,6 +4089,30 @@ clear_property(cmd_t *cmd) return; } break; + case RT_NET: + switch (prop_type) { + case PT_ALLOWED_ADDRESS: + in_progress_nwiftab.zone_nwif_allowed_address[0] = '\0'; + need_to_commit = B_TRUE; + return; + case PT_DEFROUTER: + in_progress_nwiftab.zone_nwif_defrouter[0] = '\0'; + need_to_commit = B_TRUE; + return; + case PT_GNIC: + in_progress_nwiftab.zone_nwif_gnic[0] = '\0'; + need_to_commit = B_TRUE; + return; + case PT_MAC: + in_progress_nwiftab.zone_nwif_mac[0] = '\0'; + need_to_commit = B_TRUE; + return; + case PT_VLANID: + in_progress_nwiftab.zone_nwif_vlan_id[0] = '\0'; + need_to_commit = B_TRUE; + return; + } + break; case RT_SECFLAGS: switch (prop_type) { case PT_LOWER: @@ -3785,6 +4154,8 @@ clear_global(cmd_t *cmd) /* FALLTHRU */ case PT_ZONEPATH: /* FALLTHRU */ + case PT_UUID: + /* FALLTHRU */ case PT_BRAND: zone_perror(pt_to_str(type), Z_CLEAR_DISALLOW, B_TRUE); return; @@ -3847,6 +4218,9 @@ clear_global(cmd_t *cmd) case PT_SHARES: remove_aliased_rctl(PT_SHARES, ALIAS_SHARES); return; + case PT_ZFSPRI: + remove_aliased_rctl(PT_ZFSPRI, ALIAS_ZFSPRI); + return; case PT_HOSTID: if ((err = zonecfg_set_hostid(handle, NULL)) != Z_OK) z_cmd_rt_perror(CMD_CLEAR, RT_HOSTID, err, B_TRUE); @@ -3892,7 +4266,7 @@ clear_func(cmd_t *cmd) void select_func(cmd_t *cmd) { - int type, err, res; + int type, err; uint64_t limit; uint64_t tmp; @@ -3987,7 +4361,8 @@ select_func(cmd_t *cmd) return; case RT_MCAP: /* if none of these exist, there is no resource to select */ - if ((res = zonecfg_lookup_mcap(handle, &old_mcaptab)) != Z_OK && + if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, &limit) + != Z_OK && zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &limit) != Z_OK && zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &limit) @@ -3996,12 +4371,6 @@ select_func(cmd_t *cmd) B_TRUE); global_scope = B_TRUE; } - if (res == Z_OK) - bcopy(&old_mcaptab, &in_progress_mcaptab, - sizeof (struct zone_mcaptab)); - else - bzero(&in_progress_mcaptab, - sizeof (in_progress_mcaptab)); return; case RT_ADMIN: if ((err = fill_in_admintab(cmd, &old_admintab, B_FALSE)) @@ -4278,9 +4647,8 @@ set_func(cmd_t *cmd) boolean_t autoboot; zone_iptype_t iptype; boolean_t force_set = B_FALSE; - size_t physmem_size = sizeof (in_progress_mcaptab.zone_physmem_cap); uint64_t mem_cap, mem_limit; - float cap; + double cap; char *unitp; struct zone_psettab tmp_psettab; boolean_t arg_err = B_FALSE; @@ -4353,6 +4721,10 @@ set_func(cmd_t *cmd) res_type = RT_HOSTID; } else if (prop_type == PT_FS_ALLOWED) { res_type = RT_FS_ALLOWED; + } else if (prop_type == PT_ZFSPRI) { + res_type = RT_ZFSPRI; + } else if (prop_type == PT_UUID) { + res_type = RT_UUID; } else { zerr(gettext("Cannot set a resource-specific property " "from the global scope.")); @@ -4382,10 +4754,12 @@ set_func(cmd_t *cmd) * A nasty expression but not that complicated: * 1. fs options are simple or list (tested below) * 2. rctl value's are complex or list (tested below) + * 3. net attr's are complex (tested below) * Anything else should be simple. */ if (!(res_type == RT_FS && prop_type == PT_OPTIONS) && !(res_type == RT_RCTL && prop_type == PT_VALUE) && + !(res_type == RT_NET && prop_type == PT_NPROP) && (pp->pv_type != PROP_VAL_SIMPLE || (prop_id = pp->pv_simple) == NULL)) { zerr(gettext("A %s value was expected here."), @@ -4558,6 +4932,9 @@ set_func(cmd_t *cmd) case RT_SHARES: set_aliased_rctl(ALIAS_SHARES, prop_type, prop_id); return; + case RT_ZFSPRI: + set_aliased_rctl(ALIAS_ZFSPRI, prop_type, prop_id); + return; case RT_HOSTID: if ((err = zonecfg_set_hostid(handle, prop_id)) != Z_OK) { if (err == Z_TOO_BIG) { @@ -4571,6 +4948,15 @@ set_func(cmd_t *cmd) } need_to_commit = B_TRUE; return; + case RT_UUID: + /* + * We can't set here. We have to wait until commit since the + * uuid will be updating the index file and we may not have + * created the zone yet. + */ + (void) strlcpy(new_uuid, prop_id, sizeof (new_uuid)); + need_to_commit = B_TRUE; + return; case RT_FS_ALLOWED: if ((err = zonecfg_set_fs_allowed(handle, prop_id)) != Z_OK) zone_perror(zone, err, B_TRUE); @@ -4645,6 +5031,21 @@ set_func(cmd_t *cmd) prop_id, sizeof (in_progress_nwiftab.zone_nwif_physical)); break; + case PT_MAC: + normalize_mac_addr(in_progress_nwiftab.zone_nwif_mac, + prop_id, + sizeof (in_progress_nwiftab.zone_nwif_mac)); + break; + case PT_VLANID: + (void) strlcpy(in_progress_nwiftab.zone_nwif_vlan_id, + prop_id, + sizeof (in_progress_nwiftab.zone_nwif_vlan_id)); + break; + case PT_GNIC: + (void) strlcpy(in_progress_nwiftab.zone_nwif_gnic, + prop_id, + sizeof (in_progress_nwiftab.zone_nwif_gnic)); + break; case PT_DEFROUTER: if (validate_net_address_syntax(prop_id, B_TRUE) != Z_OK) { @@ -4655,6 +5056,20 @@ set_func(cmd_t *cmd) prop_id, sizeof (in_progress_nwiftab.zone_nwif_defrouter)); break; + case PT_NPROP: + if (pp->pv_type != PROP_VAL_COMPLEX) { + zerr(gettext("A %s value was expected here."), + pvt_to_str(PROP_VAL_COMPLEX)); + saw_error = B_TRUE; + return; + } + zonecfg_free_res_attr_list( + in_progress_nwiftab.zone_nwif_attrp); + in_progress_nwiftab.zone_nwif_attrp = NULL; + if (!(pp->pv_type == PROP_VAL_LIST && + pp->pv_list == NULL)) + add_property(cmd); + break; default: zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, B_TRUE); @@ -4670,6 +5085,20 @@ set_func(cmd_t *cmd) prop_id, sizeof (in_progress_devtab.zone_dev_match)); break; + case PT_NPROP: + if (pp->pv_type != PROP_VAL_COMPLEX) { + zerr(gettext("A %s value was expected here."), + pvt_to_str(PROP_VAL_COMPLEX)); + saw_error = B_TRUE; + return; + } + zonecfg_free_res_attr_list( + in_progress_devtab.zone_dev_attrp); + in_progress_devtab.zone_dev_attrp = NULL; + if (!(pp->pv_type == PROP_VAL_LIST && + pp->pv_list == NULL)) + add_property(cmd); + break; default: zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE, B_TRUE); @@ -4813,35 +5242,50 @@ set_func(cmd_t *cmd) * the add_resource() function. */ - if ((cap = strtof(prop_id, &unitp)) <= 0 || *unitp != '\0' || - (int)(cap * 100) < 1) { + if ((cap = strtod(prop_id, &unitp)) <= 0 || *unitp != '\0' || + (cap * 100.0) < 1) { zerr(gettext("%s property is out of range."), pt_to_str(PT_NCPUS)); saw_error = B_TRUE; return; } + cap *= 100.0; + /* To avoid rounding issues add .5 to force correct value. */ if ((err = zonecfg_set_aliased_rctl(handle, ALIAS_CPUCAP, - (int)(cap * 100))) != Z_OK) + (uint_t)(cap + 0.5))) != Z_OK) { zone_perror(zone, err, B_TRUE); - else + } else { need_to_commit = B_TRUE; + } return; case RT_MCAP: switch (prop_type) { case PT_PHYSICAL: + /* + * We have to check if an rctl is allowed here since + * there might already be a rctl defined that blocks + * the alias. + */ + if (!zonecfg_aliased_rctl_ok(handle, + ALIAS_MAXPHYSMEM)) { + zone_perror(pt_to_str(PT_LOCKED), + Z_ALIAS_DISALLOW, B_FALSE); + saw_error = B_TRUE; + return; + } + if (!zonecfg_valid_memlimit(prop_id, &mem_cap)) { - zerr(gettext("A positive number with a " + zerr(gettext("A non-negative number with a " "required scale suffix (K, M, G or T) was " - "expected here.")); - saw_error = B_TRUE; - } else if (mem_cap < ONE_MB) { - zerr(gettext("%s value is too small. It must " - "be at least 1M."), pt_to_str(PT_PHYSICAL)); + "expected\nhere.")); saw_error = B_TRUE; } else { - snprintf(in_progress_mcaptab.zone_physmem_cap, - physmem_size, "%llu", mem_cap); + if ((err = zonecfg_set_aliased_rctl(handle, + ALIAS_MAXPHYSMEM, mem_cap)) != Z_OK) + zone_perror(zone, err, B_TRUE); + else + need_to_commit = B_TRUE; } break; case PT_SWAP: @@ -5136,6 +5580,23 @@ info_hostid(zone_dochandle_t handle, FILE *fp) } static void +info_uuid(FILE *fp) +{ + uuid_t uuid; + char suuid[UUID_PRINTABLE_STRING_LENGTH]; + + if (new_uuid[0] != '\0') { + (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_UUID), new_uuid); + } else if (zonecfg_get_uuid(zone, uuid) == Z_OK && + !uuid_is_null(uuid)) { + uuid_unparse(uuid, suuid); + (void) fprintf(fp, "%s: %s\n", pt_to_str(PT_UUID), suuid); + } else { + (void) fprintf(fp, "%s:\n", pt_to_str(PT_UUID)); + } +} + +static void info_fs_allowed(zone_dochandle_t handle, FILE *fp) { char fsallowedp[ZONE_FS_ALLOWED_MAX]; @@ -5217,12 +5678,25 @@ loopend: static void output_net(FILE *fp, struct zone_nwiftab *nwiftab) { + struct zone_res_attrtab *np; + (void) fprintf(fp, "%s:\n", rt_to_str(RT_NET)); output_prop(fp, PT_ADDRESS, nwiftab->zone_nwif_address, B_TRUE); output_prop(fp, PT_ALLOWED_ADDRESS, nwiftab->zone_nwif_allowed_address, B_TRUE); - output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE); output_prop(fp, PT_DEFROUTER, nwiftab->zone_nwif_defrouter, B_TRUE); + output_prop(fp, PT_GNIC, nwiftab->zone_nwif_gnic, B_TRUE); + output_prop(fp, PT_MAC, nwiftab->zone_nwif_mac, B_TRUE); + output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE); + output_prop(fp, PT_VLANID, nwiftab->zone_nwif_vlan_id, B_TRUE); + + for (np = nwiftab->zone_nwif_attrp; np != NULL; + np = np->zone_res_attr_next) { + fprintf(fp, "\t%s: (%s=%s,%s=\"%s\")\n", + pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), np->zone_res_attr_name, + pt_to_str(PT_VALUE), np->zone_res_attr_value); + } } static void @@ -5265,8 +5739,18 @@ info_net(zone_dochandle_t handle, FILE *fp, cmd_t *cmd) static void output_dev(FILE *fp, struct zone_devtab *devtab) { + struct zone_res_attrtab *np; + (void) fprintf(fp, "%s:\n", rt_to_str(RT_DEVICE)); output_prop(fp, PT_MATCH, devtab->zone_dev_match, B_TRUE); + + for (np = devtab->zone_dev_attrp; np != NULL; + np = np->zone_res_attr_next) { + fprintf(fp, "\t%s: (%s=%s,%s=\"%s\")\n", + pt_to_str(PT_NPROP), + pt_to_str(PT_NAME), np->zone_res_attr_name, + pt_to_str(PT_VALUE), np->zone_res_attr_value); + } } static void @@ -5525,15 +6009,18 @@ bytes_to_units(char *str, char *buf, int bufsize) } static void -output_mcap(FILE *fp, struct zone_mcaptab *mcaptab, int showswap, +output_mcap(FILE *fp, int showphys, uint64_t maxphys, int showswap, uint64_t maxswap, int showlocked, uint64_t maxlocked) { char buf[128]; (void) fprintf(fp, "%s:\n", rt_to_str(RT_MCAP)); - if (mcaptab->zone_physmem_cap[0] != '\0') { - bytes_to_units(mcaptab->zone_physmem_cap, buf, sizeof (buf)); - output_prop(fp, PT_PHYSICAL, buf, B_TRUE); + + if (showphys == Z_OK) { + (void) snprintf(buf, sizeof (buf), "%llu", maxphys); + bytes_to_units(buf, buf, sizeof (buf)); + /* Print directly since "physical" also is a net property. */ + (void) fprintf(fp, "\t[%s: %s]\n", pt_to_str(PT_PHYSICAL), buf); } if (showswap == Z_OK) { @@ -5555,16 +6042,16 @@ info_mcap(zone_dochandle_t handle, FILE *fp) int res1, res2, res3; uint64_t swap_limit; uint64_t locked_limit; - struct zone_mcaptab lookup; + uint64_t phys_limit; - bzero(&lookup, sizeof (lookup)); - res1 = zonecfg_getmcapent(handle, &lookup); + res1 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, &phys_limit); res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &swap_limit); res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &locked_limit); if (res1 == Z_OK || res2 == Z_OK || res3 == Z_OK) - output_mcap(fp, &lookup, res2, swap_limit, res3, locked_limit); + output_mcap(fp, res1, phys_limit, res2, swap_limit, + res3, locked_limit); } static void @@ -5634,9 +6121,11 @@ info_func(cmd_t *cmd) FILE *fp = stdout; boolean_t need_to_close = B_FALSE; int type; - int res1, res2; + int res1, res2, res3; uint64_t swap_limit; uint64_t locked_limit; + uint64_t phys_limit; + struct stat statbuf; assert(cmd != NULL); @@ -5684,7 +6173,9 @@ info_func(cmd_t *cmd) &swap_limit); res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, &locked_limit); - output_mcap(fp, &in_progress_mcaptab, res1, swap_limit, + res3 = zonecfg_get_aliased_rctl(handle, + ALIAS_MAXPHYSMEM, &phys_limit); + output_mcap(fp, res3, phys_limit, res1, swap_limit, res2, locked_limit); break; case RT_ADMIN: @@ -5727,6 +6218,7 @@ info_func(cmd_t *cmd) info_iptype(handle, fp); info_hostid(handle, fp); info_fs_allowed(handle, fp); + info_uuid(fp); } info_aliased_rctl(handle, fp, ALIAS_MAXLWPS); info_aliased_rctl(handle, fp, ALIAS_MAXPROCS); @@ -5735,6 +6227,7 @@ info_func(cmd_t *cmd) info_aliased_rctl(handle, fp, ALIAS_MAXMSGIDS); info_aliased_rctl(handle, fp, ALIAS_MAXSEMIDS); info_aliased_rctl(handle, fp, ALIAS_SHARES); + info_aliased_rctl(handle, fp, ALIAS_ZFSPRI); if (!global_zone) { info_fs(handle, fp, cmd); info_net(handle, fp, cmd); @@ -5799,6 +6292,9 @@ info_func(cmd_t *cmd) case RT_SHARES: info_aliased_rctl(handle, fp, ALIAS_SHARES); break; + case RT_ZFSPRI: + info_aliased_rctl(handle, fp, ALIAS_ZFSPRI); + break; case RT_FS: info_fs(handle, fp, cmd); break; @@ -5829,6 +6325,9 @@ info_func(cmd_t *cmd) case RT_HOSTID: info_hostid(handle, fp); break; + case RT_UUID: + info_uuid(fp); + break; case RT_ADMIN: info_auth(handle, fp, cmd); break; @@ -6407,10 +6906,33 @@ verify_func(cmd_t *cmd) if (save) { if (ret_val == Z_OK) { + /* + * If the zone doesn't yet have a debug ID, set one now. + */ + if (zonecfg_get_did(handle) == -1) + zonecfg_set_did(handle); + if ((ret_val = zonecfg_save(handle)) == Z_OK) { need_to_commit = B_FALSE; (void) strlcpy(revert_zone, zone, sizeof (revert_zone)); + + if (is_create) { + zonecfg_notify_create(handle); + is_create = B_FALSE; + } + } + + /* + * Commit a new uuid at this point since we now know the + * zone index entry will exist. + */ + if (new_uuid[0] != '\0') { + if ((err = zonecfg_set_uuid(zone, zonepath, + new_uuid)) != Z_OK) + zone_perror(zone, err, B_FALSE); + else + new_uuid[0] = '\0'; } } else { zerr(gettext("Zone %s failed to verify"), zone); @@ -6581,6 +7103,7 @@ end_func(cmd_t *cmd) int err, arg, res1, res2, res3; uint64_t swap_limit; uint64_t locked_limit; + uint64_t phys_limit; uint64_t proc_cap; assert(cmd != NULL); @@ -6884,8 +7407,8 @@ end_func(cmd_t *cmd) break; case RT_MCAP: /* Make sure everything was filled in. */ - res1 = strlen(in_progress_mcaptab.zone_physmem_cap) == 0 ? - Z_ERR : Z_OK; + res1 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXPHYSMEM, + &phys_limit); res2 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXSWAP, &swap_limit); res3 = zonecfg_get_aliased_rctl(handle, ALIAS_MAXLOCKEDMEM, @@ -6901,11 +7424,6 @@ end_func(cmd_t *cmd) /* if phys & locked are both set, verify locked <= phys */ if (res1 == Z_OK && res3 == Z_OK) { - uint64_t phys_limit; - char *endp; - - phys_limit = strtoull( - in_progress_mcaptab.zone_physmem_cap, &endp, 10); if (phys_limit < locked_limit) { zerr(gettext("The %s cap must be less than or " "equal to the %s cap."), @@ -6917,23 +7435,6 @@ end_func(cmd_t *cmd) } err = Z_OK; - if (res1 == Z_OK) { - /* - * We could be ending from either an add operation - * or a select operation. Since all of the properties - * within this resource are optional, we always use - * modify on the mcap entry. zonecfg_modify_mcap() - * will handle both adding and modifying a memory cap. - */ - err = zonecfg_modify_mcap(handle, &in_progress_mcaptab); - } else if (end_op == CMD_SELECT) { - /* - * If we're ending from a select and the physical - * memory cap is empty then the user could have cleared - * the physical cap value, so try to delete the entry. - */ - (void) zonecfg_delete_mcap(handle); - } break; case RT_ADMIN: /* First make sure everything was filled in. */ @@ -7496,8 +7997,10 @@ get_execbasename(char *execfullname) int main(int argc, char *argv[]) { - int err, arg; + int err, arg, uflag = 0, zflag = 0; struct stat st; + uuid_t uuidin; + char zonename[ZONENAME_MAX + 1]; /* This must be before anything goes to stdout. */ setbuf(stdout, NULL); @@ -7524,7 +8027,7 @@ main(int argc, char *argv[]) exit(Z_OK); } - while ((arg = getopt(argc, argv, "?f:R:z:")) != EOF) { + while ((arg = getopt(argc, argv, "?f:R:z:u:")) != EOF) { switch (arg) { case '?': if (optopt == '?') @@ -7551,6 +8054,21 @@ main(int argc, char *argv[]) } zonecfg_set_root(optarg); break; + case 'u': + if (uuid_parse((char *)optarg, uuidin) == -1) + return (Z_INVALID_PROPERTY); + + if (zonecfg_get_name_by_uuid(uuidin, zonename, + ZONENAME_MAX) != Z_OK) { + zone_perror(optarg, Z_BOGUS_ZONE_NAME, B_TRUE); + usage(B_FALSE, HELP_SYNTAX); + exit(Z_USAGE); + } + + (void) strlcpy(zone, zonename, sizeof (zone)); + (void) strlcpy(revert_zone, zonename, sizeof (zone)); + uflag = 1; + break; case 'z': if (strcmp(optarg, GLOBAL_ZONENAME) == 0) { global_zone = B_TRUE; @@ -7561,6 +8079,7 @@ main(int argc, char *argv[]) } (void) strlcpy(zone, optarg, sizeof (zone)); (void) strlcpy(revert_zone, optarg, sizeof (zone)); + zflag = 1; break; default: usage(B_FALSE, HELP_USAGE); @@ -7568,7 +8087,7 @@ main(int argc, char *argv[]) } } - if (optind > argc || strcmp(zone, "") == 0) { + if (optind > argc || strcmp(zone, "") == 0 || (uflag && zflag)) { usage(B_FALSE, HELP_USAGE); exit(Z_USAGE); } diff --git a/usr/src/cmd/zonecfg/zonecfg.h b/usr/src/cmd/zonecfg/zonecfg.h index 108d0ce507..e4ae4d4d61 100644 --- a/usr/src/cmd/zonecfg/zonecfg.h +++ b/usr/src/cmd/zonecfg/zonecfg.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ #ifndef _ZONECFG_H @@ -90,7 +91,9 @@ extern "C" { #define RT_ADMIN 26 #define RT_FS_ALLOWED 27 #define RT_MAXPROCS 28 /* really a rctl alias property, but for info */ -#define RT_SECFLAGS 29 +#define RT_ZFSPRI 29 /* really a rctl alias property, but for info */ +#define RT_UUID 30 /* really a property, but for info */ +#define RT_SECFLAGS 31 #define RT_MIN RT_UNKNOWN #define RT_MAX RT_SECFLAGS @@ -138,9 +141,15 @@ extern "C" { #define PT_FS_ALLOWED 39 #define PT_MAXPROCS 40 #define PT_ALLOWED_ADDRESS 41 -#define PT_DEFAULT 42 -#define PT_LOWER 43 -#define PT_UPPER 44 +#define PT_ZFSPRI 42 +#define PT_MAC 43 +#define PT_VLANID 44 +#define PT_GNIC 45 +#define PT_NPROP 46 +#define PT_UUID 47 +#define PT_DEFAULT 48 +#define PT_LOWER 49 +#define PT_UPPER 50 #define PT_MIN PT_UNKNOWN #define PT_MAX PT_UPPER diff --git a/usr/src/cmd/zonecfg/zonecfg_grammar.y b/usr/src/cmd/zonecfg/zonecfg_grammar.y index 2e950512ec..d8b2fadb2f 100644 --- a/usr/src/cmd/zonecfg/zonecfg_grammar.y +++ b/usr/src/cmd/zonecfg/zonecfg_grammar.y @@ -22,6 +22,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2013, Joyent Inc. All rights reserved. */ /* @@ -135,7 +136,8 @@ complex_piece_func(int cp_type, const char *str, complex_property_ptr_t cp_next) %token NAME MATCH PRIV LIMIT ACTION VALUE EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET %token OPEN_PAREN CLOSE_PAREN COMMA DATASET LIMITPRIV BOOTARGS BRAND PSET PCAP %token MCAP NCPUS IMPORTANCE SHARES MAXLWPS MAXSHMMEM MAXSHMIDS MAXMSGIDS -%token MAXSEMIDS LOCKED SWAP SCHED CLEAR DEFROUTER ADMIN SECFLAGS USER AUTHS MAXPROCS +%token MAXSEMIDS LOCKED SWAP SCHED CLEAR DEFROUTER ADMIN USER AUTHS MAXPROCS +%token ZFSPRI MAC VLANID GNIC NPROP UUID SECFLAGS %token DEFAULT UPPER LOWER %type <strval> TOKEN EQUAL OPEN_SQ_BRACKET CLOSE_SQ_BRACKET @@ -146,7 +148,7 @@ complex_piece_func(int cp_type, const char *str, complex_property_ptr_t cp_next) %type <ival> property_name SPECIAL RAW DIR OPTIONS TYPE ADDRESS PHYSICAL NAME MATCH ZONENAME ZONEPATH AUTOBOOT POOL LIMITPRIV BOOTARGS VALUE PRIV LIMIT ACTION BRAND SCHED IPTYPE DEFROUTER HOSTID USER AUTHS FS_ALLOWED - ALLOWED_ADDRESS DEFAULT UPPER LOWER + ALLOWED_ADDRESS MAC VLANID GNIC NPROP UUID DEFAULT UPPER LOWER %type <cmd> command %type <cmd> add_command ADD %type <cmd> cancel_command CANCEL @@ -651,6 +653,24 @@ info_command: INFO $$->cmd_res_type = RT_FS_ALLOWED; $$->cmd_prop_nv_pairs = 0; } + | INFO UUID + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &info_func; + $$->cmd_res_type = RT_UUID; + $$->cmd_prop_nv_pairs = 0; + } + | INFO ZFSPRI + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &info_func; + $$->cmd_res_type = RT_ZFSPRI; + $$->cmd_prop_nv_pairs = 0; + } | INFO resource_type property_name EQUAL property_value { if (($$ = alloc_cmd()) == NULL) @@ -735,6 +755,19 @@ remove_command: REMOVE $$->cmd_prop_name[0] = $2; $$->cmd_property_ptr[0] = &property[0]; } + | REMOVE TOKEN property_name property_value + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &remove_func; + $$->cmd_argc = 1; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = NULL; + $$->cmd_prop_nv_pairs = 1; + $$->cmd_prop_name[0] = $3; + $$->cmd_property_ptr[0] = &property[0]; + } | REMOVE resource_type property_name EQUAL property_value { if (($$ = alloc_cmd()) == NULL) @@ -746,6 +779,20 @@ remove_command: REMOVE $$->cmd_prop_name[0] = $3; $$->cmd_property_ptr[0] = &property[0]; } + | REMOVE TOKEN resource_type property_name EQUAL property_value + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &remove_func; + $$->cmd_res_type = $3; + $$->cmd_argc = 1; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = NULL; + $$->cmd_prop_nv_pairs = 1; + $$->cmd_prop_name[0] = $4; + $$->cmd_property_ptr[0] = &property[0]; + } | REMOVE resource_type property_name EQUAL property_value property_name EQUAL property_value { if (($$ = alloc_cmd()) == NULL) @@ -759,6 +806,22 @@ remove_command: REMOVE $$->cmd_prop_name[1] = $6; $$->cmd_property_ptr[1] = &property[1]; } + | REMOVE TOKEN resource_type property_name EQUAL property_value property_name EQUAL property_value + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &remove_func; + $$->cmd_res_type = $3; + $$->cmd_argc = 1; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = NULL; + $$->cmd_prop_nv_pairs = 2; + $$->cmd_prop_name[0] = $4; + $$->cmd_property_ptr[0] = &property[0]; + $$->cmd_prop_name[1] = $7; + $$->cmd_property_ptr[1] = &property[1]; + } | REMOVE resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value { if (($$ = alloc_cmd()) == NULL) @@ -774,6 +837,24 @@ remove_command: REMOVE $$->cmd_prop_name[2] = $9; $$->cmd_property_ptr[2] = &property[2]; } + | REMOVE TOKEN resource_type property_name EQUAL property_value property_name EQUAL property_value property_name EQUAL property_value + { + if (($$ = alloc_cmd()) == NULL) + YYERROR; + cmd = $$; + $$->cmd_handler = &remove_func; + $$->cmd_res_type = $3; + $$->cmd_argc = 1; + $$->cmd_argv[0] = claim_token($2); + $$->cmd_argv[1] = NULL; + $$->cmd_prop_nv_pairs = 3; + $$->cmd_prop_name[0] = $4; + $$->cmd_property_ptr[0] = &property[0]; + $$->cmd_prop_name[1] = $7; + $$->cmd_property_ptr[1] = &property[1]; + $$->cmd_prop_name[2] = $10; + $$->cmd_property_ptr[2] = &property[2]; + } revert_command: REVERT { @@ -978,6 +1059,10 @@ property_name: SPECIAL { $$ = PT_SPECIAL; } | ALLOWED_ADDRESS { $$ = PT_ALLOWED_ADDRESS; } | PHYSICAL { $$ = PT_PHYSICAL; } | DEFROUTER { $$ = PT_DEFROUTER; } + | MAC { $$ = PT_MAC; } + | VLANID { $$ = PT_VLANID; } + | GNIC { $$ = PT_GNIC; } + | NPROP { $$ = PT_NPROP; } | NAME { $$ = PT_NAME; } | VALUE { $$ = PT_VALUE; } | MATCH { $$ = PT_MATCH; } @@ -1001,6 +1086,8 @@ property_name: SPECIAL { $$ = PT_SPECIAL; } | USER { $$ = PT_USER; } | AUTHS { $$ = PT_AUTHS; } | FS_ALLOWED { $$ = PT_FS_ALLOWED; } + | UUID { $$ = PT_UUID; } + | ZFSPRI { $$ = PT_ZFSPRI; } | DEFAULT { $$ = PT_DEFAULT; } | UPPER { $$ = PT_UPPER; } | LOWER { $$ = PT_LOWER; } diff --git a/usr/src/cmd/zonecfg/zonecfg_lex.l b/usr/src/cmd/zonecfg/zonecfg_lex.l index 8714c55499..05b41df48b 100644 --- a/usr/src/cmd/zonecfg/zonecfg_lex.l +++ b/usr/src/cmd/zonecfg/zonecfg_lex.l @@ -22,6 +22,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ #include <assert.h> @@ -57,10 +58,11 @@ extern void yyerror(char *s); static char *create_token(char *s); %} -%a 7000 -%p 5000 +%a 8000 +%p 5500 %e 2000 %n 1000 +%o 14000 %{ /* @@ -238,6 +240,18 @@ static char *create_token(char *s); <TSTATE>defrouter { return DEFROUTER; } <CSTATE>defrouter { return DEFROUTER; } +<TSTATE>mac-addr { return MAC; } +<CSTATE>mac-addr { return MAC; } + +<TSTATE>vlan-id { return VLANID; } +<CSTATE>vlan-id { return VLANID; } + +<TSTATE>global-nic { return GNIC; } +<CSTATE>global-nic { return GNIC; } + +<TSTATE>property { return NPROP; } +<CSTATE>property { return NPROP; } + <TSTATE>dir { return DIR; } <CSTATE>dir { return DIR; } @@ -310,6 +324,12 @@ static char *create_token(char *s); <TSTATE>fs-allowed { return FS_ALLOWED; } <CSTATE>fs-allowed { return FS_ALLOWED; } +<TSTATE>uuid { return UUID; } +<CSTATE>uuid { return UUID; } + +<TSTATE>zfs-io-priority { return ZFSPRI; } +<CSTATE>zfs-io-priority { return ZFSPRI; } + <TSTATE>default { return DEFAULT; } <CSTATE>default { return DEFAULT; } @@ -368,6 +388,13 @@ static char *create_token(char *s); return TOKEN; } +<CSTATE>\"[^\"\n]*[\"\n] { + yylval.strval = create_token(yytext + 1); + if (yylval.strval[yyleng - 2] == '"') + yylval.strval[yyleng - 2] = 0; + return TOKEN; + } + <TSTATE>\"[^\"\n]*[\"\n] { yylval.strval = create_token(yytext + 1); if (yylval.strval[yyleng - 2] == '"') diff --git a/usr/src/cmd/zonename/Makefile b/usr/src/cmd/zonename/Makefile index 566e893a67..3a51952455 100644 --- a/usr/src/cmd/zonename/Makefile +++ b/usr/src/cmd/zonename/Makefile @@ -28,8 +28,10 @@ # PROG= zonename +OBJS= zonename.o include ../Makefile.cmd +include ../Makefile.ctf LDLIBS += -lzonecfg @@ -37,6 +39,10 @@ LDLIBS += -lzonecfg all: $(PROG) +$(PROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) + install: all $(ROOTSBINPROG) $(RM) $(ROOTPROG) $(SYMLINK) ../../sbin/$(PROG) $(ROOTPROG) @@ -44,6 +50,10 @@ install: all $(ROOTSBINPROG) check: $(PROG).c $(CSTYLE) -pP $(PROG).c +%.o: %.c + $(COMPILE.c) $< + $(POST_PROCESS_O) + clean: lint: lint_PROG diff --git a/usr/src/cmd/zonestat/zonestatd/zonestatd.c b/usr/src/cmd/zonestat/zonestatd/zonestatd.c index b764551131..6c293bcc0e 100644 --- a/usr/src/cmd/zonestat/zonestatd/zonestatd.c +++ b/usr/src/cmd/zonestat/zonestatd/zonestatd.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. */ #include <alloca.h> #include <assert.h> @@ -2190,7 +2191,7 @@ zsd_get_zone_rctl_usage(char *name) return (rctlblk_get_value(rblk)); } -#define ZSD_NUM_RCTL_VALS 19 +#define ZSD_NUM_RCTL_VALS 20 /* * Fetch the limit information for a zone. This uses zone_enter() as the @@ -2237,12 +2238,6 @@ zsd_get_zone_caps(zsd_ctl_t *ctl, zsd_zone_t *zone, uint64_t *cpu_shares, *msgids = 0; *lofi = 0; - /* Get the ram cap first since it is a zone attr */ - ret = zone_getattr(zone->zsz_id, ZONE_ATTR_PHYS_MCAP, - ram_cap, sizeof (*ram_cap)); - if (ret < 0 || *ram_cap == 0) - *ram_cap = ZS_LIMIT_NONE; - /* Get the zone's default scheduling class */ ret = zone_getattr(zone->zsz_id, ZONE_ATTR_SCHED_CLASS, class, sizeof (class)); @@ -2298,6 +2293,7 @@ zsd_get_zone_caps(zsd_ctl_t *ctl, zsd_zone_t *zone, uint64_t *cpu_shares, vals[i++] = zsd_get_zone_rctl_usage("zone.max-msg-ids"); vals[i++] = zsd_get_zone_rctl_limit("zone.max-lofi"); vals[i++] = zsd_get_zone_rctl_usage("zone.max-lofi"); + vals[i++] = zsd_get_zone_rctl_usage("zone.max-physical-memory"); if (write(p[1], vals, ZSD_NUM_RCTL_VALS * sizeof (uint64_t)) != ZSD_NUM_RCTL_VALS * sizeof (uint64_t)) { @@ -2342,6 +2338,7 @@ zsd_get_zone_caps(zsd_ctl_t *ctl, zsd_zone_t *zone, uint64_t *cpu_shares, *msgids = vals[i++]; *lofi_cap = vals[i++]; *lofi = vals[i++]; + *ram_cap = vals[i++]; /* Interpret maximum values as no cap */ if (*cpu_cap == UINT32_MAX || *cpu_cap == 0) diff --git a/usr/src/cmd/zpool/zpool_main.c b/usr/src/cmd/zpool/zpool_main.c index 240e74f6da..a25fd97a74 100644 --- a/usr/src/cmd/zpool/zpool_main.c +++ b/usr/src/cmd/zpool/zpool_main.c @@ -24,6 +24,7 @@ * Copyright (c) 2011, 2018 by Delphix. All rights reserved. * Copyright (c) 2012 by Frederik Wessels. All rights reserved. * Copyright (c) 2013 by Prasad Joshi (sTec). All rights reserved. + * Copyright (c) 2013 Joyent, Inc. All rights reserved. * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>. * Copyright 2016 Nexenta Systems, Inc. * Copyright (c) 2017 Datto Inc. @@ -2422,6 +2423,8 @@ zpool_do_checkpoint(int argc, char **argv) * * -F Attempt rewind if necessary. * + * -m Allow import with a missing log device. + * * -n See if rewind would work, but don't actually rewind. * * -N Import the pool but don't mount datasets. |