aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-10-31 19:02:42 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-10-31 19:02:42 +0000
commit02ebdc78239c4e929e42896931a4f04526e04440 (patch)
treeb2635ce18a57392f126c5599b6baaf68c4b92575
parent5763f79695f9b1ffacce55a8594cb7be08c3f31c (diff)
parent130a08a362287342b83f8a78914db38a325145a3 (diff)
downloadsrc-02ebdc78239c4e929e42896931a4f04526e04440.tar.gz
src-02ebdc78239c4e929e42896931a4f04526e04440.zip
Merge ^/head r307736 through r308146.
Notes
Notes: svn path=/projects/clang390-import/; revision=308147
-rw-r--r--Makefile6
-rw-r--r--Makefile.inc120
-rw-r--r--UPDATING17
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h1
-rw-r--r--cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c22
-rwxr-xr-xcontrib/binutils/bfd/config.bfd2
-rw-r--r--contrib/bsnmp/lib/snmp.c2
-rw-r--r--contrib/elftoolchain/elfcopy/main.c26
-rw-r--r--contrib/elftoolchain/strings/strings.c27
-rw-r--r--contrib/gcc/config/rs6000/freebsdspe.h77
-rw-r--r--contrib/libarchive/NEWS3
-rw-r--r--contrib/libarchive/cat/test/main.c47
-rw-r--r--contrib/libarchive/cat/test/test.h9
-rw-r--r--contrib/libarchive/cpio/test/main.c31
-rw-r--r--contrib/libarchive/cpio/test/test.h4
-rw-r--r--contrib/libarchive/libarchive/archive.h4
-rw-r--r--contrib/libarchive/libarchive/archive_entry.h2
-rw-r--r--contrib/libarchive/libarchive/test/main.c31
-rw-r--r--contrib/libarchive/libarchive/test/test.h4
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c5
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_zip_high_compression.c10
-rw-r--r--contrib/libarchive/libarchive/test/test_read_set_format.c29
-rw-r--r--contrib/libarchive/libarchive/test/test_write_format_iso9660.c203
-rw-r--r--contrib/libarchive/tar/test/main.c4
-rw-r--r--contrib/libarchive/tar/test/test.h2
-rw-r--r--contrib/libarchive/tar/test/test_option_b.c2
-rw-r--r--contrib/libarchive/tar/test/test_symlink_dir.c2
-rw-r--r--contrib/llvm/projects/libunwind/include/libunwind.h4
-rw-r--r--contrib/llvm/projects/libunwind/src/AddressSpace.hpp2
-rw-r--r--contrib/llvm/projects/libunwind/src/CompactUnwinder.hpp8
-rw-r--r--contrib/llvm/projects/libunwind/src/EHHeaderParser.hpp2
-rw-r--r--contrib/llvm/projects/libunwind/src/Unwind-EHABI.cpp44
-rw-r--r--contrib/llvm/projects/libunwind/src/Unwind-sjlj.c68
-rw-r--r--contrib/llvm/projects/libunwind/src/UnwindCursor.hpp14
-rw-r--r--contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c44
-rw-r--r--contrib/llvm/projects/libunwind/src/UnwindLevel1.c76
-rw-r--r--contrib/llvm/projects/libunwind/src/config.h4
-rw-r--r--contrib/llvm/projects/libunwind/src/libunwind.cpp32
-rw-r--r--contrib/netbsd-tests/lib/libc/stdio/t_printf.c6
-rw-r--r--contrib/tzdata/asia80
-rw-r--r--contrib/tzdata/australasia8
-rw-r--r--contrib/tzdata/europe44
-rw-r--r--contrib/tzdata/northamerica28
-rwxr-xr-xcrypto/openssl/crypto/aes/asm/aesv8-armx.pl2
-rw-r--r--crypto/openssl/crypto/arm64cpuid.S1
-rwxr-xr-xcrypto/openssl/crypto/modes/asm/ghashv8-armx.pl2
-rw-r--r--etc/devd/usb.conf2
-rw-r--r--etc/mtree/BSD.root.dist2
-rw-r--r--etc/rc6
-rw-r--r--etc/rc.d/Makefile7
-rwxr-xr-xetc/rc.d/swaplate2
-rw-r--r--gnu/lib/libgcc/Makefile4
-rw-r--r--gnu/lib/libgomp/Makefile2
-rw-r--r--gnu/usr.bin/binutils/Makefile.inc06
-rw-r--r--gnu/usr.bin/binutils/ld/Makefile.mips2
-rw-r--r--gnu/usr.bin/binutils/libbfd/Makefile.mips2
-rw-r--r--gnu/usr.bin/cc/Makefile.inc2
-rw-r--r--gnu/usr.bin/cc/Makefile.tgt4
-rw-r--r--gnu/usr.bin/cc/cc_tools/Makefile.hdrs4
-rw-r--r--gnu/usr.bin/cc/include/Makefile3
-rw-r--r--gnu/usr.bin/gdb/Makefile.inc2
-rw-r--r--gnu/usr.bin/gdb/libgdb/Makefile2
-rw-r--r--include/limits.h2
-rw-r--r--include/stddef.h8
-rw-r--r--lib/libarchive/Makefile2
-rw-r--r--lib/libc/Makefile2
-rw-r--r--lib/libc/gen/sysctl.3242
-rw-r--r--lib/libc/mips/Makefile.inc2
-rw-r--r--lib/libc/mips/Symbol.map4
-rw-r--r--lib/libc/mips/gen/Makefile.inc2
-rw-r--r--lib/libc/mips/gen/flt_rounds.c20
-rw-r--r--lib/libc/powerpc/gen/Makefile.common6
-rw-r--r--lib/libc/powerpc/gen/Makefile.inc12
-rw-r--r--lib/libc/powerpcspe/Makefile.inc8
-rw-r--r--lib/libc/powerpcspe/gen/Makefile.inc7
-rw-r--r--lib/libc/powerpcspe/gen/_setjmp.S117
-rw-r--r--lib/libc/powerpcspe/gen/fabs.S38
-rw-r--r--lib/libc/powerpcspe/gen/flt_rounds.c57
-rw-r--r--lib/libc/powerpcspe/gen/fpgetmask.c49
-rw-r--r--lib/libc/powerpcspe/gen/fpgetround.c49
-rw-r--r--lib/libc/powerpcspe/gen/fpgetsticky.c55
-rw-r--r--lib/libc/powerpcspe/gen/fpsetmask.c53
-rw-r--r--lib/libc/powerpcspe/gen/fpsetround.c53
-rw-r--r--lib/libc/powerpcspe/gen/setjmp.S138
-rw-r--r--lib/libc/powerpcspe/gen/sigsetjmp.S150
-rw-r--r--lib/libc/powerpcspe/softfloat/milieu.h49
-rw-r--r--lib/libc/powerpcspe/softfloat/powerpc-gcc.h92
-rw-r--r--lib/libc/powerpcspe/softfloat/softfloat.h307
-rw-r--r--lib/libc/powerpcspe/sys/Makefile.inc4
-rw-r--r--lib/libc/stdio/printf-pos.c45
-rw-r--r--lib/libcapsicum/capsicum_helpers.37
-rw-r--r--lib/libcasper/services/cap_dns/Makefile3
-rw-r--r--lib/libcasper/services/cap_grp/Makefile3
-rw-r--r--lib/libcasper/services/cap_pwd/Makefile3
-rw-r--r--lib/libcasper/services/cap_sysctl/Makefile3
-rw-r--r--lib/libgcc_eh/Makefile.inc25
-rw-r--r--lib/libgcc_s/Makefile1
-rw-r--r--lib/libnetbsd/sys/cdefs.h2
-rw-r--r--lib/libnetbsd/util.c3
-rw-r--r--lib/libproc/proc_bkpt.c28
-rw-r--r--lib/librss/Makefile1
-rw-r--r--lib/librss/librss.36
-rw-r--r--lib/libstand/bootp.c12
-rw-r--r--lib/libsysdecode/flags.c2
-rw-r--r--lib/libusb/libusb20_ugen20.c4
-rw-r--r--lib/msun/mips/Makefile.inc4
-rw-r--r--lib/msun/mips/Symbol.map8
-rw-r--r--lib/msun/mips/fenv.c14
-rw-r--r--lib/msun/mips/fenv.h166
-rw-r--r--lib/msun/powerpc/fenv.h5
-rw-r--r--release/tools/arm.subr1
-rw-r--r--release/tools/vagrant-virtualbox.conf4
-rw-r--r--sbin/Makefile1
-rw-r--r--sbin/camcontrol/camcontrol.c120
-rw-r--r--sbin/geom/class/eli/geom_eli.c2
-rw-r--r--sbin/swapon/swapon.88
-rw-r--r--sbin/swapon/swapon.c4
-rw-r--r--sbin/zfsbootcfg/Makefile27
-rw-r--r--sbin/zfsbootcfg/zfsbootcfg.8112
-rw-r--r--sbin/zfsbootcfg/zfsbootcfg.c98
-rw-r--r--secure/lib/libcrypto/Makefile19
-rw-r--r--secure/lib/libcrypto/Makefile.asm39
-rw-r--r--secure/lib/libcrypto/Makefile.inc10
-rw-r--r--secure/lib/libcrypto/aarch64/aesv8-armx.S748
-rw-r--r--secure/lib/libcrypto/aarch64/ghashv8-armx.S228
-rw-r--r--secure/lib/libcrypto/aarch64/sha1-armv8.S1213
-rw-r--r--secure/lib/libcrypto/aarch64/sha256-armv8.S1143
-rw-r--r--secure/lib/libcrypto/aarch64/sha512-armv8.S1023
-rw-r--r--share/doc/psd/contents/contents.ms11
-rw-r--r--share/doc/psd/title/Title6
-rw-r--r--share/man/man4/chromebook_platform.468
-rw-r--r--share/man/man4/cyapa.429
-rw-r--r--share/man/man4/ig4.423
-rw-r--r--share/man/man4/isl.429
-rw-r--r--share/man/man4/jedec_ts.4130
-rw-r--r--share/man/man4/tcp.44
-rw-r--r--share/man/man4/ure.419
-rw-r--r--share/man/man7/arch.722
-rw-r--r--share/misc/pci_vendors88
-rw-r--r--share/mk/bsd.compiler.mk2
-rw-r--r--share/mk/bsd.cpu.mk9
-rw-r--r--share/mk/bsd.endian.mk3
-rw-r--r--share/mk/bsd.subdir.mk2
-rw-r--r--share/mk/local.meta.sys.mk2
-rw-r--r--share/mk/sys.mk4
-rw-r--r--sys/amd64/amd64/mem.c4
-rw-r--r--sys/amd64/amd64/sys_machdep.c5
-rw-r--r--sys/amd64/amd64/trap.c42
-rw-r--r--sys/amd64/include/pmap.h2
-rw-r--r--sys/amd64/include/smp.h3
-rw-r--r--sys/amd64/vmm/amd/svm.c9
-rw-r--r--sys/arm/allwinner/aw_cir.c535
-rw-r--r--sys/arm/allwinner/aw_nmi.c11
-rw-r--r--sys/arm/allwinner/aw_rsb.c105
-rw-r--r--sys/arm/allwinner/aw_thermal.c204
-rw-r--r--sys/arm/allwinner/clk/aw_pll.c51
-rw-r--r--sys/arm/allwinner/files.allwinner3
-rw-r--r--sys/arm/arm/cpufunc_asm_arm11x6.S8
-rw-r--r--sys/arm/arm/cpufunc_asm_armv7.S42
-rw-r--r--sys/arm/arm/gic.c7
-rw-r--r--sys/arm/conf/GENERIC13
-rw-r--r--sys/arm/include/cpu-v6.h73
-rw-r--r--sys/arm/include/cpufunc.h4
-rw-r--r--sys/arm/include/platformvar.h2
-rw-r--r--sys/arm/ti/am335x/am335x_dmtimer.c42
-rw-r--r--sys/arm/ti/ti_machdep.c2
-rw-r--r--sys/arm64/arm64/bcopy.c139
-rw-r--r--sys/arm64/arm64/gic_v3.c11
-rw-r--r--sys/arm64/arm64/memcpy.S219
-rw-r--r--sys/arm64/arm64/memmove.S150
-rw-r--r--sys/arm64/arm64/mp_machdep.c14
-rw-r--r--sys/arm64/arm64/trap.c2
-rw-r--r--sys/arm64/include/param.h2
-rw-r--r--sys/boot/Makefile.ficl43
-rw-r--r--sys/boot/common/Makefile.inc3
-rw-r--r--sys/boot/common/pnp.c4
-rw-r--r--sys/boot/efi/Makefile4
-rw-r--r--sys/boot/efi/Makefile.inc1
-rw-r--r--sys/boot/efi/libefi/Makefile11
-rw-r--r--sys/boot/efi/libefi/env.c179
-rw-r--r--sys/boot/efi/loader/main.c25
-rw-r--r--sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts4
-rw-r--r--sys/boot/ficl/Makefile45
-rw-r--r--sys/boot/ficl/efi.c207
-rw-r--r--sys/boot/ficl/loader.c3
-rw-r--r--sys/boot/ficl32/Makefile5
-rw-r--r--sys/boot/forth/Makefile.inc1
-rw-r--r--sys/boot/forth/efi.4th30
-rw-r--r--sys/boot/forth/loader.4th3
-rw-r--r--sys/boot/i386/Makefile.inc6
-rw-r--r--sys/boot/i386/common/drv.c4
-rw-r--r--sys/boot/i386/common/drv.h4
-rw-r--r--sys/boot/i386/gptboot/Makefile2
-rw-r--r--sys/boot/i386/gptzfsboot/Makefile4
-rw-r--r--sys/boot/i386/libi386/biospci.c4
-rw-r--r--sys/boot/i386/loader/Makefile4
-rw-r--r--sys/boot/i386/zfsboot/Makefile2
-rw-r--r--sys/boot/i386/zfsboot/zfsboot.c127
-rw-r--r--sys/boot/mips/uboot/Makefile2
-rw-r--r--sys/boot/powerpc/Makefile5
-rw-r--r--sys/boot/zfs/zfsimpl.c9
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c138
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c38
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c50
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c5
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c48
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c26
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h1
-rw-r--r--sys/conf/Makefile.powerpc4
-rw-r--r--sys/conf/NOTES7
-rw-r--r--sys/conf/files11
-rw-r--r--sys/conf/files.amd644
-rw-r--r--sys/conf/files.arm644
-rw-r--r--sys/conf/files.i3864
-rw-r--r--sys/conf/files.powerpc29
-rw-r--r--sys/conf/kern.mk8
-rw-r--r--sys/conf/ldscript.powerpcspe144
-rw-r--r--sys/conf/options.powerpc1
-rw-r--r--sys/contrib/rdma/krping/krping.c12
-rw-r--r--sys/dev/aacraid/aacraid_pci.c2
-rw-r--r--sys/dev/bfe/if_bfe.c2
-rw-r--r--sys/dev/bxe/bxe.c4
-rw-r--r--sys/dev/chromebook_platform/chromebook_platform.c102
-rw-r--r--sys/dev/cxgbe/common/t4_hw.c37
-rw-r--r--sys/dev/cxgbe/t4_sge.c33
-rw-r--r--sys/dev/cyapa/cyapa.c110
-rw-r--r--sys/dev/dpaa/bman_fdt.c2
-rw-r--r--sys/dev/dpaa/qman_fdt.c12
-rw-r--r--sys/dev/evdev/evdev.c15
-rw-r--r--sys/dev/evdev/evdev.h66
-rw-r--r--sys/dev/evdev/evdev_utils.c7
-rw-r--r--sys/dev/fdt/fdt_intr.h44
-rw-r--r--sys/dev/gpio/gpiobusvar.h1
-rw-r--r--sys/dev/gpio/ofw_gpiobus.c2
-rw-r--r--sys/dev/hwpmc/hwpmc_amd.c3
-rw-r--r--sys/dev/hyperv/netvsc/hn_nvs.c (renamed from sys/dev/hyperv/netvsc/hv_net_vsc.c)174
-rw-r--r--sys/dev/hyperv/netvsc/hn_nvs.h106
-rw-r--r--sys/dev/hyperv/netvsc/hn_rndis.c (renamed from sys/dev/hyperv/netvsc/hv_rndis_filter.c)549
-rw-r--r--sys/dev/hyperv/netvsc/hn_rndis.h (renamed from sys/dev/hyperv/netvsc/hv_rndis_filter.h)31
-rw-r--r--sys/dev/hyperv/netvsc/hv_net_vsc.h288
-rw-r--r--sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c1001
-rw-r--r--sys/dev/hyperv/netvsc/if_hnvar.h310
-rw-r--r--sys/dev/hyperv/netvsc/ndis.h12
-rw-r--r--sys/dev/hyperv/utilities/hv_heartbeat.c11
-rw-r--r--sys/dev/hyperv/utilities/hv_kvp.c70
-rw-r--r--sys/dev/hyperv/utilities/hv_kvp.h7
-rw-r--r--sys/dev/hyperv/utilities/hv_shutdown.c11
-rw-r--r--sys/dev/hyperv/utilities/hv_timesync.c11
-rw-r--r--sys/dev/hyperv/utilities/hv_util.c162
-rw-r--r--sys/dev/hyperv/utilities/hv_util.h5
-rw-r--r--sys/dev/hyperv/utilities/hv_utilreg.h12
-rw-r--r--sys/dev/hyperv/utilities/vmbus_icreg.h6
-rw-r--r--sys/dev/hyperv/vmbus/vmbus.c2
-rw-r--r--sys/dev/hyperv/vmbus/vmbus_chan.c136
-rw-r--r--sys/dev/ichiic/ig4_iic.c250
-rw-r--r--sys/dev/ichiic/ig4_pci.c9
-rw-r--r--sys/dev/ichiic/ig4_var.h5
-rw-r--r--sys/dev/iicbus/iicbus.c4
-rw-r--r--sys/dev/ioat/ioat.c39
-rw-r--r--sys/dev/ioat/ioat_internal.h9
-rw-r--r--sys/dev/isl/isl.c147
-rw-r--r--sys/dev/jedec_ts/jedec_ts.c179
-rw-r--r--sys/dev/mii/miidevs2
-rw-r--r--sys/dev/mii/rgephy.c12
-rw-r--r--sys/dev/mii/rgephyreg.h3
-rw-r--r--sys/dev/mlx4/mlx4_en/mlx4_en_tx.c15
-rw-r--r--sys/dev/netmap/if_em_netmap.h2
-rw-r--r--sys/dev/netmap/if_ptnet.c29
-rw-r--r--sys/dev/netmap/netmap.c21
-rw-r--r--sys/dev/netmap/netmap_freebsd.c110
-rw-r--r--sys/dev/netmap/netmap_kern.h11
-rw-r--r--sys/dev/netmap/netmap_mem2.c269
-rw-r--r--sys/dev/netmap/netmap_mem2.h4
-rw-r--r--sys/dev/netmap/netmap_pt.c53
-rw-r--r--sys/dev/netmap/netmap_vale.c2
-rw-r--r--sys/dev/psci/psci.c4
-rw-r--r--sys/dev/psci/psci.h4
-rw-r--r--sys/dev/re/if_re.c8
-rw-r--r--sys/dev/usb/input/ums.c68
-rw-r--r--sys/dev/usb/net/if_ure.c279
-rw-r--r--sys/dev/usb/net/if_urereg.h9
-rw-r--r--sys/dev/usb/net/uhso.c2
-rw-r--r--sys/dev/usb/usb_device.c9
-rw-r--r--sys/dev/xen/gntdev/gntdev.c1275
-rw-r--r--sys/dev/xen/netfront/netfront.c38
-rw-r--r--sys/fs/cd9660/cd9660_vnops.c42
-rw-r--r--sys/fs/msdosfs/msdosfs_fat.c63
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c5
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c46
-rw-r--r--sys/geom/eli/g_eli.h12
-rw-r--r--sys/geom/eli/g_eli_integrity.c5
-rw-r--r--sys/i386/i386/initcpu.c20
-rw-r--r--sys/i386/i386/mem.c9
-rw-r--r--sys/i386/i386/pmap.c32
-rw-r--r--sys/i386/i386/trap.c42
-rw-r--r--sys/kern/subr_prf.c4
-rw-r--r--sys/kern/subr_smp.c53
-rw-r--r--sys/kern/subr_turnstile.c7
-rw-r--r--sys/kern/subr_uio.c2
-rw-r--r--sys/kern/subr_witness.c4
-rw-r--r--sys/kern/uipc_syscalls.c13
-rw-r--r--sys/kern/vfs_bio.c160
-rw-r--r--sys/kern/vfs_syscalls.c18
-rw-r--r--sys/mips/include/float.h4
-rw-r--r--sys/mips/include/signal.h4
-rw-r--r--sys/mips/mips/exception.S6
-rw-r--r--sys/mips/mips/locore.S2
-rw-r--r--sys/mips/mips/swtch.S16
-rw-r--r--sys/mips/mips/trap.c9
-rw-r--r--sys/modules/Makefile10
-rw-r--r--sys/modules/chromebook_platform/Makefile7
-rw-r--r--sys/modules/geom/Makefile6
-rw-r--r--sys/modules/hyperv/netvsc/Makefile4
-rw-r--r--sys/modules/i2c/Makefile2
-rw-r--r--sys/modules/i2c/controllers/ichiic/Makefile2
-rw-r--r--sys/modules/i2c/cyapa/Makefile2
-rw-r--r--sys/modules/i2c/isl/Makefile2
-rw-r--r--sys/modules/i2c/jedec_ts/Makefile7
-rw-r--r--sys/net/if_bridge.c2
-rw-r--r--sys/net/netmap.h26
-rw-r--r--sys/net/netmap_virt.h173
-rw-r--r--sys/net/rndis.h11
-rw-r--r--sys/net80211/ieee80211.h4
-rw-r--r--sys/net80211/ieee80211_freebsd.c15
-rw-r--r--sys/net80211/ieee80211_freebsd.h1
-rw-r--r--sys/net80211/ieee80211_scan.c3
-rw-r--r--sys/net80211/ieee80211_scan_sw.c5
-rw-r--r--sys/netinet/cc/cc_cdg.c15
-rw-r--r--sys/netinet/cc/cc_chd.c8
-rw-r--r--sys/netinet/cc/cc_cubic.c15
-rw-r--r--sys/netinet/cc/cc_dctcp.c19
-rw-r--r--sys/netinet/cc/cc_htcp.c11
-rw-r--r--sys/netinet/cc/cc_newreno.c23
-rw-r--r--sys/netinet/ip_output.c7
-rw-r--r--sys/netinet/sctp_bsd_addr.c3
-rw-r--r--sys/netinet/sctp_output.c247
-rw-r--r--sys/netinet/tcp_input.c34
-rw-r--r--sys/netinet/tcp_stacks/fastpath.c22
-rw-r--r--sys/netinet/tcp_syncache.c4
-rw-r--r--sys/powerpc/booke/booke_machdep.c5
-rw-r--r--sys/powerpc/booke/spe.c183
-rw-r--r--sys/powerpc/conf/MPC85XX7
-rw-r--r--sys/powerpc/conf/MPC85XXSPE107
-rw-r--r--sys/powerpc/include/cpu.h6
-rw-r--r--sys/powerpc/include/param.h4
-rw-r--r--sys/powerpc/include/spr.h1
-rw-r--r--sys/powerpc/include/trap.h1
-rw-r--r--sys/powerpc/powerpc/cpu.c7
-rw-r--r--sys/powerpc/powerpc/trap.c39
-rw-r--r--sys/sys/_types.h5
-rw-r--r--sys/sys/buf.h7
-rw-r--r--sys/ufs/ffs/ffs_tables.c1
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c22
-rw-r--r--sys/ufs/ffs/ffs_vnops.c166
-rw-r--r--sys/ufs/ufs/ufs_vnops.c59
-rw-r--r--sys/vm/device_pager.c5
-rw-r--r--sys/vm/vm_fault.c72
-rw-r--r--sys/vm/vm_pager.h1
-rw-r--r--sys/x86/cpufreq/hwpstate.c16
-rw-r--r--sys/x86/include/x86_smp.h3
-rw-r--r--sys/x86/include/x86_var.h18
-rw-r--r--sys/x86/x86/cpu_machdep.c53
-rw-r--r--sys/x86/x86/mp_x86.c37
-rw-r--r--sys/x86/xen/xen_intr.c41
-rw-r--r--sys/xen/gntdev.h192
-rw-r--r--sys/xen/xen_intr.h12
-rw-r--r--tests/sys/geom/class/uzip/Makefile4
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc9
-rw-r--r--usr.bin/bsdcat/Makefile2
-rw-r--r--usr.bin/cpio/Makefile2
-rw-r--r--usr.bin/tar/Makefile2
-rw-r--r--usr.sbin/Makefile2
-rw-r--r--usr.sbin/Makefile.powerpc2
-rw-r--r--usr.sbin/amd/Makefile.inc4
-rw-r--r--usr.sbin/amd/amd/Makefile4
-rw-r--r--usr.sbin/amd/libamu/Makefile2
-rw-r--r--usr.sbin/bhyve/dbgport.c2
-rw-r--r--usr.sbin/bhyve/vga.c8
-rw-r--r--usr.sbin/config/Makefile9
-rw-r--r--usr.sbin/cron/cron/cron.88
-rw-r--r--usr.sbin/cron/cron/cron.h2
-rw-r--r--usr.sbin/cron/cron/database.c46
-rw-r--r--usr.sbin/cron/cron/pathnames.h2
-rw-r--r--usr.sbin/cron/lib/misc.c6
-rw-r--r--usr.sbin/ctld/ctld.c4
-rw-r--r--usr.sbin/daemon/daemon.878
-rw-r--r--usr.sbin/daemon/daemon.c480
-rw-r--r--usr.sbin/makefs/Makefile20
-rw-r--r--usr.sbin/makefs/cd9660.c5
-rw-r--r--usr.sbin/makefs/cd9660/Makefile.inc4
-rw-r--r--usr.sbin/makefs/cd9660/cd9660_archimedes.c2
-rw-r--r--usr.sbin/makefs/cd9660/iso9660_rrip.c12
-rw-r--r--usr.sbin/makefs/ffs/Makefile.inc4
-rw-r--r--usr.sbin/makefs/ffs/ffs_bswap.c9
-rw-r--r--usr.sbin/makefs/ffs/ffs_subr.c1
-rw-r--r--usr.sbin/makefs/mtree.c5
-rw-r--r--usr.sbin/makefs/walk.c1
-rw-r--r--usr.sbin/mountd/mountd.84
-rw-r--r--usr.sbin/mountd/mountd.c2
-rw-r--r--usr.sbin/pw/grupd.c3
-rw-r--r--usr.sbin/pw/pw_nis.c3
-rw-r--r--usr.sbin/pw/pwupd.c2
-rw-r--r--usr.sbin/tzsetup/Makefile8
-rw-r--r--usr.sbin/tzsetup/tzsetup.c154
-rw-r--r--usr.sbin/watchdogd/watchdogd.c7
406 files changed, 16364 insertions, 4333 deletions
diff --git a/Makefile b/Makefile
index 00dbc23bb79c..5904a3f967e3 100644
--- a/Makefile
+++ b/Makefile
@@ -239,7 +239,7 @@ _MAKE+= MK_META_MODE=no
_TARGET_ARCH= ${TARGET:S/pc98/i386/:S/arm64/aarch64/}
.elif !defined(TARGET) && defined(TARGET_ARCH) && \
${TARGET_ARCH} != ${MACHINE_ARCH}
-_TARGET= ${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/riscv64/riscv/}
+_TARGET= ${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/powerpcspe/powerpc/:C/riscv64/riscv/}
.endif
.if defined(TARGET) && !defined(_TARGET)
_TARGET=${TARGET}
@@ -421,8 +421,8 @@ TARGETS?=amd64 arm arm64 i386 mips pc98 powerpc sparc64
_UNIVERSE_TARGETS= ${TARGETS}
TARGET_ARCHES_arm?= arm armeb armv6
TARGET_ARCHES_arm64?= aarch64
-TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32
-TARGET_ARCHES_powerpc?= powerpc powerpc64
+TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipselhf mipshf mips64elhf mips64hf
+TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe
TARGET_ARCHES_pc98?= i386
.for target in ${TARGETS}
TARGET_ARCHES_${target}?= ${target}
diff --git a/Makefile.inc1 b/Makefile.inc1
index f31febdbd4f5..dc6c721caf60 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -356,8 +356,13 @@ KNOWN_ARCHES?= aarch64/arm64 \
mipsn32el/mips \
mips64/mips \
mipsn32/mips \
+ mipshf/mips \
+ mipselhf/mips \
+ mips64elhf/mips \
+ mips64hf/mips \
powerpc \
powerpc64/powerpc \
+ powerpcspe/powerpc \
riscv64/riscv \
sparc64
@@ -452,7 +457,7 @@ PACKAGE= kernel
#
BOOTSTRAPPING?= 0
-# Keep these in sync
+# Keep these in sync -- see below for special case exception
MINIMUM_SUPPORTED_OSREL?= 900044
MINIMUM_SUPPORTED_REL?= 9.1
@@ -1556,10 +1561,23 @@ _elftoolchain_libs= lib/libelf lib/libdwarf
.endif
legacy: .PHONY
+# Temporary special case for automatically detecting the clang compiler issue
+# Note: 9.x didn't have FreeBSD_version bumps often enough, so you may need to
+# set BOOTSTRAPPING to 0 if you're stable/9 tree post-dates r286035 but is before
+# the version bump in r296219 (from July 29, 2015 -> Feb 29, 2016).
+.if ${BOOTSTRAPPING} != 0 && \
+ ${WANT_COMPILER_TYPE} == "clang" && ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} < 30601
+.if ${BOOTSTRAPPING} > 10000000 && ${BOOTSTRAPPING} < 1002501
+ @echo "ERROR: Source upgrades from stable/10 prior to r286033 are not supported."; false
+.elif ${BOOTSTRAPPING} > 9000000 && ${BOOTSTRAPPING} < 903509
+ @echo "ERROR: Source upgrades from stable/9 prior to r286035 are not supported."; false
+.endif
+.endif
.if ${BOOTSTRAPPING} < ${MINIMUM_SUPPORTED_OSREL} && ${BOOTSTRAPPING} != 0
@echo "ERROR: Source upgrades from versions prior to ${MINIMUM_SUPPORTED_REL} are not supported."; \
false
.endif
+
.for _tool in tools/build ${_elftoolchain_libs}
${_+_}@${ECHODIR} "===> ${_tool} (obj,includes,all,install)"; \
cd ${.CURDIR}/${_tool}; \
diff --git a/UPDATING b/UPDATING
index 20a82940a5c8..fb869480ebc9 100644
--- a/UPDATING
+++ b/UPDATING
@@ -41,13 +41,22 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
11.0-RELEASE). These revisions post-date the 10.2 and 9.3 releases, so
you'll need to take the unusual step of upgrading to the tip of the
stable branch before moving to 11 or -current via a source upgrade.
- stable/11 and 11.0-RELEASE post-date the fix so you can move from them
- to -current. This differs from the historical situation where one could
- upgrade from anywhere on the last couple of stable branches, so be
- careful.
+ stable/11 and 11.0-RELEASE have working newer compiler. This differs
+ from the historical situation where one could upgrade from anywhere on
+ the last couple of stable branches, so be careful.
+
+ If you're running a hybrid system on 9.x or 10.x with an updated clang
+ compiler or are using an supported external toolchain, the build system
+ will allow the upgrade. Otherwise it will print a reminder.
****************************** SPECIAL WARNING: ******************************
+20161030:
+ isl(4) and cyapa(4) drivers now require a new driver,
+ chromebook_platform(4), to work properly on Chromebook-class hardware.
+ On other types of hardware the drivers may need to be configured using
+ device hints. Please see the corresponding manual pages for details.
+
20161017:
The urtwn(4) driver was merged into rtwn(4) and now consists of
rtwn(4) main module + rtwn_usb(4) and rtwn_pci(4) bus-specific
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
index c84124ea3af6..1aa64aab462a 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
@@ -213,6 +213,7 @@ extern int zpool_get_state(zpool_handle_t *);
extern const char *zpool_state_to_name(vdev_state_t, vdev_aux_t);
extern const char *zpool_pool_state_to_name(pool_state_t);
extern void zpool_free_handles(libzfs_handle_t *);
+extern int zpool_nextboot(libzfs_handle_t *, uint64_t, uint64_t, const char *);
/*
* Iterate over all active pools in the system.
diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
index 035f028fa968..face63086888 100644
--- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
+++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
@@ -4126,3 +4126,25 @@ out:
libzfs_fini(hdl);
return (ret);
}
+
+int
+zpool_nextboot(libzfs_handle_t *hdl, uint64_t pool_guid, uint64_t dev_guid,
+ const char *command)
+{
+ zfs_cmd_t zc = { 0 };
+ nvlist_t *args;
+ char *packed;
+ size_t size;
+ int error;
+
+ args = fnvlist_alloc();
+ fnvlist_add_uint64(args, ZPOOL_CONFIG_POOL_GUID, pool_guid);
+ fnvlist_add_uint64(args, ZPOOL_CONFIG_GUID, dev_guid);
+ fnvlist_add_string(args, "command", command);
+ error = zcmd_write_src_nvlist(hdl, &zc, args);
+ if (error == 0)
+ error = ioctl(hdl->libzfs_fd, ZFS_IOC_NEXTBOOT, &zc);
+ zcmd_free_nvlists(&zc);
+ nvlist_free(args);
+ return (error);
+}
diff --git a/contrib/binutils/bfd/config.bfd b/contrib/binutils/bfd/config.bfd
index 6b108c0b8fdb..1365ac12f8a5 100755
--- a/contrib/binutils/bfd/config.bfd
+++ b/contrib/binutils/bfd/config.bfd
@@ -1103,7 +1103,7 @@ case "${targ}" in
want64=true
;;
#endif
- powerpc-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | \
+ powerpc-*-*bsd* | powerpcspe-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | \
powerpc-*-solaris2* | powerpc-*-linux-* | powerpc-*-rtems* | \
powerpc-*-chorus*)
targ_defvec=bfd_elf32_powerpc_vec
diff --git a/contrib/bsnmp/lib/snmp.c b/contrib/bsnmp/lib/snmp.c
index 6b9e3e87aaaa..a91be77e081c 100644
--- a/contrib/bsnmp/lib/snmp.c
+++ b/contrib/bsnmp/lib/snmp.c
@@ -288,7 +288,7 @@ parse_secparams(struct asn_buf *b, struct snmp_pdu *pdu)
memset(buf, 0, 256);
tb.asn_ptr = buf;
tb.asn_len = 256;
- u_int len;
+ u_int len = 256;
if (asn_get_octetstring(b, buf, &len) != ASN_ERR_OK) {
snmp_error("cannot parse usm header");
diff --git a/contrib/elftoolchain/elfcopy/main.c b/contrib/elftoolchain/elfcopy/main.c
index ebc0c92a1c01..1917c646c887 100644
--- a/contrib/elftoolchain/elfcopy/main.c
+++ b/contrib/elftoolchain/elfcopy/main.c
@@ -1529,6 +1529,22 @@ print_version(void)
exit(EXIT_SUCCESS);
}
+/*
+ * Compare the ending of s with end.
+ */
+static int
+strrcmp(const char *s, const char *end)
+{
+ size_t endlen, slen;
+
+ slen = strlen(s);
+ endlen = strlen(end);
+
+ if (slen >= endlen)
+ s += slen - endlen;
+ return (strcmp(s, end));
+}
+
int
main(int argc, char **argv)
{
@@ -1562,12 +1578,16 @@ main(int argc, char **argv)
if ((ecp->progname = ELFTC_GETPROGNAME()) == NULL)
ecp->progname = "elfcopy";
- if (strcmp(ecp->progname, "strip") == 0)
+ if (strrcmp(ecp->progname, "strip") == 0)
strip_main(ecp, argc, argv);
- else if (strcmp(ecp->progname, "mcs") == 0)
+ else if (strrcmp(ecp->progname, "mcs") == 0)
mcs_main(ecp, argc, argv);
- else
+ else {
+ if (strrcmp(ecp->progname, "elfcopy") != 0 &&
+ strrcmp(ecp->progname, "objcopy") != 0)
+ warnx("program mode not known, defaulting to elfcopy");
elfcopy_main(ecp, argc, argv);
+ }
free_sec_add(ecp);
free_sec_act(ecp);
diff --git a/contrib/elftoolchain/strings/strings.c b/contrib/elftoolchain/strings/strings.c
index 8de29ca7d25b..a936b6be1bbb 100644
--- a/contrib/elftoolchain/strings/strings.c
+++ b/contrib/elftoolchain/strings/strings.c
@@ -48,12 +48,6 @@
ELFTC_VCSID("$Id: strings.c 3446 2016-05-03 01:31:17Z emaste $");
-enum return_code {
- RETURN_OK,
- RETURN_NOINPUT,
- RETURN_SOFTWARE
-};
-
enum radix_style {
RADIX_DECIMAL,
RADIX_HEX,
@@ -107,7 +101,7 @@ main(int argc, char **argv)
{
int ch, rc;
- rc = RETURN_OK;
+ rc = 0;
min_len = 0;
encoding_size = 1;
if (elf_version(EV_CURRENT) == EV_NONE)
@@ -197,7 +191,8 @@ main(int argc, char **argv)
if (!*argv)
rc = handle_file("{standard input}");
else while (*argv) {
- rc = handle_file(*argv);
+ if (handle_file(*argv) != 0)
+ rc = 1;
argv++;
}
return (rc);
@@ -209,11 +204,11 @@ handle_file(const char *name)
int fd, rt;
if (name == NULL)
- return (RETURN_NOINPUT);
+ return (1);
if (strcmp("{standard input}", name) != 0) {
if (freopen(name, "rb", stdin) == NULL) {
warnx("'%s': %s", name, strerror(errno));
- return (RETURN_NOINPUT);
+ return (1);
}
} else {
return (find_strings(name, (off_t)0, (off_t)0));
@@ -221,7 +216,7 @@ handle_file(const char *name)
fd = fileno(stdin);
if (fd < 0)
- return (RETURN_NOINPUT);
+ return (1);
rt = handle_elf(name, fd);
return (rt);
}
@@ -239,7 +234,7 @@ handle_binary(const char *name, int fd)
(void) lseek(fd, (off_t)0, SEEK_SET);
if (!fstat(fd, &buf))
return (find_strings(name, (off_t)0, buf.st_size));
- return (RETURN_SOFTWARE);
+ return (1);
}
/*
@@ -257,7 +252,7 @@ handle_elf(const char *name, int fd)
Elf_Scn *scn;
int rc;
- rc = RETURN_OK;
+ rc = 0;
/* If entire file is chosen, treat it as a binary file */
if (entire_file)
return (handle_binary(name, fd));
@@ -272,7 +267,7 @@ handle_elf(const char *name, int fd)
if (gelf_getehdr(elf, &elfhdr) == NULL) {
(void) elf_end(elf);
warnx("%s: ELF file could not be processed", name);
- return (RETURN_SOFTWARE);
+ return (1);
}
if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) {
@@ -352,7 +347,7 @@ find_strings(const char *name, off_t offset, off_t size)
if ((obuf = (char*)calloc(1, min_len + 1)) == NULL) {
(void) fprintf(stderr, "Unable to allocate memory: %s\n",
strerror(errno));
- return (RETURN_SOFTWARE);
+ return (1);
}
(void) fseeko(stdin, offset, SEEK_SET);
@@ -426,7 +421,7 @@ find_strings(const char *name, off_t offset, off_t size)
}
_exit1:
free(obuf);
- return (RETURN_OK);
+ return (0);
}
#define USAGE_MESSAGE "\
diff --git a/contrib/gcc/config/rs6000/freebsdspe.h b/contrib/gcc/config/rs6000/freebsdspe.h
new file mode 100644
index 000000000000..9c960298f6ef
--- /dev/null
+++ b/contrib/gcc/config/rs6000/freebsdspe.h
@@ -0,0 +1,77 @@
+/* Definitions of target machine for GNU compiler,
+ for PowerPC e500 machines running FreeBSD.
+ Based on linuxspe.h
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Contributed by Aldy Hernandez (aldy@quesejoda.com).
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to the
+ Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+ MA 02110-1301, USA. */
+
+#undef TARGET_VERSION
+#define TARGET_VERSION fprintf (stderr, " (PowerPC E500 FreeBSD)");
+
+/* Override rs6000.h and sysv4.h definition. */
+#undef TARGET_DEFAULT
+#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN)
+
+#undef TARGET_SPE_ABI
+#undef TARGET_SPE
+#undef TARGET_E500
+#undef TARGET_ISEL
+#undef TARGET_FPRS
+#undef TARGET_E500_SINGLE
+#undef TARGET_E500_DOUBLE
+
+#define TARGET_SPE_ABI rs6000_spe_abi
+#define TARGET_SPE rs6000_spe
+#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540)
+#define TARGET_ISEL rs6000_isel
+#define TARGET_FPRS (rs6000_float_gprs == 0)
+#define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1)
+#define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2)
+
+#undef SUBSUBTARGET_OVERRIDE_OPTIONS
+#define SUBSUBTARGET_OVERRIDE_OPTIONS \
+ if (rs6000_select[1].string == NULL) \
+ rs6000_cpu = PROCESSOR_PPC8540; \
+ if (!rs6000_explicit_options.abi) \
+ rs6000_spe_abi = 1; \
+ if (!rs6000_explicit_options.float_gprs) \
+ rs6000_float_gprs = 1; \
+ /* See note below. */ \
+ /*if (!rs6000_explicit_options.long_double)*/ \
+ /* rs6000_long_double_type_size = 128;*/ \
+ if (!rs6000_explicit_options.spe) \
+ rs6000_spe = 1; \
+ if (!rs6000_explicit_options.isel) \
+ rs6000_isel = 1; \
+ if (target_flags & MASK_64BIT) \
+ error ("-m64 not supported in this configuration")
+
+/* The e500 ABI says that either long doubles are 128 bits, or if
+ implemented in any other size, the compiler/linker should error out.
+ We have no emulation libraries for 128 bit long doubles, and I hate
+ the dozens of failures on the regression suite. So I'm breaking ABI
+ specifications, until I properly fix the emulation.
+
+ Enable these later.
+#undef CPP_LONGDOUBLE_DEFAULT_SPEC
+#define CPP_LONGDOUBLE_DEFAULT_SPEC "-D__LONG_DOUBLE_128__=1"
+*/
+
+#undef ASM_DEFAULT_SPEC
+#define ASM_DEFAULT_SPEC "-mppc -mspe -me500"
diff --git a/contrib/libarchive/NEWS b/contrib/libarchive/NEWS
index f672d3dfe3cb..dd4cfd59fb0c 100644
--- a/contrib/libarchive/NEWS
+++ b/contrib/libarchive/NEWS
@@ -1,3 +1,6 @@
+Oct 23, 2016: libarchive 3.2.2 released
+ Security release
+
Jun 20, 2016: libarchive 3.2.1 released
This fixes a handful of security and other critical issues with 3.2.0
diff --git a/contrib/libarchive/cat/test/main.c b/contrib/libarchive/cat/test/main.c
index 29f7b14b1849..a57984294fe4 100644
--- a/contrib/libarchive/cat/test/main.c
+++ b/contrib/libarchive/cat/test/main.c
@@ -129,6 +129,13 @@
# include <crtdbg.h>
#endif
+mode_t umasked(mode_t expected_mode)
+{
+ mode_t mode = umask(0);
+ umask(mode);
+ return expected_mode & ~mode;
+}
+
/* Path to working directory for current test */
const char *testworkdir;
#ifdef PROGRAM
@@ -1156,6 +1163,35 @@ assertion_file_contains_lines_any_order(const char *file, int line,
return (0);
}
+/* Verify that a text file does not contains the specified strings */
+int
+assertion_file_contains_no_invalid_strings(const char *file, int line,
+ const char *pathname, const char *strings[])
+{
+ char *buff;
+ int i;
+
+ buff = slurpfile(NULL, "%s", pathname);
+ if (buff == NULL) {
+ failure_start(file, line, "Can't read file: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ for (i = 0; strings[i] != NULL; ++i) {
+ if (strstr(buff, strings[i]) != NULL) {
+ failure_start(file, line, "Invalid string in %s: %s", pathname,
+ strings[i]);
+ failure_finish(NULL);
+ free(buff);
+ return(0);
+ }
+ }
+
+ free(buff);
+ return (0);
+}
+
/* Test that two paths point to the same file. */
/* As a side-effect, asserts that both files exist. */
static int
@@ -1293,6 +1329,11 @@ assertion_file_time(const char *file, int line,
switch (type) {
case 'a': filet_nsec = st.st_atimespec.tv_nsec; break;
case 'b': filet = st.st_birthtime;
+ /* FreeBSD filesystems that don't support birthtime
+ * (e.g., UFS1) always return -1 here. */
+ if (filet == -1) {
+ return (1);
+ }
filet_nsec = st.st_birthtimespec.tv_nsec; break;
case 'm': filet_nsec = st.st_mtimespec.tv_nsec; break;
default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type);
@@ -1370,6 +1411,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect
assertion_count(file, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
failure_start(file, line, "assertFileMode not yet implemented for Windows");
+ (void)mode; /* UNUSED */
+ (void)r; /* UNUSED */
#else
{
struct stat st;
@@ -1424,7 +1467,7 @@ assertion_file_nlinks(const char *file, int line,
assertion_count(file, line);
r = lstat(pathname, &st);
if (r == 0 && (int)st.st_nlink == nlinks)
- return (1);
+ return (1);
failure_start(file, line, "File %s has %d links, expected %d",
pathname, st.st_nlink, nlinks);
failure_finish(NULL);
@@ -1660,6 +1703,7 @@ assertion_make_file(const char *file, int line,
if (0 != chmod(path, mode)) {
failure_start(file, line, "Could not chmod %s", path);
failure_finish(NULL);
+ close(fd);
return (0);
}
if (contents != NULL) {
@@ -1674,6 +1718,7 @@ assertion_make_file(const char *file, int line,
failure_start(file, line,
"Could not write to %s", path);
failure_finish(NULL);
+ close(fd);
return (0);
}
}
diff --git a/contrib/libarchive/cat/test/test.h b/contrib/libarchive/cat/test/test.h
index 1d219647560f..c002a2c27eee 100644
--- a/contrib/libarchive/cat/test/test.h
+++ b/contrib/libarchive/cat/test/test.h
@@ -174,6 +174,9 @@
/* Assert that file contents match a string. */
#define assertFileContents(data, data_size, pathname) \
assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
+/* Verify that a file does not contain invalid strings */
+#define assertFileContainsNoInvalidStrings(pathname, strings) \
+ assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
@@ -182,6 +185,8 @@
assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks)
#define assertFileSize(pathname, size) \
assertion_file_size(__FILE__, __LINE__, pathname, size)
+#define assertFileMode(pathname, mode) \
+ assertion_file_mode(__FILE__, __LINE__, pathname, mode)
#define assertTextFileContents(text, pathname) \
assertion_text_file_contents(__FILE__, __LINE__, text, pathname)
#define assertFileContainsLinesAnyOrder(pathname, lines) \
@@ -239,6 +244,7 @@ int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
+int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
int assertion_file_contents(const char *, int, const void *, int, const char *);
int assertion_file_exists(const char *, int, const char *);
int assertion_file_mode(const char *, int, const char *, int);
@@ -327,6 +333,9 @@ void copy_reference_file(const char *);
*/
void extract_reference_files(const char **);
+/* Subtract umask from mode */
+mode_t umasked(mode_t expected_mode);
+
/* Path to working directory for current test */
extern const char *testworkdir;
diff --git a/contrib/libarchive/cpio/test/main.c b/contrib/libarchive/cpio/test/main.c
index 77bf60613c1d..d6842f53e99d 100644
--- a/contrib/libarchive/cpio/test/main.c
+++ b/contrib/libarchive/cpio/test/main.c
@@ -1164,6 +1164,35 @@ assertion_file_contains_lines_any_order(const char *file, int line,
return (0);
}
+/* Verify that a text file does not contains the specified strings */
+int
+assertion_file_contains_no_invalid_strings(const char *file, int line,
+ const char *pathname, const char *strings[])
+{
+ char *buff;
+ int i;
+
+ buff = slurpfile(NULL, "%s", pathname);
+ if (buff == NULL) {
+ failure_start(file, line, "Can't read file: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ for (i = 0; strings[i] != NULL; ++i) {
+ if (strstr(buff, strings[i]) != NULL) {
+ failure_start(file, line, "Invalid string in %s: %s", pathname,
+ strings[i]);
+ failure_finish(NULL);
+ free(buff);
+ return(0);
+ }
+ }
+
+ free(buff);
+ return (0);
+}
+
/* Test that two paths point to the same file. */
/* As a side-effect, asserts that both files exist. */
static int
@@ -1383,6 +1412,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect
assertion_count(file, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
failure_start(file, line, "assertFileMode not yet implemented for Windows");
+ (void)mode; /* UNUSED */
+ (void)r; /* UNUSED */
#else
{
struct stat st;
diff --git a/contrib/libarchive/cpio/test/test.h b/contrib/libarchive/cpio/test/test.h
index e42840083db5..c002a2c27eee 100644
--- a/contrib/libarchive/cpio/test/test.h
+++ b/contrib/libarchive/cpio/test/test.h
@@ -174,6 +174,9 @@
/* Assert that file contents match a string. */
#define assertFileContents(data, data_size, pathname) \
assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
+/* Verify that a file does not contain invalid strings */
+#define assertFileContainsNoInvalidStrings(pathname, strings) \
+ assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
@@ -241,6 +244,7 @@ int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
+int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
int assertion_file_contents(const char *, int, const void *, int, const char *);
int assertion_file_exists(const char *, int, const char *);
int assertion_file_mode(const char *, int, const char *, int);
diff --git a/contrib/libarchive/libarchive/archive.h b/contrib/libarchive/libarchive/archive.h
index 013eee8c04db..18462bb8e579 100644
--- a/contrib/libarchive/libarchive/archive.h
+++ b/contrib/libarchive/libarchive/archive.h
@@ -36,7 +36,7 @@
* assert that ARCHIVE_VERSION_NUMBER >= 2012108.
*/
/* Note: Compiler will complain if this does not match archive_entry.h! */
-#define ARCHIVE_VERSION_NUMBER 3002001
+#define ARCHIVE_VERSION_NUMBER 3002002
#include <sys/stat.h>
#include <stddef.h> /* for wchar_t */
@@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_ONLY_STRING "3.2.1"
+#define ARCHIVE_VERSION_ONLY_STRING "3.2.2"
#define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING
__LA_DECL const char * archive_version_string(void);
diff --git a/contrib/libarchive/libarchive/archive_entry.h b/contrib/libarchive/libarchive/archive_entry.h
index 3a90ac72fec6..115088969f37 100644
--- a/contrib/libarchive/libarchive/archive_entry.h
+++ b/contrib/libarchive/libarchive/archive_entry.h
@@ -29,7 +29,7 @@
#define ARCHIVE_ENTRY_H_INCLUDED
/* Note: Compiler will complain if this does not match archive.h! */
-#define ARCHIVE_VERSION_NUMBER 3002001
+#define ARCHIVE_VERSION_NUMBER 3002002
/*
* Note: archive_entry.h is for use outside of libarchive; the
diff --git a/contrib/libarchive/libarchive/test/main.c b/contrib/libarchive/libarchive/test/main.c
index cb3810e548c3..304c7f6c28b3 100644
--- a/contrib/libarchive/libarchive/test/main.c
+++ b/contrib/libarchive/libarchive/test/main.c
@@ -1162,6 +1162,35 @@ assertion_file_contains_lines_any_order(const char *file, int line,
return (0);
}
+/* Verify that a text file does not contains the specified strings */
+int
+assertion_file_contains_no_invalid_strings(const char *file, int line,
+ const char *pathname, const char *strings[])
+{
+ char *buff;
+ int i;
+
+ buff = slurpfile(NULL, "%s", pathname);
+ if (buff == NULL) {
+ failure_start(file, line, "Can't read file: %s", pathname);
+ failure_finish(NULL);
+ return (0);
+ }
+
+ for (i = 0; strings[i] != NULL; ++i) {
+ if (strstr(buff, strings[i]) != NULL) {
+ failure_start(file, line, "Invalid string in %s: %s", pathname,
+ strings[i]);
+ failure_finish(NULL);
+ free(buff);
+ return(0);
+ }
+ }
+
+ free(buff);
+ return (0);
+}
+
/* Test that two paths point to the same file. */
/* As a side-effect, asserts that both files exist. */
static int
@@ -1381,6 +1410,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect
assertion_count(file, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
failure_start(file, line, "assertFileMode not yet implemented for Windows");
+ (void)mode; /* UNUSED */
+ (void)r; /* UNUSED */
#else
{
struct stat st;
diff --git a/contrib/libarchive/libarchive/test/test.h b/contrib/libarchive/libarchive/test/test.h
index 6b61778c4a35..f7ec59f57b6d 100644
--- a/contrib/libarchive/libarchive/test/test.h
+++ b/contrib/libarchive/libarchive/test/test.h
@@ -174,6 +174,9 @@
/* Assert that file contents match a string. */
#define assertFileContents(data, data_size, pathname) \
assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname)
+/* Verify that a file does not contain invalid strings */
+#define assertFileContainsNoInvalidStrings(pathname, strings) \
+ assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings)
#define assertFileMtime(pathname, sec, nsec) \
assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec)
#define assertFileMtimeRecent(pathname) \
@@ -241,6 +244,7 @@ int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
+int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
int assertion_file_contents(const char *, int, const void *, int, const char *);
int assertion_file_exists(const char *, int, const char *);
int assertion_file_mode(const char *, int, const char *, int);
diff --git a/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c b/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c
index c08284552131..9500bba2cdb4 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_mtree_crash747.c
@@ -33,6 +33,11 @@ DEFINE_TEST(test_read_format_mtree_crash747)
const char *reffile = "test_read_format_mtree_crash747.mtree.bz2";
struct archive *a;
+ if (archive_bzlib_version() == NULL) {
+ skipping("This test requires bzlib");
+ return;
+ }
+
extract_reference_file(reffile);
assert((a = archive_read_new()) != NULL);
diff --git a/contrib/libarchive/libarchive/test/test_read_format_zip_high_compression.c b/contrib/libarchive/libarchive/test/test_read_format_zip_high_compression.c
index 6c8aa8eee1b2..42faed378f6d 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_zip_high_compression.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_zip_high_compression.c
@@ -50,6 +50,11 @@ DEFINE_TEST(test_read_format_zip_high_compression)
size_t s;
int64_t o;
+ if (archive_zlib_version() == NULL) {
+ skipping("Zip compression test requires zlib");
+ return;
+ }
+
extract_reference_file(refname);
p = slurpfile(&archive_size, refname);
@@ -82,6 +87,11 @@ DEFINE_TEST(test_read_format_zip_high_compression2)
char *body, *body_read, *buff;
int n;
+ if (archive_zlib_version() == NULL) {
+ skipping("Zip compression test requires zlib");
+ return;
+ }
+
assert((body = malloc(body_size)) != NULL);
assert((body_read = malloc(body_size)) != NULL);
assert((buff = malloc(buff_size)) != NULL);
diff --git a/contrib/libarchive/libarchive/test/test_read_set_format.c b/contrib/libarchive/libarchive/test/test_read_set_format.c
index d333269c2ee9..fb5e0047443a 100644
--- a/contrib/libarchive/libarchive/test/test_read_set_format.c
+++ b/contrib/libarchive/libarchive/test/test_read_set_format.c
@@ -133,11 +133,12 @@ DEFINE_TEST(test_read_append_filter)
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
r = archive_read_append_filter(a, ARCHIVE_FILTER_GZIP);
- if (r == ARCHIVE_WARN && !canGzip()) {
- skipping("gzip reading not fully supported on this platform");
+ if (r != ARCHIVE_OK && archive_zlib_version() == NULL && !canGzip()) {
+ skipping("gzip tests require zlib or working gzip command");
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
+ assertEqualIntA(a, ARCHIVE_OK, r);
assertEqualInt(ARCHIVE_OK,
archive_read_open_memory(a, archive, sizeof(archive)));
assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae));
@@ -200,8 +201,11 @@ DEFINE_TEST(test_read_append_filter_wrong_program)
{
struct archive_entry *ae;
struct archive *a;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ FILE * fp;
int fd;
fpos_t pos;
+#endif
/*
* If we have "bunzip2 -q", try using that.
@@ -211,11 +215,13 @@ DEFINE_TEST(test_read_append_filter_wrong_program)
return;
}
+#if !defined(_WIN32) || defined(__CYGWIN__)
/* bunzip2 will write to stderr, redirect it to a file */
fflush(stderr);
fgetpos(stderr, &pos);
fd = dup(fileno(stderr));
- freopen("stderr1", "w", stderr);
+ fp = freopen("stderr1", "w", stderr);
+#endif
assert((a = archive_read_new()) != NULL);
assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR));
@@ -227,12 +233,15 @@ DEFINE_TEST(test_read_append_filter_wrong_program)
assertEqualIntA(a, ARCHIVE_WARN, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
- /* restore stderr */
- fflush(stderr);
- dup2(fd, fileno(stderr));
- close(fd);
- clearerr(stderr);
- fsetpos(stderr, &pos);
-
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ /* restore stderr and verify results */
+ if (fp != NULL) {
+ fflush(stderr);
+ dup2(fd, fileno(stderr));
+ close(fd);
+ clearerr(stderr);
+ fsetpos(stderr, &pos);
+ }
assertTextFileContents("bunzip2: (stdin) is not a bzip2 file.\n", "stderr1");
+#endif
}
diff --git a/contrib/libarchive/libarchive/test/test_write_format_iso9660.c b/contrib/libarchive/libarchive/test/test_write_format_iso9660.c
index 1ea69a183595..ee6db6fed3b2 100644
--- a/contrib/libarchive/libarchive/test/test_write_format_iso9660.c
+++ b/contrib/libarchive/libarchive/test/test_write_format_iso9660.c
@@ -117,8 +117,8 @@ DEFINE_TEST(test_write_format_iso9660)
*/
dirname[0] = '\0';
strcpy(dir, "/dir0");
- for (i = 0; i < 10; i++) {
- dir[4] = '0' + i;
+ for (i = 0; i < 13; i++) {
+ dir[4] = "0123456789ABCDEF"[i];
if (i == 0)
strcat(dirname, dir+1);
else
@@ -134,6 +134,19 @@ DEFINE_TEST(test_write_format_iso9660)
archive_entry_free(ae);
}
+ strcat(dirname, "/file");
+ assert((ae = archive_entry_new()) != NULL);
+ archive_entry_set_atime(ae, 2, 20);
+ archive_entry_set_birthtime(ae, 3, 30);
+ archive_entry_set_ctime(ae, 4, 40);
+ archive_entry_set_mtime(ae, 5, 50);
+ archive_entry_copy_pathname(ae, dirname);
+ archive_entry_set_mode(ae, S_IFREG | 0755);
+ archive_entry_set_size(ae, 8);
+ assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
+ archive_entry_free(ae);
+ assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));
+
/*
* "dir0/dir1/file1" has 8 bytes of data.
*/
@@ -333,6 +346,45 @@ DEFINE_TEST(test_write_format_iso9660)
assertEqualInt(2048, archive_entry_size(ae));
/*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0555) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
* Read "hardlnk"
*/
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
@@ -386,6 +438,21 @@ DEFINE_TEST(test_write_format_iso9660)
assertEqualMem(buff2, "12345678", 8);
/*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(2, archive_entry_atime(ae));
+ assertEqualInt(3, archive_entry_birthtime(ae));
+ assertEqualInt(4, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file", archive_entry_pathname(ae));
+ assert((AE_IFREG | 0555) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
* Read "dir0/dir1/file1"
*/
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
@@ -580,29 +647,65 @@ DEFINE_TEST(test_write_format_iso9660)
assertEqualInt(2048, archive_entry_size(ae));
/*
- * Read "hardlnk"
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA"
*/
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
assertEqualInt(5, archive_entry_atime(ae));
assertEqualInt(5, archive_entry_ctime(ae));
assertEqualInt(5, archive_entry_mtime(ae));
- assertEqualString("hardlnk", archive_entry_pathname(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "file"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("file", archive_entry_pathname(ae));
assert((AE_IFREG | 0400) == archive_entry_mode(ae));
- assertEqualInt(2, archive_entry_nlink(ae));
assertEqualInt(8, archive_entry_size(ae));
assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
assertEqualMem(buff2, "12345678", 8);
/*
- * Read "file"
+ * Read "hardlnk"
*/
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
assertEqualInt(5, archive_entry_atime(ae));
assertEqualInt(5, archive_entry_ctime(ae));
assertEqualInt(5, archive_entry_mtime(ae));
- assertEqualString("file", archive_entry_pathname(ae));
- assertEqualString("hardlnk", archive_entry_hardlink(ae));
+ assertEqualString("hardlnk", archive_entry_pathname(ae));
+ assertEqualString("file", archive_entry_hardlink(ae));
assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
assertEqualInt(0, archive_entry_size(ae));
assertEqualIntA(a, 0, archive_read_data(a, buff2, 10));
@@ -625,6 +728,22 @@ DEFINE_TEST(test_write_format_iso9660)
assertEqualMem(buff2, "12345678", 8);
/*
+ * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString(
+ "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file",
+ archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
* Read "dir0/dir1/file1"
*/
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
@@ -746,6 +865,42 @@ DEFINE_TEST(test_write_format_iso9660)
assertEqualInt(2048, archive_entry_size(ae));
/*
+ * Read "rr_moved/dir7/dir8/dir9/dira"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("RR_MOVED/DIR7/DIR8/DIR9/DIRA",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "rr_moved/dir7/dir8/dir9/dira/dirB"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("RR_MOVED/DIR7/DIR8/DIR9/DIRA/DIRB",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
+ * Read "rr_moved/dir7/dir8/dir9/dirA/dirB/dirC"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString("RR_MOVED/DIR7/DIR8/DIR9/DIRA/DIRB/DIRC",
+ archive_entry_pathname(ae));
+ assert((S_IFDIR | 0700) == archive_entry_mode(ae));
+ assertEqualInt(2048, archive_entry_size(ae));
+
+ /*
* Read "dir0"
*/
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
@@ -827,33 +982,35 @@ DEFINE_TEST(test_write_format_iso9660)
assertEqualInt(2048, archive_entry_size(ae));
/*
- * Read "file"
+ * Read "hardlink"
*/
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
assertEqualInt(5, archive_entry_atime(ae));
- assertEqualInt(0, archive_entry_birthtime(ae));
assertEqualInt(5, archive_entry_ctime(ae));
assertEqualInt(5, archive_entry_mtime(ae));
- assertEqualString("FILE", archive_entry_pathname(ae));
+ assertEqualString("HARDLNK", archive_entry_pathname(ae));
+ assertEqualString(NULL, archive_entry_hardlink(ae));
assert((AE_IFREG | 0400) == archive_entry_mode(ae));
- assertEqualInt(2, archive_entry_nlink(ae));
assertEqualInt(8, archive_entry_size(ae));
assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
assertEqualMem(buff2, "12345678", 8);
/*
- * Read "hardlink"
+ * Read "file"
*/
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(0, archive_entry_birthtime(ae));
assertEqualInt(5, archive_entry_ctime(ae));
assertEqualInt(5, archive_entry_mtime(ae));
- assertEqualString("HARDLNK", archive_entry_pathname(ae));
- assertEqualString("FILE", archive_entry_hardlink(ae));
+ assertEqualString("FILE", archive_entry_pathname(ae));
+ assertEqualString("HARDLNK", archive_entry_hardlink(ae));
assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(2, archive_entry_nlink(ae));
assertEqualInt(0, archive_entry_size(ae));
assertEqualIntA(a, 0, archive_read_data(a, buff2, 10));
+
/*
* Read longname
*/
@@ -871,6 +1028,22 @@ DEFINE_TEST(test_write_format_iso9660)
assertEqualMem(buff2, "12345678", 8);
/*
+ * Read "rr_moved/dir7/dir8/dir9/dirA/dirB/dirC/file"
+ */
+ assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
+ assertEqualInt(5, archive_entry_atime(ae));
+ assertEqualInt(5, archive_entry_ctime(ae));
+ assertEqualInt(5, archive_entry_mtime(ae));
+ assertEqualString(
+ "RR_MOVED/DIR7/DIR8/DIR9/DIRA/DIRB/DIRC/FILE",
+ archive_entry_pathname(ae));
+ assert((AE_IFREG | 0400) == archive_entry_mode(ae));
+ assertEqualInt(1, archive_entry_nlink(ae));
+ assertEqualInt(8, archive_entry_size(ae));
+ assertEqualIntA(a, 8, archive_read_data(a, buff2, 10));
+ assertEqualMem(buff2, "12345678", 8);
+
+ /*
* Read "dir0/dir1/file1"
*/
assertEqualIntA(a, 0, archive_read_next_header(a, &ae));
diff --git a/contrib/libarchive/tar/test/main.c b/contrib/libarchive/tar/test/main.c
index 7a035fe2c94a..6bffee203d40 100644
--- a/contrib/libarchive/tar/test/main.c
+++ b/contrib/libarchive/tar/test/main.c
@@ -1188,7 +1188,7 @@ assertion_file_contains_no_invalid_strings(const char *file, int line,
return(0);
}
}
-
+
free(buff);
return (0);
}
@@ -1412,6 +1412,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect
assertion_count(file, line);
#if defined(_WIN32) && !defined(__CYGWIN__)
failure_start(file, line, "assertFileMode not yet implemented for Windows");
+ (void)mode; /* UNUSED */
+ (void)r; /* UNUSED */
#else
{
struct stat st;
diff --git a/contrib/libarchive/tar/test/test.h b/contrib/libarchive/tar/test/test.h
index d8bdf2804643..c002a2c27eee 100644
--- a/contrib/libarchive/tar/test/test.h
+++ b/contrib/libarchive/tar/test/test.h
@@ -244,7 +244,7 @@ int assertion_file_atime_recent(const char *, int, const char *);
int assertion_file_birthtime(const char *, int, const char *, long, long);
int assertion_file_birthtime_recent(const char *, int, const char *);
int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **);
-int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
+int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **);
int assertion_file_contents(const char *, int, const void *, int, const char *);
int assertion_file_exists(const char *, int, const char *);
int assertion_file_mode(const char *, int, const char *, int);
diff --git a/contrib/libarchive/tar/test/test_option_b.c b/contrib/libarchive/tar/test/test_option_b.c
index 81f50be8355e..7c2f60476c55 100644
--- a/contrib/libarchive/tar/test/test_option_b.c
+++ b/contrib/libarchive/tar/test/test_option_b.c
@@ -33,7 +33,7 @@ DEFINE_TEST(test_option_b)
assertMakeFile("file1", 0644, "file1");
if (systemf("cat file1 > test_cat.out 2> test_cat.err") != 0) {
- skipping("Platform doesn't have cat");
+ skipping("This test requires a `cat` program");
return;
}
testprog_ustar = malloc(strlen(testprog) + sizeof(USTAR_OPT) + 1);
diff --git a/contrib/libarchive/tar/test/test_symlink_dir.c b/contrib/libarchive/tar/test/test_symlink_dir.c
index 96bc3a491276..ba643c2e8348 100644
--- a/contrib/libarchive/tar/test/test_symlink_dir.c
+++ b/contrib/libarchive/tar/test/test_symlink_dir.c
@@ -63,7 +63,7 @@ DEFINE_TEST(test_symlink_dir)
/* "dir2" is a symlink to a non-existing "real_dir2" */
assertMakeSymlink("dest1/dir2", "real_dir2");
} else {
- skipping("some symlink checks");
+ skipping("Symlinks are not supported on this platform");
}
/* "dir3" is a symlink to an existing "non_dir3" */
assertMakeFile("dest1/non_dir3", 0755, "abcdef");
diff --git a/contrib/llvm/projects/libunwind/include/libunwind.h b/contrib/llvm/projects/libunwind/include/libunwind.h
index 64534b135f82..f583f530fac9 100644
--- a/contrib/llvm/projects/libunwind/include/libunwind.h
+++ b/contrib/llvm/projects/libunwind/include/libunwind.h
@@ -6,7 +6,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//
-// Compatible with libuwind API documented at:
+// Compatible with libunwind API documented at:
// http://www.nongnu.org/libunwind/man/libunwind(3).html
//
//===----------------------------------------------------------------------===//
@@ -120,7 +120,7 @@ extern int unw_init_remote_thread(unw_cursor_t *, unw_addr_space_t, thread_t *);
#endif /* UNW_REMOTE */
/*
- * traditional libuwind "remote" API
+ * traditional libunwind "remote" API
* NOT IMPLEMENTED on Mac OS X
*
* extern int unw_init_remote(unw_cursor_t*, unw_addr_space_t,
diff --git a/contrib/llvm/projects/libunwind/src/AddressSpace.hpp b/contrib/llvm/projects/libunwind/src/AddressSpace.hpp
index 74294a33bfa3..d9ea3db36c26 100644
--- a/contrib/llvm/projects/libunwind/src/AddressSpace.hpp
+++ b/contrib/llvm/projects/libunwind/src/AddressSpace.hpp
@@ -374,7 +374,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr,
(_Unwind_Ptr) targetAddr, &length);
info.arm_section_length = (uintptr_t)length;
#endif
- _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x\n",
+ _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x",
info.arm_section, info.arm_section_length);
if (info.arm_section && info.arm_section_length)
return true;
diff --git a/contrib/llvm/projects/libunwind/src/CompactUnwinder.hpp b/contrib/llvm/projects/libunwind/src/CompactUnwinder.hpp
index f528fba984db..1be1b0be1292 100644
--- a/contrib/llvm/projects/libunwind/src/CompactUnwinder.hpp
+++ b/contrib/llvm/projects/libunwind/src/CompactUnwinder.hpp
@@ -105,7 +105,7 @@ int CompactUnwinder_x86<A>::stepWithCompactEncodingEBPFrame(
default:
(void)functionStart;
_LIBUNWIND_DEBUG_LOG("bad register for EBP frame, encoding=%08X for "
- "function starting at 0x%X\n",
+ "function starting at 0x%X",
compactEncoding, functionStart);
_LIBUNWIND_ABORT("invalid compact unwind encoding");
}
@@ -224,7 +224,7 @@ int CompactUnwinder_x86<A>::stepWithCompactEncodingFrameless(
break;
default:
_LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for "
- "function starting at 0x%X\n",
+ "function starting at 0x%X",
encoding, functionStart);
_LIBUNWIND_ABORT("invalid compact unwind encoding");
}
@@ -336,7 +336,7 @@ int CompactUnwinder_x86_64<A>::stepWithCompactEncodingRBPFrame(
default:
(void)functionStart;
_LIBUNWIND_DEBUG_LOG("bad register for RBP frame, encoding=%08X for "
- "function starting at 0x%llX\n",
+ "function starting at 0x%llX",
compactEncoding, functionStart);
_LIBUNWIND_ABORT("invalid compact unwind encoding");
}
@@ -455,7 +455,7 @@ int CompactUnwinder_x86_64<A>::stepWithCompactEncodingFrameless(
break;
default:
_LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for "
- "function starting at 0x%llX\n",
+ "function starting at 0x%llX",
encoding, functionStart);
_LIBUNWIND_ABORT("invalid compact unwind encoding");
}
diff --git a/contrib/llvm/projects/libunwind/src/EHHeaderParser.hpp b/contrib/llvm/projects/libunwind/src/EHHeaderParser.hpp
index 7945c7ba2fb0..6c3ccc863172 100644
--- a/contrib/llvm/projects/libunwind/src/EHHeaderParser.hpp
+++ b/contrib/llvm/projects/libunwind/src/EHHeaderParser.hpp
@@ -85,7 +85,7 @@ bool EHHeaderParser<A>::decodeTableEntry(
const char *message =
CFI_Parser<A>::decodeFDE(addressSpace, fde, fdeInfo, cieInfo);
if (message != NULL) {
- _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s\n",
+ _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s",
message);
return false;
}
diff --git a/contrib/llvm/projects/libunwind/src/Unwind-EHABI.cpp b/contrib/llvm/projects/libunwind/src/Unwind-EHABI.cpp
index ca7b43e113a7..719bde166959 100644
--- a/contrib/llvm/projects/libunwind/src/Unwind-EHABI.cpp
+++ b/contrib/llvm/projects/libunwind/src/Unwind-EHABI.cpp
@@ -454,7 +454,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
unw_proc_info_t frameInfo;
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
+ "failed => _URC_FATAL_PHASE1_ERROR",
static_cast<void *>(exception_object));
return _URC_FATAL_PHASE1_ERROR;
}
@@ -472,7 +472,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
unw_get_reg(cursor, UNW_REG_IP, &pc);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): pc=0x%llX, start_ip=0x%llX, func=%s, "
- "lsda=0x%llX, personality=0x%llX\n",
+ "lsda=0x%llX, personality=0x%llX",
static_cast<void *>(exception_object), (long long)pc,
(long long)frameInfo.start_ip, functionName,
(long long)frameInfo.lsda, (long long)frameInfo.handler);
@@ -484,7 +484,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
__personality_routine p =
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): calling personality function %p\n",
+ "unwind_phase1(ex_ojb=%p): calling personality function %p",
static_cast<void *>(exception_object),
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(p)));
struct _Unwind_Context *context = (struct _Unwind_Context *)(cursor);
@@ -496,7 +496,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
(*p)(_US_VIRTUAL_UNWIND_FRAME, exception_object, context);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): personality result %d start_ip %x ehtp %p "
- "additional %x\n",
+ "additional %x",
static_cast<void *>(exception_object), personalityResult,
exception_object->pr_cache.fnstart,
static_cast<void *>(exception_object->pr_cache.ehtp),
@@ -508,13 +508,13 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
handlerNotFound = false;
// p should have initialized barrier_cache. EHABI #7.3.5
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n",
+ "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND",
static_cast<void *>(exception_object));
return _URC_NO_REASON;
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
+ "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND",
static_cast<void *>(exception_object));
// continue unwinding
break;
@@ -526,7 +526,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
default:
// something went wrong
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
+ "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
static_cast<void *>(exception_object));
return _URC_FATAL_PHASE1_ERROR;
}
@@ -541,13 +541,13 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor
// See comment at the start of unwind_phase1 regarding VRS integrity.
unw_init_local(cursor, uc);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)",
static_cast<void *>(exception_object));
int frame_count = 0;
// Walk each frame until we reach where search phase said to stop.
while (true) {
- // Ask libuwind to get next frame (skip over first which is
+ // Ask libunwind to get next frame (skip over first which is
// _Unwind_RaiseException or _Unwind_Resume).
//
// Resume only ever makes sense for 1 frame.
@@ -572,7 +572,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor
unw_get_reg(cursor, UNW_REG_SP, &sp);
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE2_ERROR\n",
+ "failed => _URC_FATAL_PHASE2_ERROR",
static_cast<void *>(exception_object));
return _URC_FATAL_PHASE2_ERROR;
}
@@ -588,7 +588,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor
functionName = ".anonymous.";
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2(ex_ojb=%p): start_ip=0x%llX, func=%s, sp=0x%llX, "
- "lsda=0x%llX, personality=0x%llX\n",
+ "lsda=0x%llX, personality=0x%llX",
static_cast<void *>(exception_object), (long long)frameInfo.start_ip,
functionName, (long long)sp, (long long)frameInfo.lsda,
(long long)frameInfo.handler);
@@ -610,7 +610,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor
case _URC_CONTINUE_UNWIND:
// Continue unwinding
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
+ "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
static_cast<void *>(exception_object));
// EHABI #7.2
if (sp == exception_object->barrier_cache.sp) {
@@ -621,7 +621,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor
break;
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n",
+ "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT",
static_cast<void *>(exception_object));
// Personality routine says to transfer control to landing pad.
// We may get control back if landing pad calls _Unwind_Resume().
@@ -630,7 +630,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor
unw_get_reg(cursor, UNW_REG_IP, &pc);
unw_get_reg(cursor, UNW_REG_SP, &sp);
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
- "user code with ip=0x%llX, sp=0x%llX\n",
+ "user code with ip=0x%llX, sp=0x%llX",
static_cast<void *>(exception_object),
(long long)pc, (long long)sp);
}
@@ -668,7 +668,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor
/// Called by __cxa_throw. Only returns if there is a fatal error.
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_RaiseException(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)",
static_cast<void *>(exception_object));
unw_context_t uc;
unw_cursor_t cursor;
@@ -706,7 +706,7 @@ _LIBUNWIND_EXPORT void _Unwind_Complete(_Unwind_Exception* exception_object) {
/// in turn calls _Unwind_Resume_or_Rethrow().
_LIBUNWIND_EXPORT void
_Unwind_Resume(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)",
static_cast<void *>(exception_object));
unw_context_t uc;
unw_cursor_t cursor;
@@ -730,7 +730,7 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.lsda;
_LIBUNWIND_TRACE_API(
- "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx\n",
+ "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx",
static_cast<void *>(context), (long long)result);
return result;
}
@@ -758,7 +758,7 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
uint32_t regno, _Unwind_VRS_DataRepresentation representation,
void *valuep) {
_LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, "
- "rep=%d, value=0x%llX)\n",
+ "rep=%d, value=0x%llX)",
static_cast<void *>(context), regclass, regno,
representation,
ValueAsBitPattern(representation, valuep));
@@ -863,7 +863,7 @@ _Unwind_VRS_Result _Unwind_VRS_Get(
_Unwind_VRS_Get_Internal(context, regclass, regno, representation,
valuep);
_LIBUNWIND_TRACE_API("_Unwind_VRS_Get(context=%p, regclass=%d, reg=%d, "
- "rep=%d, value=0x%llX, result = %d)\n",
+ "rep=%d, value=0x%llX, result = %d)",
static_cast<void *>(context), regclass, regno,
representation,
ValueAsBitPattern(representation, valuep), result);
@@ -875,7 +875,7 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass,
uint32_t discriminator,
_Unwind_VRS_DataRepresentation representation) {
_LIBUNWIND_TRACE_API("_Unwind_VRS_Pop(context=%p, regclass=%d, "
- "discriminator=%d, representation=%d)\n",
+ "discriminator=%d, representation=%d)",
static_cast<void *>(context), regclass, discriminator,
representation);
switch (regclass) {
@@ -948,7 +948,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) {
uintptr_t result = 0;
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.start_ip;
- _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX\n",
+ _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX",
static_cast<void *>(context), (long long)result);
return result;
}
@@ -958,7 +958,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) {
// is caught.
_LIBUNWIND_EXPORT void
_Unwind_DeleteException(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
static_cast<void *>(exception_object));
if (exception_object->exception_cleanup != NULL)
(*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
diff --git a/contrib/llvm/projects/libunwind/src/Unwind-sjlj.c b/contrib/llvm/projects/libunwind/src/Unwind-sjlj.c
index f9256b5a9260..89944a283cfb 100644
--- a/contrib/llvm/projects/libunwind/src/Unwind-sjlj.c
+++ b/contrib/llvm/projects/libunwind/src/Unwind-sjlj.c
@@ -72,7 +72,7 @@ _Unwind_SjLj_Unregister(struct _Unwind_FunctionContext *fc) {
static _Unwind_Reason_Code
unwind_phase1(struct _Unwind_Exception *exception_object) {
_Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack();
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: initial function-context=%p\n", c);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: initial function-context=%p", c);
// walk each frame looking for a place to stop
for (bool handlerNotFound = true; handlerNotFound; c = c->prev) {
@@ -80,17 +80,17 @@ unwind_phase1(struct _Unwind_Exception *exception_object) {
// check for no more frames
if (c == NULL) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): reached "
- "bottom => _URC_END_OF_STACK\n",
+ "bottom => _URC_END_OF_STACK",
exception_object);
return _URC_END_OF_STACK;
}
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: function-context=%p\n", c);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: function-context=%p", c);
// if there is a personality routine, ask it if it will want to stop at this
// frame
if (c->personality != NULL) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): calling "
- "personality function %p\n",
+ "personality function %p",
exception_object, c->personality);
_Unwind_Reason_Code personalityResult = (*c->personality)(
1, _UA_SEARCH_PHASE, exception_object->exception_class,
@@ -102,19 +102,19 @@ unwind_phase1(struct _Unwind_Exception *exception_object) {
handlerNotFound = false;
exception_object->private_2 = (uintptr_t) c;
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): "
- "_URC_HANDLER_FOUND\n", exception_object);
+ "_URC_HANDLER_FOUND", exception_object);
return _URC_NO_REASON;
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): "
- "_URC_CONTINUE_UNWIND\n", exception_object);
+ "_URC_CONTINUE_UNWIND", exception_object);
// continue unwinding
break;
default:
// something went wrong
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
+ "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
@@ -126,18 +126,18 @@ unwind_phase1(struct _Unwind_Exception *exception_object) {
static _Unwind_Reason_Code
unwind_phase2(struct _Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", exception_object);
// walk each frame until we reach where search phase said to stop
_Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack();
while (true) {
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2s(ex_ojb=%p): context=%p\n",
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2s(ex_ojb=%p): context=%p",
exception_object, c);
// check for no more frames
if (c == NULL) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
+ "bottom => _URC_END_OF_STACK",
exception_object);
return _URC_END_OF_STACK;
}
@@ -157,7 +157,7 @@ unwind_phase2(struct _Unwind_Exception *exception_object) {
case _URC_CONTINUE_UNWIND:
// continue unwinding
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
+ "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
exception_object);
if ((uintptr_t) c == exception_object->private_2) {
// phase 1 said we would stop at this frame, but we did not...
@@ -168,7 +168,7 @@ unwind_phase2(struct _Unwind_Exception *exception_object) {
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): "
"_URC_INSTALL_CONTEXT, will resume at "
- "landing pad %p\n",
+ "landing pad %p",
exception_object, c->jbuf[1]);
// personality routine says to transfer control to landing pad
// we may get control back if landing pad calls _Unwind_Resume()
@@ -202,7 +202,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object,
// get next frame (skip over first which is _Unwind_RaiseException)
if (c == NULL) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
+ "bottom => _URC_END_OF_STACK",
exception_object);
return _URC_END_OF_STACK;
}
@@ -214,11 +214,11 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object,
(*stop)(1, action, exception_object->exception_class, exception_object,
(struct _Unwind_Context *)c, stop_parameter);
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "stop function returned %d\n",
+ "stop function returned %d",
exception_object, stopResult);
if (stopResult != _URC_NO_REASON) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "stopped by stop function\n",
+ "stopped by stop function",
exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -227,7 +227,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object,
if (c->personality != NULL) {
__personality_routine p = (__personality_routine) c->personality;
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "calling personality function %p\n",
+ "calling personality function %p",
exception_object, p);
_Unwind_Reason_Code personalityResult =
(*p)(1, action, exception_object->exception_class, exception_object,
@@ -235,13 +235,13 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object,
switch (personalityResult) {
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "personality returned _URC_CONTINUE_UNWIND\n",
+ "personality returned _URC_CONTINUE_UNWIND",
exception_object);
// destructors called, continue unwinding
break;
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
- "personality returned _URC_INSTALL_CONTEXT\n",
+ "personality returned _URC_INSTALL_CONTEXT",
exception_object);
// we may get control back if landing pad calls _Unwind_Resume()
__Unwind_SjLj_SetTopOfFunctionStack(c);
@@ -251,7 +251,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object,
// something went wrong
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
"personality returned %d, "
- "_URC_FATAL_PHASE2_ERROR\n",
+ "_URC_FATAL_PHASE2_ERROR",
exception_object, personalityResult);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -262,7 +262,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object,
// call stop function one last time and tell it we've reached the end of the
// stack
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop "
- "function with _UA_END_OF_STACK\n",
+ "function with _UA_END_OF_STACK",
exception_object);
_Unwind_Action lastAction =
(_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
@@ -278,7 +278,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object,
/// Called by __cxa_throw. Only returns if there is a fatal error
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_SjLj_RaiseException(ex_obj=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_API("_Unwind_SjLj_RaiseException(ex_obj=%p)", exception_object);
// mark that this is a non-forced unwind, so _Unwind_Resume() can do the right
// thing
@@ -308,7 +308,7 @@ _Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object) {
/// __cxa_rethrow() which in turn calls _Unwind_Resume_or_Rethrow()
_LIBUNWIND_EXPORT void
_Unwind_SjLj_Resume(struct _Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_SjLj_Resume(ex_obj=%p)\n", exception_object);
+ _LIBUNWIND_TRACE_API("_Unwind_SjLj_Resume(ex_obj=%p)", exception_object);
if (exception_object->private_1 != 0)
unwind_phase2_forced(exception_object,
@@ -326,7 +326,7 @@ _Unwind_SjLj_Resume(struct _Unwind_Exception *exception_object) {
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *exception_object) {
_LIBUNWIND_TRACE_API("__Unwind_SjLj_Resume_or_Rethrow(ex_obj=%p), "
- "private_1=%ld\n",
+ "private_1=%ld",
exception_object, exception_object->private_1);
// If this is non-forced and a stopping place was found, then this is a
// re-throw.
@@ -350,7 +350,7 @@ _LIBUNWIND_EXPORT uintptr_t
_Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
_LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p) "
- "=> 0x%0lX\n", context, ufc->lsda);
+ "=> 0x%0lX", context, ufc->lsda);
return ufc->lsda;
}
@@ -358,7 +358,7 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
/// Called by personality handler during phase 2 to get register values.
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context,
int index) {
- _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d)",
context, index);
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
return ufc->resumeParameters[index];
@@ -368,7 +368,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context,
/// Called by personality handler during phase 2 to alter register values.
_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
uintptr_t new_value) {
- _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0lX)\n"
+ _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0lX)"
, context, index, new_value);
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
ufc->resumeParameters[index] = new_value;
@@ -378,7 +378,7 @@ _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
/// Called by personality handler during phase 2 to get instruction pointer.
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
- _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%lX\n", context,
+ _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%lX", context,
ufc->resumeLocation + 1);
return ufc->resumeLocation + 1;
}
@@ -391,7 +391,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
int *ipBefore) {
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
*ipBefore = 0;
- _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX\n",
+ _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX",
context, ipBefore, ufc->resumeLocation + 1);
return ufc->resumeLocation + 1;
}
@@ -400,7 +400,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
/// Called by personality handler during phase 2 to alter instruction pointer.
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
uintptr_t new_value) {
- _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0lX)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0lX)",
context, new_value);
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
ufc->resumeLocation = new_value - 1;
@@ -413,7 +413,7 @@ _LIBUNWIND_EXPORT uintptr_t
_Unwind_GetRegionStart(struct _Unwind_Context *context) {
// Not supported or needed for sjlj based unwinding
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p)", context);
return 0;
}
@@ -422,7 +422,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) {
/// is caught.
_LIBUNWIND_EXPORT void
_Unwind_DeleteException(struct _Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
exception_object);
if (exception_object->exception_cleanup != NULL)
(*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
@@ -437,7 +437,7 @@ _LIBUNWIND_EXPORT uintptr_t
_Unwind_GetDataRelBase(struct _Unwind_Context *context) {
// Not supported or needed for sjlj based unwinding
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", context);
_LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented");
}
@@ -448,14 +448,14 @@ _LIBUNWIND_EXPORT uintptr_t
_Unwind_GetTextRelBase(struct _Unwind_Context *context) {
// Not supported or needed for sjlj based unwinding
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)", context);
_LIBUNWIND_ABORT("_Unwind_GetTextRelBase() not implemented");
}
/// Called by personality handler to get "Call Frame Area" for current frame.
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) {
- _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p)\n", context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p)", context);
if (context != NULL) {
_Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context;
// Setjmp/longjmp based exceptions don't have a true CFA.
diff --git a/contrib/llvm/projects/libunwind/src/UnwindCursor.hpp b/contrib/llvm/projects/libunwind/src/UnwindCursor.hpp
index 7c217e1c1a01..6d1cfaa03003 100644
--- a/contrib/llvm/projects/libunwind/src/UnwindCursor.hpp
+++ b/contrib/llvm/projects/libunwind/src/UnwindCursor.hpp
@@ -6,7 +6,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//
-// C++ interface to lower levels of libuwind
+// C++ interface to lower levels of libunwind
//===----------------------------------------------------------------------===//
#ifndef __UNWINDCURSOR_HPP__
@@ -935,7 +935,7 @@ bool UnwindCursor<A, R>::getInfoFromDwarfSection(pint_t pc,
return true;
}
}
- //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX\n", (uint64_t)pc);
+ //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX", (uint64_t)pc);
return false;
}
#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND
@@ -1092,13 +1092,13 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base;
if (pc < funcStart) {
_LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second "
- "level compressed unwind table. funcStart=0x%llX\n",
+ "level compressed unwind table. funcStart=0x%llX",
(uint64_t) pc, (uint64_t) funcStart);
return false;
}
if (pc > funcEnd) {
_LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second "
- "level compressed unwind table. funcEnd=0x%llX\n",
+ "level compressed unwind table. funcEnd=0x%llX",
(uint64_t) pc, (uint64_t) funcEnd);
return false;
}
@@ -1119,7 +1119,7 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
}
} else {
_LIBUNWIND_DEBUG_LOG("malformed __unwind_info at 0x%0llX bad second "
- "level page\n",
+ "level page",
(uint64_t) sects.compact_unwind_section);
return false;
}
@@ -1149,7 +1149,7 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
}
if (lsda == 0) {
_LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with HAS_LSDA bit set for "
- "pc=0x%0llX, but lsda table has no entry\n",
+ "pc=0x%0llX, but lsda table has no entry",
encoding, (uint64_t) pc);
return false;
}
@@ -1162,7 +1162,7 @@ bool UnwindCursor<A, R>::getInfoFromCompactEncodingSection(pint_t pc,
--personalityIndex; // change 1-based to zero-based index
if (personalityIndex > sectionHeader.personalityArrayCount()) {
_LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, "
- "but personality table has only %d entires\n",
+ "but personality table has only %d entires",
encoding, personalityIndex,
sectionHeader.personalityArrayCount());
return false;
diff --git a/contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c b/contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c
index 28ba0928121f..61af9e8eade8 100644
--- a/contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c
+++ b/contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c
@@ -29,11 +29,11 @@
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
#if _LIBUNWIND_ARM_EHABI
- _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n",
+ _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld",
(void *)exception_object,
(long)exception_object->unwinder_cache.reserved1);
#else
- _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n",
+ _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld",
(void *)exception_object,
(long)exception_object->private_1);
#endif
@@ -66,7 +66,7 @@ _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) {
_LIBUNWIND_EXPORT uintptr_t
_Unwind_GetDataRelBase(struct _Unwind_Context *context) {
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)\n", (void *)context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", (void *)context);
_LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented");
}
@@ -76,7 +76,7 @@ _Unwind_GetDataRelBase(struct _Unwind_Context *context) {
_LIBUNWIND_EXPORT uintptr_t
_Unwind_GetTextRelBase(struct _Unwind_Context *context) {
(void)context;
- _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)\n", (void *)context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)", (void *)context);
_LIBUNWIND_ABORT("_Unwind_GetTextRelBase() not implemented");
}
@@ -84,7 +84,7 @@ _Unwind_GetTextRelBase(struct _Unwind_Context *context) {
/// Scans unwind information to find the function that contains the
/// specified code address "pc".
_LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(void *pc) {
- _LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)\n", pc);
+ _LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)", pc);
// This is slow, but works.
// We create an unwind cursor then alter the IP to be pc
unw_cursor_t cursor;
@@ -108,7 +108,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
unw_getcontext(&uc);
unw_init_local(&cursor, &uc);
- _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)",
(void *)(uintptr_t)callback);
#if _LIBUNWIND_ARM_EHABI
@@ -123,11 +123,11 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
_Unwind_Reason_Code result;
#if !_LIBUNWIND_ARM_EHABI
- // ask libuwind to get next frame (skip over first frame which is
+ // ask libunwind to get next frame (skip over first frame which is
// _Unwind_Backtrace())
if (unw_step(&cursor) <= 0) {
_LIBUNWIND_TRACE_UNWINDING(" _backtrace: ended because cursor reached "
- "bottom of stack, returning %d\n",
+ "bottom of stack, returning %d",
_URC_END_OF_STACK);
return _URC_END_OF_STACK;
}
@@ -164,7 +164,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
unw_get_proc_name(&cursor, functionName, 512, &offset);
unw_get_proc_info(&cursor, &frame);
_LIBUNWIND_TRACE_UNWINDING(
- " _backtrace: start_ip=0x%llX, func=%s, lsda=0x%llX, context=%p\n",
+ " _backtrace: start_ip=0x%llX, func=%s, lsda=0x%llX, context=%p",
(long long)frame.start_ip, functionName, (long long)frame.lsda,
(void *)&cursor);
}
@@ -173,7 +173,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) {
result = (*callback)((struct _Unwind_Context *)(&cursor), ref);
if (result != _URC_NO_REASON) {
_LIBUNWIND_TRACE_UNWINDING(
- " _backtrace: ended because callback returned %d\n", result);
+ " _backtrace: ended because callback returned %d", result);
return result;
}
}
@@ -195,7 +195,7 @@ _LIBUNWIND_EXPORT const void *_Unwind_Find_FDE(const void *pc,
bases->tbase = (uintptr_t)info.extra;
bases->dbase = 0; // dbase not used on Mac OS X
bases->func = (uintptr_t)info.start_ip;
- _LIBUNWIND_TRACE_API("_Unwind_Find_FDE(pc=%p) => %p\n", pc,
+ _LIBUNWIND_TRACE_API("_Unwind_Find_FDE(pc=%p) => %p", pc,
(void *)(long) info.unwind_info);
return (void *)(long) info.unwind_info;
}
@@ -206,7 +206,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) {
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_word_t result;
unw_get_reg(cursor, UNW_REG_SP, &result);
- _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIx64 "\n",
+ _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIx64,
(void *)context, (uint64_t)result);
return (uintptr_t)result;
}
@@ -217,7 +217,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) {
/// site address. Normally IP is the return address.
_LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
int *ipBefore) {
- _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)\n", (void *)context);
+ _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)", (void *)context);
*ipBefore = 0;
return _Unwind_GetIP(context);
}
@@ -229,7 +229,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context,
/// This function has existed on Mac OS X since 10.4, but
/// was broken until 10.6.
_LIBUNWIND_EXPORT void __register_frame(const void *fde) {
- _LIBUNWIND_TRACE_API("__register_frame(%p)\n", fde);
+ _LIBUNWIND_TRACE_API("__register_frame(%p)", fde);
_unw_add_dynamic_fde((unw_word_t)(uintptr_t) fde);
}
@@ -239,7 +239,7 @@ _LIBUNWIND_EXPORT void __register_frame(const void *fde) {
/// This function has existed on Mac OS X since 10.4, but
/// was broken until 10.6.
_LIBUNWIND_EXPORT void __deregister_frame(const void *fde) {
- _LIBUNWIND_TRACE_API("__deregister_frame(%p)\n", fde);
+ _LIBUNWIND_TRACE_API("__deregister_frame(%p)", fde);
_unw_remove_dynamic_fde((unw_word_t)(uintptr_t) fde);
}
@@ -259,7 +259,7 @@ _LIBUNWIND_EXPORT void __register_frame_info_bases(const void *fde, void *ob,
(void)ob;
(void)tb;
(void)db;
- _LIBUNWIND_TRACE_API("__register_frame_info_bases(%p,%p, %p, %p)\n",
+ _LIBUNWIND_TRACE_API("__register_frame_info_bases(%p,%p, %p, %p)",
fde, ob, tb, db);
// do nothing, this function never worked in Mac OS X
}
@@ -267,7 +267,7 @@ _LIBUNWIND_EXPORT void __register_frame_info_bases(const void *fde, void *ob,
_LIBUNWIND_EXPORT void __register_frame_info(const void *fde, void *ob) {
(void)fde;
(void)ob;
- _LIBUNWIND_TRACE_API("__register_frame_info(%p, %p)\n", fde, ob);
+ _LIBUNWIND_TRACE_API("__register_frame_info(%p, %p)", fde, ob);
// do nothing, this function never worked in Mac OS X
}
@@ -279,33 +279,33 @@ _LIBUNWIND_EXPORT void __register_frame_info_table_bases(const void *fde,
(void)tb;
(void)db;
_LIBUNWIND_TRACE_API("__register_frame_info_table_bases"
- "(%p,%p, %p, %p)\n", fde, ob, tb, db);
+ "(%p,%p, %p, %p)", fde, ob, tb, db);
// do nothing, this function never worked in Mac OS X
}
_LIBUNWIND_EXPORT void __register_frame_info_table(const void *fde, void *ob) {
(void)fde;
(void)ob;
- _LIBUNWIND_TRACE_API("__register_frame_info_table(%p, %p)\n", fde, ob);
+ _LIBUNWIND_TRACE_API("__register_frame_info_table(%p, %p)", fde, ob);
// do nothing, this function never worked in Mac OS X
}
_LIBUNWIND_EXPORT void __register_frame_table(const void *fde) {
(void)fde;
- _LIBUNWIND_TRACE_API("__register_frame_table(%p)\n", fde);
+ _LIBUNWIND_TRACE_API("__register_frame_table(%p)", fde);
// do nothing, this function never worked in Mac OS X
}
_LIBUNWIND_EXPORT void *__deregister_frame_info(const void *fde) {
(void)fde;
- _LIBUNWIND_TRACE_API("__deregister_frame_info(%p)\n", fde);
+ _LIBUNWIND_TRACE_API("__deregister_frame_info(%p)", fde);
// do nothing, this function never worked in Mac OS X
return NULL;
}
_LIBUNWIND_EXPORT void *__deregister_frame_info_bases(const void *fde) {
(void)fde;
- _LIBUNWIND_TRACE_API("__deregister_frame_info_bases(%p)\n", fde);
+ _LIBUNWIND_TRACE_API("__deregister_frame_info_bases(%p)", fde);
// do nothing, this function never worked in Mac OS X
return NULL;
}
diff --git a/contrib/llvm/projects/libunwind/src/UnwindLevel1.c b/contrib/llvm/projects/libunwind/src/UnwindLevel1.c
index 7294f255407e..3f89e9c521cf 100644
--- a/contrib/llvm/projects/libunwind/src/UnwindLevel1.c
+++ b/contrib/llvm/projects/libunwind/src/UnwindLevel1.c
@@ -39,17 +39,17 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
// Walk each frame looking for a place to stop.
bool handlerNotFound = true;
while (handlerNotFound) {
- // Ask libuwind to get next frame (skip over first which is
+ // Ask libunwind to get next frame (skip over first which is
// _Unwind_RaiseException).
int stepResult = unw_step(cursor);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
+ "bottom => _URC_END_OF_STACK",
(void *)exception_object);
return _URC_END_OF_STACK;
} else if (stepResult < 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => "
- "_URC_FATAL_PHASE1_ERROR\n",
+ "_URC_FATAL_PHASE1_ERROR",
(void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
@@ -59,7 +59,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
unw_word_t sp;
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
+ "failed => _URC_FATAL_PHASE1_ERROR",
(void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
@@ -77,7 +77,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
unw_get_reg(cursor, UNW_REG_IP, &pc);
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase1(ex_ojb=%p): pc=0x%" PRIx64 ", start_ip=0x%" PRIx64
- ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n",
+ ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "",
(void *)exception_object, pc, frameInfo.start_ip, functionName,
frameInfo.lsda, frameInfo.handler);
}
@@ -88,7 +88,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
__personality_routine p =
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): calling personality function %p\n",
+ "unwind_phase1(ex_ojb=%p): calling personality function %p",
(void *)exception_object, (void *)(uintptr_t)p);
_Unwind_Reason_Code personalityResult =
(*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class,
@@ -101,13 +101,13 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
unw_get_reg(cursor, UNW_REG_SP, &sp);
exception_object->private_2 = (uintptr_t)sp;
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n",
+ "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND",
(void *)exception_object);
return _URC_NO_REASON;
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
+ "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND",
(void *)exception_object);
// continue unwinding
break;
@@ -115,7 +115,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
default:
// something went wrong
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n",
+ "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR",
(void *)exception_object);
return _URC_FATAL_PHASE1_ERROR;
}
@@ -129,23 +129,23 @@ static _Unwind_Reason_Code
unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
unw_init_local(cursor, uc);
- _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n",
+ _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)",
(void *)exception_object);
// Walk each frame until we reach where search phase said to stop.
while (true) {
- // Ask libuwind to get next frame (skip over first which is
+ // Ask libunwind to get next frame (skip over first which is
// _Unwind_RaiseException).
int stepResult = unw_step(cursor);
if (stepResult == 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached "
- "bottom => _URC_END_OF_STACK\n",
+ "bottom => _URC_END_OF_STACK",
(void *)exception_object);
return _URC_END_OF_STACK;
} else if (stepResult < 0) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => "
- "_URC_FATAL_PHASE1_ERROR\n",
+ "_URC_FATAL_PHASE1_ERROR",
(void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -156,7 +156,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
unw_get_reg(cursor, UNW_REG_SP, &sp);
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info "
- "failed => _URC_FATAL_PHASE1_ERROR\n",
+ "failed => _URC_FATAL_PHASE1_ERROR",
(void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -172,7 +172,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
functionName = ".anonymous.";
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIx64
", func=%s, sp=0x%" PRIx64 ", lsda=0x%" PRIx64
- ", personality=0x%" PRIx64 "\n",
+ ", personality=0x%" PRIx64,
(void *)exception_object, frameInfo.start_ip,
functionName, sp, frameInfo.lsda,
frameInfo.handler);
@@ -194,7 +194,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
case _URC_CONTINUE_UNWIND:
// Continue unwinding
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n",
+ "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND",
(void *)exception_object);
if (sp == exception_object->private_2) {
// Phase 1 said we would stop at this frame, but we did not...
@@ -204,7 +204,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
break;
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n",
+ "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT",
(void *)exception_object);
// Personality routine says to transfer control to landing pad.
// We may get control back if landing pad calls _Unwind_Resume().
@@ -214,7 +214,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
unw_get_reg(cursor, UNW_REG_SP, &sp);
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering "
"user code with ip=0x%" PRIx64
- ", sp=0x%" PRIx64 "\n",
+ ", sp=0x%" PRIx64,
(void *)exception_object, pc, sp);
}
unw_resume(cursor);
@@ -247,7 +247,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
unw_proc_info_t frameInfo;
if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) {
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step "
- "failed => _URC_END_OF_STACK\n",
+ "failed => _URC_END_OF_STACK",
(void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -263,7 +263,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
functionName = ".anonymous.";
_LIBUNWIND_TRACE_UNWINDING(
"unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIx64
- ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n",
+ ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64,
(void *)exception_object, frameInfo.start_ip, functionName,
frameInfo.lsda, frameInfo.handler);
}
@@ -275,11 +275,11 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
(*stop)(1, action, exception_object->exception_class, exception_object,
(struct _Unwind_Context *)(cursor), stop_parameter);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n",
+ "unwind_phase2_forced(ex_ojb=%p): stop function returned %d",
(void *)exception_object, stopResult);
if (stopResult != _URC_NO_REASON) {
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2_forced(ex_ojb=%p): stopped by stop function\n",
+ "unwind_phase2_forced(ex_ojb=%p): stopped by stop function",
(void *)exception_object);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -289,7 +289,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
__personality_routine p =
(__personality_routine)(long)(frameInfo.handler);
_LIBUNWIND_TRACE_UNWINDING(
- "unwind_phase2_forced(ex_ojb=%p): calling personality function %p\n",
+ "unwind_phase2_forced(ex_ojb=%p): calling personality function %p",
(void *)exception_object, (void *)(uintptr_t)p);
_Unwind_Reason_Code personalityResult =
(*p)(1, action, exception_object->exception_class, exception_object,
@@ -298,14 +298,14 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
case _URC_CONTINUE_UNWIND:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
"personality returned "
- "_URC_CONTINUE_UNWIND\n",
+ "_URC_CONTINUE_UNWIND",
(void *)exception_object);
// Destructors called, continue unwinding
break;
case _URC_INSTALL_CONTEXT:
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
"personality returned "
- "_URC_INSTALL_CONTEXT\n",
+ "_URC_INSTALL_CONTEXT",
(void *)exception_object);
// We may get control back if landing pad calls _Unwind_Resume().
unw_resume(cursor);
@@ -314,7 +314,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
// Personality routine returned an unknown result code.
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): "
"personality returned %d, "
- "_URC_FATAL_PHASE2_ERROR\n",
+ "_URC_FATAL_PHASE2_ERROR",
(void *)exception_object, personalityResult);
return _URC_FATAL_PHASE2_ERROR;
}
@@ -324,7 +324,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
// Call stop function one last time and tell it we've reached the end
// of the stack.
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop "
- "function with _UA_END_OF_STACK\n",
+ "function with _UA_END_OF_STACK",
(void *)exception_object);
_Unwind_Action lastAction =
(_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK);
@@ -340,7 +340,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
/// Called by __cxa_throw. Only returns if there is a fatal error.
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_RaiseException(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)",
(void *)exception_object);
unw_context_t uc;
unw_cursor_t cursor;
@@ -375,7 +375,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) {
/// in turn calls _Unwind_Resume_or_Rethrow().
_LIBUNWIND_EXPORT void
_Unwind_Resume(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", (void *)exception_object);
+ _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", (void *)exception_object);
unw_context_t uc;
unw_cursor_t cursor;
unw_getcontext(&uc);
@@ -399,7 +399,7 @@ _Unwind_Resume(_Unwind_Exception *exception_object) {
_LIBUNWIND_EXPORT _Unwind_Reason_Code
_Unwind_ForcedUnwind(_Unwind_Exception *exception_object,
_Unwind_Stop_Fn stop, void *stop_parameter) {
- _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)",
(void *)exception_object, (void *)(uintptr_t)stop);
unw_context_t uc;
unw_cursor_t cursor;
@@ -424,11 +424,11 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) {
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.lsda;
_LIBUNWIND_TRACE_API(
- "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR "\n",
+ "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR,
(void *)context, result);
if (result != 0) {
if (*((uint8_t *)result) != 0xFF)
- _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF\n",
+ _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF",
result);
}
return result;
@@ -444,7 +444,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) {
uintptr_t result = 0;
if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS)
result = (uintptr_t)frameInfo.start_ip;
- _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR "\n",
+ _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR,
(void *)context, result);
return result;
}
@@ -454,7 +454,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) {
// is caught.
_LIBUNWIND_EXPORT void
_Unwind_DeleteException(_Unwind_Exception *exception_object) {
- _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n",
+ _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)",
(void *)exception_object);
if (exception_object->exception_cleanup != NULL)
(*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT,
@@ -467,7 +467,7 @@ _Unwind_GetGR(struct _Unwind_Context *context, int index) {
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_word_t result;
unw_get_reg(cursor, index, &result);
- _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIx64 "\n",
+ _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIx64,
(void *)context, index, (uint64_t)result);
return (uintptr_t)result;
}
@@ -476,7 +476,7 @@ _Unwind_GetGR(struct _Unwind_Context *context, int index) {
_LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index,
uintptr_t value) {
_LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0" PRIx64
- ")\n",
+ ")",
(void *)context, index, (uint64_t)value);
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_set_reg(cursor, index, value);
@@ -487,7 +487,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_word_t result;
unw_get_reg(cursor, UNW_REG_IP, &result);
- _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64 "\n",
+ _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64,
(void *)context, (uint64_t)result);
return (uintptr_t)result;
}
@@ -497,7 +497,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) {
/// start executing in the landing pad.
_LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context,
uintptr_t value) {
- _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIx64 ")\n",
+ _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIx64 ")",
(void *)context, (uint64_t)value);
unw_cursor_t *cursor = (unw_cursor_t *)context;
unw_set_reg(cursor, UNW_REG_IP, value);
diff --git a/contrib/llvm/projects/libunwind/src/config.h b/contrib/llvm/projects/libunwind/src/config.h
index 74c63f0cebf7..48bf0c519376 100644
--- a/contrib/llvm/projects/libunwind/src/config.h
+++ b/contrib/llvm/projects/libunwind/src/config.h
@@ -6,7 +6,7 @@
// Source Licenses. See LICENSE.TXT for details.
//
//
-// Defines macros used within libuwind project.
+// Defines macros used within libunwind project.
//
//===----------------------------------------------------------------------===//
@@ -84,7 +84,7 @@
fflush(stderr); \
abort(); \
} while (0)
-#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__)
+#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__)
// Macros that define away in non-Debug builds
#ifdef NDEBUG
diff --git a/contrib/llvm/projects/libunwind/src/libunwind.cpp b/contrib/llvm/projects/libunwind/src/libunwind.cpp
index f8a4e9144b76..f1c29f2d1022 100644
--- a/contrib/llvm/projects/libunwind/src/libunwind.cpp
+++ b/contrib/llvm/projects/libunwind/src/libunwind.cpp
@@ -1,4 +1,4 @@
-//===--------------------------- libuwind.cpp -----------------------------===//
+//===--------------------------- libunwind.cpp ----------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -42,7 +42,7 @@ extern int unw_getcontext(unw_context_t *);
/// unw_getcontext().
_LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
unw_context_t *context) {
- _LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)\n",
+ _LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)",
static_cast<void *>(cursor),
static_cast<void *>(context));
#if defined(__i386__)
@@ -159,7 +159,7 @@ _LIBUNWIND_EXPORT void unw_destroy_addr_space(unw_addr_space_t asp) {
/// Get value of specified register at cursor position in stack frame.
_LIBUNWIND_EXPORT int unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_word_t *value) {
- _LIBUNWIND_TRACE_API("unw_get_reg(cursor=%p, regNum=%d, &value=%p)\n",
+ _LIBUNWIND_TRACE_API("unw_get_reg(cursor=%p, regNum=%d, &value=%p)",
static_cast<void *>(cursor), regNum,
static_cast<void *>(value));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
@@ -174,7 +174,7 @@ _LIBUNWIND_EXPORT int unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
/// Set value of specified register at cursor position in stack frame.
_LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_word_t value) {
- _LIBUNWIND_TRACE_API("unw_set_reg(cursor=%p, regNum=%d, value=0x%llX)\n",
+ _LIBUNWIND_TRACE_API("unw_set_reg(cursor=%p, regNum=%d, value=0x%llX)",
static_cast<void *>(cursor), regNum, (long long)value);
typedef LocalAddressSpace::pint_t pint_t;
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
@@ -193,7 +193,7 @@ _LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum,
/// Get value of specified float register at cursor position in stack frame.
_LIBUNWIND_EXPORT int unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_fpreg_t *value) {
- _LIBUNWIND_TRACE_API("unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)\n",
+ _LIBUNWIND_TRACE_API("unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)",
static_cast<void *>(cursor), regNum,
static_cast<void *>(value));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
@@ -209,10 +209,10 @@ _LIBUNWIND_EXPORT int unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
_LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
unw_fpreg_t value) {
#if _LIBUNWIND_ARM_EHABI
- _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)\n",
+ _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)",
static_cast<void *>(cursor), regNum, value);
#else
- _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%g)\n",
+ _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%g)",
static_cast<void *>(cursor), regNum, value);
#endif
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
@@ -226,7 +226,7 @@ _LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum,
/// Move cursor to next frame.
_LIBUNWIND_EXPORT int unw_step(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_step(cursor=%p)\n", static_cast<void *>(cursor));
+ _LIBUNWIND_TRACE_API("unw_step(cursor=%p)", static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->step();
}
@@ -235,7 +235,7 @@ _LIBUNWIND_EXPORT int unw_step(unw_cursor_t *cursor) {
/// Get unwind info at cursor position in stack frame.
_LIBUNWIND_EXPORT int unw_get_proc_info(unw_cursor_t *cursor,
unw_proc_info_t *info) {
- _LIBUNWIND_TRACE_API("unw_get_proc_info(cursor=%p, &info=%p)\n",
+ _LIBUNWIND_TRACE_API("unw_get_proc_info(cursor=%p, &info=%p)",
static_cast<void *>(cursor), static_cast<void *>(info));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
co->getInfo(info);
@@ -248,7 +248,7 @@ _LIBUNWIND_EXPORT int unw_get_proc_info(unw_cursor_t *cursor,
/// Resume execution at cursor position (aka longjump).
_LIBUNWIND_EXPORT int unw_resume(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_resume(cursor=%p)\n", static_cast<void *>(cursor));
+ _LIBUNWIND_TRACE_API("unw_resume(cursor=%p)", static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
co->jumpto();
return UNW_EUNSPEC;
@@ -258,7 +258,7 @@ _LIBUNWIND_EXPORT int unw_resume(unw_cursor_t *cursor) {
/// Get name of function at cursor position in stack frame.
_LIBUNWIND_EXPORT int unw_get_proc_name(unw_cursor_t *cursor, char *buf,
size_t bufLen, unw_word_t *offset) {
- _LIBUNWIND_TRACE_API("unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)\n",
+ _LIBUNWIND_TRACE_API("unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)",
static_cast<void *>(cursor), static_cast<void *>(buf),
static_cast<unsigned long>(bufLen));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
@@ -271,7 +271,7 @@ _LIBUNWIND_EXPORT int unw_get_proc_name(unw_cursor_t *cursor, char *buf,
/// Checks if a register is a floating-point register.
_LIBUNWIND_EXPORT int unw_is_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum) {
- _LIBUNWIND_TRACE_API("unw_is_fpreg(cursor=%p, regNum=%d)\n",
+ _LIBUNWIND_TRACE_API("unw_is_fpreg(cursor=%p, regNum=%d)",
static_cast<void *>(cursor), regNum);
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->validFloatReg(regNum);
@@ -281,7 +281,7 @@ _LIBUNWIND_EXPORT int unw_is_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum) {
/// Checks if a register is a floating-point register.
_LIBUNWIND_EXPORT const char *unw_regname(unw_cursor_t *cursor,
unw_regnum_t regNum) {
- _LIBUNWIND_TRACE_API("unw_regname(cursor=%p, regNum=%d)\n",
+ _LIBUNWIND_TRACE_API("unw_regname(cursor=%p, regNum=%d)",
static_cast<void *>(cursor), regNum);
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->getRegisterName(regNum);
@@ -290,7 +290,7 @@ _LIBUNWIND_EXPORT const char *unw_regname(unw_cursor_t *cursor,
/// Checks if current frame is signal trampoline.
_LIBUNWIND_EXPORT int unw_is_signal_frame(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_is_signal_frame(cursor=%p)\n",
+ _LIBUNWIND_TRACE_API("unw_is_signal_frame(cursor=%p)",
static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->isSignalFrame();
@@ -299,7 +299,7 @@ _LIBUNWIND_EXPORT int unw_is_signal_frame(unw_cursor_t *cursor) {
#ifdef __arm__
// Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD
_LIBUNWIND_EXPORT void unw_save_vfp_as_X(unw_cursor_t *cursor) {
- _LIBUNWIND_TRACE_API("unw_fpreg_save_vfp_as_X(cursor=%p)\n",
+ _LIBUNWIND_TRACE_API("unw_fpreg_save_vfp_as_X(cursor=%p)",
static_cast<void *>(cursor));
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
return co->saveVFPAsX();
@@ -311,7 +311,7 @@ _LIBUNWIND_EXPORT void unw_save_vfp_as_X(unw_cursor_t *cursor) {
/// SPI: walks cached dwarf entries
_LIBUNWIND_EXPORT void unw_iterate_dwarf_unwind_cache(void (*func)(
unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) {
- _LIBUNWIND_TRACE_API("unw_iterate_dwarf_unwind_cache(func=%p)\n",
+ _LIBUNWIND_TRACE_API("unw_iterate_dwarf_unwind_cache(func=%p)",
reinterpret_cast<void *>(func));
DwarfFDECache<LocalAddressSpace>::iterateCacheEntries(func);
}
diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_printf.c b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c
index 5ef58f2fc627..d6ca662273fc 100644
--- a/contrib/netbsd-tests/lib/libc/stdio/t_printf.c
+++ b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c
@@ -120,12 +120,6 @@ ATF_TC_BODY(snprintf_posarg_error, tc)
{
char s[16], fmt[32];
-#ifndef __NetBSD__
- atf_tc_expect_signal(SIGSEGV,
- "some non-NetBSD platforms including FreeBSD don't validate "
- "negative size; testcase blows up with SIGSEGV");
-#endif
-
snprintf(fmt, sizeof(fmt), "%%%zu$d", SIZE_MAX / sizeof(size_t));
ATF_CHECK(snprintf(s, sizeof(s), fmt, -23) == -1);
diff --git a/contrib/tzdata/asia b/contrib/tzdata/asia
index 71ef8787b508..b2c993085319 100644
--- a/contrib/tzdata/asia
+++ b/contrib/tzdata/asia
@@ -2544,11 +2544,6 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
# From Paul Eggert (2015-03-03):
# http://www.timeanddate.com/time/change/west-bank/ramallah?year=2014
# says that the fall 2014 transition was Oct 23 at 24:00.
-# For future dates, guess the last Friday in March at 24:00 through
-# the first Friday on or after October 21 at 00:00. This is consistent with
-# the predictions in today's editions of the following URLs:
-# http://www.timeanddate.com/time/change/gaza-strip/gaza
-# http://www.timeanddate.com/time/change/west-bank/hebron
# From Hannah Kreitem (2016-03-09):
# http://www.palestinecabinet.gov.ps/WebSite/ar/ViewDetails?ID=31728
@@ -2558,7 +2553,21 @@ Zone Asia/Karachi 4:28:12 - LMT 1907
#
# From Paul Eggert (2016-03-12):
# Predict spring transitions on March's last Saturday at 01:00 from now on.
-# Leave fall predictions alone for now.
+
+# From Sharef Mustafa (2016-10-19):
+# [T]he Palestinian cabinet decision (Mar 8th 2016) published on
+# http://www.palestinecabinet.gov.ps/WebSite/Upload/Decree/GOV_17/16032016134830.pdf
+# states that summer time will end on Oct 29th at 01:00.
+#
+# From Tim Parenti (2016-10-19):
+# Predict fall transitions on October's last Saturday at 01:00 from now on.
+# This is consistent with the 2016 transition as well as our spring
+# predictions.
+#
+# From Paul Eggert (2016-10-19):
+# It's also consistent with predictions in the following URLs today:
+# http://www.timeanddate.com/time/change/gaza-strip/gaza
+# http://www.timeanddate.com/time/change/west-bank/hebron
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule EgyptAsia 1957 only - May 10 0:00 1:00 S
@@ -2587,9 +2596,10 @@ Rule Palestine 2011 only - Sep 30 0:00 0 -
Rule Palestine 2012 2014 - Mar lastThu 24:00 1:00 S
Rule Palestine 2012 only - Sep 21 1:00 0 -
Rule Palestine 2013 only - Sep Fri>=21 0:00 0 -
-Rule Palestine 2014 max - Oct Fri>=21 0:00 0 -
+Rule Palestine 2014 2015 - Oct Fri>=21 0:00 0 -
Rule Palestine 2015 only - Mar lastFri 24:00 1:00 S
Rule Palestine 2016 max - Mar lastSat 1:00 1:00 S
+Rule Palestine 2016 max - Oct lastSat 1:00 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Gaza 2:17:52 - LMT 1900 Oct
@@ -2739,45 +2749,31 @@ Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1
# People who live in regions under Tamil control can use [TZ='Asia/Kolkata'],
# as that zone has agreed with the Tamil areas since our cutoff date of 1970.
-# From K Sethu (2006-04-25):
-# I think the abbreviation LKT originated from the world of computers at
-# the time of or subsequent to the time zone changes by SL Government
-# twice in 1996 and probably SL Government or its standardization
-# agencies never declared an abbreviation as a national standard.
-#
-# I recollect before the recent change the government announcements
-# mentioning it as simply changing Sri Lanka Standard Time or Sri Lanka
-# Time and no mention was made about the abbreviation.
-#
-# If we look at Sri Lanka Department of Government's "Official News
-# Website of Sri Lanka" ... http://www.news.lk/ we can see that they
-# use SLT as abbreviation in time stamp at the beginning of each news
-# item....
-#
-# Within Sri Lanka I think LKT is well known among computer users and
-# administrators. In my opinion SLT may not be a good choice because the
-# nation's largest telcom / internet operator Sri Lanka Telcom is well
-# known by that abbreviation - simply as SLT (there IP domains are
-# slt.lk and sltnet.lk).
-#
-# But if indeed our government has adopted SLT as standard abbreviation
-# (that we have not known so far) then it is better that it be used for
-# all computers.
-
-# From Paul Eggert (2006-04-25):
-# One possibility is that we wait for a bit for the dust to settle down
-# and then see what people actually say in practice.
+# From Sadika Sumanapala (2016-10-19):
+# According to http://www.sltime.org (maintained by Measurement Units,
+# Standards & Services Department, Sri Lanka) abbreviation for Sri Lanka
+# standard time is SLST.
+#
+# From Paul Eggert (2016-10-18):
+# "SLST" seems to be reasonably recent and rarely-used outside time
+# zone nerd sources. I searched Google News and found three uses of
+# it in the International Business Times of India in February and
+# March of this year when discussing cricket match times, but nothing
+# since then (though there has been a lot of cricket) and nothing in
+# other English-language news sources. Our old abbreviation "LKT" is
+# even worse. For now, let's use a numeric abbreviation; we can
+# switch to "SLST" if it catches on.
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Colombo 5:19:24 - LMT 1880
5:19:32 - MMT 1906 # Moratuwa Mean Time
- 5:30 - IST 1942 Jan 5
- 5:30 0:30 IHST 1942 Sep
- 5:30 1:00 IST 1945 Oct 16 2:00
- 5:30 - IST 1996 May 25 0:00
- 6:30 - LKT 1996 Oct 26 0:30
- 6:00 - LKT 2006 Apr 15 0:30
- 5:30 - IST
+ 5:30 - +0530 1942 Jan 5
+ 5:30 0:30 +0530/+06 1942 Sep
+ 5:30 1:00 +0530/+0630 1945 Oct 16 2:00
+ 5:30 - +0530 1996 May 25 0:00
+ 6:30 - +0630 1996 Oct 26 0:30
+ 6:00 - +06 2006 Apr 15 0:30
+ 5:30 - +0530
# Syria
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
diff --git a/contrib/tzdata/australasia b/contrib/tzdata/australasia
index f49df1d6e107..85d363295b88 100644
--- a/contrib/tzdata/australasia
+++ b/contrib/tzdata/australasia
@@ -350,7 +350,13 @@ Zone Indian/Cocos 6:27:40 - LMT 1900
# commencing at 2.00 am on Sunday 1st November, 2015 and ending at
# 3.00 am on Sunday 17th January, 2016.
-# From Paul Eggert (2015-09-01):
+# From Raymond Kumar (2016-10-04):
+# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVING-STARTS-ON-6th-NOVEMBER,-2016.aspx
+# "Fiji's daylight savings will begin on Sunday, 6 November 2016, when
+# clocks go forward an hour at 2am to 3am.... Daylight Saving will
+# end at 3.00am on Sunday 15th January 2017."
+
+# From Paul Eggert (2016-10-03):
# For now, guess DST from 02:00 the first Sunday in November to
# 03:00 the third Sunday in January. Although ad hoc, it matches
# transitions since late 2014 and seems more likely to match future
diff --git a/contrib/tzdata/europe b/contrib/tzdata/europe
index 6020059f696b..a7dc350d1ebf 100644
--- a/contrib/tzdata/europe
+++ b/contrib/tzdata/europe
@@ -1908,7 +1908,7 @@ Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15
# Amsterdam mean time.
# The data entries before 1945 are taken from
-# http://www.phys.uu.nl/~vgent/wettijd/wettijd.htm
+# http://www.staff.science.uu.nl/~gent0113/idl/idl.htm
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Neth 1916 only - May 1 0:00 1:00 NST # Netherlands Summer Time
@@ -3427,22 +3427,24 @@ Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16 # See above comment.
# Turkey
-# From Amar Devegowda (2007-01-03):
-# The time zone rules for Istanbul, Turkey have not been changed for years now.
-# ... The latest rules are available at:
-# http://www.timeanddate.com/worldclock/timezone.html?n=107
-# From Steffen Thorsen (2007-01-03):
-# I have been able to find press records back to 1996 which all say that
-# DST started 01:00 local time and end at 02:00 local time. I am not sure
-# what happened before that. One example for each year from 1996 to 2001:
-# http://newspot.byegm.gov.tr/arsiv/1996/21/N4.htm
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING97/03/97X03X25.TXT
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING98/03/98X03X02.HTM
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING99/10/99X10X26.HTM#%2016
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2000/03/00X03X06.HTM#%2021
-# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2001/03/23x03x01.HTM#%2027
-# From Paul Eggert (2007-01-03):
-# Prefer the above source to Shanks & Pottenger for time stamps after 1990.
+# From Kıvanç Yazan (2016-09-25):
+# 1) For 1986-2006, DST started at 01:00 local and ended at 02:00 local, with
+# no exceptions.
+# 2) 1994's lastSun was overridden with Mar 20 ...
+# Here are official papers:
+# http://www.resmigazete.gov.tr/arsiv/19032.pdf - page 2 for 1986
+# http://www.resmigazete.gov.tr/arsiv/19400.pdf - page 4 for 1987
+# http://www.resmigazete.gov.tr/arsiv/19752.pdf - page 15 for 1988
+# http://www.resmigazete.gov.tr/arsiv/20102.pdf - page 6 for 1989
+# http://www.resmigazete.gov.tr/arsiv/20464.pdf - page 1 for 1990 - 1992
+# http://www.resmigazete.gov.tr/arsiv/21531.pdf - page 15 for 1993 - 1995
+# http://www.resmigazete.gov.tr/arsiv/21879.pdf - page 1 for overriding 1994
+# http://www.resmigazete.gov.tr/arsiv/22588.pdf - page 1 for 1996, 1997
+# http://www.resmigazete.gov.tr/arsiv/23286.pdf - page 10 for 1998 - 2000
+# http://www.resmigazete.gov.tr/eskiler/2001/03/20010324.htm#2 - for 2001
+# http://www.resmigazete.gov.tr/eskiler/2002/03/20020316.htm#2 - for 2002-2006
+# From Paul Eggert (2016-09-25):
+# Prefer the above sources to Shanks & Pottenger for time stamps after 1985.
# From Steffen Thorsen (2007-03-09):
# Starting 2007 though, it seems that they are adopting EU's 1:00 UTC
@@ -3551,10 +3553,10 @@ Rule Turkey 1983 only - Jul 31 0:00 1:00 S
Rule Turkey 1983 only - Oct 2 0:00 0 -
Rule Turkey 1985 only - Apr 20 0:00 1:00 S
Rule Turkey 1985 only - Sep 28 0:00 0 -
-Rule Turkey 1986 1990 - Mar lastSun 2:00s 1:00 S
-Rule Turkey 1986 1990 - Sep lastSun 2:00s 0 -
-Rule Turkey 1991 2006 - Mar lastSun 1:00s 1:00 S
-Rule Turkey 1991 1995 - Sep lastSun 1:00s 0 -
+Rule Turkey 1986 1993 - Mar lastSun 1:00s 1:00 S
+Rule Turkey 1986 1995 - Sep lastSun 1:00s 0 -
+Rule Turkey 1994 only - Mar 20 1:00s 1:00 S
+Rule Turkey 1995 2006 - Mar lastSun 1:00s 1:00 S
Rule Turkey 1996 2006 - Oct lastSun 1:00s 0 -
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Istanbul 1:55:52 - LMT 1880
diff --git a/contrib/tzdata/northamerica b/contrib/tzdata/northamerica
index 0bafb00a22c3..e1ed9e4a8720 100644
--- a/contrib/tzdata/northamerica
+++ b/contrib/tzdata/northamerica
@@ -24,8 +24,32 @@
# was the result of his proposals at the Convention of Railroad Trunk Lines
# in New York City (1869-10). His 1870 proposal was based on Washington, DC,
# but in 1872-05 he moved the proposed origin to Greenwich.
-# His proposal was adopted by the railroads on 1883-11-18 at 12:00,
-# and the most of the country soon followed suit.
+
+# From Paul Eggert (2016-09-21):
+# Dowd's proposal left many details unresolved, such as where to draw
+# lines between time zones. The key individual who made time zones
+# work in the US was William Frederick Allen - railway engineer,
+# managing editor of the Travelers' Guide, and secretary of the
+# General Time Convention, a railway standardization group. Allen
+# spent months in dialogs with scientific and railway leaders,
+# developed a workable plan to institute time zones, and presented it
+# to the General Time Convention on 1883-04-11, saying that his plan
+# meant "local time would be practically abolished" - a plus for
+# railway scheduling. By the next convention on 1883-10-11 nearly all
+# railroads had agreed and it took effect on 1883-11-18 at 12:00.
+# That Sunday was called the "day of two noons", as the eastern parts
+# of the new zones observed noon twice. Allen witnessed the
+# transition in New York City, writing:
+#
+# I heard the bells of St. Paul's strike on the old time. Four
+# minutes later, obedient to the electrical signal from the Naval
+# Observatory ... the time-ball made its rapid descent, the chimes
+# of old Trinity rang twelve measured strokes, and local time was
+# abandoned, probably forever.
+#
+# Most of the US soon followed suit. See:
+# Bartky IR. The adoption of standard time. Technol Cult 1989 Jan;30(1):25-56.
+# http://dx.doi.org/10.2307/3105430
# From Paul Eggert (2005-04-16):
# That 1883 transition occurred at 12:00 new time, not at 12:00 old time.
diff --git a/crypto/openssl/crypto/aes/asm/aesv8-armx.pl b/crypto/openssl/crypto/aes/asm/aesv8-armx.pl
index 95ebae3beb9b..0ed263fbe2f9 100755
--- a/crypto/openssl/crypto/aes/asm/aesv8-armx.pl
+++ b/crypto/openssl/crypto/aes/asm/aesv8-armx.pl
@@ -42,7 +42,7 @@ $code=<<___;
#if __ARM_MAX_ARCH__>=7
.text
___
-$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/);
+# $code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/);
$code.=".arch armv7-a\n.fpu neon\n.code 32\n" if ($flavour !~ /64/);
#^^^^^^ this is done to simplify adoption by not depending
# on latest binutils.
diff --git a/crypto/openssl/crypto/arm64cpuid.S b/crypto/openssl/crypto/arm64cpuid.S
index 4778ac1deacc..d16a7b53488e 100644
--- a/crypto/openssl/crypto/arm64cpuid.S
+++ b/crypto/openssl/crypto/arm64cpuid.S
@@ -1,7 +1,6 @@
#include "arm_arch.h"
.text
-.arch armv8-a+crypto
.align 5
.global _armv7_neon_probe
diff --git a/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl b/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl
index 0886d2180702..3026b44ab579 100755
--- a/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl
+++ b/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl
@@ -49,7 +49,7 @@ $code=<<___;
.text
___
-$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/);
+# $code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/);
$code.=".fpu neon\n.code 32\n" if ($flavour !~ /64/);
################################################################################
diff --git a/etc/devd/usb.conf b/etc/devd/usb.conf
index 3d8858b95d7a..3c6e560810d1 100644
--- a/etc/devd/usb.conf
+++ b/etc/devd/usb.conf
@@ -2713,7 +2713,7 @@ nomatch 32 {
match "bus" "uhub[0-9]+";
match "mode" "host";
match "vendor" "0x0bda";
- match "product" "0x8152";
+ match "product" "(0x8152|0x8153)";
action "kldload -n if_ure";
};
diff --git a/etc/mtree/BSD.root.dist b/etc/mtree/BSD.root.dist
index 1c1a1ddad177..3a7bdeb6d4a8 100644
--- a/etc/mtree/BSD.root.dist
+++ b/etc/mtree/BSD.root.dist
@@ -32,6 +32,8 @@
..
casper
..
+ cron.d
+ ..
defaults
..
devd
diff --git a/etc/rc b/etc/rc
index 278c9de494c3..b2ffe0f7a04c 100644
--- a/etc/rc
+++ b/etc/rc
@@ -135,16 +135,16 @@ done
# Note: this assumes firstboot_sentinel is on / when we have
# a read-only /, or that it is on media that's writable.
if [ -e ${firstboot_sentinel} ]; then
- [ ${root_rw_mount#[Yy][Ee][Ss]} = "" ] || mount -uw /
+ checkyesno root_rw_mount && mount -uw /
chflags -R 0 ${firstboot_sentinel}
rm -rf ${firstboot_sentinel}
if [ -e ${firstboot_sentinel}-reboot ]; then
chflags -R 0 ${firstboot_sentinel}-reboot
rm -rf ${firstboot_sentinel}-reboot
- [ ${root_rw_mount#[Yy][Ee][Ss]} = "" ] || mount -ur /
+ checkyesno root_rw_mount && mount -ur /
kill -INT 1
fi
- [ ${root_rw_mount#[Yy][Ee][Ss]} = "" ] || mount -ur /
+ checkyesno root_rw_mount && mount -ur /
fi
echo ''
diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile
index ad43a20a268f..320e550aeb8a 100644
--- a/etc/rc.d/Makefile
+++ b/etc/rc.d/Makefile
@@ -118,14 +118,17 @@ FILES= DAEMON \
ugidfw \
${_utx} \
var \
- watchdogd \
- ypbind \
+ watchdogd
+
+.if ${MK_NIS} != "no"
+FILES+= ypbind \
ypldap \
yppasswdd \
ypserv \
ypset \
ypupdated \
ypxfrd
+.endif
.if ${MK_ACCT} != "no"
FILESGROUPS+= ACCT
diff --git a/etc/rc.d/swaplate b/etc/rc.d/swaplate
index f335481b6e47..fbfae2ad9bfe 100755
--- a/etc/rc.d/swaplate
+++ b/etc/rc.d/swaplate
@@ -12,7 +12,7 @@
name="swaplate"
desc="Setup late swap space"
start_cmd='/sbin/swapon -aLq'
-stop_cmd='/sbin/swapoff -aq'
+stop_cmd='/sbin/swapoff -aLq'
load_rc_config swap
run_rc_command "$1"
diff --git a/gnu/lib/libgcc/Makefile b/gnu/lib/libgcc/Makefile
index b101b4f2ea91..fba02ed935df 100644
--- a/gnu/lib/libgcc/Makefile
+++ b/gnu/lib/libgcc/Makefile
@@ -165,7 +165,7 @@ LIBADD+= compiler_rt
.if ${TARGET_CPUARCH} == mips
LIB2FUNCS_EXTRA = floatunsidf.c floatunsisf.c
# ABIs other than o32 need this
-.if ${TARGET_ARCH} != "mips" && ${TARGET_ARCH} != "mipsel"
+.if ${TARGET_ARCH:Mmips64*} != "" || ${TARGET_ARCH:Mmipsn32*} != ""
LIB2FUNCS_EXTRA+= floatdidf.c fixunsdfsi.c
LIB2FUNCS_EXTRA+= floatdisf.c floatundidf.c
LIB2FUNCS_EXTRA+= fixsfdi.c floatundisf.c
@@ -173,7 +173,7 @@ LIB2FUNCS_EXTRA+= fixdfdi.c fixunssfsi.c
.endif
.endif
-.if ${TARGET_ARCH} == "powerpc"
+.if ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "powerpcspe"
# from config/rs6000/t-ppccomm
LIB2FUNCS_EXTRA = tramp.asm
LIB2FUNCS_STATIC_EXTRA = eabi.asm
diff --git a/gnu/lib/libgomp/Makefile b/gnu/lib/libgomp/Makefile
index d428bd3f24c6..b4abf7958bcc 100644
--- a/gnu/lib/libgomp/Makefile
+++ b/gnu/lib/libgomp/Makefile
@@ -24,7 +24,7 @@ VERSION_MAP= ${SRCDIR}/libgomp.map
# Target-specific OpenMP configuration
.if ${MACHINE_CPUARCH} == arm || ${MACHINE_CPUARCH} == i386 || \
- ${MACHINE_ARCH} == powerpc || \
+ ${MACHINE_ARCH} == powerpc || ${MACHINE_ARCH} == powerpcspe || \
(${MACHINE_CPUARCH} == mips && ${MACHINE_ARCH:Mmips64*} == "")
OMP_LOCK_ALIGN = 4
OMP_LOCK_KIND= 4
diff --git a/gnu/usr.bin/binutils/Makefile.inc0 b/gnu/usr.bin/binutils/Makefile.inc0
index 28062d587393..62d03cd0a461 100644
--- a/gnu/usr.bin/binutils/Makefile.inc0
+++ b/gnu/usr.bin/binutils/Makefile.inc0
@@ -7,7 +7,7 @@
VERSION= "2.17.50 [FreeBSD] 2007-07-03"
.if defined(TARGET_ARCH)
-TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/}
+TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
.else
TARGET_CPUARCH=${MACHINE_CPUARCH}
.endif
@@ -17,7 +17,7 @@ TARGET_OS?= freebsd
BINUTILS_ARCH=${TARGET_ARCH:C/amd64/x86_64/}
TARGET_TUPLE?= ${BINUTILS_ARCH}-${TARGET_VENDOR}-${TARGET_OS}
.if ${TARGET_ARCH} == "armeb" || ${TARGET_ARCH} == "armv6eb" || \
- (${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el} == "")
+ (${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el*} == "")
TARGET_BIG_ENDIAN=t
.endif
@@ -30,7 +30,7 @@ RELSRC= ${RELTOP}/../../../contrib/binutils
SRCDIR= ${.CURDIR}/${RELSRC}
.if ${TARGET_CPUARCH} == "arm" || ${TARGET_CPUARCH} == "i386" || \
- ${TARGET_ARCH} == "powerpc" || \
+ ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "powerpcspe" || \
(${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips64*} == "")
CFLAGS+= -DBFD_DEFAULT_TARGET_SIZE=32
.else
diff --git a/gnu/usr.bin/binutils/ld/Makefile.mips b/gnu/usr.bin/binutils/ld/Makefile.mips
index 8a7dfbb5f116..afc651cfca9d 100644
--- a/gnu/usr.bin/binutils/ld/Makefile.mips
+++ b/gnu/usr.bin/binutils/ld/Makefile.mips
@@ -1,6 +1,6 @@
# $FreeBSD$
-.if ${TARGET_ARCH:Mmips*el} != ""
+.if ${TARGET_ARCH:Mmips*el*} != ""
_EMULATION_ENDIAN=l
.else
_EMULATION_ENDIAN=b
diff --git a/gnu/usr.bin/binutils/libbfd/Makefile.mips b/gnu/usr.bin/binutils/libbfd/Makefile.mips
index 02026ba5c087..9a2781a410e2 100644
--- a/gnu/usr.bin/binutils/libbfd/Makefile.mips
+++ b/gnu/usr.bin/binutils/libbfd/Makefile.mips
@@ -1,6 +1,6 @@
# $FreeBSD$
-.if ${TARGET_ARCH:Mmips*el} != ""
+.if ${TARGET_ARCH:Mmips*el*} != ""
_EMULATION_ENDIAN=little
.else
_EMULATION_ENDIAN=big
diff --git a/gnu/usr.bin/cc/Makefile.inc b/gnu/usr.bin/cc/Makefile.inc
index 1d66b3dee7ff..3f053948bada 100644
--- a/gnu/usr.bin/cc/Makefile.inc
+++ b/gnu/usr.bin/cc/Makefile.inc
@@ -39,7 +39,7 @@ CFLAGS += -DFREEBSD_ARCH_armv6
.endif
.if ${TARGET_CPUARCH} == "mips"
-.if ${TARGET_ARCH:Mmips*el} != ""
+.if ${TARGET_ARCH:Mmips*el*} != ""
CFLAGS += -DTARGET_ENDIAN_DEFAULT=0
.endif
diff --git a/gnu/usr.bin/cc/Makefile.tgt b/gnu/usr.bin/cc/Makefile.tgt
index 63be261ff48d..3acd4d7c9295 100644
--- a/gnu/usr.bin/cc/Makefile.tgt
+++ b/gnu/usr.bin/cc/Makefile.tgt
@@ -4,7 +4,7 @@
# MACHINE_CPUARCH, but there's no easy way to export make functions...
.if defined(TARGET_ARCH)
-TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/}
+TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
.else
TARGET_CPUARCH=${MACHINE_CPUARCH}
.endif
@@ -15,7 +15,7 @@ GCC_CPU=${TARGET_CPUARCH:C/amd64/i386/:C/powerpc/rs6000/:C/sparc64/sparc/}
TARGET_CPU_DEFAULT= TARGET_CPU_ultrasparc
.endif
.if ${TARGET_ARCH} == "armeb" || ${TARGET_ARCH} == "armv6eb" || \
- (${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el} == "")
+ (${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el*} == "")
TARGET_BIG_ENDIAN=t
.endif
.if ${TARGET_ARCH} == "powerpc64"
diff --git a/gnu/usr.bin/cc/cc_tools/Makefile.hdrs b/gnu/usr.bin/cc/cc_tools/Makefile.hdrs
index 959d7a73e985..f2576f7fdf0a 100644
--- a/gnu/usr.bin/cc/cc_tools/Makefile.hdrs
+++ b/gnu/usr.bin/cc/cc_tools/Makefile.hdrs
@@ -46,6 +46,10 @@ TARGET_INC+= ${GCC_CPU}/bpabi.h
TARGET_INC+= ${GCC_CPU}/biarch64.h
TARGET_INC+= ${GCC_CPU}/default64.h
.endif
+.if ${TARGET_ARCH} == "powerpcspe"
+TARGET_INC+= ${GCC_CPU}/freebsdspe.h
+TARGET_INC+= ${GCC_CPU}/e500-double.h
+.endif
TARGET_INC+= ${GCC_CPU}/freebsd.h
.if ${TARGET_CPUARCH} == "amd64"
TARGET_INC+= ${GCC_CPU}/freebsd64.h
diff --git a/gnu/usr.bin/cc/include/Makefile b/gnu/usr.bin/cc/include/Makefile
index 48060ecc7750..bcca48a7a722 100644
--- a/gnu/usr.bin/cc/include/Makefile
+++ b/gnu/usr.bin/cc/include/Makefile
@@ -14,7 +14,8 @@ INCS= ammintrin.h emmintrin.h mmintrin.h mm3dnow.h pmmintrin.h \
INCS+= wmmintrin.h __wmmintrin_aes.h __wmmintrin_pclmul.h
.elif ${TARGET_ARCH} == "arm"
INCS= mmintrin.h
-.elif ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "powerpc64"
+.elif ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "powerpc64" || \
+ ${TARGET_ARCH} == "powerpcspe"
INCS= ppc-asm.h altivec.h spe.h
.endif
diff --git a/gnu/usr.bin/gdb/Makefile.inc b/gnu/usr.bin/gdb/Makefile.inc
index 34dc90797d08..c9b6603f1992 100644
--- a/gnu/usr.bin/gdb/Makefile.inc
+++ b/gnu/usr.bin/gdb/Makefile.inc
@@ -23,7 +23,7 @@ OBJ_RL= ${OBJ_ROOT}/../lib/libreadline/readline
# MACHINE_CPUARCH, but there's no easy way to export make functions...
.if defined(TARGET_ARCH)
-TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/}
+TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
.else
TARGET_CPUARCH=${MACHINE_CPUARCH}
.endif
diff --git a/gnu/usr.bin/gdb/libgdb/Makefile b/gnu/usr.bin/gdb/libgdb/Makefile
index ed00525fad3f..272ede7ded4b 100644
--- a/gnu/usr.bin/gdb/libgdb/Makefile
+++ b/gnu/usr.bin/gdb/libgdb/Makefile
@@ -4,7 +4,7 @@
# MACHINE_CPUARCH, but there's no easy way to export make functions...
.if defined(TARGET_ARCH)
-TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/}
+TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/}
.else
TARGET_CPUARCH=${MACHINE_CPUARCH}
.endif
diff --git a/include/limits.h b/include/limits.h
index a1e1b9820821..0d37af4014cc 100644
--- a/include/limits.h
+++ b/include/limits.h
@@ -120,7 +120,7 @@
#endif
#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809
-#define NL_ARGMAX 99 /* max # of position args for printf */
+#define NL_ARGMAX 65536 /* max # of position args for printf */
#define NL_MSGMAX 32767
#define NL_SETMAX 255
#define NL_TEXTMAX 2048
diff --git a/include/stddef.h b/include/stddef.h
index 7898da251a6e..7f2d2f0cd4bd 100644
--- a/include/stddef.h
+++ b/include/stddef.h
@@ -62,6 +62,14 @@ typedef ___wchar_t wchar_t;
#endif
#endif
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
+#ifndef __CLANG_MAX_ALIGN_T_DEFINED
+typedef __max_align_t max_align_t;
+#define __CLANG_MAX_ALIGN_T_DEFINED
+#define __GCC_MAX_ALIGN_T
+#endif
+#endif
+
#define offsetof(type, member) __offsetof(type, member)
#endif /* _STDDEF_H_ */
diff --git a/lib/libarchive/Makefile b/lib/libarchive/Makefile
index ce390f8372eb..67aff5cecb26 100644
--- a/lib/libarchive/Makefile
+++ b/lib/libarchive/Makefile
@@ -30,7 +30,7 @@ SHARED_CFLAGS+= -DHAVE_ICONV=1 -DHAVE_ICONV_H=1 -DICONV_CONST=
.endif
.if ${MACHINE_ARCH:Marm*} != "" || ${MACHINE_ARCH:Mmips*} != "" || \
- ${MACHINE_ARCH:Msparc64*} != ""
+ ${MACHINE_ARCH:Msparc64*} != "" || ${MACHINE_ARCH:Mpowerpc*} != ""
NO_WCAST_ALIGN= yes
.if ${MACHINE_ARCH:M*64*} == ""
CFLAGS+= -DPPMD_32BIT
diff --git a/lib/libc/Makefile b/lib/libc/Makefile
index a97b6fcdedb4..99ddfc2e8f7f 100644
--- a/lib/libc/Makefile
+++ b/lib/libc/Makefile
@@ -111,7 +111,7 @@ NOASM=
.include "${LIBC_SRCTOP}/xdr/Makefile.inc"
.if (${LIBC_ARCH} == "arm" && \
(${MACHINE_ARCH:Marmv6*} == "" || (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))) || \
- ${LIBC_ARCH} == "mips"
+ (${LIBC_ARCH} == "mips" && ${MACHINE_ARCH:Mmips*hf} == "")
.include "${LIBC_SRCTOP}/softfloat/Makefile.inc"
.endif
.if ${LIBC_ARCH} == "i386" || ${LIBC_ARCH} == "amd64"
diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3
index 4594d9af9a50..633f364b9f2a 100644
--- a/lib/libc/gen/sysctl.3
+++ b/lib/libc/gen/sysctl.3
@@ -183,16 +183,16 @@ The top level names are defined with a CTL_ prefix in
and are as follows.
The next and subsequent levels down are found in the include files
listed here, and described in separate sections below.
-.Bl -column CTLXMACHDEPXXX "Next level namesXXXXXX" -offset indent
-.It Sy "Name Next level names Description"
-.It "CTL_DEBUG sys/sysctl.h Debugging"
-.It "CTL_VFS sys/mount.h File system"
-.It "CTL_HW sys/sysctl.h Generic CPU, I/O"
-.It "CTL_KERN sys/sysctl.h High kernel limits"
-.It "CTL_MACHDEP sys/sysctl.h Machine dependent"
-.It "CTL_NET sys/socket.h Networking"
-.It "CTL_USER sys/sysctl.h User-level"
-.It "CTL_VM vm/vm_param.h Virtual memory"
+.Bl -column CTLXMACHDEPXXX "Next Level NamesXXXXXX" -offset indent
+.It Sy Name Ta Sy Next Level Names Ta Sy Description
+.It Dv CTL_DEBUG Ta In sys/sysctl.h Ta Debugging
+.It Dv CTL_VFS Ta In sys/mount.h Ta File system
+.It Dv CTL_HW Ta In sys/sysctl.h Ta Generic CPU, I/O
+.It Dv CTL_KERN Ta In sys/sysctl.h Ta High kernel limits
+.It Dv CTL_MACHDEP Ta In sys/sysctl.h Ta Machine dependent
+.It Dv CTL_NET Ta In sys/socket.h Ta Networking
+.It Dv CTL_USER Ta In sys/sysctl.h Ta User-level
+.It Dv CTL_VM Ta In vm/vm_param.h Ta Virtual memory
.El
.Pp
For example, the following retrieves the maximum number of processes allowed
@@ -270,20 +270,20 @@ The string and integer information available for the CTL_HW level
is detailed below.
The changeable column shows whether a process with appropriate
privilege may change the value.
-.Bl -column "Second level nameXXXXXX" integerXXX -offset indent
-.It Sy "Second level name Type Changeable"
-.It "HW_MACHINE string no"
-.It "HW_MODEL string no"
-.It "HW_NCPU integer no"
-.It "HW_BYTEORDER integer no"
-.It "HW_PHYSMEM integer no"
-.It "HW_USERMEM integer no"
-.It "HW_PAGESIZE integer no"
-.\".It "HW_DISKNAMES integer no"
-.\".It "HW_DISKSTATS integer no"
-.It "HW_FLOATINGPT integer no"
-.It "HW_MACHINE_ARCH string no"
-.It "HW_REALMEM integer no"
+.Bl -column "Second Level Name" integerXXX Changeable -offset indent
+.It Sy Second Level Name Ta Sy Type Ta Sy Changeable
+.It Dv HW_MACHINE Ta string Ta no
+.It Dv HW_MODEL Ta string Ta no
+.It Dv HW_NCPU Ta integer Ta no
+.It Dv HW_BYTEORDER Ta integer Ta no
+.It Dv HW_PHYSMEM Ta integer Ta no
+.It Dv HW_USERMEM Ta integer Ta no
+.It Dv HW_PAGESIZE Ta integer Ta no
+.\".It Dv HW_DISKNAMES Ta integer Ta no
+.\".It Dv HW_DISKSTATS Ta integer Ta no
+.It Dv HW_FLOATINGPT Ta integer Ta no
+.It Dv HW_MACHINE_ARCH Ta string Ta no
+.It Dv HW_REALMEM Ta integer Ta no
.El
.Bl -tag -width 6n
.It Li HW_MACHINE
@@ -293,7 +293,7 @@ The machine model
.It Li HW_NCPU
The number of cpus.
.It Li HW_BYTEORDER
-The byteorder (4,321, or 1,234).
+The byteorder (4321 or 1234).
.It Li HW_PHYSMEM
The bytes of physical memory.
.It Li HW_USERMEM
@@ -319,36 +319,36 @@ system vnodes, the open file entries, routing table entries,
virtual memory statistics, load average history, and clock rate
information.
.Bl -column "KERNXMAXFILESPERPROCXXX" "struct clockrateXXX" -offset indent
-.It Sy "Second level name Type Changeable"
-.It "KERN_ARGMAX integer no"
-.It "KERN_BOOTFILE string yes"
-.It "KERN_BOOTTIME struct timeval no"
-.It "KERN_CLOCKRATE struct clockinfo no"
-.It "KERN_FILE struct xfile no"
-.It "KERN_HOSTID integer yes"
-.It "KERN_HOSTUUID string yes"
-.It "KERN_HOSTNAME string yes"
-.It "KERN_JOB_CONTROL integer no"
-.It "KERN_MAXFILES integer yes"
-.It "KERN_MAXFILESPERPROC integer yes"
-.It "KERN_MAXPROC integer no"
-.It "KERN_MAXPROCPERUID integer yes"
-.It "KERN_MAXVNODES integer yes"
-.It "KERN_NGROUPS integer no"
-.It "KERN_NISDOMAINNAME string yes"
-.It "KERN_OSRELDATE integer no"
-.It "KERN_OSRELEASE string no"
-.It "KERN_OSREV integer no"
-.It "KERN_OSTYPE string no"
-.It "KERN_POSIX1 integer no"
-.It "KERN_PROC node not applicable"
-.It "KERN_PROF node not applicable"
-.It "KERN_QUANTUM integer yes"
-.It "KERN_SAVED_IDS integer no"
-.It "KERN_SECURELVL integer raise only"
-.It "KERN_UPDATEINTERVAL integer no"
-.It "KERN_VERSION string no"
-.It "KERN_VNODE struct xvnode no"
+.It Sy Second Level Name Ta Sy Type Ta Sy Changeable
+.It Dv KERN_ARGMAX Ta integer Ta no
+.It Dv KERN_BOOTFILE Ta string Ta yes
+.It Dv KERN_BOOTTIME Ta struct timeval Ta no
+.It Dv KERN_CLOCKRATE Ta struct clockinfo Ta no
+.It Dv KERN_FILE Ta struct xfile Ta no
+.It Dv KERN_HOSTID Ta integer Ta yes
+.It Dv KERN_HOSTUUID Ta string Ta yes
+.It Dv KERN_HOSTNAME Ta string Ta yes
+.It Dv KERN_JOB_CONTROL Ta integer Ta no
+.It Dv KERN_MAXFILES Ta integer Ta yes
+.It Dv KERN_MAXFILESPERPROC Ta integer Ta yes
+.It Dv KERN_MAXPROC Ta integer Ta no
+.It Dv KERN_MAXPROCPERUID Ta integer Ta yes
+.It Dv KERN_MAXVNODES Ta integer Ta yes
+.It Dv KERN_NGROUPS Ta integer Ta no
+.It Dv KERN_NISDOMAINNAME Ta string Ta yes
+.It Dv KERN_OSRELDATE Ta integer Ta no
+.It Dv KERN_OSRELEASE Ta string Ta no
+.It Dv KERN_OSREV Ta integer Ta no
+.It Dv KERN_OSTYPE Ta string Ta no
+.It Dv KERN_POSIX1 Ta integer Ta no
+.It Dv KERN_PROC Ta node Ta not applicable
+.It Dv KERN_PROF Ta node Ta not applicable
+.It Dv KERN_QUANTUM Ta integer Ta yes
+.It Dv KERN_SAVED_IDS Ta integer Ta no
+.It Dv KERN_SECURELVL Ta integer Ta raise only
+.It Dv KERN_UPDATEINTERVAL Ta integer Ta no
+.It Dv KERN_VERSION Ta string Ta no
+.It Dv KERN_VNODE Ta struct xvnode Ta no
.El
.Bl -tag -width 6n
.It Li KERN_ARGMAX
@@ -439,14 +439,14 @@ For the following names, an array of
.Va struct kinfo_proc
structures is returned,
whose size depends on the current number of such objects in the system.
-.Bl -column "Third level nameXXXXXX" "Fourth level is:XXXXXX" -offset indent
-.It "Third level name Fourth level is:"
-.It "KERN_PROC_ALL None"
-.It "KERN_PROC_PID A process ID"
-.It "KERN_PROC_PGRP A process group"
-.It "KERN_PROC_TTY A tty device"
-.It "KERN_PROC_UID A user ID"
-.It "KERN_PROC_RUID A real user ID"
+.Bl -column "Third Level NameXXXXXX" "Fourth LevelXXXXXX" -offset indent
+.It Sy Third Level Name Ta Sy Fourth Level
+.It Dv KERN_PROC_ALL Ta None
+.It Dv KERN_PROC_PID Ta A process ID
+.It Dv KERN_PROC_PGRP Ta A process group
+.It Dv KERN_PROC_TTY Ta A tty device
+.It Dv KERN_PROC_UID Ta A user ID
+.It Dv KERN_PROC_RUID Ta A real user ID
.El
.Pp
If the third level name is
@@ -465,8 +465,8 @@ For
a process ID of
.Li \-1
implies the current process.
-.Bl -column "Third level nameXXXXXX" "Fourth level is:XXXXXX" -offset indent
-.It Sy "Third level name Fourth level is:"
+.Bl -column "Third Level NameXXXXXX" "Fourth LevelXXXXXX" -offset indent
+.It Sy Third Level Name Ta Sy Fourth Level
.It Dv KERN_PROC_ARGS Ta "A process ID"
.It Dv KERN_PROC_PATHNAME Ta "A process ID"
.El
@@ -481,12 +481,12 @@ is detailed below.
The changeable column shows whether a process with appropriate
privilege may change the value.
.Bl -column "GPROFXGMONPARAMXXX" "struct gmonparamXXX" -offset indent
-.It Sy "Third level name Type Changeable"
-.It "GPROF_STATE integer yes"
-.It "GPROF_COUNT u_short[\|] yes"
-.It "GPROF_FROMS u_short[\|] yes"
-.It "GPROF_TOS struct tostruct yes"
-.It "GPROF_GMONPARAM struct gmonparam no"
+.It Sy Third Level Name Ta Sy Type Ta Sy Changeable
+.It Dv GPROF_STATE Ta integer Ta yes
+.It Dv GPROF_COUNT Ta u_short[\|] Ta yes
+.It Dv GPROF_FROMS Ta u_short[\|] Ta yes
+.It Dv GPROF_TOS Ta struct tostruct Ta yes
+.It Dv GPROF_GMONPARAM Ta struct gmonparam Ta no
.El
.Pp
The variables are as follows:
@@ -530,11 +530,11 @@ The string and integer information available for the CTL_NET level
is detailed below.
The changeable column shows whether a process with appropriate
privilege may change the value.
-.Bl -column "Second level nameXXXXXX" "routing messagesXXX" -offset indent
-.It Sy "Second level name Type Changeable"
-.It "PF_ROUTE routing messages no"
-.It "PF_INET IPv4 values yes"
-.It "PF_INET6 IPv6 values yes"
+.Bl -column "Second Level NameXXXXXX" "routing messagesXXX" -offset indent
+.It Sy Second Level Name Ta Sy Type Ta Sy Changeable
+.It Dv PF_ROUTE Ta routing messages Ta no
+.It Dv PF_INET Ta IPv4 values Ta yes
+.It Dv PF_INET6 Ta IPv6 values Ta yes
.El
.Bl -tag -width 6n
.It Li PF_ROUTE
@@ -548,13 +548,13 @@ The third level name is a protocol number, which is currently always 0.
The fourth level name is an address family, which may be set to 0 to
select all address families.
The fifth, sixth, and seventh level names are as follows:
-.Bl -column -offset indent "Fifth level Sixth level" "Seventh level"
-.It Sy "Fifth level Sixth level" Ta Sy "Seventh level"
-.It "NET_RT_FLAGS rtflags" Ta "None"
-.It "NET_RT_DUMP None" Ta "None or fib number"
-.It "NET_RT_IFLIST 0 or if_index" Ta None
-.It "NET_RT_IFMALIST 0 or if_index" Ta None
-.It "NET_RT_IFLISTL 0 or if_index" Ta None
+.Bl -column -offset indent "Fifth Level" "Sixth Level" "Seventh Level"
+.It Sy Fifth level Ta Sy Sixth Level Ta Sy Seventh Level
+.It Dv NET_RT_FLAGS Ta rtflags Ta None
+.It Dv NET_RT_DUMP Ta None Ta None or fib number
+.It Dv NET_RT_IFLIST Ta 0 or if_index Ta None
+.It Dv NET_RT_IFMALIST Ta 0 or if_index Ta None
+.It Dv NET_RT_IFLISTL Ta 0 or if_index Ta None
.El
.Pp
The
@@ -582,13 +582,13 @@ The third level name is the protocol.
The fourth level name is the variable name.
The currently defined protocols and names are:
.Bl -column ProtocolXX VariableXX TypeXX ChangeableXX
-.It Sy "Protocol Variable Type Changeable"
-.It "icmp bmcastecho integer yes"
-.It "icmp maskrepl integer yes"
-.It "ip forwarding integer yes"
-.It "ip redirect integer yes"
-.It "ip ttl integer yes"
-.It "udp checksum integer yes"
+.It Sy Protocol Ta Sy Variable Ta Sy Type Ta Sy Changeable
+.It icmp Ta bmcastecho Ta integer Ta yes
+.It icmp Ta maskrepl Ta integer Ta yes
+.It ip Ta forwarding Ta integer Ta yes
+.It ip Ta redirect Ta integer Ta yes
+.It ip Ta ttl Ta integer Ta yes
+.It udp Ta checksum Ta integer Ta yes
.El
.Pp
The variables are as follows:
@@ -633,27 +633,27 @@ is detailed below.
The changeable column shows whether a process with appropriate
privilege may change the value.
.Bl -column "USER_COLL_WEIGHTS_MAXXXX" "integerXXX" -offset indent
-.It Sy "Second level name Type Changeable"
-.It "USER_BC_BASE_MAX integer no"
-.It "USER_BC_DIM_MAX integer no"
-.It "USER_BC_SCALE_MAX integer no"
-.It "USER_BC_STRING_MAX integer no"
-.It "USER_COLL_WEIGHTS_MAX integer no"
-.It "USER_CS_PATH string no"
-.It "USER_EXPR_NEST_MAX integer no"
-.It "USER_LINE_MAX integer no"
-.It "USER_POSIX2_CHAR_TERM integer no"
-.It "USER_POSIX2_C_BIND integer no"
-.It "USER_POSIX2_C_DEV integer no"
-.It "USER_POSIX2_FORT_DEV integer no"
-.It "USER_POSIX2_FORT_RUN integer no"
-.It "USER_POSIX2_LOCALEDEF integer no"
-.It "USER_POSIX2_SW_DEV integer no"
-.It "USER_POSIX2_UPE integer no"
-.It "USER_POSIX2_VERSION integer no"
-.It "USER_RE_DUP_MAX integer no"
-.It "USER_STREAM_MAX integer no"
-.It "USER_TZNAME_MAX integer no"
+.It Sy Second Level Name Ta Sy Type Ta Sy Changeable
+.It Dv USER_BC_BASE_MAX Ta integer Ta no
+.It Dv USER_BC_DIM_MAX Ta integer Ta no
+.It Dv USER_BC_SCALE_MAX Ta integer Ta no
+.It Dv USER_BC_STRING_MAX Ta integer Ta no
+.It Dv USER_COLL_WEIGHTS_MAX Ta integer Ta no
+.It Dv USER_CS_PATH Ta string Ta no
+.It Dv USER_EXPR_NEST_MAX Ta integer Ta no
+.It Dv USER_LINE_MAX Ta integer Ta no
+.It Dv USER_POSIX2_CHAR_TERM Ta integer Ta no
+.It Dv USER_POSIX2_C_BIND Ta integer Ta no
+.It Dv USER_POSIX2_C_DEV Ta integer Ta no
+.It Dv USER_POSIX2_FORT_DEV Ta integer Ta no
+.It Dv USER_POSIX2_FORT_RUN Ta integer Ta no
+.It Dv USER_POSIX2_LOCALEDEF Ta integer Ta no
+.It Dv USER_POSIX2_SW_DEV Ta integer Ta no
+.It Dv USER_POSIX2_UPE Ta integer Ta no
+.It Dv USER_POSIX2_VERSION Ta integer Ta no
+.It Dv USER_RE_DUP_MAX Ta integer Ta no
+.It Dv USER_STREAM_MAX Ta integer Ta no
+.It Dv USER_TZNAME_MAX Ta integer Ta no
.El
.Bl -tag -width 6n
.It Li USER_BC_BASE_MAX
@@ -731,16 +731,16 @@ The string and integer information available for the CTL_VM level
is detailed below.
The changeable column shows whether a process with appropriate
privilege may change the value.
-.Bl -column "Second level nameXXXXXX" "struct loadavgXXX" -offset indent
-.It Sy "Second level name Type Changeable"
-.It "VM_LOADAVG struct loadavg no"
-.It "VM_TOTAL struct vmtotal no"
-.It "VM_SWAPPING_ENABLED integer maybe"
-.It "VM_V_FREE_MIN integer yes"
-.It "VM_V_FREE_RESERVED integer yes"
-.It "VM_V_FREE_TARGET integer yes"
-.It "VM_V_INACTIVE_TARGET integer yes"
-.It "VM_V_PAGEOUT_FREE_MIN integer yes"
+.Bl -column "Second Level NameXXXXXX" "struct loadavgXXX" -offset indent
+.It Sy Second Level Name Ta Sy Type Ta Sy Changeable
+.It Dv VM_LOADAVG Ta struct loadavg Ta no
+.It Dv VM_TOTAL Ta struct vmtotal Ta no
+.It Dv VM_SWAPPING_ENABLED Ta integer Ta maybe
+.It Dv VM_V_FREE_MIN Ta integer Ta yes
+.It Dv VM_V_FREE_RESERVED Ta integer Ta yes
+.It Dv VM_V_FREE_TARGET Ta integer Ta yes
+.It Dv VM_V_INACTIVE_TARGET Ta integer Ta yes
+.It Dv VM_V_PAGEOUT_FREE_MIN Ta integer Ta yes
.El
.Bl -tag -width 6n
.It Li VM_LOADAVG
diff --git a/lib/libc/mips/Makefile.inc b/lib/libc/mips/Makefile.inc
index 4ec20d47d1dd..54ce38e49bfa 100644
--- a/lib/libc/mips/Makefile.inc
+++ b/lib/libc/mips/Makefile.inc
@@ -1,7 +1,9 @@
# $NetBSD: Makefile.inc,v 1.7 2005/09/17 11:49:39 tsutsui Exp $
# $FreeBSD$
+.if ${MACHINE_ARCH:Mmips*hf} == ""
CFLAGS+=-DSOFTFLOAT
+.endif
MDSRCS+= machdep_ldisd.c
SYM_MAPS+= ${LIBC_SRCTOP}/mips/Symbol.map
diff --git a/lib/libc/mips/Symbol.map b/lib/libc/mips/Symbol.map
index 38680807adc4..9791359c93f6 100644
--- a/lib/libc/mips/Symbol.map
+++ b/lib/libc/mips/Symbol.map
@@ -31,6 +31,10 @@ FBSD_1.0 {
sbrk;
};
+FBSD_1.3 {
+ __flt_rounds;
+};
+
FBSDprivate_1.0 {
/* PSEUDO syscalls */
__sys_getlogin;
diff --git a/lib/libc/mips/gen/Makefile.inc b/lib/libc/mips/gen/Makefile.inc
index a186fda62036..56fa380f7777 100644
--- a/lib/libc/mips/gen/Makefile.inc
+++ b/lib/libc/mips/gen/Makefile.inc
@@ -1,7 +1,7 @@
# $NetBSD: Makefile.inc,v 1.27 2005/10/07 17:16:40 tsutsui Exp $
# $FreeBSD$
-SRCS+= infinity.c fabs.c ldexp.c
+SRCS+= infinity.c fabs.c ldexp.c flt_rounds.c
# SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \
# fpsetround.c fpsetsticky.c
diff --git a/lib/libc/mips/gen/flt_rounds.c b/lib/libc/mips/gen/flt_rounds.c
index 9fc64a537053..73428d907d11 100644
--- a/lib/libc/mips/gen/flt_rounds.c
+++ b/lib/libc/mips/gen/flt_rounds.c
@@ -11,7 +11,14 @@ __FBSDID("$FreeBSD$");
__RCSID("$NetBSD: flt_rounds.c,v 1.5 2005/12/24 23:10:08 perry Exp $");
#endif /* LIBC_SCCS and not lint */
-#include <machine/float.h>
+#include <fenv.h>
+#include <float.h>
+
+#ifdef SOFTFLOAT
+#include "softfloat-for-gcc.h"
+#include "milieu.h"
+#include "softfloat.h"
+#endif
static const int map[] = {
1, /* round to nearest */
@@ -23,8 +30,13 @@ static const int map[] = {
int
__flt_rounds()
{
- int x;
+ int mode;
+
+#ifdef SOFTFLOAT
+ mode = __softfloat_float_rounding_mode;
+#else
+ __asm __volatile("cfc1 %0,$31" : "=r" (mode));
+#endif
- __asm("cfc1 %0,$31" : "=r" (x));
- return map[x & 0x03];
+ return map[mode & 0x03];
}
diff --git a/lib/libc/powerpc/gen/Makefile.common b/lib/libc/powerpc/gen/Makefile.common
new file mode 100644
index 000000000000..4ba72799a5cf
--- /dev/null
+++ b/lib/libc/powerpc/gen/Makefile.common
@@ -0,0 +1,6 @@
+# $FreeBSD$
+
+.PATH: ${LIBC_SRCTOP}/powerpc/gen
+
+SRCS += _ctx_start.S eabi.S infinity.c ldexp.c makecontext.c \
+ signalcontext.c syncicache.c _set_tp.c trivial-getcontextx.c
diff --git a/lib/libc/powerpc/gen/Makefile.inc b/lib/libc/powerpc/gen/Makefile.inc
index 2a00ba332b94..f96ad9fb0a6f 100644
--- a/lib/libc/powerpc/gen/Makefile.inc
+++ b/lib/libc/powerpc/gen/Makefile.inc
@@ -1,11 +1,7 @@
# $FreeBSD$
-SRCS += _ctx_start.S eabi.S fabs.S flt_rounds.c fpgetmask.c fpgetround.c \
- fpgetsticky.c fpsetmask.c fpsetround.c \
- infinity.c ldexp.c makecontext.c _setjmp.S \
- setjmp.S sigsetjmp.S signalcontext.c syncicache.c \
- _set_tp.c \
- trivial-getcontextx.c
-
-
+.include "${LIBC_SRCTOP}/powerpc/gen/Makefile.common"
+SRCS += fabs.S flt_rounds.c fpgetmask.c fpgetround.c \
+ fpgetsticky.c fpsetmask.c fpsetround.c \
+ _setjmp.S setjmp.S sigsetjmp.S
diff --git a/lib/libc/powerpcspe/Makefile.inc b/lib/libc/powerpcspe/Makefile.inc
new file mode 100644
index 000000000000..3a7960ab378c
--- /dev/null
+++ b/lib/libc/powerpcspe/Makefile.inc
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+CFLAGS+= -I${LIBC_SRCTOP}/powerpc
+SRCS+= trivial-vdso_tc.c
+
+# Long double is 64-bits
+MDSRCS+=machdep_ldisd.c
+SYM_MAPS+=${LIBC_SRCTOP}/powerpc/Symbol.map
diff --git a/lib/libc/powerpcspe/gen/Makefile.inc b/lib/libc/powerpcspe/gen/Makefile.inc
new file mode 100644
index 000000000000..f96ad9fb0a6f
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/Makefile.inc
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+.include "${LIBC_SRCTOP}/powerpc/gen/Makefile.common"
+
+SRCS += fabs.S flt_rounds.c fpgetmask.c fpgetround.c \
+ fpgetsticky.c fpsetmask.c fpsetround.c \
+ _setjmp.S setjmp.S sigsetjmp.S
diff --git a/lib/libc/powerpcspe/gen/_setjmp.S b/lib/libc/powerpcspe/gen/_setjmp.S
new file mode 100644
index 000000000000..0dd28fa2deb4
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/_setjmp.S
@@ -0,0 +1,117 @@
+/*-
+ * Copyright (c) 2016 Justin Hibbits
+ * 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.
+ */
+/* $NetBSD: _setjmp.S,v 1.1 1997/03/29 20:55:53 thorpej Exp $ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ * _longjmp(a,v)
+ * will generate a "return(v?v:1)" from the last call to
+ * _setjmp(a)
+ * by restoring registers from the stack.
+ * The previous signal state is NOT restored.
+ *
+ * jmpbuf layout:
+ * +------------+
+ * | unused |
+ * +------------+
+ * | unused |
+ * | |
+ * | (4 words) |
+ * | |
+ * +------------+
+ * | saved regs |
+ * | ... |
+ */
+
+ENTRY(_setjmp)
+ mflr %r11
+ mfcr %r12
+ evstdd %r1,24+0*8(%r3)
+ evstdd %r2,24+1*8(%r3)
+ evstdd %r11,24+2*8(%r3)
+ evstdd %r12,24+3*8(%r3)
+ evstdd %r13,24+4*8(%r3)
+ evstdd %r14,24+5*8(%r3)
+ evstdd %r15,24+6*8(%r3)
+ evstdd %r16,24+7*8(%r3)
+ evstdd %r17,24+8*8(%r3)
+ evstdd %r18,24+9*8(%r3)
+ evstdd %r19,24+10*8(%r3)
+ evstdd %r20,24+11*8(%r3)
+ evstdd %r21,24+12*8(%r3)
+ evstdd %r22,24+13*8(%r3)
+ evstdd %r23,24+14*8(%r3)
+ evstdd %r24,24+15*8(%r3)
+ evstdd %r25,24+16*8(%r3)
+ evstdd %r26,24+17*8(%r3)
+ evstdd %r27,24+18*8(%r3)
+ evstdd %r28,24+19*8(%r3)
+ evstdd %r29,24+20*8(%r3)
+ evstdd %r30,24+21*8(%r3)
+ evstdd %r31,24+22*8(%r3)
+
+ li %r3,0
+ blr
+END(_setjmp)
+
+ENTRY(_longjmp)
+ evldd %r1,24+0*8(%r3)
+ evldd %r2,24+1*8(%r3)
+ evldd %r11,24+2*8(%r3)
+ evldd %r12,24+3*8(%r3)
+ evldd %r13,24+4*8(%r3)
+ evldd %r14,24+5*8(%r3)
+ evldd %r15,24+6*8(%r3)
+ evldd %r16,24+7*8(%r3)
+ evldd %r17,24+8*8(%r3)
+ evldd %r18,24+9*8(%r3)
+ evldd %r19,24+10*8(%r3)
+ evldd %r20,24+11*8(%r3)
+ evldd %r21,24+12*8(%r3)
+ evldd %r22,24+13*8(%r3)
+ evldd %r23,24+14*8(%r3)
+ evldd %r24,24+15*8(%r3)
+ evldd %r25,24+16*8(%r3)
+ evldd %r26,24+17*8(%r3)
+ evldd %r27,24+18*8(%r3)
+ evldd %r28,24+19*8(%r3)
+ evldd %r29,24+20*8(%r3)
+ evldd %r30,24+21*8(%r3)
+ evldd %r31,24+22*8(%r3)
+
+ mtlr %r11
+ mtcr %r12
+ or. %r3,%r4,%r4
+ bnelr
+ li %r3,1
+ blr
+END(_longjmp)
+
+ .section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/powerpcspe/gen/fabs.S b/lib/libc/powerpcspe/gen/fabs.S
new file mode 100644
index 000000000000..da806f025394
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/fabs.S
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 Justin Hibbits
+ * 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 <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * double fabs(double)
+ */
+ENTRY(fabs)
+ efdabs %f1,%f1
+ blr
+END(fabs)
+
+ .section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/powerpcspe/gen/flt_rounds.c b/lib/libc/powerpcspe/gen/flt_rounds.c
new file mode 100644
index 000000000000..1334021fb7fa
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/flt_rounds.c
@@ -0,0 +1,57 @@
+/* $NetBSD: flt_rounds.c,v 1.4.10.3 2002/03/22 20:41:53 nathanw Exp $ */
+
+/*
+ * Copyright (c) 2016 Justin Hibbits
+ * 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 Mark Brinicombe
+ * for the NetBSD Project.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <machine/float.h>
+#include <machine/spr.h>
+
+#ifndef _SOFT_FLOAT
+static const int map[] = {
+ 1, /* round to nearest */
+ 0, /* round to zero */
+ 2, /* round to positive infinity */
+ 3 /* round to negative infinity */
+};
+
+int
+__flt_rounds()
+{
+ uint32_t fpscr;
+
+ __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR));
+ return map[(fpscr & 0x03)];
+}
+#endif
diff --git a/lib/libc/powerpcspe/gen/fpgetmask.c b/lib/libc/powerpcspe/gen/fpgetmask.c
new file mode 100644
index 000000000000..3103e05ba41d
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/fpgetmask.c
@@ -0,0 +1,49 @@
+/* $NetBSD: fpgetmask.c,v 1.3 2002/01/13 21:45:47 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2016 Justin Hibbits
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dan Winship.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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/spr.h>
+#include <ieeefp.h>
+
+#ifndef _SOFT_FLOAT
+fp_except_t
+fpgetmask()
+{
+ uint32_t fpscr;
+
+ __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR));
+ return ((fp_except_t)((fpscr >> 3) & 0x1f));
+}
+#endif
diff --git a/lib/libc/powerpcspe/gen/fpgetround.c b/lib/libc/powerpcspe/gen/fpgetround.c
new file mode 100644
index 000000000000..7815559f7b5a
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/fpgetround.c
@@ -0,0 +1,49 @@
+/* $NetBSD: fpgetround.c,v 1.3 2002/01/13 21:45:47 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2016 Justin Hibbits
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dan Winship.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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/spr.h>
+#include <ieeefp.h>
+
+#ifndef _SOFT_FLOAT
+fp_rnd_t
+fpgetround()
+{
+ uint32_t fpscr;
+
+ __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR));
+ return ((fp_rnd_t)(fpscr & 0x3));
+}
+#endif
diff --git a/lib/libc/powerpcspe/gen/fpgetsticky.c b/lib/libc/powerpcspe/gen/fpgetsticky.c
new file mode 100644
index 000000000000..87962637bc3c
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/fpgetsticky.c
@@ -0,0 +1,55 @@
+/* $NetBSD: fpgetsticky.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2016 Justin Hibbits
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dan Winship.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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>
+
+#include "namespace.h"
+
+#include <sys/types.h>
+#include <machine/spr.h>
+#include <ieeefp.h>
+
+#ifndef _SOFT_FLOAT
+#ifdef __weak_alias
+__weak_alias(fpgetsticky,_fpgetsticky)
+#endif
+
+fp_except_t
+fpgetsticky()
+{
+ uint32_t fpscr;
+
+ __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR));
+ return ((fp_except_t)((fpscr >> 25) & 0x1f));
+}
+#endif
diff --git a/lib/libc/powerpcspe/gen/fpsetmask.c b/lib/libc/powerpcspe/gen/fpsetmask.c
new file mode 100644
index 000000000000..24c0b3828b7f
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/fpsetmask.c
@@ -0,0 +1,53 @@
+/* $NetBSD: fpsetmask.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2016 Justin Hibbits
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dan Winship.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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/spr.h>
+#include <ieeefp.h>
+
+#ifndef _SOFT_FLOAT
+fp_except_t
+fpsetmask(fp_except_t mask)
+{
+ uint32_t fpscr;
+ fp_rnd_t old;
+
+ __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR));
+ old = (fp_rnd_t)((fpscr >> 3) & 0x1f);
+ fpscr = (fpscr & 0xffffff07) | (mask << 3);
+ __asm__ __volatile("mtspr %1,%0" :: "r"(fpscr), "K"(SPR_SPEFSCR));
+ return (old);
+}
+#endif
diff --git a/lib/libc/powerpcspe/gen/fpsetround.c b/lib/libc/powerpcspe/gen/fpsetround.c
new file mode 100644
index 000000000000..b5340a6d9ea2
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/fpsetround.c
@@ -0,0 +1,53 @@
+/* $NetBSD: fpsetround.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */
+
+/*
+ * Copyright (c) 2016 Justin Hibbits
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Dan Winship.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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/spr.h>
+#include <ieeefp.h>
+
+#ifndef _SOFT_FLOAT
+fp_rnd_t
+fpsetround(fp_rnd_t rnd_dir)
+{
+ uint32_t fpscr;
+ fp_rnd_t old;
+
+ __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR) );
+ old = (fp_rnd_t)(fpscr & 0x3);
+ fpscr = (fpscr & 0xfffffffc) | rnd_dir;
+ __asm__ __volatile("mtspr %1, %0" :: "r"(fpscr), "K"(SPR_SPEFSCR));
+ return (old);
+}
+#endif
diff --git a/lib/libc/powerpcspe/gen/setjmp.S b/lib/libc/powerpcspe/gen/setjmp.S
new file mode 100644
index 000000000000..7a93b2f883e8
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/setjmp.S
@@ -0,0 +1,138 @@
+/*-
+ * Copyright (c) 2016 Justin Hibbits
+ * 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.
+ */
+/* $NetBSD: setjmp.S,v 1.3 1998/10/03 12:30:38 tsubai Exp $ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/syscall.h>
+
+/*
+ * C library -- setjmp, longjmp
+ *
+ * longjmp(a,v)
+ * will generate a "return(v?v:1)" from the last call to
+ * setjmp(a)
+ * by restoring registers from the stack.
+ * The previous signal state is restored.
+ *
+ * jmpbuf layout:
+ * +------------+
+ * | unused |
+ * +------------+
+ * | sig state |
+ * | |
+ * | (4 words) |
+ * | |
+ * +------------+
+ * | saved regs |
+ * | ... |
+ */
+
+ENTRY(setjmp)
+ mr %r6,%r3
+ li %r3,1 /* SIG_BLOCK, but doesn't matter */
+ /* since set == NULL */
+ li %r4,0 /* set = NULL */
+ mr %r5,%r6 /* &oset */
+ addi %r5,%r5,4
+ li %r0, SYS_sigprocmask /*sigprocmask(SIG_BLOCK, NULL, &oset)*/
+ sc /*assume no error XXX */
+ mflr %r11 /* r11 <- link reg */
+ mfcr %r12 /* r12 <- condition reg */
+ mr %r10,%r1 /* r10 <- stackptr */
+ mr %r9,%r2 /* r9 <- global ptr */
+ evstdd %r9,24+0*8(%r6)
+ evstdd %r10,24+1*8(%r6)
+ evstdd %r11,24+2*8(%r6)
+ evstdd %r12,24+3*8(%r6)
+ evstdd %r13,24+4*8(%r6)
+ evstdd %r14,24+5*8(%r6)
+ evstdd %r15,24+6*8(%r6)
+ evstdd %r16,24+7*8(%r6)
+ evstdd %r17,24+8*8(%r6)
+ evstdd %r18,24+9*8(%r6)
+ evstdd %r19,24+10*8(%r6)
+ evstdd %r20,24+11*8(%r6)
+ evstdd %r21,24+12*8(%r6)
+ evstdd %r22,24+13*8(%r6)
+ evstdd %r23,24+14*8(%r6)
+ evstdd %r24,24+15*8(%r6)
+ evstdd %r25,24+16*8(%r6)
+ evstdd %r26,24+17*8(%r6)
+ evstdd %r27,24+18*8(%r6)
+ evstdd %r28,24+19*8(%r6)
+ evstdd %r29,24+20*8(%r6)
+ evstdd %r30,24+21*8(%r6)
+ evstdd %r31,24+22*8(%r6)
+
+ li %r3,0 /* return (0) */
+ blr
+END(setjmp)
+
+ WEAK_REFERENCE(CNAME(__longjmp), longjmp)
+ENTRY(__longjmp)
+ evldd %r9,24+0*8(%r3)
+ evldd %r10,24+1*8(%r3)
+ evldd %r11,24+2*8(%r3)
+ evldd %r12,24+3*8(%r3)
+ evldd %r13,24+4*8(%r3)
+ evldd %r14,24+5*8(%r3)
+ evldd %r15,24+6*8(%r3)
+ evldd %r16,24+7*8(%r3)
+ evldd %r17,24+8*8(%r3)
+ evldd %r18,24+9*8(%r3)
+ evldd %r19,24+10*8(%r3)
+ evldd %r20,24+11*8(%r3)
+ evldd %r21,24+12*8(%r3)
+ evldd %r22,24+13*8(%r3)
+ evldd %r23,24+14*8(%r3)
+ evldd %r24,24+15*8(%r3)
+ evldd %r25,24+16*8(%r3)
+ evldd %r26,24+17*8(%r3)
+ evldd %r27,24+18*8(%r3)
+ evldd %r28,24+19*8(%r3)
+ evldd %r29,24+20*8(%r3)
+ evldd %r30,24+21*8(%r3)
+ evldd %r31,24+22*8(%r3)
+
+ mr %r6,%r4 /* save val param */
+ mtlr %r11 /* r11 -> link reg */
+ mtcr %r12 /* r12 -> condition reg */
+ mr %r1,%r10 /* r10 -> stackptr */
+ mr %r4,%r3
+ li %r3,3 /* SIG_SETMASK */
+ addi %r4,%r4,4 /* &set */
+ li %r5,0 /* oset = NULL */
+ li %r0,SYS_sigprocmask /* sigprocmask(SIG_SET, &set, NULL) */
+ sc /* assume no error XXX */
+ or. %r3,%r6,%r6
+ bnelr
+ li %r3,1
+ blr
+END(__longjmp)
+
+ .section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/powerpcspe/gen/sigsetjmp.S b/lib/libc/powerpcspe/gen/sigsetjmp.S
new file mode 100644
index 000000000000..0c12cc3f582b
--- /dev/null
+++ b/lib/libc/powerpcspe/gen/sigsetjmp.S
@@ -0,0 +1,150 @@
+/*-
+ * Copyright (c) 2016 Justin Hibbits
+ * 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.
+ */
+/* $NetBSD: sigsetjmp.S,v 1.4 1998/10/03 12:30:38 tsubai Exp $ */
+
+#include <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * C library -- sigsetjmp, siglongjmp
+ *
+ * siglongjmp(a,v)
+ * will generate a "return(v?v:1)" from the last call to
+ * sigsetjmp(a, savemask)
+ * by restoring registers from the stack.
+ * The previous signal state is restored if savemask is non-zero
+ *
+ * jmpbuf layout:
+ * +------------+
+ * | savemask |
+ * +------------+
+ * | sig state |
+ * | |
+ * | (4 words) |
+ * | |
+ * +------------+
+ * | saved regs |
+ * | ... |
+ */
+
+
+#include <sys/syscall.h>
+
+ENTRY(sigsetjmp)
+ mr %r6,%r3
+ stw %r4,0(%r3)
+ or. %r7,%r4,%r4
+ beq 1f
+ li %r3,1 /* SIG_BLOCK, but doesn't matter */
+ /* since set == NULL */
+ li %r4,0 /* set = NULL */
+ mr %r5,%r6 /* &oset */
+ addi %r5,%r5,4
+ li %r0, SYS_sigprocmask /* sigprocmask(SIG_BLOCK, NULL, &oset)*/
+ sc /* assume no error XXX */
+1:
+ mflr %r11
+ mfcr %r12
+ mr %r10,%r1
+ mr %r9,%r2
+
+ /* FPRs */
+ evstdd %r9,24+0*8(%r6)
+ evstdd %r10,24+1*8(%r6)
+ evstdd %r11,24+2*8(%r6)
+ evstdd %r12,24+3*8(%r6)
+ evstdd %r13,24+4*8(%r6)
+ evstdd %r14,24+5*8(%r6)
+ evstdd %r15,24+6*8(%r6)
+ evstdd %r16,24+7*8(%r6)
+ evstdd %r17,24+8*8(%r6)
+ evstdd %r18,24+9*8(%r6)
+ evstdd %r19,24+10*8(%r6)
+ evstdd %r20,24+11*8(%r6)
+ evstdd %r21,24+12*8(%r6)
+ evstdd %r22,24+13*8(%r6)
+ evstdd %r23,24+14*8(%r6)
+ evstdd %r24,24+15*8(%r6)
+ evstdd %r25,24+16*8(%r6)
+ evstdd %r26,24+17*8(%r6)
+ evstdd %r27,24+18*8(%r6)
+ evstdd %r28,24+19*8(%r6)
+ evstdd %r29,24+20*8(%r6)
+ evstdd %r30,24+21*8(%r6)
+ evstdd %r31,24+22*8(%r6)
+
+ li %r3,0
+ blr
+END(sigsetjmp)
+
+ENTRY(siglongjmp)
+
+ /* FPRs */
+ evldd %r9,24+0*8(%r3)
+ evldd %r10,24+1*8(%r3)
+ evldd %r11,24+2*8(%r3)
+ evldd %r12,24+3*8(%r3)
+ evldd %r13,24+4*8(%r3)
+ evldd %r14,24+5*8(%r3)
+ evldd %r15,24+6*8(%r3)
+ evldd %r16,24+7*8(%r3)
+ evldd %r17,24+8*8(%r3)
+ evldd %r18,24+9*8(%r3)
+ evldd %r19,24+10*8(%r3)
+ evldd %r20,24+11*8(%r3)
+ evldd %r21,24+12*8(%r3)
+ evldd %r22,24+13*8(%r3)
+ evldd %r23,24+14*8(%r3)
+ evldd %r24,24+15*8(%r3)
+ evldd %r25,24+16*8(%r3)
+ evldd %r26,24+17*8(%r3)
+ evldd %r27,24+18*8(%r3)
+ evldd %r28,24+19*8(%r3)
+ evldd %r29,24+20*8(%r3)
+ evldd %r30,24+21*8(%r3)
+ evldd %r31,24+22*8(%r3)
+
+ lwz %r7,0(%r3)
+ mr %r6,%r4
+ mtlr %r11
+ mtcr %r12
+ mr %r1,%r10
+ or. %r7,%r7,%r7
+ beq 1f
+ mr %r4,%r3
+ li %r3,3 /* SIG_SETMASK */
+ addi %r4,%r4,4 /* &set */
+ li %r5,0 /* oset = NULL */
+ li %r0,SYS_sigprocmask /* sigprocmask(SIG_SET, &set, NULL) */
+ sc /* assume no error XXX */
+1:
+ or. %r3,%r6,%r6
+ bnelr
+ li %r3,1
+ blr
+END(siglongjmp)
+
+ .section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/powerpcspe/softfloat/milieu.h b/lib/libc/powerpcspe/softfloat/milieu.h
new file mode 100644
index 000000000000..e2e43b150073
--- /dev/null
+++ b/lib/libc/powerpcspe/softfloat/milieu.h
@@ -0,0 +1,49 @@
+/* $NetBSD: milieu.h,v 1.1 2000/12/29 20:13:54 bjh21 Exp $ */
+/* $FreeBSD$ */
+
+/*
+===============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2a.
+
+Written by John R. Hauser. This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704. Funding was partially provided by the
+National Science Foundation under grant MIP-9311980. The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/SoftFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+Include common integer types and flags.
+-------------------------------------------------------------------------------
+*/
+#include "powerpc-gcc.h"
+
+/*
+-------------------------------------------------------------------------------
+Symbolic Boolean literals.
+-------------------------------------------------------------------------------
+*/
+enum {
+ FALSE = 0,
+ TRUE = 1
+};
diff --git a/lib/libc/powerpcspe/softfloat/powerpc-gcc.h b/lib/libc/powerpcspe/softfloat/powerpc-gcc.h
new file mode 100644
index 000000000000..e2f8680dd74e
--- /dev/null
+++ b/lib/libc/powerpcspe/softfloat/powerpc-gcc.h
@@ -0,0 +1,92 @@
+/* $NetBSD: arm-gcc.h,v 1.2 2001/02/21 18:09:25 bjh21 Exp $ */
+/* $FreeBSD$ */
+
+/*
+-------------------------------------------------------------------------------
+One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
+-------------------------------------------------------------------------------
+*/
+#define BIGENDIAN
+
+/*
+-------------------------------------------------------------------------------
+The macro `BITS64' can be defined to indicate that 64-bit integer types are
+supported by the compiler.
+-------------------------------------------------------------------------------
+*/
+#define BITS64
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines the most convenient type that holds
+integers of at least as many bits as specified. For example, `uint8' should
+be the most convenient type that can hold unsigned integers of as many as
+8 bits. The `flag' type must be able to hold either a 0 or 1. For most
+implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
+to the same as `int'.
+-------------------------------------------------------------------------------
+*/
+typedef int flag;
+typedef unsigned int uint8;
+typedef int int8;
+typedef unsigned int uint16;
+typedef int int16;
+typedef unsigned int uint32;
+typedef signed int int32;
+#ifdef BITS64
+typedef unsigned long long int uint64;
+typedef signed long long int int64;
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Each of the following `typedef's defines a type that holds integers
+of _exactly_ the number of bits specified. For instance, for most
+implementation of C, `bits16' and `sbits16' should be `typedef'ed to
+`unsigned short int' and `signed short int' (or `short int'), respectively.
+-------------------------------------------------------------------------------
+*/
+typedef unsigned char bits8;
+typedef signed char sbits8;
+typedef unsigned short int bits16;
+typedef signed short int sbits16;
+typedef unsigned int bits32;
+typedef signed int sbits32;
+#ifdef BITS64
+typedef unsigned long long int bits64;
+typedef signed long long int sbits64;
+#endif
+
+#ifdef BITS64
+/*
+-------------------------------------------------------------------------------
+The `LIT64' macro takes as its argument a textual integer literal and
+if necessary ``marks'' the literal as having a 64-bit integer type.
+For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
+appended with the letters `LL' standing for `long long', which is `gcc's
+name for the 64-bit integer type. Some compilers may allow `LIT64' to be
+defined as the identity macro: `#define LIT64( a ) a'.
+-------------------------------------------------------------------------------
+*/
+#define LIT64( a ) a##LL
+#endif
+
+/*
+-------------------------------------------------------------------------------
+The macro `INLINE' can be used before functions that should be inlined. If
+a compiler does not support explicit inlining, this macro should be defined
+to be `static'.
+-------------------------------------------------------------------------------
+*/
+#define INLINE static __inline
+
+/*
+-------------------------------------------------------------------------------
+The ARM FPA is odd in that it stores doubles high-order word first, no matter
+what the endianness of the CPU. VFP is sane.
+-------------------------------------------------------------------------------
+*/
+#if defined(SOFTFLOAT_FOR_GCC)
+#define FLOAT64_DEMANGLE(a) (a)
+#define FLOAT64_MANGLE(a) (a)
+#endif
diff --git a/lib/libc/powerpcspe/softfloat/softfloat.h b/lib/libc/powerpcspe/softfloat/softfloat.h
new file mode 100644
index 000000000000..6b9c9b06956d
--- /dev/null
+++ b/lib/libc/powerpcspe/softfloat/softfloat.h
@@ -0,0 +1,307 @@
+/* $NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $ */
+/* $FreeBSD$ */
+
+/* This is a derivative work. */
+
+/*
+===============================================================================
+
+This C header file is part of the SoftFloat IEC/IEEE Floating-point
+Arithmetic Package, Release 2a.
+
+Written by John R. Hauser. This work was made possible in part by the
+International Computer Science Institute, located at Suite 600, 1947 Center
+Street, Berkeley, California 94704. Funding was partially provided by the
+National Science Foundation under grant MIP-9311980. The original version
+of this code was written as part of a project to build a fixed-point vector
+processor in collaboration with the University of California at Berkeley,
+overseen by Profs. Nelson Morgan and John Wawrzynek. More information
+is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
+arithmetic/SoftFloat.html'.
+
+THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
+has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
+TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
+PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
+AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
+
+Derivative works are acceptable, even for commercial purposes, so long as
+(1) they include prominent notice that the work is derivative, and (2) they
+include prominent notice akin to these four paragraphs for those parts of
+this code that are retained.
+
+===============================================================================
+*/
+
+/*
+-------------------------------------------------------------------------------
+The macro `FLOATX80' must be defined to enable the extended double-precision
+floating-point format `floatx80'. If this macro is not defined, the
+`floatx80' type will not be defined, and none of the functions that either
+input or output the `floatx80' type will be defined. The same applies to
+the `FLOAT128' macro and the quadruple-precision format `float128'.
+-------------------------------------------------------------------------------
+*/
+/* #define FLOATX80 */
+/* #define FLOAT128 */
+
+#include <machine/ieeefp.h>
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point types.
+-------------------------------------------------------------------------------
+*/
+typedef unsigned int float32;
+typedef unsigned long long float64;
+#ifdef FLOATX80
+typedef struct {
+ unsigned short high;
+ unsigned long long low;
+} floatx80;
+#endif
+#ifdef FLOAT128
+typedef struct {
+ unsigned long long high, low;
+} float128;
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point underflow tininess-detection mode.
+-------------------------------------------------------------------------------
+*/
+#ifndef SOFTFLOAT_FOR_GCC
+extern int8 float_detect_tininess;
+#endif
+enum {
+ float_tininess_after_rounding = 0,
+ float_tininess_before_rounding = 1
+};
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point rounding mode.
+-------------------------------------------------------------------------------
+*/
+extern fp_rnd_t float_rounding_mode;
+enum {
+ float_round_nearest_even = FP_RN,
+ float_round_to_zero = FP_RZ,
+ float_round_down = FP_RM,
+ float_round_up = FP_RP
+};
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE floating-point exception flags.
+-------------------------------------------------------------------------------
+*/
+typedef fp_except_t fp_except;
+
+extern fp_except float_exception_flags;
+extern fp_except float_exception_mask;
+enum {
+ float_flag_inexact = FP_X_IMP,
+ float_flag_underflow = FP_X_UFL,
+ float_flag_overflow = FP_X_OFL,
+ float_flag_divbyzero = FP_X_DZ,
+ float_flag_invalid = FP_X_INV
+};
+
+/*
+-------------------------------------------------------------------------------
+Routine to raise any or all of the software IEC/IEEE floating-point
+exception flags.
+-------------------------------------------------------------------------------
+*/
+void float_raise( fp_except );
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE integer-to-floating-point conversion routines.
+-------------------------------------------------------------------------------
+*/
+float32 int32_to_float32( int );
+float64 int32_to_float64( int );
+#ifdef FLOATX80
+floatx80 int32_to_floatx80( int );
+#endif
+#ifdef FLOAT128
+float128 int32_to_float128( int );
+#endif
+float32 int64_to_float32( long long );
+float64 int64_to_float64( long long );
+#ifdef FLOATX80
+floatx80 int64_to_floatx80( long long );
+#endif
+#ifdef FLOAT128
+float128 int64_to_float128( long long );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE single-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+int float32_to_int32( float32 );
+int float32_to_int32_round_to_zero( float32 );
+unsigned int float32_to_uint32_round_to_zero( float32 );
+long long float32_to_int64( float32 );
+long long float32_to_int64_round_to_zero( float32 );
+float64 float32_to_float64( float32 );
+#ifdef FLOATX80
+floatx80 float32_to_floatx80( float32 );
+#endif
+#ifdef FLOAT128
+float128 float32_to_float128( float32 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE single-precision operations.
+-------------------------------------------------------------------------------
+*/
+float32 float32_round_to_int( float32 );
+float32 float32_add( float32, float32 );
+float32 float32_sub( float32, float32 );
+float32 float32_mul( float32, float32 );
+float32 float32_div( float32, float32 );
+float32 float32_rem( float32, float32 );
+float32 float32_sqrt( float32 );
+int float32_eq( float32, float32 );
+int float32_le( float32, float32 );
+int float32_lt( float32, float32 );
+int float32_eq_signaling( float32, float32 );
+int float32_le_quiet( float32, float32 );
+int float32_lt_quiet( float32, float32 );
+#ifndef SOFTFLOAT_FOR_GCC
+int float32_is_signaling_nan( float32 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE double-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+int float64_to_int32( float64 );
+int float64_to_int32_round_to_zero( float64 );
+unsigned int float64_to_uint32_round_to_zero( float64 );
+long long float64_to_int64( float64 );
+long long float64_to_int64_round_to_zero( float64 );
+float32 float64_to_float32( float64 );
+#ifdef FLOATX80
+floatx80 float64_to_floatx80( float64 );
+#endif
+#ifdef FLOAT128
+float128 float64_to_float128( float64 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE double-precision operations.
+-------------------------------------------------------------------------------
+*/
+float64 float64_round_to_int( float64 );
+float64 float64_add( float64, float64 );
+float64 float64_sub( float64, float64 );
+float64 float64_mul( float64, float64 );
+float64 float64_div( float64, float64 );
+float64 float64_rem( float64, float64 );
+float64 float64_sqrt( float64 );
+int float64_eq( float64, float64 );
+int float64_le( float64, float64 );
+int float64_lt( float64, float64 );
+int float64_eq_signaling( float64, float64 );
+int float64_le_quiet( float64, float64 );
+int float64_lt_quiet( float64, float64 );
+#ifndef SOFTFLOAT_FOR_GCC
+int float64_is_signaling_nan( float64 );
+#endif
+
+#ifdef FLOATX80
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+int floatx80_to_int32( floatx80 );
+int floatx80_to_int32_round_to_zero( floatx80 );
+long long floatx80_to_int64( floatx80 );
+long long floatx80_to_int64_round_to_zero( floatx80 );
+float32 floatx80_to_float32( floatx80 );
+float64 floatx80_to_float64( floatx80 );
+#ifdef FLOAT128
+float128 floatx80_to_float128( floatx80 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision rounding precision. Valid
+values are 32, 64, and 80.
+-------------------------------------------------------------------------------
+*/
+extern int floatx80_rounding_precision;
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE extended double-precision operations.
+-------------------------------------------------------------------------------
+*/
+floatx80 floatx80_round_to_int( floatx80 );
+floatx80 floatx80_add( floatx80, floatx80 );
+floatx80 floatx80_sub( floatx80, floatx80 );
+floatx80 floatx80_mul( floatx80, floatx80 );
+floatx80 floatx80_div( floatx80, floatx80 );
+floatx80 floatx80_rem( floatx80, floatx80 );
+floatx80 floatx80_sqrt( floatx80 );
+int floatx80_eq( floatx80, floatx80 );
+int floatx80_le( floatx80, floatx80 );
+int floatx80_lt( floatx80, floatx80 );
+int floatx80_eq_signaling( floatx80, floatx80 );
+int floatx80_le_quiet( floatx80, floatx80 );
+int floatx80_lt_quiet( floatx80, floatx80 );
+int floatx80_is_signaling_nan( floatx80 );
+
+#endif
+
+#ifdef FLOAT128
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE quadruple-precision conversion routines.
+-------------------------------------------------------------------------------
+*/
+int float128_to_int32( float128 );
+int float128_to_int32_round_to_zero( float128 );
+long long float128_to_int64( float128 );
+long long float128_to_int64_round_to_zero( float128 );
+float32 float128_to_float32( float128 );
+float64 float128_to_float64( float128 );
+#ifdef FLOATX80
+floatx80 float128_to_floatx80( float128 );
+#endif
+
+/*
+-------------------------------------------------------------------------------
+Software IEC/IEEE quadruple-precision operations.
+-------------------------------------------------------------------------------
+*/
+float128 float128_round_to_int( float128 );
+float128 float128_add( float128, float128 );
+float128 float128_sub( float128, float128 );
+float128 float128_mul( float128, float128 );
+float128 float128_div( float128, float128 );
+float128 float128_rem( float128, float128 );
+float128 float128_sqrt( float128 );
+int float128_eq( float128, float128 );
+int float128_le( float128, float128 );
+int float128_lt( float128, float128 );
+int float128_eq_signaling( float128, float128 );
+int float128_le_quiet( float128, float128 );
+int float128_lt_quiet( float128, float128 );
+int float128_is_signaling_nan( float128 );
+
+#endif
+
diff --git a/lib/libc/powerpcspe/sys/Makefile.inc b/lib/libc/powerpcspe/sys/Makefile.inc
new file mode 100644
index 000000000000..7ddf4f89f05b
--- /dev/null
+++ b/lib/libc/powerpcspe/sys/Makefile.inc
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+.PATH: ${LIBC_SRCTOP}/powerpc/sys
+.sinclude "${LIBC_SRCTOP}/powerpc/sys/Makefile.inc"
diff --git a/lib/libc/stdio/printf-pos.c b/lib/libc/stdio/printf-pos.c
index 3a476496219c..9c38c2add343 100644
--- a/lib/libc/stdio/printf-pos.c
+++ b/lib/libc/stdio/printf-pos.c
@@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <sys/types.h>
+#include <limits.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>
@@ -55,6 +56,12 @@ __FBSDID("$FreeBSD$");
#include "un-namespace.h"
#include "printflocal.h"
+#ifdef NL_ARGMAX
+#define MAX_POSARG NL_ARGMAX
+#else
+#define MAX_POSARG 65536
+#endif
+
/*
* Type ids for argument type table.
*/
@@ -70,9 +77,9 @@ enum typeid {
struct typetable {
enum typeid *table; /* table of types */
enum typeid stattable[STATIC_ARG_TBL_SIZE];
- int tablesize; /* current size of type table */
- int tablemax; /* largest used index in table */
- int nextarg; /* 1-based argument index */
+ u_int tablesize; /* current size of type table */
+ u_int tablemax; /* largest used index in table */
+ u_int nextarg; /* 1-based argument index */
};
static int __grow_type_table(struct typetable *);
@@ -84,7 +91,7 @@ static void build_arg_table (struct typetable *, va_list, union arg **);
static inline void
inittypes(struct typetable *types)
{
- int n;
+ u_int n;
types->table = types->stattable;
types->tablesize = STATIC_ARG_TBL_SIZE;
@@ -185,7 +192,7 @@ static inline int
addaster(struct typetable *types, char **fmtp)
{
char *cp;
- int n2;
+ u_int n2;
n2 = 0;
cp = *fmtp;
@@ -194,7 +201,7 @@ addaster(struct typetable *types, char **fmtp)
cp++;
}
if (*cp == '$') {
- int hold = types->nextarg;
+ u_int hold = types->nextarg;
types->nextarg = n2;
if (addtype(types, T_INT))
return (-1);
@@ -211,7 +218,7 @@ static inline int
addwaster(struct typetable *types, wchar_t **fmtp)
{
wchar_t *cp;
- int n2;
+ u_int n2;
n2 = 0;
cp = *fmtp;
@@ -220,7 +227,7 @@ addwaster(struct typetable *types, wchar_t **fmtp)
cp++;
}
if (*cp == '$') {
- int hold = types->nextarg;
+ u_int hold = types->nextarg;
types->nextarg = n2;
if (addtype(types, T_INT))
return (-1);
@@ -245,7 +252,7 @@ __find_arguments (const char *fmt0, va_list ap, union arg **argtable)
{
char *fmt; /* format string */
int ch; /* character from fmt */
- int n; /* handy integer (short term usage) */
+ u_int n; /* handy integer (short term usage) */
int error;
int flags; /* flags as above */
struct typetable types; /* table of types */
@@ -296,6 +303,11 @@ reswitch: switch (ch) {
n = 0;
do {
n = 10 * n + to_digit(ch);
+ /* Detect overflow */
+ if (n > MAX_POSARG) {
+ error = -1;
+ goto error;
+ }
ch = *fmt++;
} while (is_digit(ch));
if (ch == '$') {
@@ -433,7 +445,7 @@ __find_warguments (const wchar_t *fmt0, va_list ap, union arg **argtable)
{
wchar_t *fmt; /* format string */
wchar_t ch; /* character from fmt */
- int n; /* handy integer (short term usage) */
+ u_int n; /* handy integer (short term usage) */
int error;
int flags; /* flags as above */
struct typetable types; /* table of types */
@@ -484,6 +496,11 @@ reswitch: switch (ch) {
n = 0;
do {
n = 10 * n + to_digit(ch);
+ /* Detect overflow */
+ if (n > MAX_POSARG) {
+ error = -1;
+ goto error;
+ }
ch = *fmt++;
} while (is_digit(ch));
if (ch == '$') {
@@ -624,7 +641,11 @@ __grow_type_table(struct typetable *types)
enum typeid *const oldtable = types->table;
const int oldsize = types->tablesize;
enum typeid *newtable;
- int n, newsize = oldsize * 2;
+ u_int n, newsize = oldsize * 2;
+
+ /* Detect overflow */
+ if (types->nextarg > NL_ARGMAX)
+ return (-1);
if (newsize < types->nextarg + 1)
newsize = types->nextarg + 1;
@@ -653,7 +674,7 @@ __grow_type_table(struct typetable *types)
static void
build_arg_table(struct typetable *types, va_list ap, union arg **argtable)
{
- int n;
+ u_int n;
if (types->tablemax >= STATIC_ARG_TBL_SIZE) {
*argtable = (union arg *)
diff --git a/lib/libcapsicum/capsicum_helpers.3 b/lib/libcapsicum/capsicum_helpers.3
index fe2e0e7d0876..98ea1dc64179 100644
--- a/lib/libcapsicum/capsicum_helpers.3
+++ b/lib/libcapsicum/capsicum_helpers.3
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 5, 2016
+.Dd October 21, 2016
.Dt CAPSICUM_HELPERS 3
.Os
.Sh NAME
@@ -57,7 +57,8 @@
.Sh DESCRIPTION
The
.Nm capsicum helpers
-are a set of a inline functions which simplify Capsicumizing programs.
+are a set of a inline functions which simplify modifying programs to use
+Capsicum.
The goal is to reduce duplicated code patterns.
The
.Nm capsicum helpers
@@ -70,7 +71,7 @@ restricts capabilities on
.Fa fd
to only those needed by POSIX stream objects (that is, FILEs).
.Pp
-The following flags can be provided:
+These flags can be provided:
.Pp
.Bl -tag -width "CAPH_IGNORE_EBADF" -compact -offset indent
.It Dv CAPH_IGNORE_EBADF
diff --git a/lib/libcasper/services/cap_dns/Makefile b/lib/libcasper/services/cap_dns/Makefile
index 6f7dbd580201..4a36da134b3a 100644
--- a/lib/libcasper/services/cap_dns/Makefile
+++ b/lib/libcasper/services/cap_dns/Makefile
@@ -1,12 +1,13 @@
# $FreeBSD$
+SHLIBDIR?= /lib/casper
+
.include <src.opts.mk>
PACKAGE=libcasper
LIB= cap_dns
SHLIB_MAJOR= 0
-SHLIBDIR?= /lib/casper
INCSDIR?= ${INCLUDEDIR}/casper
SRCS= cap_dns.c
diff --git a/lib/libcasper/services/cap_grp/Makefile b/lib/libcasper/services/cap_grp/Makefile
index a620be11b814..c2cc4b1a0b9f 100644
--- a/lib/libcasper/services/cap_grp/Makefile
+++ b/lib/libcasper/services/cap_grp/Makefile
@@ -1,12 +1,13 @@
# $FreeBSD$
+SHLIBDIR?= /lib/casper
+
.include <src.opts.mk>
PACKAGE=libcasper
LIB= cap_grp
SHLIB_MAJOR= 0
-SHLIBDIR?= /lib/casper
INCSDIR?= ${INCLUDEDIR}/casper
SRCS= cap_grp.c
diff --git a/lib/libcasper/services/cap_pwd/Makefile b/lib/libcasper/services/cap_pwd/Makefile
index 57876115db0b..ab4be4bacd14 100644
--- a/lib/libcasper/services/cap_pwd/Makefile
+++ b/lib/libcasper/services/cap_pwd/Makefile
@@ -1,12 +1,13 @@
# $FreeBSD$
+SHLIBDIR?= /lib/casper
+
.include <src.opts.mk>
PACKAGE=libcasper
LIB= cap_pwd
SHLIB_MAJOR= 0
-SHLIBDIR?= /lib/casper
INCSDIR?= ${INCLUDEDIR}/casper
SRCS= cap_pwd.c
diff --git a/lib/libcasper/services/cap_sysctl/Makefile b/lib/libcasper/services/cap_sysctl/Makefile
index d37b5dc461de..446ec5236e0b 100644
--- a/lib/libcasper/services/cap_sysctl/Makefile
+++ b/lib/libcasper/services/cap_sysctl/Makefile
@@ -1,12 +1,13 @@
# $FreeBSD$
+SHLIBDIR?= /lib/casper
+
.include <src.opts.mk>
PACKAGE=libcasper
LIB= cap_sysctl
SHLIB_MAJOR= 0
-SHLIBDIR?= /lib/casper
INCSDIR?= ${INCLUDEDIR}/casper
SRCS= cap_sysctl.c
diff --git a/lib/libgcc_eh/Makefile.inc b/lib/libgcc_eh/Makefile.inc
index 7321fbea78f9..6337f3890e18 100644
--- a/lib/libgcc_eh/Makefile.inc
+++ b/lib/libgcc_eh/Makefile.inc
@@ -4,19 +4,24 @@ COMPILERRTDIR= ${SRCTOP}/contrib/compiler-rt
UNWINDINCDIR= ${SRCTOP}/contrib/llvm/projects/libunwind/include
UNWINDSRCDIR= ${SRCTOP}/contrib/llvm/projects/libunwind/src
-CFLAGS+=${PICFLAG} -fvisibility=hidden -DVISIBILITY_HIDDEN
+STATIC_CFLAGS+=${PICFLAG} -fvisibility=hidden -DVISIBILITY_HIDDEN
.PATH: ${COMPILERRTDIR}/lib/builtins
.PATH: ${UNWINDSRCDIR}
-SRCS+= gcc_personality_v0.c
-SRCS+= int_util.c
-SRCS+= Unwind-EHABI.cpp
-SRCS+= Unwind-sjlj.c
-SRCS+= UnwindLevel1-gcc-ext.c
-SRCS+= UnwindLevel1.c
-SRCS+= UnwindRegistersRestore.S
-SRCS+= UnwindRegistersSave.S
-SRCS+= libunwind.cpp
+SRCS_EXC+= gcc_personality_v0.c
+SRCS_EXC+= int_util.c
+SRCS_EXC+= Unwind-EHABI.cpp
+SRCS_EXC+= Unwind-sjlj.c
+SRCS_EXC+= UnwindLevel1-gcc-ext.c
+SRCS_EXC+= UnwindLevel1.c
+SRCS_EXC+= UnwindRegistersRestore.S
+SRCS_EXC+= UnwindRegistersSave.S
+SRCS_EXC+= libunwind.cpp
+
+SRCS+= ${SRCS_EXC}
+.for file in ${SRCS_EXC:M*.c}
+CFLAGS.${file}+= -fexceptions
+.endfor
CFLAGS+= -I${UNWINDINCDIR} -I${.CURDIR} -D_LIBUNWIND_IS_NATIVE_ONLY
.if empty(CXXFLAGS:M-std=*)
diff --git a/lib/libgcc_s/Makefile b/lib/libgcc_s/Makefile
index 92fb8c3fb22d..6c57741e4d0a 100644
--- a/lib/libgcc_s/Makefile
+++ b/lib/libgcc_s/Makefile
@@ -2,6 +2,7 @@
PKG= clibs
SHLIB_NAME= libgcc_s.so.1
+SHLIBDIR?= /lib
WARNS?= 2
diff --git a/lib/libnetbsd/sys/cdefs.h b/lib/libnetbsd/sys/cdefs.h
index 051959f53132..46372f368afd 100644
--- a/lib/libnetbsd/sys/cdefs.h
+++ b/lib/libnetbsd/sys/cdefs.h
@@ -35,11 +35,13 @@
#include_next <sys/cdefs.h>
+#ifndef __dead
#ifdef __dead2
#define __dead __dead2
#else
#define __dead
#endif
+#endif /* !__dead */
/*
* The __CONCAT macro is used to concatenate parts of symbol names, e.g.
diff --git a/lib/libnetbsd/util.c b/lib/libnetbsd/util.c
index 36b9421efc39..4f922dc2c41d 100644
--- a/lib/libnetbsd/util.c
+++ b/lib/libnetbsd/util.c
@@ -36,7 +36,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <util.h>
+
+#include "util.h"
char *
flags_to_string(u_long flags, const char *def)
diff --git a/lib/libproc/proc_bkpt.c b/lib/libproc/proc_bkpt.c
index 4a100cbbd4eb..3167206af204 100644
--- a/lib/libproc/proc_bkpt.c
+++ b/lib/libproc/proc_bkpt.c
@@ -68,6 +68,14 @@ __FBSDID("$FreeBSD$");
#error "Add support for your architecture"
#endif
+/*
+ * Use 4-bytes holder for breakpoint instruction on all the platforms.
+ * Works for x86 as well until it is endian-little platform.
+ * (We are coping one byte only on x86 from this 4-bytes piece of
+ * memory).
+ */
+typedef uint32_t instr_t;
+
static int
proc_stop(struct proc_handle *phdl)
{
@@ -92,8 +100,9 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address,
unsigned long *saved)
{
struct ptrace_io_desc piod;
- unsigned long paddr, caddr;
+ unsigned long caddr;
int ret = 0, stopped;
+ instr_t instr;
*saved = 0;
if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD ||
@@ -115,10 +124,10 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address,
* Read the original instruction.
*/
caddr = address;
- paddr = 0;
+ instr = 0;
piod.piod_op = PIOD_READ_I;
piod.piod_offs = (void *)caddr;
- piod.piod_addr = &paddr;
+ piod.piod_addr = &instr;
piod.piod_len = BREAKPOINT_INSTR_SZ;
if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) {
DPRINTF("ERROR: couldn't read instruction at address 0x%"
@@ -126,15 +135,15 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address,
ret = -1;
goto done;
}
- *saved = paddr;
+ *saved = instr;
/*
* Write a breakpoint instruction to that address.
*/
caddr = address;
- paddr = BREAKPOINT_INSTR;
+ instr = BREAKPOINT_INSTR;
piod.piod_op = PIOD_WRITE_I;
piod.piod_offs = (void *)caddr;
- piod.piod_addr = &paddr;
+ piod.piod_addr = &instr;
piod.piod_len = BREAKPOINT_INSTR_SZ;
if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) {
DPRINTF("ERROR: couldn't write instruction at address 0x%"
@@ -156,8 +165,9 @@ proc_bkptdel(struct proc_handle *phdl, uintptr_t address,
unsigned long saved)
{
struct ptrace_io_desc piod;
- unsigned long paddr, caddr;
+ unsigned long caddr;
int ret = 0, stopped;
+ instr_t instr;
if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD ||
phdl->status == PS_IDLE) {
@@ -178,10 +188,10 @@ proc_bkptdel(struct proc_handle *phdl, uintptr_t address,
* Overwrite the breakpoint instruction that we setup previously.
*/
caddr = address;
- paddr = saved;
+ instr = saved;
piod.piod_op = PIOD_WRITE_I;
piod.piod_offs = (void *)caddr;
- piod.piod_addr = &paddr;
+ piod.piod_addr = &instr;
piod.piod_len = BREAKPOINT_INSTR_SZ;
if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) {
DPRINTF("ERROR: couldn't write instruction at address 0x%"
diff --git a/lib/librss/Makefile b/lib/librss/Makefile
index 384a205d85bd..51be6d91936b 100644
--- a/lib/librss/Makefile
+++ b/lib/librss/Makefile
@@ -5,6 +5,7 @@ SHLIBDIR?= /lib
.include <src.opts.mk>
+INCS= librss.h
LIB= rss
SHLIB_MAJOR= 1
diff --git a/lib/librss/librss.3 b/lib/librss/librss.3
index 02a50f89eed7..2ac5804746b2 100644
--- a/lib/librss/librss.3
+++ b/lib/librss/librss.3
@@ -1,6 +1,6 @@
.\" $FreeBSD$
.\"
-.Dd September 29, 2016
+.Dd October 23, 2016
.Dt LIBRSS 3
.Os
.Sh NAME
@@ -9,6 +9,8 @@
.Sh LIBRARY
.Lb librss
.Sh SYNOPSIS
+.In sys/param.h
+.In sys/cpuset.h
.In librss.h
.Ft struct rss_config *
.Fn rss_config_get "void"
@@ -17,6 +19,8 @@
.Ft int
.Fn rss_config_get_bucket_count "struct rss_config *cfg"
.Ft int
+.Fn rss_get_bucket_cpuset "struct rss_config *rc" "rss_bucket_type_t btype" "int bucket" "cpuset_t *cs"
+.Ft int
.Fn rss_set_bucket_rebalance_cb "rss_bucket_rebalance_cb_t *cb" "void *cbdata"
.Ft int
.Fn rss_sock_set_bindmulti "int fd" "int af" "int val"
diff --git a/lib/libstand/bootp.c b/lib/libstand/bootp.c
index 7474f8f971d5..0c48748ddd1a 100644
--- a/lib/libstand/bootp.c
+++ b/lib/libstand/bootp.c
@@ -148,7 +148,17 @@ bootp(sock, flag)
bp->bp_vend[7] = TAG_CLASSID;
bp->bp_vend[8] = 9;
bcopy("PXEClient", &bp->bp_vend[9], 9);
- bp->bp_vend[18] = TAG_END;
+ bp->bp_vend[18] = TAG_PARAM_REQ;
+ bp->bp_vend[19] = 8;
+ bp->bp_vend[20] = TAG_ROOTPATH;
+ bp->bp_vend[21] = TAG_TFTP_SERVER;
+ bp->bp_vend[22] = TAG_HOSTNAME;
+ bp->bp_vend[23] = TAG_SWAPSERVER;
+ bp->bp_vend[24] = TAG_GATEWAY;
+ bp->bp_vend[25] = TAG_SUBNET_MASK;
+ bp->bp_vend[26] = TAG_INTF_MTU;
+ bp->bp_vend[27] = TAG_SERVERID;
+ bp->bp_vend[28] = TAG_END;
} else
bp->bp_vend[7] = TAG_END;
#else
diff --git a/lib/libsysdecode/flags.c b/lib/libsysdecode/flags.c
index 3a705c7e9c5f..653b522b3c08 100644
--- a/lib/libsysdecode/flags.c
+++ b/lib/libsysdecode/flags.c
@@ -959,7 +959,7 @@ sysdecode_umtx_rwlock_flags(FILE *fp, u_long flags, u_long *rem)
}
/* XXX: This should be in <sys/capsicum.h> */
-#define CAPMASK(right) ((right) && (((uint64_t)1 << 57) - 1))
+#define CAPMASK(right) ((right) & (((uint64_t)1 << 57) - 1))
void
sysdecode_cap_rights(FILE *fp, cap_rights_t *rightsp)
diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c
index e40bc07e61e0..be2acee7e9e0 100644
--- a/lib/libusb/libusb20_ugen20.c
+++ b/lib/libusb/libusb20_ugen20.c
@@ -214,8 +214,8 @@ ugen20_enumerate(struct libusb20_device *pdev, const char *id)
snprintf(pdev->usb_desc, sizeof(pdev->usb_desc),
USB_GENERIC_NAME "%u.%u: <%s %s> at usbus%u", pdev->bus_number,
- pdev->device_address, devinfo.udi_product,
- devinfo.udi_vendor, pdev->bus_number);
+ pdev->device_address, devinfo.udi_vendor,
+ devinfo.udi_product, pdev->bus_number);
error = 0;
done:
diff --git a/lib/msun/mips/Makefile.inc b/lib/msun/mips/Makefile.inc
index 8c1a4864f4cf..b05f4fa3812b 100644
--- a/lib/msun/mips/Makefile.inc
+++ b/lib/msun/mips/Makefile.inc
@@ -1,4 +1,8 @@
# $FreeBSD$
+.if ${MACHINE_ARCH:Mmips*hf} == ""
+CFLAGS+=-DSOFTFLOAT
+.endif
+
LDBL_PREC = 53
SYM_MAPS += ${.CURDIR}/mips/Symbol.map
diff --git a/lib/msun/mips/Symbol.map b/lib/msun/mips/Symbol.map
index 971112e30c8a..081294cf5562 100644
--- a/lib/msun/mips/Symbol.map
+++ b/lib/msun/mips/Symbol.map
@@ -5,9 +5,17 @@ FBSD_1.0 {
};
FBSD_1.3 {
+ feclearexcept;
+ fegetexceptflag;
fesetexceptflag;
feraiseexcept;
+ fetestexcept;
+ fegetround;
+ fesetround;
fegetenv;
feholdexcept;
feupdateenv;
+ feenableexcept;
+ fedisableexcept;
+ fegetexcept;
};
diff --git a/lib/msun/mips/fenv.c b/lib/msun/mips/fenv.c
index a5a5c03d3a74..64beb704c74e 100644
--- a/lib/msun/mips/fenv.c
+++ b/lib/msun/mips/fenv.c
@@ -39,6 +39,17 @@
*/
const fenv_t __fe_dfl_env = 0;
+#ifdef SOFTFLOAT
+#define __set_env(env, flags, mask, rnd) env = ((flags) \
+ | (mask)<<_FPUSW_SHIFT \
+ | (rnd) << 24)
+#define __env_flags(env) ((env) & FE_ALL_EXCEPT)
+#define __env_mask(env) (((env) >> _FPUSW_SHIFT) \
+ & FE_ALL_EXCEPT)
+#define __env_round(env) (((env) >> 24) & _ROUND_MASK)
+#include "fenv-softfloat.h"
+#endif
+
extern inline int feclearexcept(int __excepts);
extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts);
extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
@@ -50,3 +61,6 @@ extern inline int fegetenv(fenv_t *__envp);
extern inline int feholdexcept(fenv_t *__envp);
extern inline int fesetenv(const fenv_t *__envp);
extern inline int feupdateenv(const fenv_t *__envp);
+extern inline int feenableexcept(int __mask);
+extern inline int fedisableexcept(int __mask);
+extern inline int fegetexcept(void);
diff --git a/lib/msun/mips/fenv.h b/lib/msun/mips/fenv.h
index f11499806bea..498af3471b5d 100644
--- a/lib/msun/mips/fenv.h
+++ b/lib/msun/mips/fenv.h
@@ -39,11 +39,21 @@ typedef __uint32_t fenv_t;
typedef __uint32_t fexcept_t;
/* Exception flags */
+#ifdef SOFTFLOAT
+#define _FPUSW_SHIFT 16
#define FE_INVALID 0x0001
#define FE_DIVBYZERO 0x0002
#define FE_OVERFLOW 0x0004
#define FE_UNDERFLOW 0x0008
#define FE_INEXACT 0x0010
+#else
+#define _FCSR_CAUSE_SHIFT 10
+#define FE_INVALID 0x0040
+#define FE_DIVBYZERO 0x0020
+#define FE_OVERFLOW 0x0010
+#define FE_UNDERFLOW 0x0008
+#define FE_INEXACT 0x0004
+#endif
#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \
FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
@@ -61,104 +71,135 @@ extern const fenv_t __fe_dfl_env;
#define FE_DFL_ENV (&__fe_dfl_env)
/* We need to be able to map status flag positions to mask flag positions */
-#define _FPUSW_SHIFT 16
-#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT)
+#define _ENABLE_SHIFT 5
+#define _ENABLE_MASK (FE_ALL_EXCEPT << _ENABLE_SHIFT)
-#ifdef ARM_HARD_FLOAT
-#define __rfs(__fpsr) __asm __volatile("rfs %0" : "=r" (*(__fpsr)))
-#define __wfs(__fpsr) __asm __volatile("wfs %0" : : "r" (__fpsr))
-#else
-#define __rfs(__fpsr)
-#define __wfs(__fpsr)
+#ifndef SOFTFLOAT
+#define __cfc1(__fcsr) __asm __volatile("cfc1 %0, $31" : "=r" (__fcsr))
+#define __ctc1(__fcsr) __asm __volatile("ctc1 %0, $31" :: "r" (__fcsr))
#endif
+#ifdef SOFTFLOAT
+int feclearexcept(int __excepts);
+int fegetexceptflag(fexcept_t *__flagp, int __excepts);
+int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
+int feraiseexcept(int __excepts);
+int fetestexcept(int __excepts);
+int fegetround(void);
+int fesetround(int __round);
+int fegetenv(fenv_t *__envp);
+int feholdexcept(fenv_t *__envp);
+int fesetenv(const fenv_t *__envp);
+int feupdateenv(const fenv_t *__envp);
+#else
__fenv_static inline int
feclearexcept(int __excepts)
{
- fexcept_t __fpsr;
+ fexcept_t fcsr;
+
+ __excepts &= FE_ALL_EXCEPT;
+ __cfc1(fcsr);
+ fcsr &= ~(__excepts | (__excepts << _FCSR_CAUSE_SHIFT));
+ __ctc1(fcsr);
- __rfs(&__fpsr);
- __fpsr &= ~__excepts;
- __wfs(__fpsr);
return (0);
}
__fenv_static inline int
fegetexceptflag(fexcept_t *__flagp, int __excepts)
{
- fexcept_t __fpsr;
+ fexcept_t fcsr;
+
+ __excepts &= FE_ALL_EXCEPT;
+ __cfc1(fcsr);
+ *__flagp = fcsr & __excepts;
- __rfs(&__fpsr);
- *__flagp = __fpsr & __excepts;
return (0);
}
__fenv_static inline int
fesetexceptflag(const fexcept_t *__flagp, int __excepts)
{
- fexcept_t __fpsr;
+ fexcept_t fcsr;
+
+ __excepts &= FE_ALL_EXCEPT;
+ __cfc1(fcsr);
+ fcsr &= ~__excepts;
+ fcsr |= *__flagp & __excepts;
+ __ctc1(fcsr);
- __rfs(&__fpsr);
- __fpsr &= ~__excepts;
- __fpsr |= *__flagp & __excepts;
- __wfs(__fpsr);
return (0);
}
__fenv_static inline int
feraiseexcept(int __excepts)
{
- fexcept_t __ex = __excepts;
+ fexcept_t fcsr;
+
+ __excepts &= FE_ALL_EXCEPT;
+ __cfc1(fcsr);
+ fcsr |= __excepts | (__excepts << _FCSR_CAUSE_SHIFT);
+ __ctc1(fcsr);
- fesetexceptflag(&__ex, __excepts); /* XXX */
return (0);
}
__fenv_static inline int
fetestexcept(int __excepts)
{
- fexcept_t __fpsr;
+ fexcept_t fcsr;
- __rfs(&__fpsr);
- return (__fpsr & __excepts);
+ __excepts &= FE_ALL_EXCEPT;
+ __cfc1(fcsr);
+
+ return (fcsr & __excepts);
}
__fenv_static inline int
fegetround(void)
{
+ fexcept_t fcsr;
+
+ __cfc1(fcsr);
- /*
- * Apparently, the rounding mode is specified as part of the
- * instruction format on ARM, so the dynamic rounding mode is
- * indeterminate. Some FPUs may differ.
- */
- return (-1);
+ return (fcsr & _ROUND_MASK);
}
__fenv_static inline int
fesetround(int __round)
{
+ fexcept_t fcsr;
+
+ if (__round & ~_ROUND_MASK)
+ return (-1);
- return (-1);
+ __cfc1(fcsr);
+ fcsr &= ~_ROUND_MASK;
+ fcsr |= __round;
+ __ctc1(fcsr);
+
+ return (0);
}
__fenv_static inline int
fegetenv(fenv_t *__envp)
{
- __rfs(__envp);
+ __cfc1(*__envp);
+
return (0);
}
__fenv_static inline int
feholdexcept(fenv_t *__envp)
{
- fenv_t __env;
+ fexcept_t fcsr;
+
+ __cfc1(fcsr);
+ *__envp = fcsr;
+ fcsr &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
+ __ctc1(fcsr);
- __rfs(&__env);
- *__envp = __env;
- __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
- __wfs(__env);
return (0);
}
@@ -166,56 +207,69 @@ __fenv_static inline int
fesetenv(const fenv_t *__envp)
{
- __wfs(*__envp);
+ __ctc1(*__envp);
+
return (0);
}
__fenv_static inline int
feupdateenv(const fenv_t *__envp)
{
- fexcept_t __fpsr;
+ fexcept_t fcsr;
+
+ __cfc1(fcsr);
+ fesetenv(__envp);
+ feraiseexcept(fcsr);
- __rfs(&__fpsr);
- __wfs(*__envp);
- feraiseexcept(__fpsr & FE_ALL_EXCEPT);
return (0);
}
+#endif /* !SOFTFLOAT */
#if __BSD_VISIBLE
/* We currently provide no external definitions of the functions below. */
+#ifdef SOFTFLOAT
+int feenableexcept(int __mask);
+int fedisableexcept(int __mask);
+int fegetexcept(void);
+#else
static inline int
feenableexcept(int __mask)
{
- fenv_t __old_fpsr, __new_fpsr;
+ fenv_t __old_fcsr, __new_fcsr;
+
+ __cfc1(__old_fcsr);
+ __new_fcsr = __old_fcsr | (__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT;
+ __ctc1(__new_fcsr);
- __rfs(&__old_fpsr);
- __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT;
- __wfs(__new_fpsr);
- return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+ return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT);
}
static inline int
fedisableexcept(int __mask)
{
- fenv_t __old_fpsr, __new_fpsr;
+ fenv_t __old_fcsr, __new_fcsr;
+
+ __cfc1(__old_fcsr);
+ __new_fcsr = __old_fcsr & ~((__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT);
+ __ctc1(__new_fcsr);
- __rfs(&__old_fpsr);
- __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT);
- __wfs(__new_fpsr);
- return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT);
+ return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT);
}
static inline int
fegetexcept(void)
{
- fenv_t __fpsr;
+ fexcept_t fcsr;
- __rfs(&__fpsr);
- return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT);
+ __cfc1(fcsr);
+
+ return ((fcsr & _ENABLE_MASK) >> _ENABLE_SHIFT);
}
+#endif /* !SOFTFLOAT */
+
#endif /* __BSD_VISIBLE */
__END_DECLS
diff --git a/lib/msun/powerpc/fenv.h b/lib/msun/powerpc/fenv.h
index 33de3750a93a..8fbecd7c0806 100644
--- a/lib/msun/powerpc/fenv.h
+++ b/lib/msun/powerpc/fenv.h
@@ -87,8 +87,13 @@ extern const fenv_t __fe_dfl_env;
FE_OVERFLOW | FE_UNDERFLOW) >> _FPUSW_SHIFT)
#ifndef _SOFT_FLOAT
+#ifdef __SPE__
+#define __mffs(__env) __asm __volatile("mfspr %0, 512" : "=r" (*(__env)))
+#define __mtfsf(__env) __asm __volatile("mtspr 512,%0" : : "r" (__env))
+#else
#define __mffs(__env) __asm __volatile("mffs %0" : "=f" (*(__env)))
#define __mtfsf(__env) __asm __volatile("mtfsf 255,%0" : : "f" (__env))
+#endif
#else
#define __mffs(__env)
#define __mtfsf(__env)
diff --git a/release/tools/arm.subr b/release/tools/arm.subr
index bc516eb4d744..97326c4d1fb7 100644
--- a/release/tools/arm.subr
+++ b/release/tools/arm.subr
@@ -88,7 +88,6 @@ arm_create_user() {
-c 'FreeBSD User' -d '/home/freebsd' -s '/bin/csh'
chroot ${CHROOTDIR} /usr/sbin/pw -R ${DESTDIR} \
usermod root -w yes
- chroot ${CHROOTDIR} ln -s /home ${DESTDIR}/usr/home
return 0
}
diff --git a/release/tools/vagrant-virtualbox.conf b/release/tools/vagrant-virtualbox.conf
index ff14674ca708..772068befd30 100644
--- a/release/tools/vagrant-virtualbox.conf
+++ b/release/tools/vagrant-virtualbox.conf
@@ -5,11 +5,11 @@
. ${WORLDDIR}/release/tools/vagrant.conf
-export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} virtualbox-ose-additions"
+export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} virtualbox-ose-additions-nox11"
vm_extra_pre_umount () {
# VirtualBox first boot pkgs
- echo 'firstboot_pkgs_list="sudo rsync virtualbox-ose-additions"' >> ${DESTDIR}/etc/rc.conf
+ echo 'firstboot_pkgs_list="sudo rsync virtualbox-ose-additions-nox11"' >> ${DESTDIR}/etc/rc.conf
echo 'vboxguest_enable="YES"' >> ${DESTDIR}/etc/rc.conf
echo 'vboxservice_enable="YES"' >> ${DESTDIR}/etc/rc.conf
diff --git a/sbin/Makefile b/sbin/Makefile
index affca8e19d91..4826bc09b26d 100644
--- a/sbin/Makefile
+++ b/sbin/Makefile
@@ -87,6 +87,7 @@ SUBDIR.${MK_PF}+= pfctl
SUBDIR.${MK_PF}+= pflogd
SUBDIR.${MK_QUOTAS}+= quotacheck
SUBDIR.${MK_ROUTED}+= routed
+SUBDIR.${MK_ZFS}+= zfsbootcfg
SUBDIR.${MK_TESTS}+= tests
diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c
index aebb90371436..3a443a9c1f3e 100644
--- a/sbin/camcontrol/camcontrol.c
+++ b/sbin/camcontrol/camcontrol.c
@@ -3127,8 +3127,8 @@ dorescan_or_reset(int argc, char **argv, int rescan)
static int
rescan_or_reset_bus(path_id_t bus, int rescan)
{
- union ccb ccb, matchccb;
- int fd, retval;
+ union ccb *ccb = NULL, *matchccb = NULL;
+ int fd = -1, retval;
int bufsize;
retval = 0;
@@ -3139,37 +3139,41 @@ rescan_or_reset_bus(path_id_t bus, int rescan)
return(1);
}
- bzero(&ccb, sizeof(ccb));
+ ccb = malloc(sizeof(*ccb));
+ if (ccb == NULL) {
+ warn("failed to allocate CCB");
+ retval = 1;
+ goto bailout;
+ }
+ bzero(ccb, sizeof(*ccb));
if (bus != CAM_BUS_WILDCARD) {
- ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
- ccb.ccb_h.path_id = bus;
- ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
- ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
- ccb.crcn.flags = CAM_FLAG_NONE;
+ ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS;
+ ccb->ccb_h.path_id = bus;
+ ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
+ ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
+ ccb->crcn.flags = CAM_FLAG_NONE;
/* run this at a low priority */
- ccb.ccb_h.pinfo.priority = 5;
+ ccb->ccb_h.pinfo.priority = 5;
- if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
+ if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
warn("CAMIOCOMMAND ioctl failed");
- close(fd);
- return(1);
+ retval = 1;
+ goto bailout;
}
- if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
+ if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
fprintf(stdout, "%s of bus %d was successful\n",
rescan ? "Re-scan" : "Reset", bus);
} else {
fprintf(stdout, "%s of bus %d returned error %#x\n",
rescan ? "Re-scan" : "Reset", bus,
- ccb.ccb_h.status & CAM_STATUS_MASK);
+ ccb->ccb_h.status & CAM_STATUS_MASK);
retval = 1;
}
- close(fd);
- return(retval);
-
+ goto bailout;
}
@@ -3183,58 +3187,64 @@ rescan_or_reset_bus(path_id_t bus, int rescan)
* no-op, sending a rescan to the xpt bus would result in a status of
* CAM_REQ_INVALID.
*/
- bzero(&matchccb, sizeof(matchccb));
- matchccb.ccb_h.func_code = XPT_DEV_MATCH;
- matchccb.ccb_h.path_id = CAM_BUS_WILDCARD;
+ matchccb = malloc(sizeof(*matchccb));
+ if (matchccb == NULL) {
+ warn("failed to allocate CCB");
+ retval = 1;
+ goto bailout;
+ }
+ bzero(matchccb, sizeof(*matchccb));
+ matchccb->ccb_h.func_code = XPT_DEV_MATCH;
+ matchccb->ccb_h.path_id = CAM_BUS_WILDCARD;
bufsize = sizeof(struct dev_match_result) * 20;
- matchccb.cdm.match_buf_len = bufsize;
- matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize);
- if (matchccb.cdm.matches == NULL) {
+ matchccb->cdm.match_buf_len = bufsize;
+ matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize);
+ if (matchccb->cdm.matches == NULL) {
warnx("can't malloc memory for matches");
retval = 1;
goto bailout;
}
- matchccb.cdm.num_matches = 0;
+ matchccb->cdm.num_matches = 0;
- matchccb.cdm.num_patterns = 1;
- matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
+ matchccb->cdm.num_patterns = 1;
+ matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern);
- matchccb.cdm.patterns = (struct dev_match_pattern *)malloc(
- matchccb.cdm.pattern_buf_len);
- if (matchccb.cdm.patterns == NULL) {
+ matchccb->cdm.patterns = (struct dev_match_pattern *)malloc(
+ matchccb->cdm.pattern_buf_len);
+ if (matchccb->cdm.patterns == NULL) {
warnx("can't malloc memory for patterns");
retval = 1;
goto bailout;
}
- matchccb.cdm.patterns[0].type = DEV_MATCH_BUS;
- matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
+ matchccb->cdm.patterns[0].type = DEV_MATCH_BUS;
+ matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY;
do {
unsigned int i;
- if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) {
+ if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) {
warn("CAMIOCOMMAND ioctl failed");
retval = 1;
goto bailout;
}
- if ((matchccb.ccb_h.status != CAM_REQ_CMP)
- || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST)
- && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) {
+ if ((matchccb->ccb_h.status != CAM_REQ_CMP)
+ || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST)
+ && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) {
warnx("got CAM error %#x, CDM error %d\n",
- matchccb.ccb_h.status, matchccb.cdm.status);
+ matchccb->ccb_h.status, matchccb->cdm.status);
retval = 1;
goto bailout;
}
- for (i = 0; i < matchccb.cdm.num_matches; i++) {
+ for (i = 0; i < matchccb->cdm.num_matches; i++) {
struct bus_match_result *bus_result;
/* This shouldn't happen. */
- if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS)
+ if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS)
continue;
- bus_result = &matchccb.cdm.matches[i].result.bus_result;
+ bus_result =&matchccb->cdm.matches[i].result.bus_result;
/*
* We don't want to rescan or reset the xpt bus.
@@ -3243,23 +3253,23 @@ rescan_or_reset_bus(path_id_t bus, int rescan)
if (bus_result->path_id == CAM_XPT_PATH_ID)
continue;
- ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS :
+ ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS :
XPT_RESET_BUS;
- ccb.ccb_h.path_id = bus_result->path_id;
- ccb.ccb_h.target_id = CAM_TARGET_WILDCARD;
- ccb.ccb_h.target_lun = CAM_LUN_WILDCARD;
- ccb.crcn.flags = CAM_FLAG_NONE;
+ ccb->ccb_h.path_id = bus_result->path_id;
+ ccb->ccb_h.target_id = CAM_TARGET_WILDCARD;
+ ccb->ccb_h.target_lun = CAM_LUN_WILDCARD;
+ ccb->crcn.flags = CAM_FLAG_NONE;
/* run this at a low priority */
- ccb.ccb_h.pinfo.priority = 5;
+ ccb->ccb_h.pinfo.priority = 5;
- if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {
+ if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) {
warn("CAMIOCOMMAND ioctl failed");
retval = 1;
goto bailout;
}
- if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){
+ if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){
fprintf(stdout, "%s of bus %d was successful\n",
rescan? "Re-scan" : "Reset",
bus_result->path_id);
@@ -3272,22 +3282,24 @@ rescan_or_reset_bus(path_id_t bus, int rescan)
fprintf(stderr, "%s of bus %d returned error "
"%#x\n", rescan? "Re-scan" : "Reset",
bus_result->path_id,
- ccb.ccb_h.status & CAM_STATUS_MASK);
+ ccb->ccb_h.status & CAM_STATUS_MASK);
retval = 1;
}
}
- } while ((matchccb.ccb_h.status == CAM_REQ_CMP)
- && (matchccb.cdm.status == CAM_DEV_MATCH_MORE));
+ } while ((matchccb->ccb_h.status == CAM_REQ_CMP)
+ && (matchccb->cdm.status == CAM_DEV_MATCH_MORE));
bailout:
if (fd != -1)
close(fd);
- if (matchccb.cdm.patterns != NULL)
- free(matchccb.cdm.patterns);
- if (matchccb.cdm.matches != NULL)
- free(matchccb.cdm.matches);
+ if (matchccb != NULL) {
+ free(matchccb->cdm.patterns);
+ free(matchccb->cdm.matches);
+ free(matchccb);
+ }
+ free(ccb);
return(retval);
}
diff --git a/sbin/geom/class/eli/geom_eli.c b/sbin/geom/class/eli/geom_eli.c
index c804622ddbe2..fe7d1974ba48 100644
--- a/sbin/geom/class/eli/geom_eli.c
+++ b/sbin/geom/class/eli/geom_eli.c
@@ -666,7 +666,7 @@ static void
eli_init(struct gctl_req *req)
{
struct g_eli_metadata md;
- unsigned char sector[sizeof(struct g_eli_metadata)];
+ unsigned char sector[sizeof(struct g_eli_metadata)] __aligned(4);
unsigned char key[G_ELI_USERKEYLEN];
char backfile[MAXPATHLEN];
const char *str, *prov;
diff --git a/sbin/swapon/swapon.8 b/sbin/swapon/swapon.8
index ffce7d9db46e..51bee68346b6 100644
--- a/sbin/swapon/swapon.8
+++ b/sbin/swapon/swapon.8
@@ -28,7 +28,7 @@
.\" @(#)swapon.8 8.1 (Berkeley) 6/5/93
.\" $FreeBSD$
.\"
-.Dd October 2, 2016
+.Dd October 21, 2016
.Dt SWAPON 8
.Os
.Sh NAME
@@ -98,6 +98,12 @@ will be removed, unless their
.Dq noauto
option is also set.
If the
+.Fl L
+option is specified,
+only swap devices with the
+.Dq late
+option will be removed.
+If the
.Fl q
option is used,
informational messages will not be
diff --git a/sbin/swapon/swapon.c b/sbin/swapon/swapon.c
index e34cfcf171bf..052fbc734afb 100644
--- a/sbin/swapon/swapon.c
+++ b/sbin/swapon/swapon.c
@@ -176,6 +176,10 @@ main(int argc, char **argv)
strstr(fsp->fs_mntops, "late") &&
late == 0)
continue;
+ if (which_prog == SWAPOFF &&
+ strstr(fsp->fs_mntops, "late") == NULL &&
+ late != 0)
+ continue;
swfile = swap_on_off(fsp->fs_spec, 1,
fsp->fs_mntops);
if (swfile == NULL) {
diff --git a/sbin/zfsbootcfg/Makefile b/sbin/zfsbootcfg/Makefile
new file mode 100644
index 000000000000..d485d8dad8dc
--- /dev/null
+++ b/sbin/zfsbootcfg/Makefile
@@ -0,0 +1,27 @@
+# @(#)Makefile 8.4 (Berkeley) 6/22/95
+# $FreeBSD$
+
+PROG= zfsbootcfg
+WARNS?= 1
+MAN= zfsbootcfg.8
+
+LIBADD+=zfs
+LIBADD+=nvpair
+LIBADD+=umem
+LIBADD+=uutil
+LIBADD+=geom
+
+CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include
+CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem
+CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs/common
+CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs_core/common
+CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common
+CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair
+CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris
+CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs
+CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common
+CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head
+
+CFLAGS+= -DNEED_SOLARIS_BOOLEAN
+
+.include <bsd.prog.mk>
diff --git a/sbin/zfsbootcfg/zfsbootcfg.8 b/sbin/zfsbootcfg/zfsbootcfg.8
new file mode 100644
index 000000000000..aa6201da15fd
--- /dev/null
+++ b/sbin/zfsbootcfg/zfsbootcfg.8
@@ -0,0 +1,112 @@
+.\" Copyright (c) 2016 Andriy Gapon
+.\" 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$
+.\"
+.Dd October 12, 2016
+.Dt ZFSBOOTCFG 8
+.Os
+.Sh NAME
+.Nm zfsbootcfg
+.Nd "specify zfsboot options for the next boot"
+.Sh SYNOPSIS
+.Nm
+.Ao Ar options Ac
+.Sh DESCRIPTION
+.Nm
+is used to set
+.Xr boot.config 5 Ns -style
+options to be used by
+.Xr zfsboot 8
+or
+.Xr gptzfsboot 8
+the next time the machine is booted.
+Once
+.Xr zfsboot 8
+or
+.Xr gptzfsboot 8
+reads the information, it is deleted.
+If booting fails, the machine automatically reverts to the previous
+boot configuration.
+The information is stored in a special reserved area of a ZFS pool.
+.Xr zfsboot 8
+or
+.Xr gptzfsboot 8
+read the boot option information from the first disk found in the first
+ZFS pool found.
+.Sh ENVIRONMENT
+.Bl -tag -width vfs.zfs.boot.primary_pool -compact
+.It Ev vfs.zfs.boot.primary_pool
+The
+.Xr kenv 1
+variable that identifies a pool for which the options are written.
+.It Ev vfs.zfs.boot.primary_vdev
+The
+.Xr kenv 1
+variable that identifies a disk within the pool where the options
+are written.
+.El
+.Sh EXAMPLES
+Try to boot to a new
+.Em boot environment
+without changing the
+.Cm bootfs
+property of a pool:
+.Pp
+.Dl "zfsbootcfg ""zfs:tank/ROOT/newbe:""
+.Pp
+To clear the boot options:
+.Pp
+.Dl "zfsbootcfg """"
+.Sh SEE ALSO
+.Xr boot.config 5 ,
+.Xr gptzfsboot 8 ,
+.Xr zfsboot 8
+.Sh HISTORY
+.Nm
+appeared in
+.Fx 12.0 .
+.Sh AUTHORS
+This manual page was written by
+.An Andriy Gapon Aq Mt avg@FreeBSD.org .
+.Sh CAVEATS
+At the moment,
+.Nm
+uses the
+.Ev vfs.zfs.boot.primary_pool
+and
+.Ev vfs.zfs.boot.primary_vdev
+.Xr kenv 1
+variables to determine a ZFS pool and a disk in it where the options
+are to be stored.
+The variables are set by the ZFS boot chain, so there is an assumption
+that the same boot disk is going to be used for the next reboot.
+There is no
+.Nm
+option to specify a different pool or a different disk.
+.Pp
+.Nm
+should be extended to install new
+.Xr zfsboot 8
+blocks in a ZFS pool.
diff --git a/sbin/zfsbootcfg/zfsbootcfg.c b/sbin/zfsbootcfg/zfsbootcfg.c
new file mode 100644
index 000000000000..096f1a4697e6
--- /dev/null
+++ b/sbin/zfsbootcfg/zfsbootcfg.c
@@ -0,0 +1,98 @@
+/*-
+ * Copyright (c) 2016 Andriy Gapon <avg@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 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 <errno.h>
+#include <limits.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <kenv.h>
+
+#include <libzfs.h>
+
+/* Keep in sync with zfsboot.c. */
+#define MAX_COMMAND_LEN 512
+
+int main(int argc, const char * const *argv)
+{
+ char buf[32];
+ libzfs_handle_t *hdl;
+ uint64_t pool_guid;
+ uint64_t vdev_guid;
+ int zfs_fd;
+ int len;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: zfsbootcfg <boot.config(5) options>\n");
+ return (1);
+ }
+
+ len = strlen(argv[1]);
+ if (len >= MAX_COMMAND_LEN) {
+ fprintf(stderr, "options string is too long\n");
+ return (1);
+ }
+
+ if (kenv(KENV_GET, "vfs.zfs.boot.primary_pool", buf, sizeof(buf)) <= 0) {
+ perror("can't get vfs.zfs.boot.primary_pool");
+ return (1);
+ }
+ pool_guid = strtoumax(buf, NULL, 10);
+ if (pool_guid == 0) {
+ perror("can't parse vfs.zfs.boot.primary_pool");
+ return (1);
+ }
+
+ if (kenv(KENV_GET, "vfs.zfs.boot.primary_vdev", buf, sizeof(buf)) <= 0) {
+ perror("can't get vfs.zfs.boot.primary_vdev");
+ return (1);
+ }
+ vdev_guid = strtoumax(buf, NULL, 10);
+ if (vdev_guid == 0) {
+ perror("can't parse vfs.zfs.boot.primary_vdev");
+ return (1);
+ }
+
+ if ((hdl = libzfs_init()) == NULL) {
+ (void) fprintf(stderr, "internal error: failed to "
+ "initialize ZFS library\n");
+ return (1);
+ }
+
+ if (zpool_nextboot(hdl, pool_guid, vdev_guid, argv[1]) != 0) {
+ perror("ZFS_IOC_NEXTBOOT failed");
+ libzfs_fini(hdl);
+ return (1);
+ }
+
+ libzfs_fini(hdl);
+ printf("zfs next boot options are successfully written\n");
+ return (0);
+}
diff --git a/secure/lib/libcrypto/Makefile b/secure/lib/libcrypto/Makefile
index 0bc2fda8c63b..ccc78212ab09 100644
--- a/secure/lib/libcrypto/Makefile
+++ b/secure/lib/libcrypto/Makefile
@@ -22,7 +22,10 @@ MAN+= config.5 des_modes.7
# base sources
SRCS= cpt_err.c cryptlib.c cversion.c ex_data.c mem.c mem_dbg.c o_dir.c \
o_fips.c o_init.c o_str.c o_time.c uid.c
-.if defined(ASM_amd64)
+.if defined(ASM_aarch64)
+SRCS+= arm64cpuid.S armcap.c mem_clr.c
+ACFLAGS.arm64cpuid.S= -march=armv8-a+crypto
+.elif defined(ASM_amd64)
SRCS+= x86_64cpuid.S
.elif defined(ASM_arm)
SRCS+= armcap.c armv4cpuid.S
@@ -35,7 +38,10 @@ INCS+= crypto.h ebcdic.h opensslv.h ossl_typ.h symhacks.h ../e_os2.h
# aes
SRCS+= aes_cfb.c aes_ctr.c aes_ecb.c aes_ige.c aes_misc.c aes_ofb.c aes_wrap.c
-.if defined(ASM_amd64)
+.if defined(ASM_aarch64)
+SRCS+= aes_cbc.c aes_core.c aesv8-armx.S
+ACFLAGS.aesv8-armx.S= -march=armv8-a+crypto
+.elif defined(ASM_amd64)
SRCS+= aes-x86_64.S aesni-mb-x86_64.S aesni-sha1-x86_64.S \
aesni-sha256-x86_64.S aesni-x86_64.S bsaes-x86_64.S vpaes-x86_64.S
.elif defined(ASM_arm)
@@ -238,7 +244,10 @@ INCS+= mdc2.h
# modes
SRCS+= cbc128.c ccm128.c cfb128.c ctr128.c cts128.c gcm128.c ofb128.c \
wrap128.c xts128.c
-.if defined(ASM_amd64)
+.if defined(ASM_aarch64)
+SRCS+= ghashv8-armx.S
+ACFLAGS.ghashv8-armx.S= -march=armv8-a+crypto
+.elif defined(ASM_amd64)
SRCS+= aesni-gcm-x86_64.S ghash-x86_64.S
.elif defined(ASM_arm)
SRCS+= ghash-armv4.S ghashv8-armx.S
@@ -324,7 +333,9 @@ INCS+= seed.h
# sha
SRCS+= sha1_one.c sha1dgst.c sha256.c sha512.c sha_dgst.c sha_one.c
-.if defined(ASM_amd64)
+.if defined(ASM_aarch64)
+SRCS+= sha1-armv8.S sha256-armv8.S sha512-armv8.S
+.elif defined(ASM_amd64)
SRCS+= sha1-mb-x86_64.S sha1-x86_64.S sha256-mb-x86_64.S sha256-x86_64.S \
sha512-x86_64.S
.elif defined(ASM_arm)
diff --git a/secure/lib/libcrypto/Makefile.asm b/secure/lib/libcrypto/Makefile.asm
index a50392003354..076d4c1e69e7 100644
--- a/secure/lib/libcrypto/Makefile.asm
+++ b/secure/lib/libcrypto/Makefile.asm
@@ -6,7 +6,44 @@
.include "Makefile.inc"
-.if defined(ASM_amd64)
+.if defined(ASM_aarch64)
+
+.PATH: ${LCRYPTO_SRC}/crypto \
+ ${LCRYPTO_SRC}/crypto/aes/asm \
+ ${LCRYPTO_SRC}/crypto/modes/asm \
+ ${LCRYPTO_SRC}/crypto/sha/asm
+
+PERLPATH= -I${LCRYPTO_SRC}/crypto/perlasm
+
+# aes
+SRCS= aesv8-armx.pl
+
+# modes
+SRCS+= ghashv8-armx.pl
+
+# sha
+SRCS+= sha1-armv8.pl sha512-armv8.pl
+
+ASM= ${SRCS:R:S/$/.S/} sha256-armv8.S
+
+all: ${ASM}
+
+CLEANFILES= ${ASM} ${SRCS:R:S/$/.s/} sha256-armv8.s
+.SUFFIXES: .pl
+
+sha256-armv8.S: sha512-armv8.pl
+ env CC=cc perl ${.ALLSRC} 64 ${.TARGET:R:S/$/.s/}
+ ( echo '/* $$'FreeBSD'$$ */' ;\
+ echo '/* Do not modify. This file is auto-generated from ${.ALLSRC:T:R:S/$/.pl/}. */' ;\
+ cat ${.TARGET:R:S/$/.s/}) > ${.TARGET}
+
+.pl.S:
+ env CC=cc perl ${.IMPSRC} 64 ${.TARGET:R:S/$/.s/}
+ ( echo '/* $$'FreeBSD'$$ */' ;\
+ echo '/* Do not modify. This file is auto-generated from ${.IMPSRC:T:R:S/$/.pl/}. */' ;\
+ cat ${.TARGET:R:S/$/.s/}) > ${.TARGET}
+
+.elif defined(ASM_amd64)
.PATH: ${LCRYPTO_SRC}/crypto \
${LCRYPTO_SRC}/crypto/aes/asm \
diff --git a/secure/lib/libcrypto/Makefile.inc b/secure/lib/libcrypto/Makefile.inc
index 3be4ddc7ea07..257c53402c68 100644
--- a/secure/lib/libcrypto/Makefile.inc
+++ b/secure/lib/libcrypto/Makefile.inc
@@ -21,7 +21,9 @@ CFLAGS+=-DL_ENDIAN
CFLAGS+=-DB_ENDIAN
.endif
-.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
+.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
+ASM_${MACHINE_CPUARCH}=
+.elif ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
_ASM_AVX!= { \
echo vzeroall | \
${CC} -x assembler -o /dev/null -c - 2> /dev/null; \
@@ -29,11 +31,11 @@ _ASM_AVX!= { \
.if ${_ASM_AVX} == yes
ASM_${MACHINE_CPUARCH}=
.endif
-.elif ${MACHINE_CPUARCH} == "arm"
-ASM_arm=
.endif
-.if defined(ASM_amd64)
+.if defined(ASM_aarch64)
+CFLAGS+=-DSHA1_ASM -DSHA256_ASM -DSHA512_ASM
+.elif defined(ASM_amd64)
CFLAGS+=-DOPENSSL_IA32_SSE2
CFLAGS+=-DAES_ASM -DBSAES_ASM -DVPAES_ASM
CFLAGS+=-DECP_NISTZ256_ASM
diff --git a/secure/lib/libcrypto/aarch64/aesv8-armx.S b/secure/lib/libcrypto/aarch64/aesv8-armx.S
new file mode 100644
index 000000000000..5c8aa5002e8a
--- /dev/null
+++ b/secure/lib/libcrypto/aarch64/aesv8-armx.S
@@ -0,0 +1,748 @@
+/* $FreeBSD$ */
+/* Do not modify. This file is auto-generated from aesv8-armx.pl. */
+#include "arm_arch.h"
+
+#if __ARM_MAX_ARCH__>=7
+.text
+.align 5
+rcon:
+.long 0x01,0x01,0x01,0x01
+.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat
+.long 0x1b,0x1b,0x1b,0x1b
+
+.globl aes_v8_set_encrypt_key
+.type aes_v8_set_encrypt_key,%function
+.align 5
+aes_v8_set_encrypt_key:
+.Lenc_key:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ mov x3,#-1
+ cmp x0,#0
+ b.eq .Lenc_key_abort
+ cmp x2,#0
+ b.eq .Lenc_key_abort
+ mov x3,#-2
+ cmp w1,#128
+ b.lt .Lenc_key_abort
+ cmp w1,#256
+ b.gt .Lenc_key_abort
+ tst w1,#0x3f
+ b.ne .Lenc_key_abort
+
+ adr x3,rcon
+ cmp w1,#192
+
+ eor v0.16b,v0.16b,v0.16b
+ ld1 {v3.16b},[x0],#16
+ mov w1,#8 // reuse w1
+ ld1 {v1.4s,v2.4s},[x3],#32
+
+ b.lt .Loop128
+ b.eq .L192
+ b .L256
+
+.align 4
+.Loop128:
+ tbl v6.16b,{v3.16b},v2.16b
+ ext v5.16b,v0.16b,v3.16b,#12
+ st1 {v3.4s},[x2],#16
+ aese v6.16b,v0.16b
+ subs w1,w1,#1
+
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v6.16b,v6.16b,v1.16b
+ eor v3.16b,v3.16b,v5.16b
+ shl v1.16b,v1.16b,#1
+ eor v3.16b,v3.16b,v6.16b
+ b.ne .Loop128
+
+ ld1 {v1.4s},[x3]
+
+ tbl v6.16b,{v3.16b},v2.16b
+ ext v5.16b,v0.16b,v3.16b,#12
+ st1 {v3.4s},[x2],#16
+ aese v6.16b,v0.16b
+
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v6.16b,v6.16b,v1.16b
+ eor v3.16b,v3.16b,v5.16b
+ shl v1.16b,v1.16b,#1
+ eor v3.16b,v3.16b,v6.16b
+
+ tbl v6.16b,{v3.16b},v2.16b
+ ext v5.16b,v0.16b,v3.16b,#12
+ st1 {v3.4s},[x2],#16
+ aese v6.16b,v0.16b
+
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v6.16b,v6.16b,v1.16b
+ eor v3.16b,v3.16b,v5.16b
+ eor v3.16b,v3.16b,v6.16b
+ st1 {v3.4s},[x2]
+ add x2,x2,#0x50
+
+ mov w12,#10
+ b .Ldone
+
+.align 4
+.L192:
+ ld1 {v4.8b},[x0],#8
+ movi v6.16b,#8 // borrow v6.16b
+ st1 {v3.4s},[x2],#16
+ sub v2.16b,v2.16b,v6.16b // adjust the mask
+
+.Loop192:
+ tbl v6.16b,{v4.16b},v2.16b
+ ext v5.16b,v0.16b,v3.16b,#12
+ st1 {v4.8b},[x2],#8
+ aese v6.16b,v0.16b
+ subs w1,w1,#1
+
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+
+ dup v5.4s,v3.s[3]
+ eor v5.16b,v5.16b,v4.16b
+ eor v6.16b,v6.16b,v1.16b
+ ext v4.16b,v0.16b,v4.16b,#12
+ shl v1.16b,v1.16b,#1
+ eor v4.16b,v4.16b,v5.16b
+ eor v3.16b,v3.16b,v6.16b
+ eor v4.16b,v4.16b,v6.16b
+ st1 {v3.4s},[x2],#16
+ b.ne .Loop192
+
+ mov w12,#12
+ add x2,x2,#0x20
+ b .Ldone
+
+.align 4
+.L256:
+ ld1 {v4.16b},[x0]
+ mov w1,#7
+ mov w12,#14
+ st1 {v3.4s},[x2],#16
+
+.Loop256:
+ tbl v6.16b,{v4.16b},v2.16b
+ ext v5.16b,v0.16b,v3.16b,#12
+ st1 {v4.4s},[x2],#16
+ aese v6.16b,v0.16b
+ subs w1,w1,#1
+
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v3.16b,v3.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v6.16b,v6.16b,v1.16b
+ eor v3.16b,v3.16b,v5.16b
+ shl v1.16b,v1.16b,#1
+ eor v3.16b,v3.16b,v6.16b
+ st1 {v3.4s},[x2],#16
+ b.eq .Ldone
+
+ dup v6.4s,v3.s[3] // just splat
+ ext v5.16b,v0.16b,v4.16b,#12
+ aese v6.16b,v0.16b
+
+ eor v4.16b,v4.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v4.16b,v4.16b,v5.16b
+ ext v5.16b,v0.16b,v5.16b,#12
+ eor v4.16b,v4.16b,v5.16b
+
+ eor v4.16b,v4.16b,v6.16b
+ b .Loop256
+
+.Ldone:
+ str w12,[x2]
+ mov x3,#0
+
+.Lenc_key_abort:
+ mov x0,x3 // return value
+ ldr x29,[sp],#16
+ ret
+.size aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key
+
+.globl aes_v8_set_decrypt_key
+.type aes_v8_set_decrypt_key,%function
+.align 5
+aes_v8_set_decrypt_key:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ bl .Lenc_key
+
+ cmp x0,#0
+ b.ne .Ldec_key_abort
+
+ sub x2,x2,#240 // restore original x2
+ mov x4,#-16
+ add x0,x2,x12,lsl#4 // end of key schedule
+
+ ld1 {v0.4s},[x2]
+ ld1 {v1.4s},[x0]
+ st1 {v0.4s},[x0],x4
+ st1 {v1.4s},[x2],#16
+
+.Loop_imc:
+ ld1 {v0.4s},[x2]
+ ld1 {v1.4s},[x0]
+ aesimc v0.16b,v0.16b
+ aesimc v1.16b,v1.16b
+ st1 {v0.4s},[x0],x4
+ st1 {v1.4s},[x2],#16
+ cmp x0,x2
+ b.hi .Loop_imc
+
+ ld1 {v0.4s},[x2]
+ aesimc v0.16b,v0.16b
+ st1 {v0.4s},[x0]
+
+ eor x0,x0,x0 // return value
+.Ldec_key_abort:
+ ldp x29,x30,[sp],#16
+ ret
+.size aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key
+.globl aes_v8_encrypt
+.type aes_v8_encrypt,%function
+.align 5
+aes_v8_encrypt:
+ ldr w3,[x2,#240]
+ ld1 {v0.4s},[x2],#16
+ ld1 {v2.16b},[x0]
+ sub w3,w3,#2
+ ld1 {v1.4s},[x2],#16
+
+.Loop_enc:
+ aese v2.16b,v0.16b
+ aesmc v2.16b,v2.16b
+ ld1 {v0.4s},[x2],#16
+ subs w3,w3,#2
+ aese v2.16b,v1.16b
+ aesmc v2.16b,v2.16b
+ ld1 {v1.4s},[x2],#16
+ b.gt .Loop_enc
+
+ aese v2.16b,v0.16b
+ aesmc v2.16b,v2.16b
+ ld1 {v0.4s},[x2]
+ aese v2.16b,v1.16b
+ eor v2.16b,v2.16b,v0.16b
+
+ st1 {v2.16b},[x1]
+ ret
+.size aes_v8_encrypt,.-aes_v8_encrypt
+.globl aes_v8_decrypt
+.type aes_v8_decrypt,%function
+.align 5
+aes_v8_decrypt:
+ ldr w3,[x2,#240]
+ ld1 {v0.4s},[x2],#16
+ ld1 {v2.16b},[x0]
+ sub w3,w3,#2
+ ld1 {v1.4s},[x2],#16
+
+.Loop_dec:
+ aesd v2.16b,v0.16b
+ aesimc v2.16b,v2.16b
+ ld1 {v0.4s},[x2],#16
+ subs w3,w3,#2
+ aesd v2.16b,v1.16b
+ aesimc v2.16b,v2.16b
+ ld1 {v1.4s},[x2],#16
+ b.gt .Loop_dec
+
+ aesd v2.16b,v0.16b
+ aesimc v2.16b,v2.16b
+ ld1 {v0.4s},[x2]
+ aesd v2.16b,v1.16b
+ eor v2.16b,v2.16b,v0.16b
+
+ st1 {v2.16b},[x1]
+ ret
+.size aes_v8_decrypt,.-aes_v8_decrypt
+.globl aes_v8_cbc_encrypt
+.type aes_v8_cbc_encrypt,%function
+.align 5
+aes_v8_cbc_encrypt:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ subs x2,x2,#16
+ mov x8,#16
+ b.lo .Lcbc_abort
+ csel x8,xzr,x8,eq
+
+ cmp w5,#0 // en- or decrypting?
+ ldr w5,[x3,#240]
+ and x2,x2,#-16
+ ld1 {v6.16b},[x4]
+ ld1 {v0.16b},[x0],x8
+
+ ld1 {v16.4s-v17.4s},[x3] // load key schedule...
+ sub w5,w5,#6
+ add x7,x3,x5,lsl#4 // pointer to last 7 round keys
+ sub w5,w5,#2
+ ld1 {v18.4s-v19.4s},[x7],#32
+ ld1 {v20.4s-v21.4s},[x7],#32
+ ld1 {v22.4s-v23.4s},[x7],#32
+ ld1 {v7.4s},[x7]
+
+ add x7,x3,#32
+ mov w6,w5
+ b.eq .Lcbc_dec
+
+ cmp w5,#2
+ eor v0.16b,v0.16b,v6.16b
+ eor v5.16b,v16.16b,v7.16b
+ b.eq .Lcbc_enc128
+
+ ld1 {v2.4s-v3.4s},[x7]
+ add x7,x3,#16
+ add x6,x3,#16*4
+ add x12,x3,#16*5
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ add x14,x3,#16*6
+ add x3,x3,#16*7
+ b .Lenter_cbc_enc
+
+.align 4
+.Loop_cbc_enc:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ st1 {v6.16b},[x1],#16
+.Lenter_cbc_enc:
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v2.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.4s},[x6]
+ cmp w5,#4
+ aese v0.16b,v3.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v17.4s},[x12]
+ b.eq .Lcbc_enc192
+
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.4s},[x14]
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v17.4s},[x3]
+ nop
+
+.Lcbc_enc192:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ subs x2,x2,#16
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ csel x8,xzr,x8,eq
+ aese v0.16b,v18.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v19.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.16b},[x0],x8
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ eor v16.16b,v16.16b,v5.16b
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v17.4s},[x7] // re-pre-load rndkey[1]
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v23.16b
+ eor v6.16b,v0.16b,v7.16b
+ b.hs .Loop_cbc_enc
+
+ st1 {v6.16b},[x1],#16
+ b .Lcbc_done
+
+.align 5
+.Lcbc_enc128:
+ ld1 {v2.4s-v3.4s},[x7]
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ b .Lenter_cbc_enc128
+.Loop_cbc_enc128:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ st1 {v6.16b},[x1],#16
+.Lenter_cbc_enc128:
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ subs x2,x2,#16
+ aese v0.16b,v2.16b
+ aesmc v0.16b,v0.16b
+ csel x8,xzr,x8,eq
+ aese v0.16b,v3.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v18.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v19.16b
+ aesmc v0.16b,v0.16b
+ ld1 {v16.16b},[x0],x8
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ eor v16.16b,v16.16b,v5.16b
+ aese v0.16b,v23.16b
+ eor v6.16b,v0.16b,v7.16b
+ b.hs .Loop_cbc_enc128
+
+ st1 {v6.16b},[x1],#16
+ b .Lcbc_done
+.align 5
+.Lcbc_dec:
+ ld1 {v18.16b},[x0],#16
+ subs x2,x2,#32 // bias
+ add w6,w5,#2
+ orr v3.16b,v0.16b,v0.16b
+ orr v1.16b,v0.16b,v0.16b
+ orr v19.16b,v18.16b,v18.16b
+ b.lo .Lcbc_dec_tail
+
+ orr v1.16b,v18.16b,v18.16b
+ ld1 {v18.16b},[x0],#16
+ orr v2.16b,v0.16b,v0.16b
+ orr v3.16b,v1.16b,v1.16b
+ orr v19.16b,v18.16b,v18.16b
+
+.Loop3x_cbc_dec:
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v16.16b
+ aesimc v18.16b,v18.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v17.16b
+ aesimc v18.16b,v18.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop3x_cbc_dec
+
+ aesd v0.16b,v16.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v16.16b
+ aesimc v18.16b,v18.16b
+ eor v4.16b,v6.16b,v7.16b
+ subs x2,x2,#0x30
+ eor v5.16b,v2.16b,v7.16b
+ csel x6,x2,x6,lo // x6, w6, is zero at this point
+ aesd v0.16b,v17.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v17.16b
+ aesimc v18.16b,v18.16b
+ eor v17.16b,v3.16b,v7.16b
+ add x0,x0,x6 // x0 is adjusted in such way that
+ // at exit from the loop v1.16b-v18.16b
+ // are loaded with last "words"
+ orr v6.16b,v19.16b,v19.16b
+ mov x7,x3
+ aesd v0.16b,v20.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v20.16b
+ aesimc v18.16b,v18.16b
+ ld1 {v2.16b},[x0],#16
+ aesd v0.16b,v21.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v21.16b
+ aesimc v18.16b,v18.16b
+ ld1 {v3.16b},[x0],#16
+ aesd v0.16b,v22.16b
+ aesimc v0.16b,v0.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v22.16b
+ aesimc v18.16b,v18.16b
+ ld1 {v19.16b},[x0],#16
+ aesd v0.16b,v23.16b
+ aesd v1.16b,v23.16b
+ aesd v18.16b,v23.16b
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ add w6,w5,#2
+ eor v4.16b,v4.16b,v0.16b
+ eor v5.16b,v5.16b,v1.16b
+ eor v18.16b,v18.16b,v17.16b
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v4.16b},[x1],#16
+ orr v0.16b,v2.16b,v2.16b
+ st1 {v5.16b},[x1],#16
+ orr v1.16b,v3.16b,v3.16b
+ st1 {v18.16b},[x1],#16
+ orr v18.16b,v19.16b,v19.16b
+ b.hs .Loop3x_cbc_dec
+
+ cmn x2,#0x30
+ b.eq .Lcbc_done
+ nop
+
+.Lcbc_dec_tail:
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v16.16b
+ aesimc v18.16b,v18.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v17.16b
+ aesimc v18.16b,v18.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Lcbc_dec_tail
+
+ aesd v1.16b,v16.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v16.16b
+ aesimc v18.16b,v18.16b
+ aesd v1.16b,v17.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v17.16b
+ aesimc v18.16b,v18.16b
+ aesd v1.16b,v20.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v20.16b
+ aesimc v18.16b,v18.16b
+ cmn x2,#0x20
+ aesd v1.16b,v21.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v21.16b
+ aesimc v18.16b,v18.16b
+ eor v5.16b,v6.16b,v7.16b
+ aesd v1.16b,v22.16b
+ aesimc v1.16b,v1.16b
+ aesd v18.16b,v22.16b
+ aesimc v18.16b,v18.16b
+ eor v17.16b,v3.16b,v7.16b
+ aesd v1.16b,v23.16b
+ aesd v18.16b,v23.16b
+ b.eq .Lcbc_dec_one
+ eor v5.16b,v5.16b,v1.16b
+ eor v17.16b,v17.16b,v18.16b
+ orr v6.16b,v19.16b,v19.16b
+ st1 {v5.16b},[x1],#16
+ st1 {v17.16b},[x1],#16
+ b .Lcbc_done
+
+.Lcbc_dec_one:
+ eor v5.16b,v5.16b,v18.16b
+ orr v6.16b,v19.16b,v19.16b
+ st1 {v5.16b},[x1],#16
+
+.Lcbc_done:
+ st1 {v6.16b},[x4]
+.Lcbc_abort:
+ ldr x29,[sp],#16
+ ret
+.size aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt
+.globl aes_v8_ctr32_encrypt_blocks
+.type aes_v8_ctr32_encrypt_blocks,%function
+.align 5
+aes_v8_ctr32_encrypt_blocks:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+ ldr w5,[x3,#240]
+
+ ldr w8, [x4, #12]
+ ld1 {v0.4s},[x4]
+
+ ld1 {v16.4s-v17.4s},[x3] // load key schedule...
+ sub w5,w5,#4
+ mov x12,#16
+ cmp x2,#2
+ add x7,x3,x5,lsl#4 // pointer to last 5 round keys
+ sub w5,w5,#2
+ ld1 {v20.4s-v21.4s},[x7],#32
+ ld1 {v22.4s-v23.4s},[x7],#32
+ ld1 {v7.4s},[x7]
+ add x7,x3,#32
+ mov w6,w5
+ csel x12,xzr,x12,lo
+#ifndef __ARMEB__
+ rev w8, w8
+#endif
+ orr v1.16b,v0.16b,v0.16b
+ add w10, w8, #1
+ orr v18.16b,v0.16b,v0.16b
+ add w8, w8, #2
+ orr v6.16b,v0.16b,v0.16b
+ rev w10, w10
+ mov v1.s[3],w10
+ b.ls .Lctr32_tail
+ rev w12, w8
+ sub x2,x2,#3 // bias
+ mov v18.s[3],w12
+ b .Loop3x_ctr32
+
+.align 4
+.Loop3x_ctr32:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v18.16b,v16.16b
+ aesmc v18.16b,v18.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ aese v18.16b,v17.16b
+ aesmc v18.16b,v18.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Loop3x_ctr32
+
+ aese v0.16b,v16.16b
+ aesmc v4.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v5.16b,v1.16b
+ ld1 {v2.16b},[x0],#16
+ orr v0.16b,v6.16b,v6.16b
+ aese v18.16b,v16.16b
+ aesmc v18.16b,v18.16b
+ ld1 {v3.16b},[x0],#16
+ orr v1.16b,v6.16b,v6.16b
+ aese v4.16b,v17.16b
+ aesmc v4.16b,v4.16b
+ aese v5.16b,v17.16b
+ aesmc v5.16b,v5.16b
+ ld1 {v19.16b},[x0],#16
+ mov x7,x3
+ aese v18.16b,v17.16b
+ aesmc v17.16b,v18.16b
+ orr v18.16b,v6.16b,v6.16b
+ add w9,w8,#1
+ aese v4.16b,v20.16b
+ aesmc v4.16b,v4.16b
+ aese v5.16b,v20.16b
+ aesmc v5.16b,v5.16b
+ eor v2.16b,v2.16b,v7.16b
+ add w10,w8,#2
+ aese v17.16b,v20.16b
+ aesmc v17.16b,v17.16b
+ eor v3.16b,v3.16b,v7.16b
+ add w8,w8,#3
+ aese v4.16b,v21.16b
+ aesmc v4.16b,v4.16b
+ aese v5.16b,v21.16b
+ aesmc v5.16b,v5.16b
+ eor v19.16b,v19.16b,v7.16b
+ rev w9,w9
+ aese v17.16b,v21.16b
+ aesmc v17.16b,v17.16b
+ mov v0.s[3], w9
+ rev w10,w10
+ aese v4.16b,v22.16b
+ aesmc v4.16b,v4.16b
+ aese v5.16b,v22.16b
+ aesmc v5.16b,v5.16b
+ mov v1.s[3], w10
+ rev w12,w8
+ aese v17.16b,v22.16b
+ aesmc v17.16b,v17.16b
+ mov v18.s[3], w12
+ subs x2,x2,#3
+ aese v4.16b,v23.16b
+ aese v5.16b,v23.16b
+ aese v17.16b,v23.16b
+
+ eor v2.16b,v2.16b,v4.16b
+ ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0]
+ st1 {v2.16b},[x1],#16
+ eor v3.16b,v3.16b,v5.16b
+ mov w6,w5
+ st1 {v3.16b},[x1],#16
+ eor v19.16b,v19.16b,v17.16b
+ ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1]
+ st1 {v19.16b},[x1],#16
+ b.hs .Loop3x_ctr32
+
+ adds x2,x2,#3
+ b.eq .Lctr32_done
+ cmp x2,#1
+ mov x12,#16
+ csel x12,xzr,x12,eq
+
+.Lctr32_tail:
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ ld1 {v16.4s},[x7],#16
+ subs w6,w6,#2
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ ld1 {v17.4s},[x7],#16
+ b.gt .Lctr32_tail
+
+ aese v0.16b,v16.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v16.16b
+ aesmc v1.16b,v1.16b
+ aese v0.16b,v17.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v17.16b
+ aesmc v1.16b,v1.16b
+ ld1 {v2.16b},[x0],x12
+ aese v0.16b,v20.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v20.16b
+ aesmc v1.16b,v1.16b
+ ld1 {v3.16b},[x0]
+ aese v0.16b,v21.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v21.16b
+ aesmc v1.16b,v1.16b
+ eor v2.16b,v2.16b,v7.16b
+ aese v0.16b,v22.16b
+ aesmc v0.16b,v0.16b
+ aese v1.16b,v22.16b
+ aesmc v1.16b,v1.16b
+ eor v3.16b,v3.16b,v7.16b
+ aese v0.16b,v23.16b
+ aese v1.16b,v23.16b
+
+ cmp x2,#1
+ eor v2.16b,v2.16b,v0.16b
+ eor v3.16b,v3.16b,v1.16b
+ st1 {v2.16b},[x1],#16
+ b.eq .Lctr32_done
+ st1 {v3.16b},[x1]
+
+.Lctr32_done:
+ ldr x29,[sp],#16
+ ret
+.size aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks
+#endif
diff --git a/secure/lib/libcrypto/aarch64/ghashv8-armx.S b/secure/lib/libcrypto/aarch64/ghashv8-armx.S
new file mode 100644
index 000000000000..61a4e4488d16
--- /dev/null
+++ b/secure/lib/libcrypto/aarch64/ghashv8-armx.S
@@ -0,0 +1,228 @@
+/* $FreeBSD$ */
+/* Do not modify. This file is auto-generated from ghashv8-armx.pl. */
+#include "arm_arch.h"
+
+.text
+.global gcm_init_v8
+.type gcm_init_v8,%function
+.align 4
+gcm_init_v8:
+ ld1 {v17.2d},[x1] //load input H
+ movi v19.16b,#0xe1
+ shl v19.2d,v19.2d,#57 //0xc2.0
+ ext v3.16b,v17.16b,v17.16b,#8
+ ushr v18.2d,v19.2d,#63
+ dup v17.4s,v17.s[1]
+ ext v16.16b,v18.16b,v19.16b,#8 //t0=0xc2....01
+ ushr v18.2d,v3.2d,#63
+ sshr v17.4s,v17.4s,#31 //broadcast carry bit
+ and v18.16b,v18.16b,v16.16b
+ shl v3.2d,v3.2d,#1
+ ext v18.16b,v18.16b,v18.16b,#8
+ and v16.16b,v16.16b,v17.16b
+ orr v3.16b,v3.16b,v18.16b //H<<<=1
+ eor v20.16b,v3.16b,v16.16b //twisted H
+ st1 {v20.2d},[x0],#16 //store Htable[0]
+
+ //calculate H^2
+ ext v16.16b,v20.16b,v20.16b,#8 //Karatsuba pre-processing
+ pmull v0.1q,v20.1d,v20.1d
+ eor v16.16b,v16.16b,v20.16b
+ pmull2 v2.1q,v20.2d,v20.2d
+ pmull v1.1q,v16.1d,v16.1d
+
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ eor v1.16b,v1.16b,v18.16b
+ pmull v18.1q,v0.1d,v19.1d //1st phase
+
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ eor v0.16b,v1.16b,v18.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase
+ pmull v0.1q,v0.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ eor v22.16b,v0.16b,v18.16b
+
+ ext v17.16b,v22.16b,v22.16b,#8 //Karatsuba pre-processing
+ eor v17.16b,v17.16b,v22.16b
+ ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed
+ st1 {v21.2d-v22.2d},[x0] //store Htable[1..2]
+
+ ret
+.size gcm_init_v8,.-gcm_init_v8
+.global gcm_gmult_v8
+.type gcm_gmult_v8,%function
+.align 4
+gcm_gmult_v8:
+ ld1 {v17.2d},[x0] //load Xi
+ movi v19.16b,#0xe1
+ ld1 {v20.2d-v21.2d},[x1] //load twisted H, ...
+ shl v19.2d,v19.2d,#57
+#ifndef __ARMEB__
+ rev64 v17.16b,v17.16b
+#endif
+ ext v3.16b,v17.16b,v17.16b,#8
+
+ pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo
+ eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing
+ pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi
+ pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi)
+
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ eor v1.16b,v1.16b,v18.16b
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ eor v0.16b,v1.16b,v18.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ eor v0.16b,v0.16b,v18.16b
+
+#ifndef __ARMEB__
+ rev64 v0.16b,v0.16b
+#endif
+ ext v0.16b,v0.16b,v0.16b,#8
+ st1 {v0.2d},[x0] //write out Xi
+
+ ret
+.size gcm_gmult_v8,.-gcm_gmult_v8
+.global gcm_ghash_v8
+.type gcm_ghash_v8,%function
+.align 4
+gcm_ghash_v8:
+ ld1 {v0.2d},[x0] //load [rotated] Xi
+ //"[rotated]" means that
+ //loaded value would have
+ //to be rotated in order to
+ //make it appear as in
+ //alorithm specification
+ subs x3,x3,#32 //see if x3 is 32 or larger
+ mov x12,#16 //x12 is used as post-
+ //increment for input pointer;
+ //as loop is modulo-scheduled
+ //x12 is zeroed just in time
+ //to preclude oversteping
+ //inp[len], which means that
+ //last block[s] are actually
+ //loaded twice, but last
+ //copy is not processed
+ ld1 {v20.2d-v21.2d},[x1],#32 //load twisted H, ..., H^2
+ movi v19.16b,#0xe1
+ ld1 {v22.2d},[x1]
+ csel x12,xzr,x12,eq //is it time to zero x12?
+ ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi
+ ld1 {v16.2d},[x2],#16 //load [rotated] I[0]
+ shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant
+#ifndef __ARMEB__
+ rev64 v16.16b,v16.16b
+ rev64 v0.16b,v0.16b
+#endif
+ ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0]
+ b.lo .Lodd_tail_v8 //x3 was less than 32
+ ld1 {v17.2d},[x2],x12 //load [rotated] I[1]
+#ifndef __ARMEB__
+ rev64 v17.16b,v17.16b
+#endif
+ ext v7.16b,v17.16b,v17.16b,#8
+ eor v3.16b,v3.16b,v0.16b //I[i]^=Xi
+ pmull v4.1q,v20.1d,v7.1d //H·Ii+1
+ eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing
+ pmull2 v6.1q,v20.2d,v7.2d
+ b .Loop_mod2x_v8
+
+.align 4
+.Loop_mod2x_v8:
+ ext v18.16b,v3.16b,v3.16b,#8
+ subs x3,x3,#32 //is there more data?
+ pmull v0.1q,v22.1d,v3.1d //H^2.lo·Xi.lo
+ csel x12,xzr,x12,lo //is it time to zero x12?
+
+ pmull v5.1q,v21.1d,v17.1d
+ eor v18.16b,v18.16b,v3.16b //Karatsuba pre-processing
+ pmull2 v2.1q,v22.2d,v3.2d //H^2.hi·Xi.hi
+ eor v0.16b,v0.16b,v4.16b //accumulate
+ pmull2 v1.1q,v21.2d,v18.2d //(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
+ ld1 {v16.2d},[x2],x12 //load [rotated] I[i+2]
+
+ eor v2.16b,v2.16b,v6.16b
+ csel x12,xzr,x12,eq //is it time to zero x12?
+ eor v1.16b,v1.16b,v5.16b
+
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3]
+#ifndef __ARMEB__
+ rev64 v16.16b,v16.16b
+#endif
+ eor v1.16b,v1.16b,v18.16b
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+
+#ifndef __ARMEB__
+ rev64 v17.16b,v17.16b
+#endif
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ ext v7.16b,v17.16b,v17.16b,#8
+ ext v3.16b,v16.16b,v16.16b,#8
+ eor v0.16b,v1.16b,v18.16b
+ pmull v4.1q,v20.1d,v7.1d //H·Ii+1
+ eor v3.16b,v3.16b,v2.16b //accumulate v3.16b early
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ eor v3.16b,v3.16b,v18.16b
+ eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing
+ eor v3.16b,v3.16b,v0.16b
+ pmull2 v6.1q,v20.2d,v7.2d
+ b.hs .Loop_mod2x_v8 //there was at least 32 more bytes
+
+ eor v2.16b,v2.16b,v18.16b
+ ext v3.16b,v16.16b,v16.16b,#8 //re-construct v3.16b
+ adds x3,x3,#32 //re-construct x3
+ eor v0.16b,v0.16b,v2.16b //re-construct v0.16b
+ b.eq .Ldone_v8 //is x3 zero?
+.Lodd_tail_v8:
+ ext v18.16b,v0.16b,v0.16b,#8
+ eor v3.16b,v3.16b,v0.16b //inp^=Xi
+ eor v17.16b,v16.16b,v18.16b //v17.16b is rotated inp^Xi
+
+ pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo
+ eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing
+ pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi
+ pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi)
+
+ ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing
+ eor v18.16b,v0.16b,v2.16b
+ eor v1.16b,v1.16b,v17.16b
+ eor v1.16b,v1.16b,v18.16b
+ pmull v18.1q,v0.1d,v19.1d //1st phase of reduction
+
+ ins v2.d[0],v1.d[1]
+ ins v1.d[1],v0.d[0]
+ eor v0.16b,v1.16b,v18.16b
+
+ ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction
+ pmull v0.1q,v0.1d,v19.1d
+ eor v18.16b,v18.16b,v2.16b
+ eor v0.16b,v0.16b,v18.16b
+
+.Ldone_v8:
+#ifndef __ARMEB__
+ rev64 v0.16b,v0.16b
+#endif
+ ext v0.16b,v0.16b,v0.16b,#8
+ st1 {v0.2d},[x0] //write out Xi
+
+ ret
+.size gcm_ghash_v8,.-gcm_ghash_v8
+.asciz "GHASH for ARMv8, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
diff --git a/secure/lib/libcrypto/aarch64/sha1-armv8.S b/secure/lib/libcrypto/aarch64/sha1-armv8.S
new file mode 100644
index 000000000000..ad5bf932fec9
--- /dev/null
+++ b/secure/lib/libcrypto/aarch64/sha1-armv8.S
@@ -0,0 +1,1213 @@
+/* $FreeBSD$ */
+/* Do not modify. This file is auto-generated from sha1-armv8.pl. */
+#include "arm_arch.h"
+
+.text
+
+.globl sha1_block_data_order
+.type sha1_block_data_order,%function
+.align 6
+sha1_block_data_order:
+ ldr x16,.LOPENSSL_armcap_P
+ adr x17,.LOPENSSL_armcap_P
+ add x16,x16,x17
+ ldr w16,[x16]
+ tst w16,#ARMV8_SHA1
+ b.ne .Lv8_entry
+
+ stp x29,x30,[sp,#-96]!
+ add x29,sp,#0
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+
+ ldp w20,w21,[x0]
+ ldp w22,w23,[x0,#8]
+ ldr w24,[x0,#16]
+
+.Loop:
+ ldr x3,[x1],#64
+ movz w28,#0x7999
+ sub x2,x2,#1
+ movk w28,#0x5a82,lsl#16
+#ifdef __ARMEB__
+ ror x3,x3,#32
+#else
+ rev32 x3,x3
+#endif
+ add w24,w24,w28 // warm it up
+ add w24,w24,w3
+ lsr x4,x3,#32
+ ldr x5,[x1,#-56]
+ bic w25,w23,w21
+ and w26,w22,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ orr w25,w25,w26
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ add w23,w23,w4 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+#ifdef __ARMEB__
+ ror x5,x5,#32
+#else
+ rev32 x5,x5
+#endif
+ bic w25,w22,w20
+ and w26,w21,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ orr w25,w25,w26
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ add w22,w22,w5 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ lsr x6,x5,#32
+ ldr x7,[x1,#-48]
+ bic w25,w21,w24
+ and w26,w20,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ orr w25,w25,w26
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ add w21,w21,w6 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+#ifdef __ARMEB__
+ ror x7,x7,#32
+#else
+ rev32 x7,x7
+#endif
+ bic w25,w20,w23
+ and w26,w24,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ orr w25,w25,w26
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ add w20,w20,w7 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ lsr x8,x7,#32
+ ldr x9,[x1,#-40]
+ bic w25,w24,w22
+ and w26,w23,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ orr w25,w25,w26
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ add w24,w24,w8 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+#ifdef __ARMEB__
+ ror x9,x9,#32
+#else
+ rev32 x9,x9
+#endif
+ bic w25,w23,w21
+ and w26,w22,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ orr w25,w25,w26
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ add w23,w23,w9 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ lsr x10,x9,#32
+ ldr x11,[x1,#-32]
+ bic w25,w22,w20
+ and w26,w21,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ orr w25,w25,w26
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ add w22,w22,w10 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+#ifdef __ARMEB__
+ ror x11,x11,#32
+#else
+ rev32 x11,x11
+#endif
+ bic w25,w21,w24
+ and w26,w20,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ orr w25,w25,w26
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ add w21,w21,w11 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ lsr x12,x11,#32
+ ldr x13,[x1,#-24]
+ bic w25,w20,w23
+ and w26,w24,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ orr w25,w25,w26
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ add w20,w20,w12 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+#ifdef __ARMEB__
+ ror x13,x13,#32
+#else
+ rev32 x13,x13
+#endif
+ bic w25,w24,w22
+ and w26,w23,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ orr w25,w25,w26
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ add w24,w24,w13 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ lsr x14,x13,#32
+ ldr x15,[x1,#-16]
+ bic w25,w23,w21
+ and w26,w22,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ orr w25,w25,w26
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ add w23,w23,w14 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+#ifdef __ARMEB__
+ ror x15,x15,#32
+#else
+ rev32 x15,x15
+#endif
+ bic w25,w22,w20
+ and w26,w21,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ orr w25,w25,w26
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ add w22,w22,w15 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ lsr x16,x15,#32
+ ldr x17,[x1,#-8]
+ bic w25,w21,w24
+ and w26,w20,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ orr w25,w25,w26
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ add w21,w21,w16 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+#ifdef __ARMEB__
+ ror x17,x17,#32
+#else
+ rev32 x17,x17
+#endif
+ bic w25,w20,w23
+ and w26,w24,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ orr w25,w25,w26
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ add w20,w20,w17 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ lsr x19,x17,#32
+ eor w3,w3,w5
+ bic w25,w24,w22
+ and w26,w23,w22
+ ror w27,w21,#27
+ eor w3,w3,w11
+ add w24,w24,w28 // future e+=K
+ orr w25,w25,w26
+ add w20,w20,w27 // e+=rot(a,5)
+ eor w3,w3,w16
+ ror w22,w22,#2
+ add w24,w24,w19 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w3,w3,#31
+ eor w4,w4,w6
+ bic w25,w23,w21
+ and w26,w22,w21
+ ror w27,w20,#27
+ eor w4,w4,w12
+ add w23,w23,w28 // future e+=K
+ orr w25,w25,w26
+ add w24,w24,w27 // e+=rot(a,5)
+ eor w4,w4,w17
+ ror w21,w21,#2
+ add w23,w23,w3 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w4,w4,#31
+ eor w5,w5,w7
+ bic w25,w22,w20
+ and w26,w21,w20
+ ror w27,w24,#27
+ eor w5,w5,w13
+ add w22,w22,w28 // future e+=K
+ orr w25,w25,w26
+ add w23,w23,w27 // e+=rot(a,5)
+ eor w5,w5,w19
+ ror w20,w20,#2
+ add w22,w22,w4 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w5,w5,#31
+ eor w6,w6,w8
+ bic w25,w21,w24
+ and w26,w20,w24
+ ror w27,w23,#27
+ eor w6,w6,w14
+ add w21,w21,w28 // future e+=K
+ orr w25,w25,w26
+ add w22,w22,w27 // e+=rot(a,5)
+ eor w6,w6,w3
+ ror w24,w24,#2
+ add w21,w21,w5 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w6,w6,#31
+ eor w7,w7,w9
+ bic w25,w20,w23
+ and w26,w24,w23
+ ror w27,w22,#27
+ eor w7,w7,w15
+ add w20,w20,w28 // future e+=K
+ orr w25,w25,w26
+ add w21,w21,w27 // e+=rot(a,5)
+ eor w7,w7,w4
+ ror w23,w23,#2
+ add w20,w20,w6 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w7,w7,#31
+ movz w28,#0xeba1
+ movk w28,#0x6ed9,lsl#16
+ eor w8,w8,w10
+ bic w25,w24,w22
+ and w26,w23,w22
+ ror w27,w21,#27
+ eor w8,w8,w16
+ add w24,w24,w28 // future e+=K
+ orr w25,w25,w26
+ add w20,w20,w27 // e+=rot(a,5)
+ eor w8,w8,w5
+ ror w22,w22,#2
+ add w24,w24,w7 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w8,w8,#31
+ eor w9,w9,w11
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w9,w9,w17
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w9,w9,w6
+ add w23,w23,w8 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w9,w9,#31
+ eor w10,w10,w12
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w10,w10,w19
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w10,w10,w7
+ add w22,w22,w9 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w10,w10,#31
+ eor w11,w11,w13
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w11,w11,w3
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w11,w11,w8
+ add w21,w21,w10 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w11,w11,#31
+ eor w12,w12,w14
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w12,w12,w4
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w12,w12,w9
+ add w20,w20,w11 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w12,w12,#31
+ eor w13,w13,w15
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w13,w13,w5
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w13,w13,w10
+ add w24,w24,w12 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w13,w13,#31
+ eor w14,w14,w16
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w14,w14,w6
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w14,w14,w11
+ add w23,w23,w13 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w14,w14,#31
+ eor w15,w15,w17
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w15,w15,w7
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w15,w15,w12
+ add w22,w22,w14 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w15,w15,#31
+ eor w16,w16,w19
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w16,w16,w8
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w16,w16,w13
+ add w21,w21,w15 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w16,w16,#31
+ eor w17,w17,w3
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w17,w17,w9
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w17,w17,w14
+ add w20,w20,w16 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w17,w17,#31
+ eor w19,w19,w4
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w19,w19,w10
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w19,w19,w15
+ add w24,w24,w17 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w19,w19,#31
+ eor w3,w3,w5
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w3,w3,w11
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w3,w3,w16
+ add w23,w23,w19 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w3,w3,#31
+ eor w4,w4,w6
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w4,w4,w12
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w4,w4,w17
+ add w22,w22,w3 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w4,w4,#31
+ eor w5,w5,w7
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w5,w5,w13
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w5,w5,w19
+ add w21,w21,w4 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w5,w5,#31
+ eor w6,w6,w8
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w6,w6,w14
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w6,w6,w3
+ add w20,w20,w5 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w6,w6,#31
+ eor w7,w7,w9
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w7,w7,w15
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w7,w7,w4
+ add w24,w24,w6 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w7,w7,#31
+ eor w8,w8,w10
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w8,w8,w16
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w8,w8,w5
+ add w23,w23,w7 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w8,w8,#31
+ eor w9,w9,w11
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w9,w9,w17
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w9,w9,w6
+ add w22,w22,w8 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w9,w9,#31
+ eor w10,w10,w12
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w10,w10,w19
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w10,w10,w7
+ add w21,w21,w9 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w10,w10,#31
+ eor w11,w11,w13
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w11,w11,w3
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w11,w11,w8
+ add w20,w20,w10 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w11,w11,#31
+ movz w28,#0xbcdc
+ movk w28,#0x8f1b,lsl#16
+ eor w12,w12,w14
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w12,w12,w4
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w12,w12,w9
+ add w24,w24,w11 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w12,w12,#31
+ orr w25,w21,w22
+ and w26,w21,w22
+ eor w13,w13,w15
+ ror w27,w20,#27
+ and w25,w25,w23
+ add w23,w23,w28 // future e+=K
+ eor w13,w13,w5
+ add w24,w24,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w21,w21,#2
+ eor w13,w13,w10
+ add w23,w23,w12 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w13,w13,#31
+ orr w25,w20,w21
+ and w26,w20,w21
+ eor w14,w14,w16
+ ror w27,w24,#27
+ and w25,w25,w22
+ add w22,w22,w28 // future e+=K
+ eor w14,w14,w6
+ add w23,w23,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w20,w20,#2
+ eor w14,w14,w11
+ add w22,w22,w13 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w14,w14,#31
+ orr w25,w24,w20
+ and w26,w24,w20
+ eor w15,w15,w17
+ ror w27,w23,#27
+ and w25,w25,w21
+ add w21,w21,w28 // future e+=K
+ eor w15,w15,w7
+ add w22,w22,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w24,w24,#2
+ eor w15,w15,w12
+ add w21,w21,w14 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w15,w15,#31
+ orr w25,w23,w24
+ and w26,w23,w24
+ eor w16,w16,w19
+ ror w27,w22,#27
+ and w25,w25,w20
+ add w20,w20,w28 // future e+=K
+ eor w16,w16,w8
+ add w21,w21,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w23,w23,#2
+ eor w16,w16,w13
+ add w20,w20,w15 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w16,w16,#31
+ orr w25,w22,w23
+ and w26,w22,w23
+ eor w17,w17,w3
+ ror w27,w21,#27
+ and w25,w25,w24
+ add w24,w24,w28 // future e+=K
+ eor w17,w17,w9
+ add w20,w20,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w22,w22,#2
+ eor w17,w17,w14
+ add w24,w24,w16 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w17,w17,#31
+ orr w25,w21,w22
+ and w26,w21,w22
+ eor w19,w19,w4
+ ror w27,w20,#27
+ and w25,w25,w23
+ add w23,w23,w28 // future e+=K
+ eor w19,w19,w10
+ add w24,w24,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w21,w21,#2
+ eor w19,w19,w15
+ add w23,w23,w17 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w19,w19,#31
+ orr w25,w20,w21
+ and w26,w20,w21
+ eor w3,w3,w5
+ ror w27,w24,#27
+ and w25,w25,w22
+ add w22,w22,w28 // future e+=K
+ eor w3,w3,w11
+ add w23,w23,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w20,w20,#2
+ eor w3,w3,w16
+ add w22,w22,w19 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w3,w3,#31
+ orr w25,w24,w20
+ and w26,w24,w20
+ eor w4,w4,w6
+ ror w27,w23,#27
+ and w25,w25,w21
+ add w21,w21,w28 // future e+=K
+ eor w4,w4,w12
+ add w22,w22,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w24,w24,#2
+ eor w4,w4,w17
+ add w21,w21,w3 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w4,w4,#31
+ orr w25,w23,w24
+ and w26,w23,w24
+ eor w5,w5,w7
+ ror w27,w22,#27
+ and w25,w25,w20
+ add w20,w20,w28 // future e+=K
+ eor w5,w5,w13
+ add w21,w21,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w23,w23,#2
+ eor w5,w5,w19
+ add w20,w20,w4 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w5,w5,#31
+ orr w25,w22,w23
+ and w26,w22,w23
+ eor w6,w6,w8
+ ror w27,w21,#27
+ and w25,w25,w24
+ add w24,w24,w28 // future e+=K
+ eor w6,w6,w14
+ add w20,w20,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w22,w22,#2
+ eor w6,w6,w3
+ add w24,w24,w5 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w6,w6,#31
+ orr w25,w21,w22
+ and w26,w21,w22
+ eor w7,w7,w9
+ ror w27,w20,#27
+ and w25,w25,w23
+ add w23,w23,w28 // future e+=K
+ eor w7,w7,w15
+ add w24,w24,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w21,w21,#2
+ eor w7,w7,w4
+ add w23,w23,w6 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w7,w7,#31
+ orr w25,w20,w21
+ and w26,w20,w21
+ eor w8,w8,w10
+ ror w27,w24,#27
+ and w25,w25,w22
+ add w22,w22,w28 // future e+=K
+ eor w8,w8,w16
+ add w23,w23,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w20,w20,#2
+ eor w8,w8,w5
+ add w22,w22,w7 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w8,w8,#31
+ orr w25,w24,w20
+ and w26,w24,w20
+ eor w9,w9,w11
+ ror w27,w23,#27
+ and w25,w25,w21
+ add w21,w21,w28 // future e+=K
+ eor w9,w9,w17
+ add w22,w22,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w24,w24,#2
+ eor w9,w9,w6
+ add w21,w21,w8 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w9,w9,#31
+ orr w25,w23,w24
+ and w26,w23,w24
+ eor w10,w10,w12
+ ror w27,w22,#27
+ and w25,w25,w20
+ add w20,w20,w28 // future e+=K
+ eor w10,w10,w19
+ add w21,w21,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w23,w23,#2
+ eor w10,w10,w7
+ add w20,w20,w9 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w10,w10,#31
+ orr w25,w22,w23
+ and w26,w22,w23
+ eor w11,w11,w13
+ ror w27,w21,#27
+ and w25,w25,w24
+ add w24,w24,w28 // future e+=K
+ eor w11,w11,w3
+ add w20,w20,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w22,w22,#2
+ eor w11,w11,w8
+ add w24,w24,w10 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w11,w11,#31
+ orr w25,w21,w22
+ and w26,w21,w22
+ eor w12,w12,w14
+ ror w27,w20,#27
+ and w25,w25,w23
+ add w23,w23,w28 // future e+=K
+ eor w12,w12,w4
+ add w24,w24,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w21,w21,#2
+ eor w12,w12,w9
+ add w23,w23,w11 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w12,w12,#31
+ orr w25,w20,w21
+ and w26,w20,w21
+ eor w13,w13,w15
+ ror w27,w24,#27
+ and w25,w25,w22
+ add w22,w22,w28 // future e+=K
+ eor w13,w13,w5
+ add w23,w23,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w20,w20,#2
+ eor w13,w13,w10
+ add w22,w22,w12 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w13,w13,#31
+ orr w25,w24,w20
+ and w26,w24,w20
+ eor w14,w14,w16
+ ror w27,w23,#27
+ and w25,w25,w21
+ add w21,w21,w28 // future e+=K
+ eor w14,w14,w6
+ add w22,w22,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w24,w24,#2
+ eor w14,w14,w11
+ add w21,w21,w13 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w14,w14,#31
+ orr w25,w23,w24
+ and w26,w23,w24
+ eor w15,w15,w17
+ ror w27,w22,#27
+ and w25,w25,w20
+ add w20,w20,w28 // future e+=K
+ eor w15,w15,w7
+ add w21,w21,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w23,w23,#2
+ eor w15,w15,w12
+ add w20,w20,w14 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w15,w15,#31
+ movz w28,#0xc1d6
+ movk w28,#0xca62,lsl#16
+ orr w25,w22,w23
+ and w26,w22,w23
+ eor w16,w16,w19
+ ror w27,w21,#27
+ and w25,w25,w24
+ add w24,w24,w28 // future e+=K
+ eor w16,w16,w8
+ add w20,w20,w27 // e+=rot(a,5)
+ orr w25,w25,w26
+ ror w22,w22,#2
+ eor w16,w16,w13
+ add w24,w24,w15 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w16,w16,#31
+ eor w17,w17,w3
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w17,w17,w9
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w17,w17,w14
+ add w23,w23,w16 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w17,w17,#31
+ eor w19,w19,w4
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w19,w19,w10
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w19,w19,w15
+ add w22,w22,w17 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w19,w19,#31
+ eor w3,w3,w5
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w3,w3,w11
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w3,w3,w16
+ add w21,w21,w19 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w3,w3,#31
+ eor w4,w4,w6
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w4,w4,w12
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w4,w4,w17
+ add w20,w20,w3 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w4,w4,#31
+ eor w5,w5,w7
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w5,w5,w13
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w5,w5,w19
+ add w24,w24,w4 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w5,w5,#31
+ eor w6,w6,w8
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w6,w6,w14
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w6,w6,w3
+ add w23,w23,w5 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w6,w6,#31
+ eor w7,w7,w9
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w7,w7,w15
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w7,w7,w4
+ add w22,w22,w6 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w7,w7,#31
+ eor w8,w8,w10
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w8,w8,w16
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w8,w8,w5
+ add w21,w21,w7 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w8,w8,#31
+ eor w9,w9,w11
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w9,w9,w17
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w9,w9,w6
+ add w20,w20,w8 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w9,w9,#31
+ eor w10,w10,w12
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w10,w10,w19
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w10,w10,w7
+ add w24,w24,w9 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w10,w10,#31
+ eor w11,w11,w13
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w11,w11,w3
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w11,w11,w8
+ add w23,w23,w10 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w11,w11,#31
+ eor w12,w12,w14
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w12,w12,w4
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w12,w12,w9
+ add w22,w22,w11 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w12,w12,#31
+ eor w13,w13,w15
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w13,w13,w5
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w13,w13,w10
+ add w21,w21,w12 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w13,w13,#31
+ eor w14,w14,w16
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w14,w14,w6
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ eor w14,w14,w11
+ add w20,w20,w13 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ror w14,w14,#31
+ eor w15,w15,w17
+ eor w25,w24,w22
+ ror w27,w21,#27
+ add w24,w24,w28 // future e+=K
+ eor w15,w15,w7
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ eor w15,w15,w12
+ add w24,w24,w14 // future e+=X[i]
+ add w20,w20,w25 // e+=F(b,c,d)
+ ror w15,w15,#31
+ eor w16,w16,w19
+ eor w25,w23,w21
+ ror w27,w20,#27
+ add w23,w23,w28 // future e+=K
+ eor w16,w16,w8
+ eor w25,w25,w22
+ add w24,w24,w27 // e+=rot(a,5)
+ ror w21,w21,#2
+ eor w16,w16,w13
+ add w23,w23,w15 // future e+=X[i]
+ add w24,w24,w25 // e+=F(b,c,d)
+ ror w16,w16,#31
+ eor w17,w17,w3
+ eor w25,w22,w20
+ ror w27,w24,#27
+ add w22,w22,w28 // future e+=K
+ eor w17,w17,w9
+ eor w25,w25,w21
+ add w23,w23,w27 // e+=rot(a,5)
+ ror w20,w20,#2
+ eor w17,w17,w14
+ add w22,w22,w16 // future e+=X[i]
+ add w23,w23,w25 // e+=F(b,c,d)
+ ror w17,w17,#31
+ eor w19,w19,w4
+ eor w25,w21,w24
+ ror w27,w23,#27
+ add w21,w21,w28 // future e+=K
+ eor w19,w19,w10
+ eor w25,w25,w20
+ add w22,w22,w27 // e+=rot(a,5)
+ ror w24,w24,#2
+ eor w19,w19,w15
+ add w21,w21,w17 // future e+=X[i]
+ add w22,w22,w25 // e+=F(b,c,d)
+ ror w19,w19,#31
+ ldp w4,w5,[x0]
+ eor w25,w20,w23
+ ror w27,w22,#27
+ add w20,w20,w28 // future e+=K
+ eor w25,w25,w24
+ add w21,w21,w27 // e+=rot(a,5)
+ ror w23,w23,#2
+ add w20,w20,w19 // future e+=X[i]
+ add w21,w21,w25 // e+=F(b,c,d)
+ ldp w6,w7,[x0,#8]
+ eor w25,w24,w22
+ ror w27,w21,#27
+ eor w25,w25,w23
+ add w20,w20,w27 // e+=rot(a,5)
+ ror w22,w22,#2
+ ldr w8,[x0,#16]
+ add w20,w20,w25 // e+=F(b,c,d)
+ add w21,w21,w5
+ add w22,w22,w6
+ add w20,w20,w4
+ add w23,w23,w7
+ add w24,w24,w8
+ stp w20,w21,[x0]
+ stp w22,w23,[x0,#8]
+ str w24,[x0,#16]
+ cbnz x2,.Loop
+
+ ldp x19,x20,[sp,#16]
+ ldp x21,x22,[sp,#32]
+ ldp x23,x24,[sp,#48]
+ ldp x25,x26,[sp,#64]
+ ldp x27,x28,[sp,#80]
+ ldr x29,[sp],#96
+ ret
+.size sha1_block_data_order,.-sha1_block_data_order
+.type sha1_block_armv8,%function
+.align 6
+sha1_block_armv8:
+.Lv8_entry:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ adr x4,.Lconst
+ eor v1.16b,v1.16b,v1.16b
+ ld1 {v0.4s},[x0],#16
+ ld1 {v1.s}[0],[x0]
+ sub x0,x0,#16
+ ld1 {v16.4s-v19.4s},[x4]
+
+.Loop_hw:
+ ld1 {v4.16b-v7.16b},[x1],#64
+ sub x2,x2,#1
+ rev32 v4.16b,v4.16b
+ rev32 v5.16b,v5.16b
+
+ add v20.4s,v16.4s,v4.4s
+ rev32 v6.16b,v6.16b
+ orr v22.16b,v0.16b,v0.16b // offload
+
+ add v21.4s,v16.4s,v5.4s
+ rev32 v7.16b,v7.16b
+ .inst 0x5e280803 //sha1h v3.16b,v0.16b
+ .inst 0x5e140020 //sha1c v0.16b,v1.16b,v20.4s // 0
+ add v20.4s,v16.4s,v6.4s
+ .inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b
+ .inst 0x5e280802 //sha1h v2.16b,v0.16b // 1
+ .inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s
+ add v21.4s,v16.4s,v7.4s
+ .inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b
+ .inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b
+ .inst 0x5e280803 //sha1h v3.16b,v0.16b // 2
+ .inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s
+ add v20.4s,v16.4s,v4.4s
+ .inst 0x5e281885 //sha1su1 v5.16b,v4.16b
+ .inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b
+ .inst 0x5e280802 //sha1h v2.16b,v0.16b // 3
+ .inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s
+ add v21.4s,v17.4s,v5.4s
+ .inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b
+ .inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b
+ .inst 0x5e280803 //sha1h v3.16b,v0.16b // 4
+ .inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s
+ add v20.4s,v17.4s,v6.4s
+ .inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b
+ .inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b
+ .inst 0x5e280802 //sha1h v2.16b,v0.16b // 5
+ .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+ add v21.4s,v17.4s,v7.4s
+ .inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b
+ .inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b
+ .inst 0x5e280803 //sha1h v3.16b,v0.16b // 6
+ .inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s
+ add v20.4s,v17.4s,v4.4s
+ .inst 0x5e281885 //sha1su1 v5.16b,v4.16b
+ .inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b
+ .inst 0x5e280802 //sha1h v2.16b,v0.16b // 7
+ .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+ add v21.4s,v17.4s,v5.4s
+ .inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b
+ .inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b
+ .inst 0x5e280803 //sha1h v3.16b,v0.16b // 8
+ .inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s
+ add v20.4s,v18.4s,v6.4s
+ .inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b
+ .inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b
+ .inst 0x5e280802 //sha1h v2.16b,v0.16b // 9
+ .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+ add v21.4s,v18.4s,v7.4s
+ .inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b
+ .inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b
+ .inst 0x5e280803 //sha1h v3.16b,v0.16b // 10
+ .inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s
+ add v20.4s,v18.4s,v4.4s
+ .inst 0x5e281885 //sha1su1 v5.16b,v4.16b
+ .inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b
+ .inst 0x5e280802 //sha1h v2.16b,v0.16b // 11
+ .inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s
+ add v21.4s,v18.4s,v5.4s
+ .inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b
+ .inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b
+ .inst 0x5e280803 //sha1h v3.16b,v0.16b // 12
+ .inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s
+ add v20.4s,v18.4s,v6.4s
+ .inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b
+ .inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b
+ .inst 0x5e280802 //sha1h v2.16b,v0.16b // 13
+ .inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s
+ add v21.4s,v19.4s,v7.4s
+ .inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b
+ .inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b
+ .inst 0x5e280803 //sha1h v3.16b,v0.16b // 14
+ .inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s
+ add v20.4s,v19.4s,v4.4s
+ .inst 0x5e281885 //sha1su1 v5.16b,v4.16b
+ .inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b
+ .inst 0x5e280802 //sha1h v2.16b,v0.16b // 15
+ .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+ add v21.4s,v19.4s,v5.4s
+ .inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b
+ .inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b
+ .inst 0x5e280803 //sha1h v3.16b,v0.16b // 16
+ .inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s
+ add v20.4s,v19.4s,v6.4s
+ .inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b
+ .inst 0x5e280802 //sha1h v2.16b,v0.16b // 17
+ .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+ add v21.4s,v19.4s,v7.4s
+
+ .inst 0x5e280803 //sha1h v3.16b,v0.16b // 18
+ .inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s
+
+ .inst 0x5e280802 //sha1h v2.16b,v0.16b // 19
+ .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s
+
+ add v1.4s,v1.4s,v2.4s
+ add v0.4s,v0.4s,v22.4s
+
+ cbnz x2,.Loop_hw
+
+ st1 {v0.4s},[x0],#16
+ st1 {v1.s}[0],[x0]
+
+ ldr x29,[sp],#16
+ ret
+.size sha1_block_armv8,.-sha1_block_armv8
+.align 6
+.Lconst:
+.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 //K_00_19
+.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39
+.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59
+.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79
+.LOPENSSL_armcap_P:
+.quad OPENSSL_armcap_P-.
+.asciz "SHA1 block transform for ARMv8, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
+.comm OPENSSL_armcap_P,4,4
diff --git a/secure/lib/libcrypto/aarch64/sha256-armv8.S b/secure/lib/libcrypto/aarch64/sha256-armv8.S
new file mode 100644
index 000000000000..eff9d2433a0b
--- /dev/null
+++ b/secure/lib/libcrypto/aarch64/sha256-armv8.S
@@ -0,0 +1,1143 @@
+/* $FreeBSD$ */
+/* Do not modify. This file is auto-generated from sha512-armv8.pl. */
+#include "arm_arch.h"
+
+.text
+
+.globl sha256_block_data_order
+.type sha256_block_data_order,%function
+.align 6
+sha256_block_data_order:
+ ldr x16,.LOPENSSL_armcap_P
+ adr x17,.LOPENSSL_armcap_P
+ add x16,x16,x17
+ ldr w16,[x16]
+ tst w16,#ARMV8_SHA256
+ b.ne .Lv8_entry
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ sub sp,sp,#4*4
+
+ ldp w20,w21,[x0] // load context
+ ldp w22,w23,[x0,#2*4]
+ ldp w24,w25,[x0,#4*4]
+ add x2,x1,x2,lsl#6 // end of input
+ ldp w26,w27,[x0,#6*4]
+ adr x30,K256
+ stp x0,x2,[x29,#96]
+
+.Loop:
+ ldp w3,w4,[x1],#2*4
+ ldr w19,[x30],#4 // *K++
+ eor w28,w21,w22 // magic seed
+ str x1,[x29,#112]
+#ifndef __ARMEB__
+ rev w3,w3 // 0
+#endif
+ ror w16,w24,#6
+ add w27,w27,w19 // h+=K[i]
+ eor w6,w24,w24,ror#14
+ and w17,w25,w24
+ bic w19,w26,w24
+ add w27,w27,w3 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w20,w21 // a^b, b^c in next round
+ eor w16,w16,w6,ror#11 // Sigma1(e)
+ ror w6,w20,#2
+ add w27,w27,w17 // h+=Ch(e,f,g)
+ eor w17,w20,w20,ror#9
+ add w27,w27,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w23,w23,w27 // d+=h
+ eor w28,w28,w21 // Maj(a,b,c)
+ eor w17,w6,w17,ror#13 // Sigma0(a)
+ add w27,w27,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w27,w27,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w4,w4 // 1
+#endif
+ ldp w5,w6,[x1],#2*4
+ add w27,w27,w17 // h+=Sigma0(a)
+ ror w16,w23,#6
+ add w26,w26,w28 // h+=K[i]
+ eor w7,w23,w23,ror#14
+ and w17,w24,w23
+ bic w28,w25,w23
+ add w26,w26,w4 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w27,w20 // a^b, b^c in next round
+ eor w16,w16,w7,ror#11 // Sigma1(e)
+ ror w7,w27,#2
+ add w26,w26,w17 // h+=Ch(e,f,g)
+ eor w17,w27,w27,ror#9
+ add w26,w26,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w22,w22,w26 // d+=h
+ eor w19,w19,w20 // Maj(a,b,c)
+ eor w17,w7,w17,ror#13 // Sigma0(a)
+ add w26,w26,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w26,w26,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w5,w5 // 2
+#endif
+ add w26,w26,w17 // h+=Sigma0(a)
+ ror w16,w22,#6
+ add w25,w25,w19 // h+=K[i]
+ eor w8,w22,w22,ror#14
+ and w17,w23,w22
+ bic w19,w24,w22
+ add w25,w25,w5 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w26,w27 // a^b, b^c in next round
+ eor w16,w16,w8,ror#11 // Sigma1(e)
+ ror w8,w26,#2
+ add w25,w25,w17 // h+=Ch(e,f,g)
+ eor w17,w26,w26,ror#9
+ add w25,w25,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w21,w21,w25 // d+=h
+ eor w28,w28,w27 // Maj(a,b,c)
+ eor w17,w8,w17,ror#13 // Sigma0(a)
+ add w25,w25,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w25,w25,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w6,w6 // 3
+#endif
+ ldp w7,w8,[x1],#2*4
+ add w25,w25,w17 // h+=Sigma0(a)
+ ror w16,w21,#6
+ add w24,w24,w28 // h+=K[i]
+ eor w9,w21,w21,ror#14
+ and w17,w22,w21
+ bic w28,w23,w21
+ add w24,w24,w6 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w25,w26 // a^b, b^c in next round
+ eor w16,w16,w9,ror#11 // Sigma1(e)
+ ror w9,w25,#2
+ add w24,w24,w17 // h+=Ch(e,f,g)
+ eor w17,w25,w25,ror#9
+ add w24,w24,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w20,w20,w24 // d+=h
+ eor w19,w19,w26 // Maj(a,b,c)
+ eor w17,w9,w17,ror#13 // Sigma0(a)
+ add w24,w24,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w24,w24,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w7,w7 // 4
+#endif
+ add w24,w24,w17 // h+=Sigma0(a)
+ ror w16,w20,#6
+ add w23,w23,w19 // h+=K[i]
+ eor w10,w20,w20,ror#14
+ and w17,w21,w20
+ bic w19,w22,w20
+ add w23,w23,w7 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w24,w25 // a^b, b^c in next round
+ eor w16,w16,w10,ror#11 // Sigma1(e)
+ ror w10,w24,#2
+ add w23,w23,w17 // h+=Ch(e,f,g)
+ eor w17,w24,w24,ror#9
+ add w23,w23,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w27,w27,w23 // d+=h
+ eor w28,w28,w25 // Maj(a,b,c)
+ eor w17,w10,w17,ror#13 // Sigma0(a)
+ add w23,w23,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w23,w23,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w8,w8 // 5
+#endif
+ ldp w9,w10,[x1],#2*4
+ add w23,w23,w17 // h+=Sigma0(a)
+ ror w16,w27,#6
+ add w22,w22,w28 // h+=K[i]
+ eor w11,w27,w27,ror#14
+ and w17,w20,w27
+ bic w28,w21,w27
+ add w22,w22,w8 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w23,w24 // a^b, b^c in next round
+ eor w16,w16,w11,ror#11 // Sigma1(e)
+ ror w11,w23,#2
+ add w22,w22,w17 // h+=Ch(e,f,g)
+ eor w17,w23,w23,ror#9
+ add w22,w22,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w26,w26,w22 // d+=h
+ eor w19,w19,w24 // Maj(a,b,c)
+ eor w17,w11,w17,ror#13 // Sigma0(a)
+ add w22,w22,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w22,w22,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w9,w9 // 6
+#endif
+ add w22,w22,w17 // h+=Sigma0(a)
+ ror w16,w26,#6
+ add w21,w21,w19 // h+=K[i]
+ eor w12,w26,w26,ror#14
+ and w17,w27,w26
+ bic w19,w20,w26
+ add w21,w21,w9 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w22,w23 // a^b, b^c in next round
+ eor w16,w16,w12,ror#11 // Sigma1(e)
+ ror w12,w22,#2
+ add w21,w21,w17 // h+=Ch(e,f,g)
+ eor w17,w22,w22,ror#9
+ add w21,w21,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w25,w25,w21 // d+=h
+ eor w28,w28,w23 // Maj(a,b,c)
+ eor w17,w12,w17,ror#13 // Sigma0(a)
+ add w21,w21,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w21,w21,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w10,w10 // 7
+#endif
+ ldp w11,w12,[x1],#2*4
+ add w21,w21,w17 // h+=Sigma0(a)
+ ror w16,w25,#6
+ add w20,w20,w28 // h+=K[i]
+ eor w13,w25,w25,ror#14
+ and w17,w26,w25
+ bic w28,w27,w25
+ add w20,w20,w10 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w21,w22 // a^b, b^c in next round
+ eor w16,w16,w13,ror#11 // Sigma1(e)
+ ror w13,w21,#2
+ add w20,w20,w17 // h+=Ch(e,f,g)
+ eor w17,w21,w21,ror#9
+ add w20,w20,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w24,w24,w20 // d+=h
+ eor w19,w19,w22 // Maj(a,b,c)
+ eor w17,w13,w17,ror#13 // Sigma0(a)
+ add w20,w20,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w20,w20,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w11,w11 // 8
+#endif
+ add w20,w20,w17 // h+=Sigma0(a)
+ ror w16,w24,#6
+ add w27,w27,w19 // h+=K[i]
+ eor w14,w24,w24,ror#14
+ and w17,w25,w24
+ bic w19,w26,w24
+ add w27,w27,w11 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w20,w21 // a^b, b^c in next round
+ eor w16,w16,w14,ror#11 // Sigma1(e)
+ ror w14,w20,#2
+ add w27,w27,w17 // h+=Ch(e,f,g)
+ eor w17,w20,w20,ror#9
+ add w27,w27,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w23,w23,w27 // d+=h
+ eor w28,w28,w21 // Maj(a,b,c)
+ eor w17,w14,w17,ror#13 // Sigma0(a)
+ add w27,w27,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w27,w27,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w12,w12 // 9
+#endif
+ ldp w13,w14,[x1],#2*4
+ add w27,w27,w17 // h+=Sigma0(a)
+ ror w16,w23,#6
+ add w26,w26,w28 // h+=K[i]
+ eor w15,w23,w23,ror#14
+ and w17,w24,w23
+ bic w28,w25,w23
+ add w26,w26,w12 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w27,w20 // a^b, b^c in next round
+ eor w16,w16,w15,ror#11 // Sigma1(e)
+ ror w15,w27,#2
+ add w26,w26,w17 // h+=Ch(e,f,g)
+ eor w17,w27,w27,ror#9
+ add w26,w26,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w22,w22,w26 // d+=h
+ eor w19,w19,w20 // Maj(a,b,c)
+ eor w17,w15,w17,ror#13 // Sigma0(a)
+ add w26,w26,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w26,w26,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w13,w13 // 10
+#endif
+ add w26,w26,w17 // h+=Sigma0(a)
+ ror w16,w22,#6
+ add w25,w25,w19 // h+=K[i]
+ eor w0,w22,w22,ror#14
+ and w17,w23,w22
+ bic w19,w24,w22
+ add w25,w25,w13 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w26,w27 // a^b, b^c in next round
+ eor w16,w16,w0,ror#11 // Sigma1(e)
+ ror w0,w26,#2
+ add w25,w25,w17 // h+=Ch(e,f,g)
+ eor w17,w26,w26,ror#9
+ add w25,w25,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w21,w21,w25 // d+=h
+ eor w28,w28,w27 // Maj(a,b,c)
+ eor w17,w0,w17,ror#13 // Sigma0(a)
+ add w25,w25,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w25,w25,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w14,w14 // 11
+#endif
+ ldp w15,w0,[x1],#2*4
+ add w25,w25,w17 // h+=Sigma0(a)
+ str w6,[sp,#12]
+ ror w16,w21,#6
+ add w24,w24,w28 // h+=K[i]
+ eor w6,w21,w21,ror#14
+ and w17,w22,w21
+ bic w28,w23,w21
+ add w24,w24,w14 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w25,w26 // a^b, b^c in next round
+ eor w16,w16,w6,ror#11 // Sigma1(e)
+ ror w6,w25,#2
+ add w24,w24,w17 // h+=Ch(e,f,g)
+ eor w17,w25,w25,ror#9
+ add w24,w24,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w20,w20,w24 // d+=h
+ eor w19,w19,w26 // Maj(a,b,c)
+ eor w17,w6,w17,ror#13 // Sigma0(a)
+ add w24,w24,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w24,w24,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w15,w15 // 12
+#endif
+ add w24,w24,w17 // h+=Sigma0(a)
+ str w7,[sp,#0]
+ ror w16,w20,#6
+ add w23,w23,w19 // h+=K[i]
+ eor w7,w20,w20,ror#14
+ and w17,w21,w20
+ bic w19,w22,w20
+ add w23,w23,w15 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w24,w25 // a^b, b^c in next round
+ eor w16,w16,w7,ror#11 // Sigma1(e)
+ ror w7,w24,#2
+ add w23,w23,w17 // h+=Ch(e,f,g)
+ eor w17,w24,w24,ror#9
+ add w23,w23,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w27,w27,w23 // d+=h
+ eor w28,w28,w25 // Maj(a,b,c)
+ eor w17,w7,w17,ror#13 // Sigma0(a)
+ add w23,w23,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w23,w23,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w0,w0 // 13
+#endif
+ ldp w1,w2,[x1]
+ add w23,w23,w17 // h+=Sigma0(a)
+ str w8,[sp,#4]
+ ror w16,w27,#6
+ add w22,w22,w28 // h+=K[i]
+ eor w8,w27,w27,ror#14
+ and w17,w20,w27
+ bic w28,w21,w27
+ add w22,w22,w0 // h+=X[i]
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w23,w24 // a^b, b^c in next round
+ eor w16,w16,w8,ror#11 // Sigma1(e)
+ ror w8,w23,#2
+ add w22,w22,w17 // h+=Ch(e,f,g)
+ eor w17,w23,w23,ror#9
+ add w22,w22,w16 // h+=Sigma1(e)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ add w26,w26,w22 // d+=h
+ eor w19,w19,w24 // Maj(a,b,c)
+ eor w17,w8,w17,ror#13 // Sigma0(a)
+ add w22,w22,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ //add w22,w22,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w1,w1 // 14
+#endif
+ ldr w6,[sp,#12]
+ add w22,w22,w17 // h+=Sigma0(a)
+ str w9,[sp,#8]
+ ror w16,w26,#6
+ add w21,w21,w19 // h+=K[i]
+ eor w9,w26,w26,ror#14
+ and w17,w27,w26
+ bic w19,w20,w26
+ add w21,w21,w1 // h+=X[i]
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w22,w23 // a^b, b^c in next round
+ eor w16,w16,w9,ror#11 // Sigma1(e)
+ ror w9,w22,#2
+ add w21,w21,w17 // h+=Ch(e,f,g)
+ eor w17,w22,w22,ror#9
+ add w21,w21,w16 // h+=Sigma1(e)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ add w25,w25,w21 // d+=h
+ eor w28,w28,w23 // Maj(a,b,c)
+ eor w17,w9,w17,ror#13 // Sigma0(a)
+ add w21,w21,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ //add w21,w21,w17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev w2,w2 // 15
+#endif
+ ldr w7,[sp,#0]
+ add w21,w21,w17 // h+=Sigma0(a)
+ str w10,[sp,#12]
+ ror w16,w25,#6
+ add w20,w20,w28 // h+=K[i]
+ ror w9,w4,#7
+ and w17,w26,w25
+ ror w8,w1,#17
+ bic w28,w27,w25
+ ror w10,w21,#2
+ add w20,w20,w2 // h+=X[i]
+ eor w16,w16,w25,ror#11
+ eor w9,w9,w4,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w21,w22 // a^b, b^c in next round
+ eor w16,w16,w25,ror#25 // Sigma1(e)
+ eor w10,w10,w21,ror#13
+ add w20,w20,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w8,w8,w1,ror#19
+ eor w9,w9,w4,lsr#3 // sigma0(X[i+1])
+ add w20,w20,w16 // h+=Sigma1(e)
+ eor w19,w19,w22 // Maj(a,b,c)
+ eor w17,w10,w21,ror#22 // Sigma0(a)
+ eor w8,w8,w1,lsr#10 // sigma1(X[i+14])
+ add w3,w3,w12
+ add w24,w24,w20 // d+=h
+ add w20,w20,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w3,w3,w9
+ add w20,w20,w17 // h+=Sigma0(a)
+ add w3,w3,w8
+.Loop_16_xx:
+ ldr w8,[sp,#4]
+ str w11,[sp,#0]
+ ror w16,w24,#6
+ add w27,w27,w19 // h+=K[i]
+ ror w10,w5,#7
+ and w17,w25,w24
+ ror w9,w2,#17
+ bic w19,w26,w24
+ ror w11,w20,#2
+ add w27,w27,w3 // h+=X[i]
+ eor w16,w16,w24,ror#11
+ eor w10,w10,w5,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w20,w21 // a^b, b^c in next round
+ eor w16,w16,w24,ror#25 // Sigma1(e)
+ eor w11,w11,w20,ror#13
+ add w27,w27,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w9,w9,w2,ror#19
+ eor w10,w10,w5,lsr#3 // sigma0(X[i+1])
+ add w27,w27,w16 // h+=Sigma1(e)
+ eor w28,w28,w21 // Maj(a,b,c)
+ eor w17,w11,w20,ror#22 // Sigma0(a)
+ eor w9,w9,w2,lsr#10 // sigma1(X[i+14])
+ add w4,w4,w13
+ add w23,w23,w27 // d+=h
+ add w27,w27,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w4,w4,w10
+ add w27,w27,w17 // h+=Sigma0(a)
+ add w4,w4,w9
+ ldr w9,[sp,#8]
+ str w12,[sp,#4]
+ ror w16,w23,#6
+ add w26,w26,w28 // h+=K[i]
+ ror w11,w6,#7
+ and w17,w24,w23
+ ror w10,w3,#17
+ bic w28,w25,w23
+ ror w12,w27,#2
+ add w26,w26,w4 // h+=X[i]
+ eor w16,w16,w23,ror#11
+ eor w11,w11,w6,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w27,w20 // a^b, b^c in next round
+ eor w16,w16,w23,ror#25 // Sigma1(e)
+ eor w12,w12,w27,ror#13
+ add w26,w26,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w10,w10,w3,ror#19
+ eor w11,w11,w6,lsr#3 // sigma0(X[i+1])
+ add w26,w26,w16 // h+=Sigma1(e)
+ eor w19,w19,w20 // Maj(a,b,c)
+ eor w17,w12,w27,ror#22 // Sigma0(a)
+ eor w10,w10,w3,lsr#10 // sigma1(X[i+14])
+ add w5,w5,w14
+ add w22,w22,w26 // d+=h
+ add w26,w26,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w5,w5,w11
+ add w26,w26,w17 // h+=Sigma0(a)
+ add w5,w5,w10
+ ldr w10,[sp,#12]
+ str w13,[sp,#8]
+ ror w16,w22,#6
+ add w25,w25,w19 // h+=K[i]
+ ror w12,w7,#7
+ and w17,w23,w22
+ ror w11,w4,#17
+ bic w19,w24,w22
+ ror w13,w26,#2
+ add w25,w25,w5 // h+=X[i]
+ eor w16,w16,w22,ror#11
+ eor w12,w12,w7,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w26,w27 // a^b, b^c in next round
+ eor w16,w16,w22,ror#25 // Sigma1(e)
+ eor w13,w13,w26,ror#13
+ add w25,w25,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w11,w11,w4,ror#19
+ eor w12,w12,w7,lsr#3 // sigma0(X[i+1])
+ add w25,w25,w16 // h+=Sigma1(e)
+ eor w28,w28,w27 // Maj(a,b,c)
+ eor w17,w13,w26,ror#22 // Sigma0(a)
+ eor w11,w11,w4,lsr#10 // sigma1(X[i+14])
+ add w6,w6,w15
+ add w21,w21,w25 // d+=h
+ add w25,w25,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w6,w6,w12
+ add w25,w25,w17 // h+=Sigma0(a)
+ add w6,w6,w11
+ ldr w11,[sp,#0]
+ str w14,[sp,#12]
+ ror w16,w21,#6
+ add w24,w24,w28 // h+=K[i]
+ ror w13,w8,#7
+ and w17,w22,w21
+ ror w12,w5,#17
+ bic w28,w23,w21
+ ror w14,w25,#2
+ add w24,w24,w6 // h+=X[i]
+ eor w16,w16,w21,ror#11
+ eor w13,w13,w8,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w25,w26 // a^b, b^c in next round
+ eor w16,w16,w21,ror#25 // Sigma1(e)
+ eor w14,w14,w25,ror#13
+ add w24,w24,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w12,w12,w5,ror#19
+ eor w13,w13,w8,lsr#3 // sigma0(X[i+1])
+ add w24,w24,w16 // h+=Sigma1(e)
+ eor w19,w19,w26 // Maj(a,b,c)
+ eor w17,w14,w25,ror#22 // Sigma0(a)
+ eor w12,w12,w5,lsr#10 // sigma1(X[i+14])
+ add w7,w7,w0
+ add w20,w20,w24 // d+=h
+ add w24,w24,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w7,w7,w13
+ add w24,w24,w17 // h+=Sigma0(a)
+ add w7,w7,w12
+ ldr w12,[sp,#4]
+ str w15,[sp,#0]
+ ror w16,w20,#6
+ add w23,w23,w19 // h+=K[i]
+ ror w14,w9,#7
+ and w17,w21,w20
+ ror w13,w6,#17
+ bic w19,w22,w20
+ ror w15,w24,#2
+ add w23,w23,w7 // h+=X[i]
+ eor w16,w16,w20,ror#11
+ eor w14,w14,w9,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w24,w25 // a^b, b^c in next round
+ eor w16,w16,w20,ror#25 // Sigma1(e)
+ eor w15,w15,w24,ror#13
+ add w23,w23,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w13,w13,w6,ror#19
+ eor w14,w14,w9,lsr#3 // sigma0(X[i+1])
+ add w23,w23,w16 // h+=Sigma1(e)
+ eor w28,w28,w25 // Maj(a,b,c)
+ eor w17,w15,w24,ror#22 // Sigma0(a)
+ eor w13,w13,w6,lsr#10 // sigma1(X[i+14])
+ add w8,w8,w1
+ add w27,w27,w23 // d+=h
+ add w23,w23,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w8,w8,w14
+ add w23,w23,w17 // h+=Sigma0(a)
+ add w8,w8,w13
+ ldr w13,[sp,#8]
+ str w0,[sp,#4]
+ ror w16,w27,#6
+ add w22,w22,w28 // h+=K[i]
+ ror w15,w10,#7
+ and w17,w20,w27
+ ror w14,w7,#17
+ bic w28,w21,w27
+ ror w0,w23,#2
+ add w22,w22,w8 // h+=X[i]
+ eor w16,w16,w27,ror#11
+ eor w15,w15,w10,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w23,w24 // a^b, b^c in next round
+ eor w16,w16,w27,ror#25 // Sigma1(e)
+ eor w0,w0,w23,ror#13
+ add w22,w22,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w14,w14,w7,ror#19
+ eor w15,w15,w10,lsr#3 // sigma0(X[i+1])
+ add w22,w22,w16 // h+=Sigma1(e)
+ eor w19,w19,w24 // Maj(a,b,c)
+ eor w17,w0,w23,ror#22 // Sigma0(a)
+ eor w14,w14,w7,lsr#10 // sigma1(X[i+14])
+ add w9,w9,w2
+ add w26,w26,w22 // d+=h
+ add w22,w22,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w9,w9,w15
+ add w22,w22,w17 // h+=Sigma0(a)
+ add w9,w9,w14
+ ldr w14,[sp,#12]
+ str w1,[sp,#8]
+ ror w16,w26,#6
+ add w21,w21,w19 // h+=K[i]
+ ror w0,w11,#7
+ and w17,w27,w26
+ ror w15,w8,#17
+ bic w19,w20,w26
+ ror w1,w22,#2
+ add w21,w21,w9 // h+=X[i]
+ eor w16,w16,w26,ror#11
+ eor w0,w0,w11,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w22,w23 // a^b, b^c in next round
+ eor w16,w16,w26,ror#25 // Sigma1(e)
+ eor w1,w1,w22,ror#13
+ add w21,w21,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w15,w15,w8,ror#19
+ eor w0,w0,w11,lsr#3 // sigma0(X[i+1])
+ add w21,w21,w16 // h+=Sigma1(e)
+ eor w28,w28,w23 // Maj(a,b,c)
+ eor w17,w1,w22,ror#22 // Sigma0(a)
+ eor w15,w15,w8,lsr#10 // sigma1(X[i+14])
+ add w10,w10,w3
+ add w25,w25,w21 // d+=h
+ add w21,w21,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w10,w10,w0
+ add w21,w21,w17 // h+=Sigma0(a)
+ add w10,w10,w15
+ ldr w15,[sp,#0]
+ str w2,[sp,#12]
+ ror w16,w25,#6
+ add w20,w20,w28 // h+=K[i]
+ ror w1,w12,#7
+ and w17,w26,w25
+ ror w0,w9,#17
+ bic w28,w27,w25
+ ror w2,w21,#2
+ add w20,w20,w10 // h+=X[i]
+ eor w16,w16,w25,ror#11
+ eor w1,w1,w12,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w21,w22 // a^b, b^c in next round
+ eor w16,w16,w25,ror#25 // Sigma1(e)
+ eor w2,w2,w21,ror#13
+ add w20,w20,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w0,w0,w9,ror#19
+ eor w1,w1,w12,lsr#3 // sigma0(X[i+1])
+ add w20,w20,w16 // h+=Sigma1(e)
+ eor w19,w19,w22 // Maj(a,b,c)
+ eor w17,w2,w21,ror#22 // Sigma0(a)
+ eor w0,w0,w9,lsr#10 // sigma1(X[i+14])
+ add w11,w11,w4
+ add w24,w24,w20 // d+=h
+ add w20,w20,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w11,w11,w1
+ add w20,w20,w17 // h+=Sigma0(a)
+ add w11,w11,w0
+ ldr w0,[sp,#4]
+ str w3,[sp,#0]
+ ror w16,w24,#6
+ add w27,w27,w19 // h+=K[i]
+ ror w2,w13,#7
+ and w17,w25,w24
+ ror w1,w10,#17
+ bic w19,w26,w24
+ ror w3,w20,#2
+ add w27,w27,w11 // h+=X[i]
+ eor w16,w16,w24,ror#11
+ eor w2,w2,w13,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w20,w21 // a^b, b^c in next round
+ eor w16,w16,w24,ror#25 // Sigma1(e)
+ eor w3,w3,w20,ror#13
+ add w27,w27,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w1,w1,w10,ror#19
+ eor w2,w2,w13,lsr#3 // sigma0(X[i+1])
+ add w27,w27,w16 // h+=Sigma1(e)
+ eor w28,w28,w21 // Maj(a,b,c)
+ eor w17,w3,w20,ror#22 // Sigma0(a)
+ eor w1,w1,w10,lsr#10 // sigma1(X[i+14])
+ add w12,w12,w5
+ add w23,w23,w27 // d+=h
+ add w27,w27,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w12,w12,w2
+ add w27,w27,w17 // h+=Sigma0(a)
+ add w12,w12,w1
+ ldr w1,[sp,#8]
+ str w4,[sp,#4]
+ ror w16,w23,#6
+ add w26,w26,w28 // h+=K[i]
+ ror w3,w14,#7
+ and w17,w24,w23
+ ror w2,w11,#17
+ bic w28,w25,w23
+ ror w4,w27,#2
+ add w26,w26,w12 // h+=X[i]
+ eor w16,w16,w23,ror#11
+ eor w3,w3,w14,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w27,w20 // a^b, b^c in next round
+ eor w16,w16,w23,ror#25 // Sigma1(e)
+ eor w4,w4,w27,ror#13
+ add w26,w26,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w2,w2,w11,ror#19
+ eor w3,w3,w14,lsr#3 // sigma0(X[i+1])
+ add w26,w26,w16 // h+=Sigma1(e)
+ eor w19,w19,w20 // Maj(a,b,c)
+ eor w17,w4,w27,ror#22 // Sigma0(a)
+ eor w2,w2,w11,lsr#10 // sigma1(X[i+14])
+ add w13,w13,w6
+ add w22,w22,w26 // d+=h
+ add w26,w26,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w13,w13,w3
+ add w26,w26,w17 // h+=Sigma0(a)
+ add w13,w13,w2
+ ldr w2,[sp,#12]
+ str w5,[sp,#8]
+ ror w16,w22,#6
+ add w25,w25,w19 // h+=K[i]
+ ror w4,w15,#7
+ and w17,w23,w22
+ ror w3,w12,#17
+ bic w19,w24,w22
+ ror w5,w26,#2
+ add w25,w25,w13 // h+=X[i]
+ eor w16,w16,w22,ror#11
+ eor w4,w4,w15,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w26,w27 // a^b, b^c in next round
+ eor w16,w16,w22,ror#25 // Sigma1(e)
+ eor w5,w5,w26,ror#13
+ add w25,w25,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w3,w3,w12,ror#19
+ eor w4,w4,w15,lsr#3 // sigma0(X[i+1])
+ add w25,w25,w16 // h+=Sigma1(e)
+ eor w28,w28,w27 // Maj(a,b,c)
+ eor w17,w5,w26,ror#22 // Sigma0(a)
+ eor w3,w3,w12,lsr#10 // sigma1(X[i+14])
+ add w14,w14,w7
+ add w21,w21,w25 // d+=h
+ add w25,w25,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w14,w14,w4
+ add w25,w25,w17 // h+=Sigma0(a)
+ add w14,w14,w3
+ ldr w3,[sp,#0]
+ str w6,[sp,#12]
+ ror w16,w21,#6
+ add w24,w24,w28 // h+=K[i]
+ ror w5,w0,#7
+ and w17,w22,w21
+ ror w4,w13,#17
+ bic w28,w23,w21
+ ror w6,w25,#2
+ add w24,w24,w14 // h+=X[i]
+ eor w16,w16,w21,ror#11
+ eor w5,w5,w0,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w25,w26 // a^b, b^c in next round
+ eor w16,w16,w21,ror#25 // Sigma1(e)
+ eor w6,w6,w25,ror#13
+ add w24,w24,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w4,w4,w13,ror#19
+ eor w5,w5,w0,lsr#3 // sigma0(X[i+1])
+ add w24,w24,w16 // h+=Sigma1(e)
+ eor w19,w19,w26 // Maj(a,b,c)
+ eor w17,w6,w25,ror#22 // Sigma0(a)
+ eor w4,w4,w13,lsr#10 // sigma1(X[i+14])
+ add w15,w15,w8
+ add w20,w20,w24 // d+=h
+ add w24,w24,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w15,w15,w5
+ add w24,w24,w17 // h+=Sigma0(a)
+ add w15,w15,w4
+ ldr w4,[sp,#4]
+ str w7,[sp,#0]
+ ror w16,w20,#6
+ add w23,w23,w19 // h+=K[i]
+ ror w6,w1,#7
+ and w17,w21,w20
+ ror w5,w14,#17
+ bic w19,w22,w20
+ ror w7,w24,#2
+ add w23,w23,w15 // h+=X[i]
+ eor w16,w16,w20,ror#11
+ eor w6,w6,w1,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w24,w25 // a^b, b^c in next round
+ eor w16,w16,w20,ror#25 // Sigma1(e)
+ eor w7,w7,w24,ror#13
+ add w23,w23,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w5,w5,w14,ror#19
+ eor w6,w6,w1,lsr#3 // sigma0(X[i+1])
+ add w23,w23,w16 // h+=Sigma1(e)
+ eor w28,w28,w25 // Maj(a,b,c)
+ eor w17,w7,w24,ror#22 // Sigma0(a)
+ eor w5,w5,w14,lsr#10 // sigma1(X[i+14])
+ add w0,w0,w9
+ add w27,w27,w23 // d+=h
+ add w23,w23,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w0,w0,w6
+ add w23,w23,w17 // h+=Sigma0(a)
+ add w0,w0,w5
+ ldr w5,[sp,#8]
+ str w8,[sp,#4]
+ ror w16,w27,#6
+ add w22,w22,w28 // h+=K[i]
+ ror w7,w2,#7
+ and w17,w20,w27
+ ror w6,w15,#17
+ bic w28,w21,w27
+ ror w8,w23,#2
+ add w22,w22,w0 // h+=X[i]
+ eor w16,w16,w27,ror#11
+ eor w7,w7,w2,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w23,w24 // a^b, b^c in next round
+ eor w16,w16,w27,ror#25 // Sigma1(e)
+ eor w8,w8,w23,ror#13
+ add w22,w22,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w6,w6,w15,ror#19
+ eor w7,w7,w2,lsr#3 // sigma0(X[i+1])
+ add w22,w22,w16 // h+=Sigma1(e)
+ eor w19,w19,w24 // Maj(a,b,c)
+ eor w17,w8,w23,ror#22 // Sigma0(a)
+ eor w6,w6,w15,lsr#10 // sigma1(X[i+14])
+ add w1,w1,w10
+ add w26,w26,w22 // d+=h
+ add w22,w22,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w1,w1,w7
+ add w22,w22,w17 // h+=Sigma0(a)
+ add w1,w1,w6
+ ldr w6,[sp,#12]
+ str w9,[sp,#8]
+ ror w16,w26,#6
+ add w21,w21,w19 // h+=K[i]
+ ror w8,w3,#7
+ and w17,w27,w26
+ ror w7,w0,#17
+ bic w19,w20,w26
+ ror w9,w22,#2
+ add w21,w21,w1 // h+=X[i]
+ eor w16,w16,w26,ror#11
+ eor w8,w8,w3,ror#18
+ orr w17,w17,w19 // Ch(e,f,g)
+ eor w19,w22,w23 // a^b, b^c in next round
+ eor w16,w16,w26,ror#25 // Sigma1(e)
+ eor w9,w9,w22,ror#13
+ add w21,w21,w17 // h+=Ch(e,f,g)
+ and w28,w28,w19 // (b^c)&=(a^b)
+ eor w7,w7,w0,ror#19
+ eor w8,w8,w3,lsr#3 // sigma0(X[i+1])
+ add w21,w21,w16 // h+=Sigma1(e)
+ eor w28,w28,w23 // Maj(a,b,c)
+ eor w17,w9,w22,ror#22 // Sigma0(a)
+ eor w7,w7,w0,lsr#10 // sigma1(X[i+14])
+ add w2,w2,w11
+ add w25,w25,w21 // d+=h
+ add w21,w21,w28 // h+=Maj(a,b,c)
+ ldr w28,[x30],#4 // *K++, w19 in next round
+ add w2,w2,w8
+ add w21,w21,w17 // h+=Sigma0(a)
+ add w2,w2,w7
+ ldr w7,[sp,#0]
+ str w10,[sp,#12]
+ ror w16,w25,#6
+ add w20,w20,w28 // h+=K[i]
+ ror w9,w4,#7
+ and w17,w26,w25
+ ror w8,w1,#17
+ bic w28,w27,w25
+ ror w10,w21,#2
+ add w20,w20,w2 // h+=X[i]
+ eor w16,w16,w25,ror#11
+ eor w9,w9,w4,ror#18
+ orr w17,w17,w28 // Ch(e,f,g)
+ eor w28,w21,w22 // a^b, b^c in next round
+ eor w16,w16,w25,ror#25 // Sigma1(e)
+ eor w10,w10,w21,ror#13
+ add w20,w20,w17 // h+=Ch(e,f,g)
+ and w19,w19,w28 // (b^c)&=(a^b)
+ eor w8,w8,w1,ror#19
+ eor w9,w9,w4,lsr#3 // sigma0(X[i+1])
+ add w20,w20,w16 // h+=Sigma1(e)
+ eor w19,w19,w22 // Maj(a,b,c)
+ eor w17,w10,w21,ror#22 // Sigma0(a)
+ eor w8,w8,w1,lsr#10 // sigma1(X[i+14])
+ add w3,w3,w12
+ add w24,w24,w20 // d+=h
+ add w20,w20,w19 // h+=Maj(a,b,c)
+ ldr w19,[x30],#4 // *K++, w28 in next round
+ add w3,w3,w9
+ add w20,w20,w17 // h+=Sigma0(a)
+ add w3,w3,w8
+ cbnz w19,.Loop_16_xx
+
+ ldp x0,x2,[x29,#96]
+ ldr x1,[x29,#112]
+ sub x30,x30,#260 // rewind
+
+ ldp w3,w4,[x0]
+ ldp w5,w6,[x0,#2*4]
+ add x1,x1,#14*4 // advance input pointer
+ ldp w7,w8,[x0,#4*4]
+ add w20,w20,w3
+ ldp w9,w10,[x0,#6*4]
+ add w21,w21,w4
+ add w22,w22,w5
+ add w23,w23,w6
+ stp w20,w21,[x0]
+ add w24,w24,w7
+ add w25,w25,w8
+ stp w22,w23,[x0,#2*4]
+ add w26,w26,w9
+ add w27,w27,w10
+ cmp x1,x2
+ stp w24,w25,[x0,#4*4]
+ stp w26,w27,[x0,#6*4]
+ b.ne .Loop
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#4*4
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#128
+ ret
+.size sha256_block_data_order,.-sha256_block_data_order
+
+.align 6
+.type K256,%object
+K256:
+ .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
+ .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
+ .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
+ .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
+ .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
+ .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
+ .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
+ .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
+ .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
+ .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
+ .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
+ .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
+ .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
+ .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
+ .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
+ .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+ .long 0 //terminator
+.size K256,.-K256
+.align 3
+.LOPENSSL_armcap_P:
+ .quad OPENSSL_armcap_P-.
+.asciz "SHA256 block transform for ARMv8, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
+.type sha256_block_armv8,%function
+.align 6
+sha256_block_armv8:
+.Lv8_entry:
+ stp x29,x30,[sp,#-16]!
+ add x29,sp,#0
+
+ ld1 {v0.4s,v1.4s},[x0]
+ adr x3,K256
+
+.Loop_hw:
+ ld1 {v4.16b-v7.16b},[x1],#64
+ sub x2,x2,#1
+ ld1 {v16.4s},[x3],#16
+ rev32 v4.16b,v4.16b
+ rev32 v5.16b,v5.16b
+ rev32 v6.16b,v6.16b
+ rev32 v7.16b,v7.16b
+ orr v18.16b,v0.16b,v0.16b // offload
+ orr v19.16b,v1.16b,v1.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v4.4s
+ .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+ .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v5.4s
+ .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+ .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v6.4s
+ .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+ .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v7.4s
+ .inst 0x5e282887 //sha256su0 v7.16b,v4.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+ .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v4.4s
+ .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+ .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v5.4s
+ .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+ .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v6.4s
+ .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+ .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v7.4s
+ .inst 0x5e282887 //sha256su0 v7.16b,v4.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+ .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v4.4s
+ .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+ .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v5.4s
+ .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+ .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v6.4s
+ .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+ .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v7.4s
+ .inst 0x5e282887 //sha256su0 v7.16b,v4.16b
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+ .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b
+ ld1 {v17.4s},[x3],#16
+ add v16.4s,v16.4s,v4.4s
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+
+ ld1 {v16.4s},[x3],#16
+ add v17.4s,v17.4s,v5.4s
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+
+ ld1 {v17.4s},[x3]
+ add v16.4s,v16.4s,v6.4s
+ sub x3,x3,#64*4-16 // rewind
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s
+ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s
+
+ add v17.4s,v17.4s,v7.4s
+ orr v2.16b,v0.16b,v0.16b
+ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s
+ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s
+
+ add v0.4s,v0.4s,v18.4s
+ add v1.4s,v1.4s,v19.4s
+
+ cbnz x2,.Loop_hw
+
+ st1 {v0.4s,v1.4s},[x0]
+
+ ldr x29,[sp],#16
+ ret
+.size sha256_block_armv8,.-sha256_block_armv8
+.comm OPENSSL_armcap_P,4,4
diff --git a/secure/lib/libcrypto/aarch64/sha512-armv8.S b/secure/lib/libcrypto/aarch64/sha512-armv8.S
new file mode 100644
index 000000000000..108e7ed8aeac
--- /dev/null
+++ b/secure/lib/libcrypto/aarch64/sha512-armv8.S
@@ -0,0 +1,1023 @@
+/* $FreeBSD$ */
+/* Do not modify. This file is auto-generated from sha512-armv8.pl. */
+#include "arm_arch.h"
+
+.text
+
+.globl sha512_block_data_order
+.type sha512_block_data_order,%function
+.align 6
+sha512_block_data_order:
+ stp x29,x30,[sp,#-128]!
+ add x29,sp,#0
+
+ stp x19,x20,[sp,#16]
+ stp x21,x22,[sp,#32]
+ stp x23,x24,[sp,#48]
+ stp x25,x26,[sp,#64]
+ stp x27,x28,[sp,#80]
+ sub sp,sp,#4*8
+
+ ldp x20,x21,[x0] // load context
+ ldp x22,x23,[x0,#2*8]
+ ldp x24,x25,[x0,#4*8]
+ add x2,x1,x2,lsl#7 // end of input
+ ldp x26,x27,[x0,#6*8]
+ adr x30,K512
+ stp x0,x2,[x29,#96]
+
+.Loop:
+ ldp x3,x4,[x1],#2*8
+ ldr x19,[x30],#8 // *K++
+ eor x28,x21,x22 // magic seed
+ str x1,[x29,#112]
+#ifndef __ARMEB__
+ rev x3,x3 // 0
+#endif
+ ror x16,x24,#14
+ add x27,x27,x19 // h+=K[i]
+ eor x6,x24,x24,ror#23
+ and x17,x25,x24
+ bic x19,x26,x24
+ add x27,x27,x3 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x20,x21 // a^b, b^c in next round
+ eor x16,x16,x6,ror#18 // Sigma1(e)
+ ror x6,x20,#28
+ add x27,x27,x17 // h+=Ch(e,f,g)
+ eor x17,x20,x20,ror#5
+ add x27,x27,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x23,x23,x27 // d+=h
+ eor x28,x28,x21 // Maj(a,b,c)
+ eor x17,x6,x17,ror#34 // Sigma0(a)
+ add x27,x27,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x27,x27,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x4,x4 // 1
+#endif
+ ldp x5,x6,[x1],#2*8
+ add x27,x27,x17 // h+=Sigma0(a)
+ ror x16,x23,#14
+ add x26,x26,x28 // h+=K[i]
+ eor x7,x23,x23,ror#23
+ and x17,x24,x23
+ bic x28,x25,x23
+ add x26,x26,x4 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x27,x20 // a^b, b^c in next round
+ eor x16,x16,x7,ror#18 // Sigma1(e)
+ ror x7,x27,#28
+ add x26,x26,x17 // h+=Ch(e,f,g)
+ eor x17,x27,x27,ror#5
+ add x26,x26,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x22,x22,x26 // d+=h
+ eor x19,x19,x20 // Maj(a,b,c)
+ eor x17,x7,x17,ror#34 // Sigma0(a)
+ add x26,x26,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x26,x26,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x5,x5 // 2
+#endif
+ add x26,x26,x17 // h+=Sigma0(a)
+ ror x16,x22,#14
+ add x25,x25,x19 // h+=K[i]
+ eor x8,x22,x22,ror#23
+ and x17,x23,x22
+ bic x19,x24,x22
+ add x25,x25,x5 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x26,x27 // a^b, b^c in next round
+ eor x16,x16,x8,ror#18 // Sigma1(e)
+ ror x8,x26,#28
+ add x25,x25,x17 // h+=Ch(e,f,g)
+ eor x17,x26,x26,ror#5
+ add x25,x25,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x21,x21,x25 // d+=h
+ eor x28,x28,x27 // Maj(a,b,c)
+ eor x17,x8,x17,ror#34 // Sigma0(a)
+ add x25,x25,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x25,x25,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x6,x6 // 3
+#endif
+ ldp x7,x8,[x1],#2*8
+ add x25,x25,x17 // h+=Sigma0(a)
+ ror x16,x21,#14
+ add x24,x24,x28 // h+=K[i]
+ eor x9,x21,x21,ror#23
+ and x17,x22,x21
+ bic x28,x23,x21
+ add x24,x24,x6 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x25,x26 // a^b, b^c in next round
+ eor x16,x16,x9,ror#18 // Sigma1(e)
+ ror x9,x25,#28
+ add x24,x24,x17 // h+=Ch(e,f,g)
+ eor x17,x25,x25,ror#5
+ add x24,x24,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x20,x20,x24 // d+=h
+ eor x19,x19,x26 // Maj(a,b,c)
+ eor x17,x9,x17,ror#34 // Sigma0(a)
+ add x24,x24,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x24,x24,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x7,x7 // 4
+#endif
+ add x24,x24,x17 // h+=Sigma0(a)
+ ror x16,x20,#14
+ add x23,x23,x19 // h+=K[i]
+ eor x10,x20,x20,ror#23
+ and x17,x21,x20
+ bic x19,x22,x20
+ add x23,x23,x7 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x24,x25 // a^b, b^c in next round
+ eor x16,x16,x10,ror#18 // Sigma1(e)
+ ror x10,x24,#28
+ add x23,x23,x17 // h+=Ch(e,f,g)
+ eor x17,x24,x24,ror#5
+ add x23,x23,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x27,x27,x23 // d+=h
+ eor x28,x28,x25 // Maj(a,b,c)
+ eor x17,x10,x17,ror#34 // Sigma0(a)
+ add x23,x23,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x23,x23,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x8,x8 // 5
+#endif
+ ldp x9,x10,[x1],#2*8
+ add x23,x23,x17 // h+=Sigma0(a)
+ ror x16,x27,#14
+ add x22,x22,x28 // h+=K[i]
+ eor x11,x27,x27,ror#23
+ and x17,x20,x27
+ bic x28,x21,x27
+ add x22,x22,x8 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x23,x24 // a^b, b^c in next round
+ eor x16,x16,x11,ror#18 // Sigma1(e)
+ ror x11,x23,#28
+ add x22,x22,x17 // h+=Ch(e,f,g)
+ eor x17,x23,x23,ror#5
+ add x22,x22,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x26,x26,x22 // d+=h
+ eor x19,x19,x24 // Maj(a,b,c)
+ eor x17,x11,x17,ror#34 // Sigma0(a)
+ add x22,x22,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x22,x22,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x9,x9 // 6
+#endif
+ add x22,x22,x17 // h+=Sigma0(a)
+ ror x16,x26,#14
+ add x21,x21,x19 // h+=K[i]
+ eor x12,x26,x26,ror#23
+ and x17,x27,x26
+ bic x19,x20,x26
+ add x21,x21,x9 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x22,x23 // a^b, b^c in next round
+ eor x16,x16,x12,ror#18 // Sigma1(e)
+ ror x12,x22,#28
+ add x21,x21,x17 // h+=Ch(e,f,g)
+ eor x17,x22,x22,ror#5
+ add x21,x21,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x25,x25,x21 // d+=h
+ eor x28,x28,x23 // Maj(a,b,c)
+ eor x17,x12,x17,ror#34 // Sigma0(a)
+ add x21,x21,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x21,x21,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x10,x10 // 7
+#endif
+ ldp x11,x12,[x1],#2*8
+ add x21,x21,x17 // h+=Sigma0(a)
+ ror x16,x25,#14
+ add x20,x20,x28 // h+=K[i]
+ eor x13,x25,x25,ror#23
+ and x17,x26,x25
+ bic x28,x27,x25
+ add x20,x20,x10 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x21,x22 // a^b, b^c in next round
+ eor x16,x16,x13,ror#18 // Sigma1(e)
+ ror x13,x21,#28
+ add x20,x20,x17 // h+=Ch(e,f,g)
+ eor x17,x21,x21,ror#5
+ add x20,x20,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x24,x24,x20 // d+=h
+ eor x19,x19,x22 // Maj(a,b,c)
+ eor x17,x13,x17,ror#34 // Sigma0(a)
+ add x20,x20,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x20,x20,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x11,x11 // 8
+#endif
+ add x20,x20,x17 // h+=Sigma0(a)
+ ror x16,x24,#14
+ add x27,x27,x19 // h+=K[i]
+ eor x14,x24,x24,ror#23
+ and x17,x25,x24
+ bic x19,x26,x24
+ add x27,x27,x11 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x20,x21 // a^b, b^c in next round
+ eor x16,x16,x14,ror#18 // Sigma1(e)
+ ror x14,x20,#28
+ add x27,x27,x17 // h+=Ch(e,f,g)
+ eor x17,x20,x20,ror#5
+ add x27,x27,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x23,x23,x27 // d+=h
+ eor x28,x28,x21 // Maj(a,b,c)
+ eor x17,x14,x17,ror#34 // Sigma0(a)
+ add x27,x27,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x27,x27,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x12,x12 // 9
+#endif
+ ldp x13,x14,[x1],#2*8
+ add x27,x27,x17 // h+=Sigma0(a)
+ ror x16,x23,#14
+ add x26,x26,x28 // h+=K[i]
+ eor x15,x23,x23,ror#23
+ and x17,x24,x23
+ bic x28,x25,x23
+ add x26,x26,x12 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x27,x20 // a^b, b^c in next round
+ eor x16,x16,x15,ror#18 // Sigma1(e)
+ ror x15,x27,#28
+ add x26,x26,x17 // h+=Ch(e,f,g)
+ eor x17,x27,x27,ror#5
+ add x26,x26,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x22,x22,x26 // d+=h
+ eor x19,x19,x20 // Maj(a,b,c)
+ eor x17,x15,x17,ror#34 // Sigma0(a)
+ add x26,x26,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x26,x26,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x13,x13 // 10
+#endif
+ add x26,x26,x17 // h+=Sigma0(a)
+ ror x16,x22,#14
+ add x25,x25,x19 // h+=K[i]
+ eor x0,x22,x22,ror#23
+ and x17,x23,x22
+ bic x19,x24,x22
+ add x25,x25,x13 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x26,x27 // a^b, b^c in next round
+ eor x16,x16,x0,ror#18 // Sigma1(e)
+ ror x0,x26,#28
+ add x25,x25,x17 // h+=Ch(e,f,g)
+ eor x17,x26,x26,ror#5
+ add x25,x25,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x21,x21,x25 // d+=h
+ eor x28,x28,x27 // Maj(a,b,c)
+ eor x17,x0,x17,ror#34 // Sigma0(a)
+ add x25,x25,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x25,x25,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x14,x14 // 11
+#endif
+ ldp x15,x0,[x1],#2*8
+ add x25,x25,x17 // h+=Sigma0(a)
+ str x6,[sp,#24]
+ ror x16,x21,#14
+ add x24,x24,x28 // h+=K[i]
+ eor x6,x21,x21,ror#23
+ and x17,x22,x21
+ bic x28,x23,x21
+ add x24,x24,x14 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x25,x26 // a^b, b^c in next round
+ eor x16,x16,x6,ror#18 // Sigma1(e)
+ ror x6,x25,#28
+ add x24,x24,x17 // h+=Ch(e,f,g)
+ eor x17,x25,x25,ror#5
+ add x24,x24,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x20,x20,x24 // d+=h
+ eor x19,x19,x26 // Maj(a,b,c)
+ eor x17,x6,x17,ror#34 // Sigma0(a)
+ add x24,x24,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x24,x24,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x15,x15 // 12
+#endif
+ add x24,x24,x17 // h+=Sigma0(a)
+ str x7,[sp,#0]
+ ror x16,x20,#14
+ add x23,x23,x19 // h+=K[i]
+ eor x7,x20,x20,ror#23
+ and x17,x21,x20
+ bic x19,x22,x20
+ add x23,x23,x15 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x24,x25 // a^b, b^c in next round
+ eor x16,x16,x7,ror#18 // Sigma1(e)
+ ror x7,x24,#28
+ add x23,x23,x17 // h+=Ch(e,f,g)
+ eor x17,x24,x24,ror#5
+ add x23,x23,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x27,x27,x23 // d+=h
+ eor x28,x28,x25 // Maj(a,b,c)
+ eor x17,x7,x17,ror#34 // Sigma0(a)
+ add x23,x23,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x23,x23,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x0,x0 // 13
+#endif
+ ldp x1,x2,[x1]
+ add x23,x23,x17 // h+=Sigma0(a)
+ str x8,[sp,#8]
+ ror x16,x27,#14
+ add x22,x22,x28 // h+=K[i]
+ eor x8,x27,x27,ror#23
+ and x17,x20,x27
+ bic x28,x21,x27
+ add x22,x22,x0 // h+=X[i]
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x23,x24 // a^b, b^c in next round
+ eor x16,x16,x8,ror#18 // Sigma1(e)
+ ror x8,x23,#28
+ add x22,x22,x17 // h+=Ch(e,f,g)
+ eor x17,x23,x23,ror#5
+ add x22,x22,x16 // h+=Sigma1(e)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ add x26,x26,x22 // d+=h
+ eor x19,x19,x24 // Maj(a,b,c)
+ eor x17,x8,x17,ror#34 // Sigma0(a)
+ add x22,x22,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ //add x22,x22,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x1,x1 // 14
+#endif
+ ldr x6,[sp,#24]
+ add x22,x22,x17 // h+=Sigma0(a)
+ str x9,[sp,#16]
+ ror x16,x26,#14
+ add x21,x21,x19 // h+=K[i]
+ eor x9,x26,x26,ror#23
+ and x17,x27,x26
+ bic x19,x20,x26
+ add x21,x21,x1 // h+=X[i]
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x22,x23 // a^b, b^c in next round
+ eor x16,x16,x9,ror#18 // Sigma1(e)
+ ror x9,x22,#28
+ add x21,x21,x17 // h+=Ch(e,f,g)
+ eor x17,x22,x22,ror#5
+ add x21,x21,x16 // h+=Sigma1(e)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ add x25,x25,x21 // d+=h
+ eor x28,x28,x23 // Maj(a,b,c)
+ eor x17,x9,x17,ror#34 // Sigma0(a)
+ add x21,x21,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ //add x21,x21,x17 // h+=Sigma0(a)
+#ifndef __ARMEB__
+ rev x2,x2 // 15
+#endif
+ ldr x7,[sp,#0]
+ add x21,x21,x17 // h+=Sigma0(a)
+ str x10,[sp,#24]
+ ror x16,x25,#14
+ add x20,x20,x28 // h+=K[i]
+ ror x9,x4,#1
+ and x17,x26,x25
+ ror x8,x1,#19
+ bic x28,x27,x25
+ ror x10,x21,#28
+ add x20,x20,x2 // h+=X[i]
+ eor x16,x16,x25,ror#18
+ eor x9,x9,x4,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x21,x22 // a^b, b^c in next round
+ eor x16,x16,x25,ror#41 // Sigma1(e)
+ eor x10,x10,x21,ror#34
+ add x20,x20,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x8,x8,x1,ror#61
+ eor x9,x9,x4,lsr#7 // sigma0(X[i+1])
+ add x20,x20,x16 // h+=Sigma1(e)
+ eor x19,x19,x22 // Maj(a,b,c)
+ eor x17,x10,x21,ror#39 // Sigma0(a)
+ eor x8,x8,x1,lsr#6 // sigma1(X[i+14])
+ add x3,x3,x12
+ add x24,x24,x20 // d+=h
+ add x20,x20,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x3,x3,x9
+ add x20,x20,x17 // h+=Sigma0(a)
+ add x3,x3,x8
+.Loop_16_xx:
+ ldr x8,[sp,#8]
+ str x11,[sp,#0]
+ ror x16,x24,#14
+ add x27,x27,x19 // h+=K[i]
+ ror x10,x5,#1
+ and x17,x25,x24
+ ror x9,x2,#19
+ bic x19,x26,x24
+ ror x11,x20,#28
+ add x27,x27,x3 // h+=X[i]
+ eor x16,x16,x24,ror#18
+ eor x10,x10,x5,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x20,x21 // a^b, b^c in next round
+ eor x16,x16,x24,ror#41 // Sigma1(e)
+ eor x11,x11,x20,ror#34
+ add x27,x27,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x9,x9,x2,ror#61
+ eor x10,x10,x5,lsr#7 // sigma0(X[i+1])
+ add x27,x27,x16 // h+=Sigma1(e)
+ eor x28,x28,x21 // Maj(a,b,c)
+ eor x17,x11,x20,ror#39 // Sigma0(a)
+ eor x9,x9,x2,lsr#6 // sigma1(X[i+14])
+ add x4,x4,x13
+ add x23,x23,x27 // d+=h
+ add x27,x27,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x4,x4,x10
+ add x27,x27,x17 // h+=Sigma0(a)
+ add x4,x4,x9
+ ldr x9,[sp,#16]
+ str x12,[sp,#8]
+ ror x16,x23,#14
+ add x26,x26,x28 // h+=K[i]
+ ror x11,x6,#1
+ and x17,x24,x23
+ ror x10,x3,#19
+ bic x28,x25,x23
+ ror x12,x27,#28
+ add x26,x26,x4 // h+=X[i]
+ eor x16,x16,x23,ror#18
+ eor x11,x11,x6,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x27,x20 // a^b, b^c in next round
+ eor x16,x16,x23,ror#41 // Sigma1(e)
+ eor x12,x12,x27,ror#34
+ add x26,x26,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x10,x10,x3,ror#61
+ eor x11,x11,x6,lsr#7 // sigma0(X[i+1])
+ add x26,x26,x16 // h+=Sigma1(e)
+ eor x19,x19,x20 // Maj(a,b,c)
+ eor x17,x12,x27,ror#39 // Sigma0(a)
+ eor x10,x10,x3,lsr#6 // sigma1(X[i+14])
+ add x5,x5,x14
+ add x22,x22,x26 // d+=h
+ add x26,x26,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x5,x5,x11
+ add x26,x26,x17 // h+=Sigma0(a)
+ add x5,x5,x10
+ ldr x10,[sp,#24]
+ str x13,[sp,#16]
+ ror x16,x22,#14
+ add x25,x25,x19 // h+=K[i]
+ ror x12,x7,#1
+ and x17,x23,x22
+ ror x11,x4,#19
+ bic x19,x24,x22
+ ror x13,x26,#28
+ add x25,x25,x5 // h+=X[i]
+ eor x16,x16,x22,ror#18
+ eor x12,x12,x7,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x26,x27 // a^b, b^c in next round
+ eor x16,x16,x22,ror#41 // Sigma1(e)
+ eor x13,x13,x26,ror#34
+ add x25,x25,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x11,x11,x4,ror#61
+ eor x12,x12,x7,lsr#7 // sigma0(X[i+1])
+ add x25,x25,x16 // h+=Sigma1(e)
+ eor x28,x28,x27 // Maj(a,b,c)
+ eor x17,x13,x26,ror#39 // Sigma0(a)
+ eor x11,x11,x4,lsr#6 // sigma1(X[i+14])
+ add x6,x6,x15
+ add x21,x21,x25 // d+=h
+ add x25,x25,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x6,x6,x12
+ add x25,x25,x17 // h+=Sigma0(a)
+ add x6,x6,x11
+ ldr x11,[sp,#0]
+ str x14,[sp,#24]
+ ror x16,x21,#14
+ add x24,x24,x28 // h+=K[i]
+ ror x13,x8,#1
+ and x17,x22,x21
+ ror x12,x5,#19
+ bic x28,x23,x21
+ ror x14,x25,#28
+ add x24,x24,x6 // h+=X[i]
+ eor x16,x16,x21,ror#18
+ eor x13,x13,x8,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x25,x26 // a^b, b^c in next round
+ eor x16,x16,x21,ror#41 // Sigma1(e)
+ eor x14,x14,x25,ror#34
+ add x24,x24,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x12,x12,x5,ror#61
+ eor x13,x13,x8,lsr#7 // sigma0(X[i+1])
+ add x24,x24,x16 // h+=Sigma1(e)
+ eor x19,x19,x26 // Maj(a,b,c)
+ eor x17,x14,x25,ror#39 // Sigma0(a)
+ eor x12,x12,x5,lsr#6 // sigma1(X[i+14])
+ add x7,x7,x0
+ add x20,x20,x24 // d+=h
+ add x24,x24,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x7,x7,x13
+ add x24,x24,x17 // h+=Sigma0(a)
+ add x7,x7,x12
+ ldr x12,[sp,#8]
+ str x15,[sp,#0]
+ ror x16,x20,#14
+ add x23,x23,x19 // h+=K[i]
+ ror x14,x9,#1
+ and x17,x21,x20
+ ror x13,x6,#19
+ bic x19,x22,x20
+ ror x15,x24,#28
+ add x23,x23,x7 // h+=X[i]
+ eor x16,x16,x20,ror#18
+ eor x14,x14,x9,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x24,x25 // a^b, b^c in next round
+ eor x16,x16,x20,ror#41 // Sigma1(e)
+ eor x15,x15,x24,ror#34
+ add x23,x23,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x13,x13,x6,ror#61
+ eor x14,x14,x9,lsr#7 // sigma0(X[i+1])
+ add x23,x23,x16 // h+=Sigma1(e)
+ eor x28,x28,x25 // Maj(a,b,c)
+ eor x17,x15,x24,ror#39 // Sigma0(a)
+ eor x13,x13,x6,lsr#6 // sigma1(X[i+14])
+ add x8,x8,x1
+ add x27,x27,x23 // d+=h
+ add x23,x23,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x8,x8,x14
+ add x23,x23,x17 // h+=Sigma0(a)
+ add x8,x8,x13
+ ldr x13,[sp,#16]
+ str x0,[sp,#8]
+ ror x16,x27,#14
+ add x22,x22,x28 // h+=K[i]
+ ror x15,x10,#1
+ and x17,x20,x27
+ ror x14,x7,#19
+ bic x28,x21,x27
+ ror x0,x23,#28
+ add x22,x22,x8 // h+=X[i]
+ eor x16,x16,x27,ror#18
+ eor x15,x15,x10,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x23,x24 // a^b, b^c in next round
+ eor x16,x16,x27,ror#41 // Sigma1(e)
+ eor x0,x0,x23,ror#34
+ add x22,x22,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x14,x14,x7,ror#61
+ eor x15,x15,x10,lsr#7 // sigma0(X[i+1])
+ add x22,x22,x16 // h+=Sigma1(e)
+ eor x19,x19,x24 // Maj(a,b,c)
+ eor x17,x0,x23,ror#39 // Sigma0(a)
+ eor x14,x14,x7,lsr#6 // sigma1(X[i+14])
+ add x9,x9,x2
+ add x26,x26,x22 // d+=h
+ add x22,x22,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x9,x9,x15
+ add x22,x22,x17 // h+=Sigma0(a)
+ add x9,x9,x14
+ ldr x14,[sp,#24]
+ str x1,[sp,#16]
+ ror x16,x26,#14
+ add x21,x21,x19 // h+=K[i]
+ ror x0,x11,#1
+ and x17,x27,x26
+ ror x15,x8,#19
+ bic x19,x20,x26
+ ror x1,x22,#28
+ add x21,x21,x9 // h+=X[i]
+ eor x16,x16,x26,ror#18
+ eor x0,x0,x11,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x22,x23 // a^b, b^c in next round
+ eor x16,x16,x26,ror#41 // Sigma1(e)
+ eor x1,x1,x22,ror#34
+ add x21,x21,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x15,x15,x8,ror#61
+ eor x0,x0,x11,lsr#7 // sigma0(X[i+1])
+ add x21,x21,x16 // h+=Sigma1(e)
+ eor x28,x28,x23 // Maj(a,b,c)
+ eor x17,x1,x22,ror#39 // Sigma0(a)
+ eor x15,x15,x8,lsr#6 // sigma1(X[i+14])
+ add x10,x10,x3
+ add x25,x25,x21 // d+=h
+ add x21,x21,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x10,x10,x0
+ add x21,x21,x17 // h+=Sigma0(a)
+ add x10,x10,x15
+ ldr x15,[sp,#0]
+ str x2,[sp,#24]
+ ror x16,x25,#14
+ add x20,x20,x28 // h+=K[i]
+ ror x1,x12,#1
+ and x17,x26,x25
+ ror x0,x9,#19
+ bic x28,x27,x25
+ ror x2,x21,#28
+ add x20,x20,x10 // h+=X[i]
+ eor x16,x16,x25,ror#18
+ eor x1,x1,x12,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x21,x22 // a^b, b^c in next round
+ eor x16,x16,x25,ror#41 // Sigma1(e)
+ eor x2,x2,x21,ror#34
+ add x20,x20,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x0,x0,x9,ror#61
+ eor x1,x1,x12,lsr#7 // sigma0(X[i+1])
+ add x20,x20,x16 // h+=Sigma1(e)
+ eor x19,x19,x22 // Maj(a,b,c)
+ eor x17,x2,x21,ror#39 // Sigma0(a)
+ eor x0,x0,x9,lsr#6 // sigma1(X[i+14])
+ add x11,x11,x4
+ add x24,x24,x20 // d+=h
+ add x20,x20,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x11,x11,x1
+ add x20,x20,x17 // h+=Sigma0(a)
+ add x11,x11,x0
+ ldr x0,[sp,#8]
+ str x3,[sp,#0]
+ ror x16,x24,#14
+ add x27,x27,x19 // h+=K[i]
+ ror x2,x13,#1
+ and x17,x25,x24
+ ror x1,x10,#19
+ bic x19,x26,x24
+ ror x3,x20,#28
+ add x27,x27,x11 // h+=X[i]
+ eor x16,x16,x24,ror#18
+ eor x2,x2,x13,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x20,x21 // a^b, b^c in next round
+ eor x16,x16,x24,ror#41 // Sigma1(e)
+ eor x3,x3,x20,ror#34
+ add x27,x27,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x1,x1,x10,ror#61
+ eor x2,x2,x13,lsr#7 // sigma0(X[i+1])
+ add x27,x27,x16 // h+=Sigma1(e)
+ eor x28,x28,x21 // Maj(a,b,c)
+ eor x17,x3,x20,ror#39 // Sigma0(a)
+ eor x1,x1,x10,lsr#6 // sigma1(X[i+14])
+ add x12,x12,x5
+ add x23,x23,x27 // d+=h
+ add x27,x27,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x12,x12,x2
+ add x27,x27,x17 // h+=Sigma0(a)
+ add x12,x12,x1
+ ldr x1,[sp,#16]
+ str x4,[sp,#8]
+ ror x16,x23,#14
+ add x26,x26,x28 // h+=K[i]
+ ror x3,x14,#1
+ and x17,x24,x23
+ ror x2,x11,#19
+ bic x28,x25,x23
+ ror x4,x27,#28
+ add x26,x26,x12 // h+=X[i]
+ eor x16,x16,x23,ror#18
+ eor x3,x3,x14,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x27,x20 // a^b, b^c in next round
+ eor x16,x16,x23,ror#41 // Sigma1(e)
+ eor x4,x4,x27,ror#34
+ add x26,x26,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x2,x2,x11,ror#61
+ eor x3,x3,x14,lsr#7 // sigma0(X[i+1])
+ add x26,x26,x16 // h+=Sigma1(e)
+ eor x19,x19,x20 // Maj(a,b,c)
+ eor x17,x4,x27,ror#39 // Sigma0(a)
+ eor x2,x2,x11,lsr#6 // sigma1(X[i+14])
+ add x13,x13,x6
+ add x22,x22,x26 // d+=h
+ add x26,x26,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x13,x13,x3
+ add x26,x26,x17 // h+=Sigma0(a)
+ add x13,x13,x2
+ ldr x2,[sp,#24]
+ str x5,[sp,#16]
+ ror x16,x22,#14
+ add x25,x25,x19 // h+=K[i]
+ ror x4,x15,#1
+ and x17,x23,x22
+ ror x3,x12,#19
+ bic x19,x24,x22
+ ror x5,x26,#28
+ add x25,x25,x13 // h+=X[i]
+ eor x16,x16,x22,ror#18
+ eor x4,x4,x15,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x26,x27 // a^b, b^c in next round
+ eor x16,x16,x22,ror#41 // Sigma1(e)
+ eor x5,x5,x26,ror#34
+ add x25,x25,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x3,x3,x12,ror#61
+ eor x4,x4,x15,lsr#7 // sigma0(X[i+1])
+ add x25,x25,x16 // h+=Sigma1(e)
+ eor x28,x28,x27 // Maj(a,b,c)
+ eor x17,x5,x26,ror#39 // Sigma0(a)
+ eor x3,x3,x12,lsr#6 // sigma1(X[i+14])
+ add x14,x14,x7
+ add x21,x21,x25 // d+=h
+ add x25,x25,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x14,x14,x4
+ add x25,x25,x17 // h+=Sigma0(a)
+ add x14,x14,x3
+ ldr x3,[sp,#0]
+ str x6,[sp,#24]
+ ror x16,x21,#14
+ add x24,x24,x28 // h+=K[i]
+ ror x5,x0,#1
+ and x17,x22,x21
+ ror x4,x13,#19
+ bic x28,x23,x21
+ ror x6,x25,#28
+ add x24,x24,x14 // h+=X[i]
+ eor x16,x16,x21,ror#18
+ eor x5,x5,x0,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x25,x26 // a^b, b^c in next round
+ eor x16,x16,x21,ror#41 // Sigma1(e)
+ eor x6,x6,x25,ror#34
+ add x24,x24,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x4,x4,x13,ror#61
+ eor x5,x5,x0,lsr#7 // sigma0(X[i+1])
+ add x24,x24,x16 // h+=Sigma1(e)
+ eor x19,x19,x26 // Maj(a,b,c)
+ eor x17,x6,x25,ror#39 // Sigma0(a)
+ eor x4,x4,x13,lsr#6 // sigma1(X[i+14])
+ add x15,x15,x8
+ add x20,x20,x24 // d+=h
+ add x24,x24,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x15,x15,x5
+ add x24,x24,x17 // h+=Sigma0(a)
+ add x15,x15,x4
+ ldr x4,[sp,#8]
+ str x7,[sp,#0]
+ ror x16,x20,#14
+ add x23,x23,x19 // h+=K[i]
+ ror x6,x1,#1
+ and x17,x21,x20
+ ror x5,x14,#19
+ bic x19,x22,x20
+ ror x7,x24,#28
+ add x23,x23,x15 // h+=X[i]
+ eor x16,x16,x20,ror#18
+ eor x6,x6,x1,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x24,x25 // a^b, b^c in next round
+ eor x16,x16,x20,ror#41 // Sigma1(e)
+ eor x7,x7,x24,ror#34
+ add x23,x23,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x5,x5,x14,ror#61
+ eor x6,x6,x1,lsr#7 // sigma0(X[i+1])
+ add x23,x23,x16 // h+=Sigma1(e)
+ eor x28,x28,x25 // Maj(a,b,c)
+ eor x17,x7,x24,ror#39 // Sigma0(a)
+ eor x5,x5,x14,lsr#6 // sigma1(X[i+14])
+ add x0,x0,x9
+ add x27,x27,x23 // d+=h
+ add x23,x23,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x0,x0,x6
+ add x23,x23,x17 // h+=Sigma0(a)
+ add x0,x0,x5
+ ldr x5,[sp,#16]
+ str x8,[sp,#8]
+ ror x16,x27,#14
+ add x22,x22,x28 // h+=K[i]
+ ror x7,x2,#1
+ and x17,x20,x27
+ ror x6,x15,#19
+ bic x28,x21,x27
+ ror x8,x23,#28
+ add x22,x22,x0 // h+=X[i]
+ eor x16,x16,x27,ror#18
+ eor x7,x7,x2,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x23,x24 // a^b, b^c in next round
+ eor x16,x16,x27,ror#41 // Sigma1(e)
+ eor x8,x8,x23,ror#34
+ add x22,x22,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x6,x6,x15,ror#61
+ eor x7,x7,x2,lsr#7 // sigma0(X[i+1])
+ add x22,x22,x16 // h+=Sigma1(e)
+ eor x19,x19,x24 // Maj(a,b,c)
+ eor x17,x8,x23,ror#39 // Sigma0(a)
+ eor x6,x6,x15,lsr#6 // sigma1(X[i+14])
+ add x1,x1,x10
+ add x26,x26,x22 // d+=h
+ add x22,x22,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x1,x1,x7
+ add x22,x22,x17 // h+=Sigma0(a)
+ add x1,x1,x6
+ ldr x6,[sp,#24]
+ str x9,[sp,#16]
+ ror x16,x26,#14
+ add x21,x21,x19 // h+=K[i]
+ ror x8,x3,#1
+ and x17,x27,x26
+ ror x7,x0,#19
+ bic x19,x20,x26
+ ror x9,x22,#28
+ add x21,x21,x1 // h+=X[i]
+ eor x16,x16,x26,ror#18
+ eor x8,x8,x3,ror#8
+ orr x17,x17,x19 // Ch(e,f,g)
+ eor x19,x22,x23 // a^b, b^c in next round
+ eor x16,x16,x26,ror#41 // Sigma1(e)
+ eor x9,x9,x22,ror#34
+ add x21,x21,x17 // h+=Ch(e,f,g)
+ and x28,x28,x19 // (b^c)&=(a^b)
+ eor x7,x7,x0,ror#61
+ eor x8,x8,x3,lsr#7 // sigma0(X[i+1])
+ add x21,x21,x16 // h+=Sigma1(e)
+ eor x28,x28,x23 // Maj(a,b,c)
+ eor x17,x9,x22,ror#39 // Sigma0(a)
+ eor x7,x7,x0,lsr#6 // sigma1(X[i+14])
+ add x2,x2,x11
+ add x25,x25,x21 // d+=h
+ add x21,x21,x28 // h+=Maj(a,b,c)
+ ldr x28,[x30],#8 // *K++, x19 in next round
+ add x2,x2,x8
+ add x21,x21,x17 // h+=Sigma0(a)
+ add x2,x2,x7
+ ldr x7,[sp,#0]
+ str x10,[sp,#24]
+ ror x16,x25,#14
+ add x20,x20,x28 // h+=K[i]
+ ror x9,x4,#1
+ and x17,x26,x25
+ ror x8,x1,#19
+ bic x28,x27,x25
+ ror x10,x21,#28
+ add x20,x20,x2 // h+=X[i]
+ eor x16,x16,x25,ror#18
+ eor x9,x9,x4,ror#8
+ orr x17,x17,x28 // Ch(e,f,g)
+ eor x28,x21,x22 // a^b, b^c in next round
+ eor x16,x16,x25,ror#41 // Sigma1(e)
+ eor x10,x10,x21,ror#34
+ add x20,x20,x17 // h+=Ch(e,f,g)
+ and x19,x19,x28 // (b^c)&=(a^b)
+ eor x8,x8,x1,ror#61
+ eor x9,x9,x4,lsr#7 // sigma0(X[i+1])
+ add x20,x20,x16 // h+=Sigma1(e)
+ eor x19,x19,x22 // Maj(a,b,c)
+ eor x17,x10,x21,ror#39 // Sigma0(a)
+ eor x8,x8,x1,lsr#6 // sigma1(X[i+14])
+ add x3,x3,x12
+ add x24,x24,x20 // d+=h
+ add x20,x20,x19 // h+=Maj(a,b,c)
+ ldr x19,[x30],#8 // *K++, x28 in next round
+ add x3,x3,x9
+ add x20,x20,x17 // h+=Sigma0(a)
+ add x3,x3,x8
+ cbnz x19,.Loop_16_xx
+
+ ldp x0,x2,[x29,#96]
+ ldr x1,[x29,#112]
+ sub x30,x30,#648 // rewind
+
+ ldp x3,x4,[x0]
+ ldp x5,x6,[x0,#2*8]
+ add x1,x1,#14*8 // advance input pointer
+ ldp x7,x8,[x0,#4*8]
+ add x20,x20,x3
+ ldp x9,x10,[x0,#6*8]
+ add x21,x21,x4
+ add x22,x22,x5
+ add x23,x23,x6
+ stp x20,x21,[x0]
+ add x24,x24,x7
+ add x25,x25,x8
+ stp x22,x23,[x0,#2*8]
+ add x26,x26,x9
+ add x27,x27,x10
+ cmp x1,x2
+ stp x24,x25,[x0,#4*8]
+ stp x26,x27,[x0,#6*8]
+ b.ne .Loop
+
+ ldp x19,x20,[x29,#16]
+ add sp,sp,#4*8
+ ldp x21,x22,[x29,#32]
+ ldp x23,x24,[x29,#48]
+ ldp x25,x26,[x29,#64]
+ ldp x27,x28,[x29,#80]
+ ldp x29,x30,[sp],#128
+ ret
+.size sha512_block_data_order,.-sha512_block_data_order
+
+.align 6
+.type K512,%object
+K512:
+ .quad 0x428a2f98d728ae22,0x7137449123ef65cd
+ .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+ .quad 0x3956c25bf348b538,0x59f111f1b605d019
+ .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118
+ .quad 0xd807aa98a3030242,0x12835b0145706fbe
+ .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+ .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1
+ .quad 0x9bdc06a725c71235,0xc19bf174cf692694
+ .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3
+ .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+ .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483
+ .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+ .quad 0x983e5152ee66dfab,0xa831c66d2db43210
+ .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4
+ .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725
+ .quad 0x06ca6351e003826f,0x142929670a0e6e70
+ .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926
+ .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+ .quad 0x650a73548baf63de,0x766a0abb3c77b2a8
+ .quad 0x81c2c92e47edaee6,0x92722c851482353b
+ .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001
+ .quad 0xc24b8b70d0f89791,0xc76c51a30654be30
+ .quad 0xd192e819d6ef5218,0xd69906245565a910
+ .quad 0xf40e35855771202a,0x106aa07032bbd1b8
+ .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53
+ .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+ .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+ .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+ .quad 0x748f82ee5defb2fc,0x78a5636f43172f60
+ .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec
+ .quad 0x90befffa23631e28,0xa4506cebde82bde9
+ .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b
+ .quad 0xca273eceea26619c,0xd186b8c721c0c207
+ .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+ .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6
+ .quad 0x113f9804bef90dae,0x1b710b35131c471b
+ .quad 0x28db77f523047d84,0x32caab7b40c72493
+ .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+ .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+ .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817
+ .quad 0 // terminator
+.size K512,.-K512
+.align 3
+.LOPENSSL_armcap_P:
+ .quad OPENSSL_armcap_P-.
+.asciz "SHA512 block transform for ARMv8, CRYPTOGAMS by <appro@openssl.org>"
+.align 2
+.comm OPENSSL_armcap_P,4,4
diff --git a/share/doc/psd/contents/contents.ms b/share/doc/psd/contents/contents.ms
index 4a222460600a..989fb16ce6c1 100644
--- a/share/doc/psd/contents/contents.ms
+++ b/share/doc/psd/contents/contents.ms
@@ -145,17 +145,6 @@ Indispensable tool for making sure large programs are properly
compiled with minimal effort.
.sp
.IP
-.tl 'An Introduction to the Revision Control System''PSD:13'
-.if \n(.U \{\
-.br
-.>> <a href="13.rcs/paper.html">13.rcs/paper.html</a>
-.\}
-.QP
-RCS is a user-contributed tool for working together with other people
-without stepping on each other's toes.
-An alternative to \fIsccs\fR for controlling software changes.
-.sp
-.IP
.tl 'An Introduction to the Source Code Control System''PSD:14'
.QP
A useful introductory article for those users with
diff --git a/share/doc/psd/title/Title b/share/doc/psd/title/Title
index eb1ad942274f..1cdf9b4751f4 100644
--- a/share/doc/psd/title/Title
+++ b/share/doc/psd/title/Title
@@ -117,12 +117,6 @@ Permission is granted to make and distribute verbatim copies of
this document provided the copyright notice and this permission notice
are preserved on all copies.
.sp 2
-Document PSD:13 is part of the user contributed software and is
-copyright 1983 by Walter F. Tichy.
-Permission to copy the RCS documentation or any portion thereof as
-necessary for licensed use of the software is granted to licensees
-of this software, provided this copyright notice is included.
-.sp 2
The views and conclusions contained in this manual are those of the
authors and should not be interpreted as representing official policies,
either expressed or implied, of the Regents of the University of California.
diff --git a/share/man/man4/chromebook_platform.4 b/share/man/man4/chromebook_platform.4
new file mode 100644
index 000000000000..d6998b23700a
--- /dev/null
+++ b/share/man/man4/chromebook_platform.4
@@ -0,0 +1,68 @@
+.\" Copyright (c) 2016 Andriy Gapon <avg@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$
+.\"
+.Dd October 13, 2016
+.Dt CHROMEBOOK_PLATFORM 4
+.Os
+.Sh NAME
+.Nm chromebook_platform
+.Nd support driver for hardware on various Chromebook models
+.Sh SYNOPSIS
+To compile this driver into the kernel, place the following lines into
+the kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device chromebook_platform"
+.Ed
+.Pp
+Alternatively, to load the driver as a module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+chromebook_platform_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides automatic configuration for devices that cannot be enumerated
+or safely probed.
+In particular, I2C peripherals are different from model to model.
+.Nm
+has a model-specific information about the I2C peripherals, their drivers,
+their bus attachments and slave addresses.
+.Pp
+Note that
+.Nm
+does not load driver modules for the peripherals.
+Those have to be compiled into the kernel or loaded separately.
+.Sh SEE ALSO
+.Xr cyapa 4 ,
+.Xr iicbus 4 ,
+.Xr isl 4 ,
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver and this manual page were written by
+.An Andriy Gapon Aq Mt avg@FreeBSD.org .
diff --git a/share/man/man4/cyapa.4 b/share/man/man4/cyapa.4
index dc312f490637..e1983ad13872 100644
--- a/share/man/man4/cyapa.4
+++ b/share/man/man4/cyapa.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 25, 2015
+.Dd October 03, 2016
.Dt CYAPA 4
.Os
.Sh NAME
@@ -36,7 +36,7 @@ the kernel configuration file:
.Bd -ragged -offset indent
.Cd "device cyapa"
.Cd "device ig4"
-.Cd "device smbus"
+.Cd "device iicbus"
.Ed
.Pp
Alternatively, to load the driver as a module at boot time, place the following line in
@@ -45,6 +45,13 @@ Alternatively, to load the driver as a module at boot time, place the following
cyapa_load="YES"
ig4_load="YES"
.Ed
+.Pp
+In
+.Pa /boot/device.hints :
+.Cd hint.cyapa.0.at="iicbus0"
+.Cd hint.cyapa.0.addr="0xCE"
+.Cd hint.cyapa.1.at="iicbus1"
+.Cd hint.cyapa.1.addr="0xCE"
.Sh DESCRIPTION
The
.Nm
@@ -86,6 +93,20 @@ The upper right corner issues a MIDDLE button event.
The lower right corner issues a RIGHT button.
Optionally, tap to click can be enabled (see below).
.El
+.Pp
+On a system using
+.Xr device.hints 5 ,
+these values are configurable for
+.Nm :
+.Bl -tag -width "hint.cyapa.%d.addr"
+.It Va hint.cyapa.%d.at
+target
+.Xr iicbus 4 .
+.It Va hint.cyapa.%d.addr
+.Nm
+i2c address on the
+.Xr iicbus 4 .
+.El
.Sh SYSCTL VARIABLES
These
.Xr sysctl 8
@@ -175,7 +196,7 @@ file:
.Dl debug.cyapa_enable_tapclick=2
.Sh SEE ALSO
.Xr ig4 4 ,
-.Xr smbus 4 ,
+.Xr iicbus 4 ,
.Xr sysmouse 4 ,
.Xr moused 8
.Sh AUTHORS
@@ -195,6 +216,6 @@ This manual page was written by
.Sh BUGS
The
.Nm
-driver detects the device based on its I2C address (0x67).
+driver detects the device from the I2C address.
This might have unforeseen consequences if the initialization sequence
is sent to an unknown device at that address.
diff --git a/share/man/man4/ig4.4 b/share/man/man4/ig4.4
index d4d7300a5f89..9237b96635d7 100644
--- a/share/man/man4/ig4.4
+++ b/share/man/man4/ig4.4
@@ -24,18 +24,18 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 30, 2015
+.Dd October 03, 2016
.Dt IG4 4
.Os
.Sh NAME
.Nm ig4
-.Nd Intel(R) fourth generation mobile CPU integrated I2C SMBus driver
+.Nd Intel(R) fourth generation mobile CPU integrated I2C driver
.Sh SYNOPSIS
To compile this driver into the kernel, place the following lines into
the kernel configuration file:
.Bd -ragged -offset indent
.Cd "device ig4"
-.Cd "device smbus"
+.Cd "device iicbus"
.Ed
.Pp
Alternatively, to load the driver as a module at boot time, place the following line in
@@ -46,9 +46,10 @@ ig4_load="YES"
.Sh DESCRIPTION
The
.Nm
-driver provides access to peripherals attached to an I2C SMB controller.
+driver provides access to peripherals attached to an I2C controller.
+.Sh HARDWARE
.Nm
-supports the SMBus controller found in fourth generation Intel(R) Core(TM)
+supports the I2C controllers found in fourth generation Intel(R) Core(TM)
processors based on the mobile U-processor line for intelligent systems.
This includes the i7-4650U, i5-4300U, i3-4010U, and 2980U.
.Sh SYSCTL VARIABLES
@@ -57,13 +58,15 @@ These
variables are available:
.Bl -tag -width "debug.ig4_dump"
.It Va debug.ig4_dump
-Setting this to a non-zero value dumps controller registers to console and
-syslog once.
-The sysctl resets to zero immediately.
+This sysctl is a zero-based bit mask.
+When any of the bits are set, a register dump is printed for
+every I2C transfer on an
+.Nm
+device with the same unit number.
.El
.Sh SEE ALSO
-.Xr smb 4 ,
-.Xr smbus 4
+.Xr iic 4 ,
+.Xr iicbus 4
.Sh AUTHORS
.An -nosplit
The
diff --git a/share/man/man4/isl.4 b/share/man/man4/isl.4
index 56a0cc3c6dcf..f0535ba3eb6b 100644
--- a/share/man/man4/isl.4
+++ b/share/man/man4/isl.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 25, 2015
+.Dd October 03, 2016
.Dt ISL 4
.Os
.Sh NAME
@@ -36,7 +36,7 @@ the kernel configuration file:
.Bd -ragged -offset indent
.Cd "device isl"
.Cd "device ig4"
-.Cd "device smbus"
+.Cd "device iicbus"
.Ed
.Pp
Alternatively, to load the driver as a module at boot time, place the following line in
@@ -45,6 +45,13 @@ Alternatively, to load the driver as a module at boot time, place the following
isl_load="YES"
ig4_load="YES"
.Ed
+.Pp
+In
+.Pa /boot/device.hints :
+.Cd hint.isl.0.at="iicbus0"
+.Cd hint.isl.0.addr="0x88"
+.Cd hint.isl.1.at="iicbus1"
+.Cd hint.isl.1.addr="0x88"
.Sh DESCRIPTION
The
.Nm
@@ -54,6 +61,20 @@ Function.
Functionality is basic and provided through the
.Xr sysctl 8
interface.
+.Pp
+On a system using
+.Xr device.hints 5 ,
+these values are configurable for
+.Nm :
+.Bl -tag -width "hint.isl.%d.addr"
+.It Va hint.isl.%d.at
+target
+.Xr iicbus 4 .
+.It Va hint.isl.%d.addr
+.Nm
+i2c address on the
+.Xr iicbus 4 .
+.El
.Sh SYSCTL VARIABLES
The following
.Xr sysctl 8
@@ -86,7 +107,7 @@ $ sh /usr/local/share/examples/intel-backlight/isl_backlight.sh
.Ed
.Sh SEE ALSO
.Xr ig4 4 ,
-.Xr smbus 4
+.Xr iicbus 4
.Sh AUTHORS
.An -nosplit
The
@@ -99,6 +120,6 @@ This manual page was written by
.Sh BUGS
The
.Nm
-driver detects the device based on its I2C address (0x44).
+driver detects the device based from the I2C address.
This might have unforeseen consequences if the initialization sequence
is sent to an unknown device at that address.
diff --git a/share/man/man4/jedec_ts.4 b/share/man/man4/jedec_ts.4
new file mode 100644
index 000000000000..567beb66b58b
--- /dev/null
+++ b/share/man/man4/jedec_ts.4
@@ -0,0 +1,130 @@
+.\"
+.\" Copyright (c) 2016 Andriy Gapon <avg@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 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$
+.\"
+.Dd October 13, 2016
+.Dt JEDEC_TS 4
+.Os
+.Sh NAME
+.Nm jedec_ts
+.Nd driver for temperature sensors on memory modules
+.Sh SYNOPSIS
+.Bd -ragged -offset indent
+.Cd "device jedec_ts"
+.Cd "device smbus"
+.Ed
+.Pp
+Alternatively, to load the driver as a
+module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+jedec_ts_load="YES"
+.Ed
+.Pp
+In
+.Pa /boot/device.hints :
+.Bd -literal -offset indent
+.Cd hint.jedec_ts.0.at="smbus0"
+.Cd hint.jedec_ts.0.addr="0x30"
+.Cd hint.jedec_ts.1.at="smbus0"
+.Cd hint.jedec_ts.1.addr="0x32"
+.Cd hint.jedec_ts.2.at="smbus0"
+.Cd hint.jedec_ts.2.addr="0x34"
+.Cd hint.jedec_ts.3.at="smbus0"
+.Cd hint.jedec_ts.3.addr="0x36"
+.Cd hint.jedec_ts.4.at="smbus0"
+.Cd hint.jedec_ts.4.addr="0x38"
+.Cd hint.jedec_ts.5.at="smbus0"
+.Cd hint.jedec_ts.5.addr="0x3A"
+.Cd hint.jedec_ts.6.at="smbus0"
+.Cd hint.jedec_ts.6.addr="0x3C"
+.Cd hint.jedec_ts.7.at="smbus0"
+.Cd hint.jedec_ts.7.addr="0x3E"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides access to sensor data over the
+.Xr smbus 4 .
+The driver supports temperature sensors on memory modules that conform
+to JEDEC Standard 21-C, TSE2002 Specification.
+.Pp
+The access to
+.Nm
+data is made via the
+.Xr sysctl 8
+interface:
+.Bl -tag -width "dev.jedec_ts.%d.temp"
+.It Va dev.jedec_ts.%d.temp
+read-only value of the current temperature read by the sensor.
+.El
+.Pp
+On a system using
+.Xr device.hints 5 ,
+these values are configurable for
+.Nm :
+.Bl -tag -width "hint.jedec_ts.%d.addr"
+.It Va hint.jedec_ts.%d.at
+target
+.Xr smbus 4 .
+.It Va hint.jedec_ts.%d.addr
+.Nm
+SMBus address on the
+.Xr smbus 4 .
+.El
+.Pp
+.Nm
+temperature sensors can be wired to eight different addresses,
+allowing up to eight sensors on the same
+.Xr smbus 4 .
+.Pp
+If the sensors are on an I2C bus behind an
+.Xr iicbus 4
+controller, then the
+.Xr iicsmb 4
+bridge driver can be used to attach the
+.Xr smbus 4 .
+.Sh EXAMPLES
+.Ss Sensor read out for two memory modules:
+.Bd -literal
+dev.jedec_ts.0.temp: 40.2500C
+dev.jedec_ts.1.temp: 40.7500C
+.Ed
+.Sh SEE ALSO
+.Xr iicbus 4 ,
+.Xr iicsmb 4 ,
+.Xr smbus 4 ,
+.Xr sysctl 8
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Fx 12.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver and this manual page were written by
+.An Andriy Gapon Aq Mt avg@FreeBSD.org .
diff --git a/share/man/man4/tcp.4 b/share/man/man4/tcp.4
index 4d1473082b36..49fe2afaee95 100644
--- a/share/man/man4/tcp.4
+++ b/share/man/man4/tcp.4
@@ -587,10 +587,10 @@ List of available TCP function blocks (TCP stacks).
.It Va functions_default
The default TCP function block (TCP stack).
.It Va insecure_rst
-Use criterias defined in RFC793 instead of RFC5961 for accepting RST segments.
+Use criteria defined in RFC793 instead of RFC5961 for accepting RST segments.
Default is false.
.It Va insecure_syn
-Use criterias defined in RFC793 instead of RFC5961 for accepting SYN segments.
+Use criteria defined in RFC793 instead of RFC5961 for accepting SYN segments.
Default is false.
.El
.Sh ERRORS
diff --git a/share/man/man4/ure.4 b/share/man/man4/ure.4
index 1b2ebb885d79..cf483dca9d11 100644
--- a/share/man/man4/ure.4
+++ b/share/man/man4/ure.4
@@ -1,5 +1,5 @@
.\"
-.\" Copyright (c) 2015 Kevin Lo <kevlo@FreeBSD.org>
+.\" Copyright (c) 2015-2016 Kevin Lo <kevlo@FreeBSD.org>
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@@ -25,12 +25,12 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 1, 2015
+.Dd October 31, 2016
.Dt URE 4
.Os
.Sh NAME
.Nm ure
-.Nd "RealTek RTL8152 USB to Fast Ethernet controller driver"
+.Nd "RealTek RTL8152/RTL8153 USB to Ethernet controller driver"
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following lines in your
@@ -54,10 +54,10 @@ if_ure_load="YES"
The
.Nm
driver provides support for USB Ethernet adapters based on the RealTek
-RTL8152 USB to Fast Ethernet controller chip.
+RealTek RTL8152 and RTL8153 USB Ethernet controllers.
.Pp
-The RTL8152 contains an integrated Fast Ethernet MAC, which supports
-both 10 and 100Mbps speeds in either full or half duplex.
+NICs based on the RTL8152 are capable of 10 and 100Mbps speeds.
+NICs based on the RTL8153 are capable of 10, 100 and 1000Mbps operation.
.Pp
The
.Nm
@@ -87,12 +87,17 @@ option can also be used to select either
or
.Cm half-duplex
modes.
+.It Cm 1000baseTX
+Set 1000baseTX operation over twisted pair.
+The RealTek gigE chips support 1000Mbps in
+.Cm full-duplex
+mode only.
.El
.Pp
The
.Nm
driver supports the following media options:
-.Bl -tag -width ".Cm 10baseT/UTP"
+.Bl -tag -width ".Cm full-duplex"
.It Cm full-duplex
Force full duplex operation.
.It Cm half-duplex
diff --git a/share/man/man7/arch.7 b/share/man/man7/arch.7
index 488cd05b1f90..d198c98665bf 100644
--- a/share/man/man7/arch.7
+++ b/share/man/man7/arch.7
@@ -57,9 +57,13 @@ On all supported architectures,
.It i386 Ta 4 Ta 12
.It mips Ta 4 Ta 8
.It mipsel Ta 4 Ta 8
+.It mipselhf Ta 4 Ta 8
+.It mipshf Ta 4 Ta 8
.It mipsn32 Ta 4 Ta 8
.It mips64 Ta 8 Ta 8
.It mips64el Ta 8 Ta 8
+.It mips64elhf Ta 8 Ta 8
+.It mips64hf Ta 8 Ta 8
.It powerpc Ta 4 Ta 8
.It powerpc64 Ta 8 Ta 8
.It riscv Ta 8 Ta
@@ -76,9 +80,13 @@ On all supported architectures,
.It i386 Ta little Ta signed
.It mips Ta big Ta signed
.It mipsel Ta little Ta signed
+.It mipselhf Ta little Ta signed
+.It mipshf Ta big Ta signed
.It mipsn32 Ta big Ta signed
.It mips64 Ta big Ta signed
.It mips64el Ta little Ta signed
+.It mips64elhf Ta little Ta signed
+.It mips64hf Ta big Ta signed
.It powerpc Ta big Ta unsigned
.It powerpc64 Ta big Ta unsigned
.It riscv Ta little Ta signed
@@ -95,9 +103,13 @@ On all supported architectures,
.It i386 Ta 4K, 2M (PAE), 4M
.It mips Ta 4K
.It mipsel Ta 4K
+.It mipselhf Ta 4K
+.It mipshf Ta 4K
.It mipsn32 Ta 4K
.It mips64 Ta 4K
.It mips64el Ta 4K
+.It mips64elhf Ta 4K
+.It mips64hf Ta 4K
.It powerpc Ta 4K
.It powerpc64 Ta 4K
.It riscv Ta 4K
@@ -114,9 +126,13 @@ On all supported architectures,
.It i386 Ta hard Ta hard, 80 bit
.It mips Ta soft Ta identical to double
.It mipsel Ta soft Ta identical to double
-.It mipsn32 Ta soft Ta identical to double
+.It mipselhf Ta hard Ta identical to double
+.It mipshf Ta hard Ta identical to double
+.It mipsn32 Ta soft Ta identical to double
.It mips64 Ta soft Ta identical to double
.It mips64el Ta soft Ta identical to double
+.It mips64elhf Ta hard Ta identical to double
+.It mips64hf Ta hard Ta identical to double
.It powerpc Ta hard Ta hard, double precision
.It powerpc64 Ta hard Ta hard, double precision
.It riscv Ta
@@ -155,9 +171,13 @@ Architecture-specific macros:
.It i386 Ta Dv __i386__
.It mips Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_o32
.It mipsel Ta Dv __mips__, Dv __mips_o32
+.It mipselhf Ta Dv __mips__, Dv __mips_o32
+.It mipshf Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_o32
.It mipsn32 Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n32
.It mips64 Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n64
.It mips64el Ta Dv __mips__, Dv __mips_n64
+.It mips64elhf Ta Dv __mips__, Dv __mips_n64
+.It mips64hf Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n64
.It powerpc Ta Dv __powerpc__
.It powerpc64 Ta Dv __powerpc__, Dv __powerpc64__
.It riscv Ta Dv __riscv__, Dv __riscv64
diff --git a/share/misc/pci_vendors b/share/misc/pci_vendors
index 2bc34d3c42d1..3d9c83c3e2d4 100644
--- a/share/misc/pci_vendors
+++ b/share/misc/pci_vendors
@@ -3,8 +3,8 @@
#
# List of PCI ID's
#
-# Version: 2016.10.03
-# Date: 2016-10-03 03:15:01
+# Version: 2016.10.20
+# Date: 2016-10-20 03:15:02
#
# Maintained by Albert Pool, Martin Mares, and other volunteers from
# the PCI ID Project at http://pci-ids.ucw.cz/.
@@ -245,8 +245,13 @@
0013 53c875a
1000 1000 LSI53C875A PCI to Ultra SCSI Controller
0014 MegaRAID Tri-Mode SAS3516
+ 1028 1fd4 PERC H745P MX
1d49 0602 ThinkSystem RAID 930-16i 4GB Flash PCIe 12Gb Adapter
0016 MegaRAID Tri-Mode SAS3508
+ 1028 1fc9 PERC H840 Adapter
+ 1028 1fcb PERC H740P Adapter
+ 1028 1fcd PERC H740P Mini
+ 1028 1fcf PERC H740P Mini
1d49 0601 ThinkSystem RAID 930-8i 2GB Flash PCIe 12Gb Adapter
1d49 0603 ThinkSystem RAID 930-24i 4GB Flash PCIe 12Gb Adapter
1d49 0604 ThinkSystem RAID 930-8e 4GB Flash PCIe 12Gb Adapter
@@ -376,6 +381,7 @@
1028 1f4d PERC FD33xS
1028 1f4f PERC H730P Slim
1028 1f54 PERC FD33xD
+ 1028 1fd1 PERC H730P MX
17aa 1052 ThinkServer RAID 720i
17aa 1053 ThinkServer RAID 720ix
1d49 0600 ThinkSystem RAID 730-8i 1GB Cache PCIe 12Gb Adapter
@@ -535,8 +541,11 @@
0097 SAS3008 PCI-Express Fusion-MPT SAS-3
1000 3090 SAS9311-8i
1000 30e0 SAS9300-8i
- 1028 1f45 12GB/s HBA internal
+ 1028 1f45 HBA330 Adapter
1028 1f46 12Gbps HBA
+ 1028 1f53 HBA330 Mini
+ 1028 1fd2 HBA330 MX
+ 1028 1fd3 HBA330 MMZ
00ab SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC)
00ac SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC)
1d49 0201 ThinkSystem 9400-16i PCIe 12Gb HBA
@@ -1588,7 +1597,7 @@
1462 2938 Radeon R9 360 OEM
1462 3271 Radeon R9 360 OEM
1682 7360 Radeon R7 360
- 6660 Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330]
+ 6660 Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430]
1028 05ea Radeon HD 8670M
1028 06bf Radeon R5 M335
103c 1970 Radeon HD 8670M
@@ -1596,6 +1605,7 @@
103c 8136 Radeon R5 M330
17aa 3804 Radeon R5 M330
17aa 3809 Radeon R5 M330
+ 17aa 381a Radeon R5 M430
17aa 390c Radeon R5 M330
6663 Sun PRO [Radeon HD 8570A/8570M]
1025 0846 Radeon HD 8570A
@@ -2866,11 +2876,12 @@
174b e180 Radeon HD 7350
17af 3015 Radeon HD 7350
68fe Cedar LE
- 6900 Topaz XT [Radeon R7 M260/M265 / M340/M360]
+ 6900 Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445]
1025 1056 Radeon R7 M360 / R8 M365DX
1028 0640 Radeon R7 M260/M265
1028 0643 Radeon R7 M260/M265
1028 067f Radeon R7 M260
+ 1028 0767 Radeon R7 M445
1028 130a Radeon R7 M260
103c 2263 Radeon R7 M260
103c 2269 Radeon R7 M260
@@ -2881,6 +2892,7 @@
103c 80b5 Radeon R7 M360
103c 80b9 Radeon R7 M360
103c 811c Radeon R7 M340
+ 103c 8226 Radeon R7 M440
10cf 1906 Radeon R7 M260
1170 9979 Radeon R7 M360
1179 f903 Radeon R7 M260
@@ -2892,6 +2904,7 @@
17aa 5021 Radeon R7 M260
6901 Topaz PRO [Radeon R5 M255]
103c 1318 Radeon R6 M255DX
+ 6907 Meso XT [Radeon R5 M315]
6921 Amethyst XT [Radeon R9 M295X]
6929 Tonga XT GL [FirePro S7150]
692b Tonga PRO GL [FirePro W7100]
@@ -3349,7 +3362,7 @@
99a4 Trinity [Radeon HD 7400G]
aa00 R600 HDMI Audio [Radeon HD 2900 GT/PRO/XT]
aa01 RV635 HDMI Audio [Radeon HD 3650/3730/3750]
- aa08 RV630 HDMI Audio [Radeon HD 2600 Series]
+ aa08 RV630 HDMI Audio [Radeon HD 2600 PRO/XT / HD 3610]
aa10 RV610 HDMI Audio [Radeon HD 2350 PRO / 2400 PRO/XT / HD 3410]
174b aa10 Radeon HD 2400 PRO
18bc aa10 Radeon HD 2400 PRO
@@ -3369,10 +3382,10 @@
aa68 Cedar HDMI Audio [Radeon HD 5400/6300/7300 Series]
1028 aa68 XPS 8300
aa80 Cayman/Antilles HDMI Audio [Radeon HD 6930/6950/6970/6990]
- aa88 Barts HDMI Audio [Radeon HD 6800 Series]
+ aa88 Barts HDMI Audio [Radeon HD 6790/6850/6870 / 7720 OEM]
aa90 Turks HDMI Audio [Radeon HD 6500/6600 / 6700M Series]
1028 04a3 Precision M4600
- aa98 Caicos HDMI Audio [Radeon HD 6400 Series]
+ aa98 Caicos HDMI Audio [Radeon HD 6450 / 7450/8450/8490 OEM / R5 230/235/235X OEM]
174b aa98 Radeon HD 6450 1GB DDR3
aaa0 Tahiti HDMI Audio [Radeon HD 7870 XT / 7950/7970]
aab0 Cape Verde/Pitcairn HDMI Audio [Radeon HD 7700/7800 Series]
@@ -7347,6 +7360,7 @@
8533 PEX 8533 32-lane, 6-port PCI Express Switch
8547 PEX 8547 48-lane, 3-port PCI Express Switch
8548 PEX 8548 48-lane, 9-port PCI Express Switch
+ 8603 PEX 8603 3-lane, 3-Port PCI Express Gen 2 (5.0 GT/s) Switch
8604 PEX 8604 4-lane, 4-Port PCI Express Gen 2 (5.0 GT/s) Switch
8605 PEX 8605 PCI Express 4-port Gen2 Switch
8606 PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch
@@ -17921,7 +17935,7 @@
1015 MT27710 Family [ConnectX-4 Lx]
1016 MT27710 Family [ConnectX-4 Lx Virtual Function]
1017 MT27800 Family [ConnectX-5]
- 1018 MT28800 Family [ConnectX-5 Virtual Function]
+ 1018 MT27800 Family [ConnectX-5 Virtual Function]
1019 MT28800 Family [ConnectX-5 Ex]
101a MT28800 Family [ConnectX-5 Ex Virtual Function]
101b MT28831
@@ -17932,6 +17946,7 @@
1020 MT28860
1021 MT28861
1974 MT28800 Family [ConnectX-5 PCIe Bridge]
+ 1975 MT416842 Family [BlueField SoC PCIe Bridge]
5274 MT21108 InfiniBridge
5a44 MT23108 InfiniHost
5a45 MT23108 [Infinihost HCA Flash Recovery]
@@ -17966,6 +17981,9 @@
7121 NPS-600 configuration and management interface
7122 NPS-600 network interface PF
7123 NPS-600 network interface VF
+ a2d0 MT416842
+ a2d1 MT416842
+ a2d3 MT416842 BlueField multicore SoC family VF
# SwitchX-2, 40GbE switch
c738 MT51136
c739 MT51136 GW
@@ -18638,7 +18656,12 @@
7018 AP408: 32-Channel Digital I/O Module
701a AP220-16 12-Bit, 16-Channel Analog Output Module
701b AP231-16 16-Bit, 16-Channel Analog Output Module
+ 7021 APA7-201 Reconfigurable Artix-7 FPGA module 48 TTL channels
+ 7022 APA7-202 Reconfigurable Artix-7 FPGA module 24 RS485 channels
+ 7023 APA7-203 Reconfigurable Artix-7 FPGA module 24 TTL & 12 RS485 channels
+ 7024 APA7-204 Reconfigurable Artix-7 FPGA module 24 LVDS channels
7042 AP482 Counter Timer Module with TTL Level Input/Output
+ 7043 AP483 Counter Timer Module with TTL Level and RS422 Input/Output
7044 AP484 Counter Timer Module with RS422 Input/Output
16da Advantech Co., Ltd.
0011 INES GPIB-PCI
@@ -18881,6 +18904,7 @@
0401 Datacenter Technologies QDF2400 PCI Express Root Port
17cc NetChip Technology, Inc
2280 USB 2.0
+17cd Cadence Design Systems, Inc.
17cf Z-Com, Inc.
17d3 Areca Technology Corp.
1110 ARC-1110 4-Port PCI-X to SATA RAID Controller
@@ -20290,7 +20314,8 @@
1432 8102 EN-8102P 10GbE Ethernet Adapter
1fc9 3015 Ethernet Adapter
4026 TN9610 10GbE SFP+ Ethernet Adapter
- 4027 TN9710 10GBase-T/NBASE-T Ethernet Adapter
+ 4027 TN9710P 10GBase-T/NBASE-T Ethernet Adapter
+ 4527 TN9710Q 5GBase-T/NBASE-T Ethernet Adapter
1fcc StreamLabs
f416 MS416
fb01 MH4LM
@@ -22295,6 +22320,7 @@
17aa 4007 82599ES 10-Gigabit SFI/SFP+ Network Connection
17aa 402b 82599ES 10Gb 2-port Server Adapter X520-DA2
17aa 402f FPGA Card XC7VX690T-3FFG1157E
+ 18d4 0c09 82599ES 10Gb 2-port SFP+ OCP Mezz Card MOP81-I-10GS2
1bd4 001b 10G SFP+ DP ER102Fi4 Rack Adapter
1bd4 002f 10G SFP+ DP EP102Fi4A Adapter
1bd4 0032 10G SFP+ DP EP102Fi4 Adapter
@@ -22570,8 +22596,15 @@
1520 I350 Ethernet Controller Virtual Function
1521 I350 Gigabit Network Connection
1028 0602 Gigabit 2P I350-t LOM
+ 1028 0693 Gigabit 2P I350-t LOM
+ 1028 06e2 Gigabit 2P I350-t LOM
+ 1028 0757 Gigabit I350-t LOM
+ 1028 075a Gigabit I350-t LOM
1028 1f60 Gigabit 4P I350-t rNDC
1028 1f62 Gigabit 4P X540/I350 rNDC
+ 1028 1fa8 Ethernet 10G 4P X550/I350 rNDC
+ 1028 1fa9 Ethernet 10G 4P X550 rNDC
+ 1028 1faa Gigabit 4P X550/I350 rNDC
1028 ff9a Gigabit 4P X710/I350 rNDC
103c 17d1 Ethernet 1Gb 4-port 366FLR Adapter
103c 2003 Ethernet 1Gb 2-port 367i Adapter
@@ -22590,6 +22623,7 @@
15d9 0652 Dual Port i350 GbE MicroLP [AOC-CGP-i2]
17aa 1074 ThinkServer I350-T4 AnyFabric
17aa 4005 I350 Gigabit Network Connection
+ 18d4 0c07 I350 1Gb 2-port RJ45 OCP Mezz Card MOP41-I-1GT2
1bd4 001d 1G base-T QP EP014Ti1 Adapter
1bd4 0035 1G base-T QP EP014Ti1 Adapter
8086 0001 Ethernet Server Adapter I350-T4
@@ -22698,6 +22732,7 @@
1028 1fa9 Ethernet 10G 4P X550 rNDC
1590 00d1 Ethernet 10Gb 2-port 562T Adapter
1590 00d2 Ethernet 10Gb 2-port 562FLR-T Adapter
+ 18d4 0c08 X550 10Gb 2-port RJ45 OCP Mezz Card MOP81-I-10GT2
8086 0001 Ethernet Converged Network Adapter X550-T2
8086 001a Ethernet Converged Network Adapter X550-T2
8086 0022 Ethernet Converged Network Adapter X550-T2
@@ -22782,11 +22817,11 @@
108e 0000 Ethernet Controller X710 for 10GBASE-T
108e 4857 Ethernet Controller X710 for 10GBASE-T
1587 Ethernet Controller XL710 for 20GbE backplane
- 103c 0000 HP Flex-20 20Gb 2-port 660FLB Adapter
- 103c 22fe HP Flex-20 20Gb 2-port 660FLB Adapter
+ 103c 0000 HPE Ethernet 10/20Gb 2-port 660FLB Adapter
+ 103c 22fe HPE Ethernet 10/20Gb 2-port 660FLB Adapter
1588 Ethernet Controller XL710 for 20GbE backplane
- 103c 0000 HP Flex-20 20Gb 2-port 660M Adapter
- 103c 22ff HP Flex-20 20Gb 2-port 660M Adapter
+ 103c 0000 HPE Ethernet 10/20Gb 2-port 660M Adapter
+ 103c 22ff HPE Ethernet 10/20Gb 2-port 660M Adapter
1589 Ethernet Controller X710/X557-AT 10GBASE-T
108e 0000 Quad Port 10GBase-T Adapter
108e 7b1c Quad Port 10GBase-T Adapter
@@ -23169,7 +23204,7 @@
1e09 7 Series Chipset Family 2-port SATA Controller [IDE mode]
144d c652 NP300E5C series laptop
1e0e 7 Series/C210 Series Chipset Family SATA Controller [RAID mode]
- 1e10 7 Series/C210 Series Chipset Family PCI Express Root Port 1
+ 1e10 7 Series/C216 Chipset Family PCI Express Root Port 1
1043 108d VivoBook X202EV
1043 1477 N56VZ
1043 1517 Zenbook Prime UX31A
@@ -23181,7 +23216,7 @@
1043 1477 N56VZ
1043 1517 Zenbook Prime UX31A
1e14 7 Series/C210 Series Chipset Family PCI Express Root Port 3
- 1e16 7 Series/C210 Series Chipset Family PCI Express Root Port 4
+ 1e16 7 Series/C216 Chipset Family PCI Express Root Port 4
1043 108d VivoBook X202EV
1043 1477 N56VZ
144d c652 NP300E5C series laptop
@@ -23194,7 +23229,7 @@
1e1c 7 Series/C210 Series Chipset Family PCI Express Root Port 7
1e1e 7 Series/C210 Series Chipset Family PCI Express Root Port 8
1849 1e1e Motherboard
- 1e20 7 Series/C210 Series Chipset Family High Definition Audio Controller
+ 1e20 7 Series/C216 Chipset Family High Definition Audio Controller
1028 054b Dell XPS One 2710
1043 108d VivoBook X202EV
1043 1477 N56VZ
@@ -23203,7 +23238,7 @@
1043 8445 ASUS P8Z77-V LX Motherboard
144d c652 NP300E5C series laptop
1849 1898 Z77 Extreme4 motherboard
- 1e22 7 Series/C210 Series Chipset Family SMBus Controller
+ 1e22 7 Series/C216 Chipset Family SMBus Controller
1043 108d VivoBook X202EV
1043 1477 N56VZ
1043 1517 Zenbook Prime UX31A
@@ -23213,14 +23248,14 @@
1e24 7 Series/C210 Series Chipset Family Thermal Management Controller
1043 1517 Zenbook Prime UX31A
1e25 7 Series/C210 Series Chipset Family DMI to PCI Bridge
- 1e26 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1
+ 1e26 7 Series/C216 Chipset Family USB Enhanced Host Controller #1
1043 108d VivoBook X202EV
1043 1477 N56VZ
1043 1517 Zenbook Prime UX31A
1043 84ca P8 series motherboard
144d c652 NP300E5C series laptop
1849 1e26 Motherboard
- 1e2d 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2
+ 1e2d 7 Series/C216 Chipset Family USB Enhanced Host Controller #2
1043 108d VivoBook X202EV
1043 1477 N56VZ
1043 1517 Zenbook Prime UX31A
@@ -23235,7 +23270,7 @@
1043 84ca P8 series motherboard
1849 1e31 Motherboard
1e33 7 Series/C210 Series Chipset Family LAN Controller
- 1e3a 7 Series/C210 Series Chipset Family MEI Controller #1
+ 1e3a 7 Series/C216 Chipset Family MEI Controller #1
1043 108d VivoBook X202EV
1043 1477 N56VZ
1043 1517 Zenbook Prime UX31A
@@ -26234,10 +26269,21 @@
37cd X722 Virtual Function
37ce Ethernet Connection X722 for 10GbE backplane
1590 0215 Ethernet 10Gb 2-port 568i Adapter
+ 17aa 4023 Intel Ethernet Connection X722 for 10GbE backplane
37cf Ethernet Connection X722 for 10GbE QSFP+
37d0 Ethernet Connection X722 for 10GbE SFP+
37d1 Ethernet Connection X722 for 1GbE
+ 17aa 4020 Intel Ethernet Connection X722 for 1GbE
+ 17aa 4021 Intel Ethernet Connection X722 for 1GbE
+ 17aa 4022 Intel Ethernet Connection X722 for 1GbE
+ 8086 4020 Ethernet Connection X722 for 1GbE
+ 8086 4021 Ethernet Connection X722 for 1GbE
+ 8086 4022 Ethernet Connection X722 for 1GbE
37d2 Ethernet Connection X722 for 10GBASE-T
+ 17aa 4020 Intel Ethernet Connection X722 for 10GBASE
+ 17aa 4021 Intel Ethernet Connection X722 for 10GBASE
+ 8086 4020 Ethernet Connection X722 for 10GBASE
+ 8086 4021 Ethernet Connection X722 for 10GBASE
37d3 Ethernet Connection X722 for 10GbE SFP+
37d4 Ethernet Connection X722 for 10GbE QSFP+
37d9 X722 Hyper-V Virtual Function
diff --git a/share/mk/bsd.compiler.mk b/share/mk/bsd.compiler.mk
index 38c4f5f24600..954ba5e572e2 100644
--- a/share/mk/bsd.compiler.mk
+++ b/share/mk/bsd.compiler.mk
@@ -147,7 +147,7 @@ ${X_}COMPILER_TYPE:= clang
${X_}COMPILER_TYPE:= gcc
. elif ${_v:M\(GCC\)}
${X_}COMPILER_TYPE:= gcc
-. elif ${_v:Mclang}
+. elif ${_v:Mclang} || ${_v:M(clang-*.*.*)}
${X_}COMPILER_TYPE:= clang
. else
.error Unable to determine compiler type for ${cc}=${${cc}}. Consider setting ${X_}COMPILER_TYPE.
diff --git a/share/mk/bsd.cpu.mk b/share/mk/bsd.cpu.mk
index a967f892846b..5ccfe548cbc1 100644
--- a/share/mk/bsd.cpu.mk
+++ b/share/mk/bsd.cpu.mk
@@ -137,6 +137,8 @@ _CPUCFLAGS = -Wa,-me500 -msoft-float
. else
_CPUCFLAGS = -mcpu=${CPUTYPE} -mno-powerpc64
. endif
+. elif ${MACHINE_ARCH} == "powerpcspe"
+_CPUCFLAGS = -Wa,-me500 -mspe=yes -mabi=spe -mfloat-gprs=double
. elif ${MACHINE_ARCH} == "powerpc64"
_CPUCFLAGS = -mcpu=${CPUTYPE}
. elif ${MACHINE_CPUARCH} == "mips"
@@ -301,6 +303,9 @@ MACHINE_CPU = v9 ultrasparc ultrasparc3
.if ${MACHINE_CPUARCH} == "mips"
CFLAGS += -G0
+.if ${TARGET_ARCH:Mmips*hf}
+CFLAGS += -mhard-float
+.endif
.endif
########## arm
@@ -327,6 +332,10 @@ CFLAGS += -mfloat-abi=softfp
.endif
.endif
+.if ${MACHINE_ARCH} == "powerpcspe"
+CFLAGS += -mcpu=8540 -Wa,-me500 -mspe=yes -mabi=spe -mfloat-gprs=double
+.endif
+
.if ${MACHINE_CPUARCH} == "riscv"
CFLAGS += -msoft-float
ACFLAGS += -msoft-float
diff --git a/share/mk/bsd.endian.mk b/share/mk/bsd.endian.mk
index c7ec42cb2876..eac92c6838f7 100644
--- a/share/mk/bsd.endian.mk
+++ b/share/mk/bsd.endian.mk
@@ -5,10 +5,11 @@
${MACHINE_ARCH} == "i386" || \
(${MACHINE} == "arm" && ${MACHINE_ARCH:Marm*eb*} == "") || \
${MACHINE_CPUARCH} == "riscv" || \
- ${MACHINE_ARCH:Mmips*el} != ""
+ ${MACHINE_ARCH:Mmips*el*} != ""
TARGET_ENDIANNESS= 1234
.elif ${MACHINE_ARCH} == "powerpc" || \
${MACHINE_ARCH} == "powerpc64" || \
+ ${MACHINE_ARCH} == "powerpcspe" || \
${MACHINE_ARCH} == "sparc64" || \
(${MACHINE} == "arm" && ${MACHINE_ARCH:Marm*eb*} != "") || \
${MACHINE_ARCH:Mmips*} != ""
diff --git a/share/mk/bsd.subdir.mk b/share/mk/bsd.subdir.mk
index 34fc8325ae3f..9d1fed72073d 100644
--- a/share/mk/bsd.subdir.mk
+++ b/share/mk/bsd.subdir.mk
@@ -110,7 +110,7 @@ install: beforeinstall realinstall afterinstall
# SUBDIR recursing may be disabled for MK_DIRDEPS_BUILD
.if !target(_SUBDIR)
-.if defined(SUBDIR)
+.if defined(SUBDIR) || defined(SUBDIR.yes)
SUBDIR:=${SUBDIR} ${SUBDIR.yes}
SUBDIR:=${SUBDIR:u}
.endif
diff --git a/share/mk/local.meta.sys.mk b/share/mk/local.meta.sys.mk
index 2ac23d613b1f..49f625ccefa9 100644
--- a/share/mk/local.meta.sys.mk
+++ b/share/mk/local.meta.sys.mk
@@ -46,7 +46,7 @@ OBJROOT:= ${OBJROOT:H:tA}/${OBJROOT:T}
TARGET_ARCHES_arm?= arm armeb armv6
TARGET_ARCHES_arm64?= aarch64
TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipsn32el
-TARGET_ARCHES_powerpc?= powerpc powerpc64
+TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe
TARGET_ARCHES_pc98?= i386
TARGET_ARCHES_riscv?= riscv64
diff --git a/share/mk/sys.mk b/share/mk/sys.mk
index 3f768844794c..cc4a1feb61bb 100644
--- a/share/mk/sys.mk
+++ b/share/mk/sys.mk
@@ -13,7 +13,7 @@ unix ?= We run FreeBSD, not UNIX.
# and/or endian. This is called MACHINE_CPU in NetBSD, but that's used
# for something different in FreeBSD.
#
-MACHINE_CPUARCH=${MACHINE_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc64/powerpc/:C/riscv64/riscv/}
+MACHINE_CPUARCH=${MACHINE_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc(64|spe)/powerpc/:C/riscv64/riscv/}
.endif
@@ -121,7 +121,7 @@ META_MODE?= normal
.if defined(%POSIX)
.SUFFIXES: .o .c .y .l .a .sh .f
.else
-.SUFFIXES: .out .a .ln .o .c .cc .cpp .cxx .C .m .F .f .e .r .y .l .S .asm .s .cl .p .h .sh
+.SUFFIXES: .out .a .ln .o .bco .llo .c .cc .cpp .cxx .C .m .F .f .e .r .y .l .S .asm .s .cl .p .h .sh
.endif
AR ?= ar
diff --git a/sys/amd64/amd64/mem.c b/sys/amd64/amd64/mem.c
index 51f465074363..c2e74ff63b06 100644
--- a/sys/amd64/amd64/mem.c
+++ b/sys/amd64/amd64/mem.c
@@ -140,7 +140,7 @@ memrw(struct cdev *dev, struct uio *uio, int flags)
error = uiomove((void *)vd, c, uio);
break;
}
- if (v >= (1ULL << cpu_maxphyaddr)) {
+ if (v > cpu_getmaxphyaddr()) {
error = EFAULT;
break;
}
@@ -169,7 +169,7 @@ memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
int prot __unused, vm_memattr_t *memattr __unused)
{
if (dev2unit(dev) == CDEV_MINOR_MEM) {
- if (offset >= (1ULL << cpu_maxphyaddr))
+ if (offset > cpu_getmaxphyaddr())
return (-1);
*paddr = offset;
return (0);
diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c
index 4f85e1f03174..24009dbaed5e 100644
--- a/sys/amd64/amd64/sys_machdep.c
+++ b/sys/amd64/amd64/sys_machdep.c
@@ -608,6 +608,8 @@ amd64_set_ldt(td, uap, descs)
largest_ld = uap->start + uap->num;
if (largest_ld > max_ldt_segment)
largest_ld = max_ldt_segment;
+ if (largest_ld < uap->start)
+ return (EINVAL);
i = largest_ld - uap->start;
mtx_lock(&dt_lock);
bzero(&((struct user_segment_descriptor *)(pldt->ldt_base))
@@ -620,7 +622,8 @@ amd64_set_ldt(td, uap, descs)
/* verify range of descriptors to modify */
largest_ld = uap->start + uap->num;
if (uap->start >= max_ldt_segment ||
- largest_ld > max_ldt_segment)
+ largest_ld > max_ldt_segment ||
+ largest_ld < uap->start)
return (EINVAL);
}
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 8d2b3990f019..024c1b34a6cc 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -144,14 +144,6 @@ static char *trap_msg[] = {
"DTrace pid return trap", /* 32 T_DTRACE_RET */
};
-#ifdef KDB
-static int kdb_on_nmi = 1;
-SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN,
- &kdb_on_nmi, 0, "Go to KDB on NMI");
-#endif
-static int panic_on_nmi = 1;
-SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN,
- &panic_on_nmi, 0, "Panic on NMI");
static int prot_fault_translation;
SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RWTUN,
&prot_fault_translation, 0,
@@ -377,21 +369,7 @@ trap(struct trapframe *frame)
#ifdef DEV_ISA
case T_NMI:
- /* machine/parity/power fail/"kitchen sink" faults */
- if (isa_nmi(frame->tf_err) == 0) {
-#ifdef KDB
- /*
- * NMI can be hooked up to a pushbutton
- * for debugging.
- */
- if (kdb_on_nmi) {
- printf ("NMI ... going to debugger\n");
- kdb_trap(type, 0, frame);
- }
-#endif /* KDB */
- goto userout;
- } else if (panic_on_nmi)
- panic("NMI indicates hardware failure");
+ nmi_handle_intr(type, frame);
break;
#endif /* DEV_ISA */
@@ -563,22 +541,8 @@ trap(struct trapframe *frame)
#ifdef DEV_ISA
case T_NMI:
- /* machine/parity/power fail/"kitchen sink" faults */
- if (isa_nmi(frame->tf_err) == 0) {
-#ifdef KDB
- /*
- * NMI can be hooked up to a pushbutton
- * for debugging.
- */
- if (kdb_on_nmi) {
- printf ("NMI ... going to debugger\n");
- kdb_trap(type, 0, frame);
- }
-#endif /* KDB */
- goto out;
- } else if (panic_on_nmi == 0)
- goto out;
- /* FALLTHROUGH */
+ nmi_handle_intr(type, frame);
+ goto out;
#endif /* DEV_ISA */
}
diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h
index 4d924bdbf31e..99285a99e1d9 100644
--- a/sys/amd64/include/pmap.h
+++ b/sys/amd64/include/pmap.h
@@ -382,6 +382,8 @@ extern vm_paddr_t dump_avail[];
extern vm_offset_t virtual_avail;
extern vm_offset_t virtual_end;
extern vm_paddr_t dmaplimit;
+extern int pmap_pcid_enabled;
+extern int invpcid_works;
#define pmap_page_get_memattr(m) ((vm_memattr_t)(m)->md.pat_mode)
#define pmap_page_is_write_mapped(m) (((m)->aflags & PGA_WRITEABLE) != 0)
diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h
index 212d1ee50f23..d97c7304f204 100644
--- a/sys/amd64/include/smp.h
+++ b/sys/amd64/include/smp.h
@@ -21,9 +21,6 @@
#include <x86/x86_smp.h>
-extern int pmap_pcid_enabled;
-extern int invpcid_works;
-
/* global symbols in mpboot.S */
extern char mptramp_start[];
extern char mptramp_end[];
diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c
index bd70d1135b44..5aa17d0fbb1e 100644
--- a/sys/amd64/vmm/amd/svm.c
+++ b/sys/amd64/vmm/amd/svm.c
@@ -514,10 +514,11 @@ svm_vminit(struct vm *vm, pmap_t pmap)
{
struct svm_softc *svm_sc;
struct svm_vcpu *vcpu;
- vm_paddr_t msrpm_pa, iopm_pa, pml4_pa;
+ vm_paddr_t msrpm_pa, iopm_pa, pml4_pa;
int i;
- svm_sc = malloc(sizeof (struct svm_softc), M_SVM, M_WAITOK | M_ZERO);
+ svm_sc = contigmalloc(sizeof (*svm_sc), M_SVM, M_WAITOK | M_ZERO,
+ 0, ~(vm_paddr_t)0, PAGE_SIZE, 0);
svm_sc->vm = vm;
svm_sc->nptp = (vm_offset_t)vtophys(pmap->pm_pml4);
@@ -534,7 +535,7 @@ svm_vminit(struct vm *vm, pmap_t pmap)
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_GSBASE);
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_FSBASE);
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_KGSBASE);
-
+
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_STAR);
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_LSTAR);
svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_CSTAR);
@@ -2042,7 +2043,7 @@ svm_vmcleanup(void *arg)
{
struct svm_softc *sc = arg;
- free(sc, M_SVM);
+ contigfree(sc, sizeof (*sc), M_SVM);
}
static register_t *
diff --git a/sys/arm/allwinner/aw_cir.c b/sys/arm/allwinner/aw_cir.c
new file mode 100644
index 000000000000..19f49fbe7761
--- /dev/null
+++ b/sys/arm/allwinner/aw_cir.c
@@ -0,0 +1,535 @@
+/*-
+ * Copyright (c) 2016 Ganbold Tsagaankhuu <ganbold@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.
+ */
+
+/*
+ * Allwinner Consumer IR controller
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <machine/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+
+#include <dev/evdev/input.h>
+#include <dev/evdev/evdev.h>
+
+#define READ(_sc, _r) bus_read_4((_sc)->res[0], (_r))
+#define WRITE(_sc, _r, _v) bus_write_4((_sc)->res[0], (_r), (_v))
+
+/* IR Control */
+#define AW_IR_CTL 0x00
+/* Global Enable */
+#define AW_IR_CTL_GEN (1 << 0)
+/* RX enable */
+#define AW_IR_CTL_RXEN (1 << 1)
+/* CIR mode enable */
+#define AW_IR_CTL_MD (1 << 4) | (1 << 5)
+
+/* RX Config Reg */
+#define AW_IR_RXCTL 0x10
+/* Pulse Polarity Invert flag */
+#define AW_IR_RXCTL_RPPI (1 << 2)
+
+/* RX Data */
+#define AW_IR_RXFIFO 0x20
+
+/* RX Interrupt Control */
+#define AW_IR_RXINT 0x2C
+/* RX FIFO Overflow */
+#define AW_IR_RXINT_ROI_EN (1 << 0)
+/* RX Packet End */
+#define AW_IR_RXINT_RPEI_EN (1 << 1)
+/* RX FIFO Data Available */
+#define AW_IR_RXINT_RAI_EN (1 << 4)
+/* RX FIFO available byte level */
+#define AW_IR_RXINT_RAL(val) ((val) << 8)
+
+/* RX Interrupt Status Reg */
+#define AW_IR_RXSTA 0x30
+/* RX FIFO Get Available Counter */
+#define AW_IR_RXSTA_COUNTER(val) (((val) >> 8) & (sc->fifo_size * 2 - 1))
+/* Clear all interrupt status */
+#define AW_IR_RXSTA_CLEARALL 0xff
+
+/* IR Sample Configure Reg */
+#define AW_IR_CIR 0x34
+/* Filter Threshold = 8 * 21.3 = ~128us < 200us */
+#define AW_IR_RXFILT_VAL (((8) & 0x3f) << 2)
+/* Idle Threshold = (2 + 1) * 128 * 42.7 = ~16.4ms > 9ms */
+#define AW_IR_RXIDLE_VAL (((2) & 0xff) << 8)
+
+/* Bit 15 - value (pulse/space) */
+#define VAL_MASK 0x80
+/* Bits 0:14 - sample duration */
+#define PERIOD_MASK 0x7f
+
+/* Clock rate for IR0 or IR1 clock in CIR mode */
+#define AW_IR_BASE_CLK 3000000
+/* Frequency sample 3MHz/64 = 46875Hz (21.3us) */
+#define AW_IR_SAMPLE_64 (0 << 0)
+/* Frequency sample 3MHz/128 = 23437.5Hz (42.7us) */
+#define AW_IR_SAMPLE_128 (1 << 0)
+
+#define AW_IR_ERROR_CODE 0xffffffff
+#define AW_IR_REPEAT_CODE 0x0
+
+/* 80 * 42.7 = ~3.4ms, Lead1(4.5ms) > AW_IR_L1_MIN */
+#define AW_IR_L1_MIN 80
+/* 40 * 42.7 = ~1.7ms, Lead0(4.5ms) Lead0R(2.25ms) > AW_IR_L0_MIN */
+#define AW_IR_L0_MIN 40
+/* 26 * 42.7 = ~1109us ~= 561 * 2, Pulse < AW_IR_PMAX */
+#define AW_IR_PMAX 26
+/* 26 * 42.7 = ~1109us ~= 561 * 2, D1 > AW_IR_DMID, D0 <= AW_IR_DMID */
+#define AW_IR_DMID 26
+/* 53 * 42.7 = ~2263us ~= 561 * 4, D < AW_IR_DMAX */
+#define AW_IR_DMAX 53
+
+/* Active Thresholds */
+#define AW_IR_ACTIVE_T ((0 & 0xff) << 16)
+#define AW_IR_ACTIVE_T_C ((1 & 0xff) << 23)
+
+/* Code masks */
+#define CODE_MASK 0x00ff00ff
+#define INV_CODE_MASK 0xff00ff00
+#define VALID_CODE_MASK 0x00ff0000
+
+#define A10_IR 1
+#define A13_IR 2
+
+#define AW_IR_RAW_BUF_SIZE 128
+
+struct aw_ir_softc {
+ device_t dev;
+ struct resource *res[2];
+ void * intrhand;
+ int fifo_size;
+ int dcnt; /* Packet Count */
+ unsigned char buf[AW_IR_RAW_BUF_SIZE];
+ struct evdev_dev *sc_evdev;
+};
+
+static struct resource_spec aw_ir_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
+ { -1, 0 }
+};
+
+static struct ofw_compat_data compat_data[] = {
+ { "allwinner,sun4i-a10-ir", A10_IR },
+ { "allwinner,sun5i-a13-ir", A13_IR },
+ { NULL, 0 }
+};
+
+static void
+aw_ir_buf_reset(struct aw_ir_softc *sc)
+{
+
+ sc->dcnt = 0;
+}
+
+static void
+aw_ir_buf_write(struct aw_ir_softc *sc, unsigned char data)
+{
+
+ if (sc->dcnt < AW_IR_RAW_BUF_SIZE)
+ sc->buf[sc->dcnt++] = data;
+ else
+ if (bootverbose)
+ device_printf(sc->dev, "IR RX Buffer Full!\n");
+}
+
+static int
+aw_ir_buf_full(struct aw_ir_softc *sc)
+{
+
+ return (sc->dcnt >= AW_IR_RAW_BUF_SIZE);
+}
+
+static unsigned char
+aw_ir_read_data(struct aw_ir_softc *sc)
+{
+
+ return (unsigned char)(READ(sc, AW_IR_RXFIFO) & 0xff);
+}
+
+static unsigned long
+aw_ir_decode_packets(struct aw_ir_softc *sc)
+{
+ unsigned long len, code;
+ unsigned char val, last;
+ unsigned int active_delay;
+ int i, bitcount;
+
+ if (bootverbose)
+ device_printf(sc->dev, "sc->dcnt = %d\n", sc->dcnt);
+
+ /* Find Lead 1 (bit separator) */
+ active_delay = (AW_IR_ACTIVE_T + 1) * (AW_IR_ACTIVE_T_C ? 128 : 1);
+ len = 0;
+ len += (active_delay >> 1);
+ if (bootverbose)
+ device_printf(sc->dev, "Initial len: %ld\n", len);
+ for (i = 0; i < sc->dcnt; i++) {
+ val = sc->buf[i];
+ if (val & VAL_MASK)
+ len += val & PERIOD_MASK;
+ else {
+ if (len > AW_IR_L1_MIN)
+ break;
+ len = 0;
+ }
+ }
+ if (bootverbose)
+ device_printf(sc->dev, "len = %ld\n", len);
+ if ((val & VAL_MASK) || (len <= AW_IR_L1_MIN)) {
+ if (bootverbose)
+ device_printf(sc->dev, "Bit separator error\n");
+ goto error_code;
+ }
+
+ /* Find Lead 0 (bit length) */
+ len = 0;
+ for (; i < sc->dcnt; i++) {
+ val = sc->buf[i];
+ if (val & VAL_MASK) {
+ if(len > AW_IR_L0_MIN)
+ break;
+ len = 0;
+ } else
+ len += val & PERIOD_MASK;
+ }
+ if ((!(val & VAL_MASK)) || (len <= AW_IR_L0_MIN)) {
+ if (bootverbose)
+ device_printf(sc->dev, "Bit length error\n");
+ goto error_code;
+ }
+
+ /* Start decoding */
+ code = 0;
+ bitcount = 0;
+ last = 1;
+ len = 0;
+ for (; i < sc->dcnt; i++) {
+ val = sc->buf[i];
+ if (last) {
+ if (val & VAL_MASK)
+ len += val & PERIOD_MASK;
+ else {
+ if (len > AW_IR_PMAX) {
+ if (bootverbose)
+ device_printf(sc->dev,
+ "Pulse error\n");
+ goto error_code;
+ }
+ last = 0;
+ len = val & PERIOD_MASK;
+ }
+ } else {
+ if (val & VAL_MASK) {
+ if (len > AW_IR_DMAX) {
+ if (bootverbose)
+ device_printf(sc->dev,
+ "Distant error\n");
+ goto error_code;
+ } else {
+ if (len > AW_IR_DMID) {
+ /* Decode */
+ code |= 1 << bitcount;
+ }
+ bitcount++;
+ if (bitcount == 32)
+ break; /* Finish decoding */
+ }
+ last = 1;
+ len = val & PERIOD_MASK;
+ } else
+ len += val & PERIOD_MASK;
+ }
+ }
+ return (code);
+
+error_code:
+
+ return (AW_IR_ERROR_CODE);
+}
+
+static int
+aw_ir_validate_code(unsigned long code)
+{
+ unsigned long v1, v2;
+
+ /* Don't check address */
+ v1 = code & CODE_MASK;
+ v2 = (code & INV_CODE_MASK) >> 8;
+
+ if (((v1 ^ v2) & VALID_CODE_MASK) == VALID_CODE_MASK)
+ return (0); /* valid */
+ else
+ return (1); /* invalid */
+}
+
+static void
+aw_ir_intr(void *arg)
+{
+ struct aw_ir_softc *sc;
+ uint32_t val;
+ int i, dcnt;
+ unsigned long ir_code;
+ int stat;
+
+ sc = (struct aw_ir_softc *)arg;
+
+ /* Read RX interrupt status */
+ val = READ(sc, AW_IR_RXSTA);
+
+ /* Clean all pending interrupt statuses */
+ WRITE(sc, AW_IR_RXSTA, val | AW_IR_RXSTA_CLEARALL);
+
+ /* When Rx FIFO Data available or Packet end */
+ if (val & (AW_IR_RXINT_RAI_EN | AW_IR_RXINT_RPEI_EN)) {
+ /* Get available message count in RX FIFO */
+ dcnt = AW_IR_RXSTA_COUNTER(val);
+ /* Read FIFO */
+ for (i = 0; i < dcnt; i++) {
+ if (aw_ir_buf_full(sc)) {
+ if (bootverbose)
+ device_printf(sc->dev,
+ "raw buffer full\n");
+ break;
+ } else
+ aw_ir_buf_write(sc, aw_ir_read_data(sc));
+ }
+ }
+
+ if (val & AW_IR_RXINT_RPEI_EN) {
+ /* RX Packet end */
+ if (bootverbose)
+ device_printf(sc->dev, "RX Packet end\n");
+ ir_code = aw_ir_decode_packets(sc);
+ stat = aw_ir_validate_code(ir_code);
+ if (stat == 0) {
+ evdev_push_event(sc->sc_evdev,
+ EV_MSC, MSC_SCAN, ir_code);
+ evdev_sync(sc->sc_evdev);
+ }
+ if (bootverbose) {
+ device_printf(sc->dev, "Final IR code: %lx\n",
+ ir_code);
+ device_printf(sc->dev, "IR code status: %d\n",
+ stat);
+ }
+ sc->dcnt = 0;
+ }
+ if (val & AW_IR_RXINT_ROI_EN) {
+ /* RX FIFO overflow */
+ if (bootverbose)
+ device_printf(sc->dev, "RX FIFO overflow\n");
+ /* Flush raw buffer */
+ aw_ir_buf_reset(sc);
+ }
+}
+
+static int
+aw_ir_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Allwinner CIR controller");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+aw_ir_attach(device_t dev)
+{
+ struct aw_ir_softc *sc;
+ hwreset_t rst_apb;
+ clk_t clk_ir, clk_gate;
+ int err;
+ uint32_t val = 0;
+
+ clk_ir = clk_gate = NULL;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ if (bus_alloc_resources(dev, aw_ir_spec, sc->res) != 0) {
+ device_printf(dev, "could not allocate memory resource\n");
+ return (ENXIO);
+ }
+
+ switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
+ case A10_IR:
+ sc->fifo_size = 16;
+ break;
+ case A13_IR:
+ sc->fifo_size = 64;
+ break;
+ }
+
+ /* De-assert reset */
+ if (hwreset_get_by_ofw_name(dev, 0, "apb", &rst_apb) == 0) {
+ err = hwreset_deassert(rst_apb);
+ if (err != 0) {
+ device_printf(dev, "cannot de-assert reset\n");
+ goto error;
+ }
+ }
+
+ /* Reset buffer */
+ aw_ir_buf_reset(sc);
+
+ /* Get clocks and enable them */
+ err = clk_get_by_ofw_name(dev, 0, "apb", &clk_gate);
+ if (err != 0) {
+ device_printf(dev, "Cannot get gate clock\n");
+ goto error;
+ }
+ err = clk_get_by_ofw_name(dev, 0, "ir", &clk_ir);
+ if (err != 0) {
+ device_printf(dev, "Cannot get IR clock\n");
+ goto error;
+ }
+ /* Set clock rate */
+ err = clk_set_freq(clk_ir, AW_IR_BASE_CLK, 0);
+ if (err != 0) {
+ device_printf(dev, "cannot set IR clock rate\n");
+ goto error;
+ }
+ /* Enable clocks */
+ err = clk_enable(clk_gate);
+ if (err != 0) {
+ device_printf(dev, "Cannot enable clk gate\n");
+ goto error;
+ }
+ err = clk_enable(clk_ir);
+ if (err != 0) {
+ device_printf(dev, "Cannot enable IR clock\n");
+ goto error;
+ }
+
+ if (bus_setup_intr(dev, sc->res[1],
+ INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_ir_intr, sc,
+ &sc->intrhand)) {
+ bus_release_resources(dev, aw_ir_spec, sc->res);
+ device_printf(dev, "cannot setup interrupt handler\n");
+ return (ENXIO);
+ }
+
+ /* Enable CIR Mode */
+ WRITE(sc, AW_IR_CTL, AW_IR_CTL_MD);
+
+ /*
+ * Set clock sample, filter, idle thresholds.
+ * Frequency sample = 3MHz/128 = 23437.5Hz (42.7us)
+ */
+ val = AW_IR_SAMPLE_128;
+ val |= (AW_IR_RXFILT_VAL | AW_IR_RXIDLE_VAL);
+ val |= (AW_IR_ACTIVE_T | AW_IR_ACTIVE_T_C);
+ WRITE(sc, AW_IR_CIR, val);
+
+ /* Invert Input Signal */
+ WRITE(sc, AW_IR_RXCTL, AW_IR_RXCTL_RPPI);
+
+ /* Clear All RX Interrupt Status */
+ WRITE(sc, AW_IR_RXSTA, AW_IR_RXSTA_CLEARALL);
+
+ /*
+ * Enable RX interrupt in case of overflow, packet end
+ * and FIFO available.
+ * RX FIFO Threshold = FIFO size / 2
+ */
+ WRITE(sc, AW_IR_RXINT, AW_IR_RXINT_ROI_EN | AW_IR_RXINT_RPEI_EN |
+ AW_IR_RXINT_RAI_EN | AW_IR_RXINT_RAL((sc->fifo_size >> 1) - 1));
+
+ /* Enable IR Module */
+ val = READ(sc, AW_IR_CTL);
+ WRITE(sc, AW_IR_CTL, val | AW_IR_CTL_GEN | AW_IR_CTL_RXEN);
+
+ sc->sc_evdev = evdev_alloc();
+ evdev_set_name(sc->sc_evdev, device_get_desc(sc->dev));
+ evdev_set_phys(sc->sc_evdev, device_get_nameunit(sc->dev));
+ evdev_set_id(sc->sc_evdev, BUS_HOST, 0, 0, 0);
+ evdev_support_event(sc->sc_evdev, EV_SYN);
+ evdev_support_event(sc->sc_evdev, EV_MSC);
+ evdev_support_msc(sc->sc_evdev, MSC_SCAN);
+
+ err = evdev_register(sc->sc_evdev);
+ if (err) {
+ device_printf(dev,
+ "failed to register evdev: error=%d\n", err);
+ goto error;
+ }
+
+ return (0);
+error:
+ if (clk_gate != NULL)
+ clk_release(clk_gate);
+ if (clk_ir != NULL)
+ clk_release(clk_ir);
+ if (rst_apb != NULL)
+ hwreset_release(rst_apb);
+ evdev_free(sc->sc_evdev);
+ sc->sc_evdev = NULL; /* Avoid double free */
+
+ bus_release_resources(dev, aw_ir_spec, sc->res);
+ return (ENXIO);
+}
+
+static device_method_t aw_ir_methods[] = {
+ DEVMETHOD(device_probe, aw_ir_probe),
+ DEVMETHOD(device_attach, aw_ir_attach),
+
+ DEVMETHOD_END
+};
+
+static driver_t aw_ir_driver = {
+ "aw_ir",
+ aw_ir_methods,
+ sizeof(struct aw_ir_softc),
+};
+static devclass_t aw_ir_devclass;
+
+DRIVER_MODULE(aw_ir, simplebus, aw_ir_driver, aw_ir_devclass, 0, 0);
+MODULE_DEPEND(aw_ir, evdev, 1, 1, 1);
diff --git a/sys/arm/allwinner/aw_nmi.c b/sys/arm/allwinner/aw_nmi.c
index a281a6b0e0ba..67be72d6b056 100644
--- a/sys/arm/allwinner/aw_nmi.c
+++ b/sys/arm/allwinner/aw_nmi.c
@@ -40,12 +40,11 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#include <dev/fdt/fdt_common.h>
+#include <dev/fdt/fdt_intr.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-
#include "pic_if.h"
#define NMI_IRQ_CTRL_REG 0x0
@@ -155,19 +154,19 @@ aw_nmi_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp,
tripol = cells[1];
switch (tripol) {
- case IRQ_TYPE_EDGE_RISING:
+ case FDT_INTR_EDGE_RISING:
trig = INTR_TRIGGER_EDGE;
pol = INTR_POLARITY_HIGH;
break;
- case IRQ_TYPE_EDGE_FALLING:
+ case FDT_INTR_EDGE_FALLING:
trig = INTR_TRIGGER_EDGE;
pol = INTR_POLARITY_LOW;
break;
- case IRQ_TYPE_LEVEL_HIGH:
+ case FDT_INTR_LEVEL_HIGH:
trig = INTR_TRIGGER_LEVEL;
pol = INTR_POLARITY_HIGH;
break;
- case IRQ_TYPE_LEVEL_LOW:
+ case FDT_INTR_LEVEL_LOW:
trig = INTR_TRIGGER_LEVEL;
pol = INTR_POLARITY_LOW;
break;
diff --git a/sys/arm/allwinner/aw_rsb.c b/sys/arm/allwinner/aw_rsb.c
index 073479420a26..9ea9294ba9c1 100644
--- a/sys/arm/allwinner/aw_rsb.c
+++ b/sys/arm/allwinner/aw_rsb.c
@@ -27,7 +27,7 @@
*/
/*
- * Allwinner RSB (Reduced Serial Bus)
+ * Allwinner RSB (Reduced Serial Bus) and P2WI (Push-Pull Two Wire Interface)
*/
#include <sys/cdefs.h>
@@ -92,8 +92,12 @@ __FBSDID("$FreeBSD$");
#define RSB_ADDR_PMIC_SECONDARY 0x745
#define RSB_ADDR_PERIPH_IC 0xe89
+#define A31_P2WI 1
+#define A23_RSB 2
+
static struct ofw_compat_data compat_data[] = {
- { "allwinner,sun8i-a23-rsb", 1 },
+ { "allwinner,sun6i-a31-p2wi", A31_P2WI },
+ { "allwinner,sun8i-a23-rsb", A23_RSB },
{ NULL, 0 }
};
@@ -131,6 +135,7 @@ struct rsb_softc {
int busy;
uint32_t status;
uint16_t cur_addr;
+ int type;
struct iic_msg *msg;
};
@@ -270,8 +275,8 @@ rsb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
sc = device_get_softc(dev);
/*
- * RSB is not really an I2C or SMBus controller, so there are some
- * restrictions imposed by the driver.
+ * P2WI and RSB are not really I2C or SMBus controllers, so there are
+ * some restrictions imposed by the driver.
*
* Transfers must contain exactly two messages. The first is always
* a write, containing a single data byte offset. Data will either
@@ -284,34 +289,36 @@ rsb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
msgs[0].len != 1 || msgs[1].len > RSB_MAXLEN)
return (EINVAL);
- /* The controller can read or write 1, 2, or 4 bytes at a time. */
- if ((msgs[1].flags & IIC_M_RD) != 0) {
- switch (msgs[1].len) {
- case 1:
- cmd = CMD_RD8;
- break;
- case 2:
- cmd = CMD_RD16;
- break;
- case 4:
- cmd = CMD_RD32;
- break;
- default:
- return (EINVAL);
- }
- } else {
- switch (msgs[1].len) {
- case 1:
- cmd = CMD_WR8;
- break;
- case 2:
- cmd = CMD_WR16;
- break;
- case 4:
- cmd = CMD_WR32;
- break;
- default:
- return (EINVAL);
+ /* The RSB controller can read or write 1, 2, or 4 bytes at a time. */
+ if (sc->type == A23_RSB) {
+ if ((msgs[1].flags & IIC_M_RD) != 0) {
+ switch (msgs[1].len) {
+ case 1:
+ cmd = CMD_RD8;
+ break;
+ case 2:
+ cmd = CMD_RD16;
+ break;
+ case 4:
+ cmd = CMD_RD32;
+ break;
+ default:
+ return (EINVAL);
+ }
+ } else {
+ switch (msgs[1].len) {
+ case 1:
+ cmd = CMD_WR8;
+ break;
+ case 2:
+ cmd = CMD_WR16;
+ break;
+ case 4:
+ cmd = CMD_WR32;
+ break;
+ default:
+ return (EINVAL);
+ }
}
}
@@ -322,13 +329,15 @@ rsb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
sc->status = 0;
/* Select current run-time address if necessary */
- device_addr = msgs[0].slave >> 1;
- if (sc->cur_addr != device_addr) {
- error = rsb_set_rta(dev, device_addr);
- if (error != 0)
- goto done;
- sc->cur_addr = device_addr;
- sc->status = 0;
+ if (sc->type == A23_RSB) {
+ device_addr = msgs[0].slave >> 1;
+ if (sc->cur_addr != device_addr) {
+ error = rsb_set_rta(dev, device_addr);
+ if (error != 0)
+ goto done;
+ sc->cur_addr = device_addr;
+ sc->status = 0;
+ }
}
/* Clear interrupt status */
@@ -344,8 +353,9 @@ rsb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
RSB_WRITE(sc, RSB_DATA0, data[0]);
}
- /* Set command type */
- RSB_WRITE(sc, RSB_CMD, cmd);
+ /* Set command type for RSB */
+ if (sc->type == A23_RSB)
+ RSB_WRITE(sc, RSB_CMD, cmd);
/* Program data length register and transfer direction */
dlen = msgs[0].len - 1;
@@ -379,10 +389,17 @@ rsb_probe(device_t dev)
if (!ofw_bus_status_okay(dev))
return (ENXIO);
- if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) {
+ case A23_RSB:
+ device_set_desc(dev, "Allwinner RSB");
+ break;
+ case A31_P2WI:
+ device_set_desc(dev, "Allwinner P2WI");
+ break;
+ default:
return (ENXIO);
+ }
- device_set_desc(dev, "Allwinner RSB");
return (BUS_PROBE_DEFAULT);
}
@@ -395,6 +412,8 @@ rsb_attach(device_t dev)
sc = device_get_softc(dev);
mtx_init(&sc->mtx, device_get_nameunit(dev), "rsb", MTX_DEF);
+ sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+
if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) == 0) {
error = clk_enable(sc->clk);
if (error != 0) {
diff --git a/sys/arm/allwinner/aw_thermal.c b/sys/arm/allwinner/aw_thermal.c
index c8bbe3edef9c..12146afd968d 100644
--- a/sys/arm/allwinner/aw_thermal.c
+++ b/sys/arm/allwinner/aw_thermal.c
@@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/reboot.h>
#include <sys/module.h>
+#include <sys/cpu.h>
+#include <sys/taskqueue.h>
#include <machine/bus.h>
#include <dev/ofw/ofw_bus.h>
@@ -51,6 +53,8 @@ __FBSDID("$FreeBSD$");
#include <arm/allwinner/aw_sid.h>
+#include "cpufreq_if.h"
+
#define THS_CTRL0 0x00
#define THS_CTRL1 0x04
#define ADC_CALI_EN (1 << 17)
@@ -70,6 +74,14 @@ __FBSDID("$FreeBSD$");
#define ALARM_INT2_STS (1 << 2)
#define ALARM_INT1_STS (1 << 1)
#define ALARM_INT0_STS (1 << 0)
+#define THS_ALARM0_CTRL 0x50
+#define ALARM_T_HOT_MASK 0xfff
+#define ALARM_T_HOT_SHIFT 16
+#define ALARM_T_HYST_MASK 0xfff
+#define ALARM_T_HYST_SHIFT 0
+#define THS_SHUTDOWN0_CTRL 0x60
+#define SHUT_T_HOT_MASK 0xfff
+#define SHUT_T_HOT_SHIFT 16
#define THS_FILTER 0x70
#define THS_CALIB0 0x74
#define THS_CALIB1 0x78
@@ -97,16 +109,24 @@ __FBSDID("$FreeBSD$");
#define H3_ADC_ACQUIRE_TIME 0x3f
#define H3_FILTER 0x6
#define H3_INTC 0x191000
-#define H3_TEMP_BASE 217000000
-#define H3_TEMP_MUL 121168
-#define H3_TEMP_DIV 1000000
+#define H3_TEMP_BASE 1794000
+#define H3_TEMP_MUL 1000
+#define H3_TEMP_DIV -8253
#define H3_CLK_RATE 4000000
#define TEMP_C_TO_K 273
#define SENSOR_ENABLE_ALL (SENSOR0_EN|SENSOR1_EN|SENSOR2_EN)
#define SHUT_INT_ALL (SHUT_INT0_STS|SHUT_INT1_STS|SHUT_INT2_STS)
+#define ALARM_INT_ALL (ALARM_INT0_STS)
#define MAX_SENSORS 3
+#define MAX_CF_LEVELS 64
+
+#define THROTTLE_ENABLE_DEFAULT 1
+
+/* Enable thermal throttling */
+static int aw_thermal_throttle_enable = THROTTLE_ENABLE_DEFAULT;
+TUNABLE_INT("hw.aw_thermal.throttle_enable", &aw_thermal_throttle_enable);
struct aw_thermal_sensor {
const char *name;
@@ -118,14 +138,23 @@ struct aw_thermal_config {
int nsensors;
uint64_t clk_rate;
uint32_t adc_acquire_time;
+ int adc_cali_en;
uint32_t filter;
uint32_t intc;
+ int (*to_temp)(uint32_t);
int temp_base;
int temp_mul;
int temp_div;
- int calib;
+ int calib0, calib1;
+ uint32_t calib0_mask, calib1_mask;
};
+static int
+a83t_to_temp(uint32_t val)
+{
+ return ((A83T_TEMP_BASE - (val * A83T_TEMP_MUL)) / A83T_TEMP_DIV);
+}
+
static const struct aw_thermal_config a83t_config = {
.nsensors = 3,
.sensors = {
@@ -144,14 +173,22 @@ static const struct aw_thermal_config a83t_config = {
},
.clk_rate = A83T_CLK_RATE,
.adc_acquire_time = A83T_ADC_ACQUIRE_TIME,
+ .adc_cali_en = 1,
.filter = A83T_FILTER,
.intc = A83T_INTC,
- .temp_base = A83T_TEMP_BASE,
- .temp_mul = A83T_TEMP_MUL,
- .temp_div = A83T_TEMP_DIV,
- .calib = 1,
+ .to_temp = a83t_to_temp,
+ .calib0 = 1,
+ .calib0_mask = 0xffffffff,
+ .calib1 = 1,
+ .calib1_mask = 0xffffffff,
};
+static int
+a64_to_temp(uint32_t val)
+{
+ return ((A64_TEMP_BASE - (val * A64_TEMP_MUL)) / A64_TEMP_DIV);
+}
+
static const struct aw_thermal_config a64_config = {
.nsensors = 3,
.sensors = {
@@ -172,11 +209,15 @@ static const struct aw_thermal_config a64_config = {
.adc_acquire_time = A64_ADC_ACQUIRE_TIME,
.filter = A64_FILTER,
.intc = A64_INTC,
- .temp_base = A64_TEMP_BASE,
- .temp_mul = A64_TEMP_MUL,
- .temp_div = A64_TEMP_DIV,
+ .to_temp = a64_to_temp,
};
+static int
+h3_to_temp(uint32_t val)
+{
+ return (((int)(val * H3_TEMP_MUL) - H3_TEMP_BASE) / H3_TEMP_DIV);
+}
+
static const struct aw_thermal_config h3_config = {
.nsensors = 1,
.sensors = {
@@ -189,9 +230,9 @@ static const struct aw_thermal_config h3_config = {
.adc_acquire_time = H3_ADC_ACQUIRE_TIME,
.filter = H3_FILTER,
.intc = H3_INTC,
- .temp_base = H3_TEMP_BASE,
- .temp_mul = H3_TEMP_MUL,
- .temp_div = H3_TEMP_DIV,
+ .to_temp = h3_to_temp,
+ .calib0 = 1,
+ .calib0_mask = 0xfff,
};
static struct ofw_compat_data compat_data[] = {
@@ -205,8 +246,15 @@ static struct ofw_compat_data compat_data[] = {
(void *)ofw_bus_search_compatible((d), compat_data)->ocd_data
struct aw_thermal_softc {
+ device_t dev;
struct resource *res[2];
struct aw_thermal_config *conf;
+
+ struct task cf_task;
+ int throttle;
+ int min_freq;
+ struct cf_level levels[MAX_CF_LEVELS];
+ eventhandler_tag cf_pre_tag;
};
static struct resource_spec aw_thermal_spec[] = {
@@ -224,15 +272,20 @@ aw_thermal_init(struct aw_thermal_softc *sc)
uint32_t calib0, calib1;
int error;
- if (sc->conf->calib) {
+ if (sc->conf->calib0 != 0 || sc->conf->calib1 != 0) {
/* Read calibration settings from SRAM */
error = aw_sid_read_tscalib(&calib0, &calib1);
if (error != 0)
return (error);
+ calib0 &= sc->conf->calib0_mask;
+ calib1 &= sc->conf->calib1_mask;
+
/* Write calibration settings to thermal controller */
- WR4(sc, THS_CALIB0, calib0);
- WR4(sc, THS_CALIB1, calib1);
+ if (sc->conf->calib0 != 0 && calib0 != 0)
+ WR4(sc, THS_CALIB0, calib0);
+ if (sc->conf->calib1 != 0 && calib1 != 0)
+ WR4(sc, THS_CALIB1, calib1);
}
/* Configure ADC acquire time (CLK_IN/(N+1)) and enable sensors */
@@ -245,7 +298,7 @@ aw_thermal_init(struct aw_thermal_softc *sc)
/* Enable interrupts */
WR4(sc, THS_INTS, RD4(sc, THS_INTS));
- WR4(sc, THS_INTC, sc->conf->intc | SHUT_INT_ALL);
+ WR4(sc, THS_INTC, sc->conf->intc | SHUT_INT_ALL | ALARM_INT_ALL);
/* Enable sensors */
WR4(sc, THS_CTRL2, RD4(sc, THS_CTRL2) | SENSOR_ENABLE_ALL);
@@ -254,20 +307,46 @@ aw_thermal_init(struct aw_thermal_softc *sc)
}
static int
-aw_thermal_reg_to_temp(struct aw_thermal_softc *sc, uint32_t val)
+aw_thermal_gettemp(struct aw_thermal_softc *sc, int sensor)
{
- return ((sc->conf->temp_base - (val * sc->conf->temp_mul)) /
- sc->conf->temp_div);
+ uint32_t val;
+
+ val = RD4(sc, THS_DATA0 + (sensor * 4));
+
+ return (sc->conf->to_temp(val) + TEMP_C_TO_K);
}
static int
-aw_thermal_gettemp(struct aw_thermal_softc *sc, int sensor)
+aw_thermal_getshut(struct aw_thermal_softc *sc, int sensor)
{
uint32_t val;
- val = RD4(sc, THS_DATA0 + (sensor * 4));
+ val = RD4(sc, THS_SHUTDOWN0_CTRL + (sensor * 4));
+ val = (val >> SHUT_T_HOT_SHIFT) & SHUT_T_HOT_MASK;
+
+ return (sc->conf->to_temp(val) + TEMP_C_TO_K);
+}
+
+static int
+aw_thermal_gethyst(struct aw_thermal_softc *sc, int sensor)
+{
+ uint32_t val;
+
+ val = RD4(sc, THS_ALARM0_CTRL + (sensor * 4));
+ val = (val >> ALARM_T_HYST_SHIFT) & ALARM_T_HYST_MASK;
- return (aw_thermal_reg_to_temp(sc, val) + TEMP_C_TO_K);
+ return (sc->conf->to_temp(val) + TEMP_C_TO_K);
+}
+
+static int
+aw_thermal_getalarm(struct aw_thermal_softc *sc, int sensor)
+{
+ uint32_t val;
+
+ val = RD4(sc, THS_ALARM0_CTRL + (sensor * 4));
+ val = (val >> ALARM_T_HOT_SHIFT) & ALARM_T_HOT_MASK;
+
+ return (sc->conf->to_temp(val) + TEMP_C_TO_K);
}
static int
@@ -285,6 +364,65 @@ aw_thermal_sysctl(SYSCTL_HANDLER_ARGS)
}
static void
+aw_thermal_throttle(struct aw_thermal_softc *sc, int enable)
+{
+ device_t cf_dev;
+ int count, error;
+
+ if (enable == sc->throttle)
+ return;
+
+ if (enable != 0) {
+ /* Set the lowest available frequency */
+ cf_dev = devclass_get_device(devclass_find("cpufreq"), 0);
+ if (cf_dev == NULL)
+ return;
+ count = MAX_CF_LEVELS;
+ error = CPUFREQ_LEVELS(cf_dev, sc->levels, &count);
+ if (error != 0 || count == 0)
+ return;
+ sc->min_freq = sc->levels[count - 1].total_set.freq;
+ error = CPUFREQ_SET(cf_dev, &sc->levels[count - 1],
+ CPUFREQ_PRIO_USER);
+ if (error != 0)
+ return;
+ }
+
+ sc->throttle = enable;
+}
+
+static void
+aw_thermal_cf_task(void *arg, int pending)
+{
+ struct aw_thermal_softc *sc;
+
+ sc = arg;
+
+ aw_thermal_throttle(sc, 1);
+}
+
+static void
+aw_thermal_cf_pre_change(void *arg, const struct cf_level *level, int *status)
+{
+ struct aw_thermal_softc *sc;
+ int temp_cur, temp_alarm;
+
+ sc = arg;
+
+ if (aw_thermal_throttle_enable == 0 || sc->throttle == 0 ||
+ level->total_set.freq == sc->min_freq)
+ return;
+
+ temp_cur = aw_thermal_gettemp(sc, 0);
+ temp_alarm = aw_thermal_getalarm(sc, 0);
+
+ if (temp_cur < temp_alarm)
+ aw_thermal_throttle(sc, 0);
+ else
+ *status = ENXIO;
+}
+
+static void
aw_thermal_intr(void *arg)
{
struct aw_thermal_softc *sc;
@@ -299,9 +437,12 @@ aw_thermal_intr(void *arg)
if ((ints & SHUT_INT_ALL) != 0) {
device_printf(dev,
- "WARNING - current temperature exceeds safe limits\n");
+ "WARNING - current temperature exceeds safe limits\n");
shutdown_nice(RB_POWEROFF);
}
+
+ if ((ints & ALARM_INT_ALL) != 0)
+ taskqueue_enqueue(taskqueue_thread, &sc->cf_task);
}
static int
@@ -332,6 +473,7 @@ aw_thermal_attach(device_t dev)
ih = NULL;
sc->conf = THS_CONF(dev);
+ TASK_INIT(&sc->cf_task, 0, aw_thermal_cf_task, sc);
if (bus_alloc_resources(dev, aw_thermal_spec, sc->res) != 0) {
device_printf(dev, "cannot allocate resources for device\n");
@@ -383,6 +525,18 @@ aw_thermal_attach(device_t dev)
sc, i, aw_thermal_sysctl, "IK0",
sc->conf->sensors[i].desc);
+ if (bootverbose)
+ for (i = 0; i < sc->conf->nsensors; i++) {
+ device_printf(dev,
+ "#%d: alarm %dC hyst %dC shut %dC\n", i,
+ aw_thermal_getalarm(sc, i) - TEMP_C_TO_K,
+ aw_thermal_gethyst(sc, i) - TEMP_C_TO_K,
+ aw_thermal_getshut(sc, i) - TEMP_C_TO_K);
+ }
+
+ sc->cf_pre_tag = EVENTHANDLER_REGISTER(cpufreq_pre_change,
+ aw_thermal_cf_pre_change, sc, EVENTHANDLER_PRI_FIRST);
+
return (0);
fail:
diff --git a/sys/arm/allwinner/clk/aw_pll.c b/sys/arm/allwinner/clk/aw_pll.c
index b5ee409c95d3..6d159c8eaa0d 100644
--- a/sys/arm/allwinner/clk/aw_pll.c
+++ b/sys/arm/allwinner/clk/aw_pll.c
@@ -47,12 +47,15 @@ __FBSDID("$FreeBSD$");
#include <dev/extres/clk/clk.h>
-#include <dt-bindings/clock/sun4i-a10-pll2.h>
-
#include <arm/allwinner/aw_machdep.h>
#include "clkdev_if.h"
+#define SUN4I_A10_PLL2_1X 0
+#define SUN4I_A10_PLL2_2X 1
+#define SUN4I_A10_PLL2_4X 2
+#define SUN4I_A10_PLL2_8X 3
+
#define AW_PLL_ENABLE (1 << 31)
#define A10_PLL1_OUT_EXT_DIVP (0x3 << 16)
@@ -192,6 +195,16 @@ struct aw_pll_factor {
#define PLLFACTOR(_n, _k, _m, _p, _freq) \
{ .n = (_n), .k = (_k), .m = (_m), .p = (_p), .freq = (_freq) }
+static struct aw_pll_factor aw_a10_pll1_factors[] = {
+ PLLFACTOR(6, 0, 0, 0, 144000000),
+ PLLFACTOR(12, 0, 0, 0, 312000000),
+ PLLFACTOR(21, 0, 0, 0, 528000000),
+ PLLFACTOR(29, 0, 0, 0, 720000000),
+ PLLFACTOR(18, 1, 0, 0, 864000000),
+ PLLFACTOR(19, 1, 0, 0, 912000000),
+ PLLFACTOR(20, 1, 0, 0, 960000000),
+};
+
static struct aw_pll_factor aw_a23_pll1_factors[] = {
PLLFACTOR(9, 0, 0, 2, 60000000),
PLLFACTOR(10, 0, 0, 2, 66000000),
@@ -300,6 +313,38 @@ struct aw_pll_funcs {
#define DEVICE_UNLOCK(sc) CLKDEV_DEVICE_UNLOCK((sc)->clkdev)
static int
+a10_pll1_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
+ int flags)
+{
+ struct aw_pll_factor *f;
+ uint32_t val;
+ int n;
+
+ f = NULL;
+ for (n = 0; n < nitems(aw_a10_pll1_factors); n++) {
+ if (aw_a10_pll1_factors[n].freq == *fout) {
+ f = &aw_a10_pll1_factors[n];
+ break;
+ }
+ }
+ if (f == NULL)
+ return (EINVAL);
+
+ DEVICE_LOCK(sc);
+ PLL_READ(sc, &val);
+ val &= ~(A10_PLL1_FACTOR_N|A10_PLL1_FACTOR_K|A10_PLL1_FACTOR_M|
+ A10_PLL1_OUT_EXT_DIVP);
+ val |= (f->p << A10_PLL1_OUT_EXT_DIVP_SHIFT);
+ val |= (f->n << A10_PLL1_FACTOR_N_SHIFT);
+ val |= (f->k << A10_PLL1_FACTOR_K_SHIFT);
+ val |= (f->m << A10_PLL1_FACTOR_M_SHIFT);
+ PLL_WRITE(sc, val);
+ DEVICE_UNLOCK(sc);
+
+ return (0);
+}
+
+static int
a10_pll1_recalc(struct aw_pll_sc *sc, uint64_t *freq)
{
uint32_t val, m, n, k, p;
@@ -948,7 +993,7 @@ a83t_pllcpux_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
}
static struct aw_pll_funcs aw_pll_func[] = {
- PLL(AWPLL_A10_PLL1, a10_pll1_recalc, NULL, NULL),
+ PLL(AWPLL_A10_PLL1, a10_pll1_recalc, a10_pll1_set_freq, NULL),
PLL(AWPLL_A10_PLL2, a10_pll2_recalc, a10_pll2_set_freq, NULL),
PLL(AWPLL_A10_PLL3, a10_pll3_recalc, a10_pll3_set_freq, a10_pll3_init),
PLL(AWPLL_A10_PLL5, a10_pll5_recalc, NULL, NULL),
diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner
index d06f6aebbe8f..d4e6a88456c7 100644
--- a/sys/arm/allwinner/files.allwinner
+++ b/sys/arm/allwinner/files.allwinner
@@ -12,7 +12,7 @@ arm/allwinner/a10_mmc.c optional mmc
arm/allwinner/a10_sramc.c standard
arm/allwinner/aw_nmi.c optional intrng
arm/allwinner/aw_if_dwc.c optional dwc
-arm/allwinner/aw_rsb.c optional rsb
+arm/allwinner/aw_rsb.c optional rsb | p2wi
arm/allwinner/aw_rtc.c standard
arm/allwinner/aw_ts.c standard
arm/allwinner/aw_wdog.c standard
@@ -29,6 +29,7 @@ dev/usb/controller/generic_usb_if.m optional ohci
arm/allwinner/aw_sid.c standard
arm/allwinner/aw_thermal.c standard
dev/iicbus/sy8106a.c optional sy8106a
+arm/allwinner/aw_cir.c optional aw_cir evdev
#arm/allwinner/console.c standard
arm/allwinner/a10_fb.c optional vt
diff --git a/sys/arm/arm/cpufunc_asm_arm11x6.S b/sys/arm/arm/cpufunc_asm_arm11x6.S
index 02a698e650cd..8346211ec21e 100644
--- a/sys/arm/arm/cpufunc_asm_arm11x6.S
+++ b/sys/arm/arm/cpufunc_asm_arm11x6.S
@@ -64,14 +64,6 @@ __FBSDID("$FreeBSD$");
.cpu arm1176jz-s
-ENTRY(arm11x6_setttb)
- mov r1, #0
- mcr p15, 0, r0, c2, c0, 0 /* load new TTB */
- mcr p15, 0, r1, c8, c7, 0 /* invalidate I+D TLBs */
- mcr p15, 0, r1, c7, c10, 4 /* drain write buffer */
- RET
-END(arm11x6_setttb)
-
/*
* Preload the cache before issuing the WFI by conditionally disabling the
* mcr intstructions the first time around the loop. Ensure the function is
diff --git a/sys/arm/arm/cpufunc_asm_armv7.S b/sys/arm/arm/cpufunc_asm_armv7.S
index d086fa893ea2..c6f14fe78da8 100644
--- a/sys/arm/arm/cpufunc_asm_armv7.S
+++ b/sys/arm/arm/cpufunc_asm_armv7.S
@@ -37,56 +37,16 @@ __FBSDID("$FreeBSD$");
.cpu cortex-a8
+#ifdef ELF_TRAMPOLINE
.Lcoherency_level:
.word _C_LABEL(arm_cache_loc)
.Lcache_type:
.word _C_LABEL(arm_cache_type)
-.Larmv7_dcache_line_size:
- .word _C_LABEL(arm_dcache_min_line_size)
-.Larmv7_icache_line_size:
- .word _C_LABEL(arm_icache_min_line_size)
-.Larmv7_idcache_line_size:
- .word _C_LABEL(arm_idcache_min_line_size)
.Lway_mask:
.word 0x3ff
.Lmax_index:
.word 0x7fff
-.Lpage_mask:
- .word 0xfff
-
-#define PT_NOS (1 << 5)
-#define PT_S (1 << 1)
-#define PT_INNER_NC 0
-#define PT_INNER_WT (1 << 0)
-#define PT_INNER_WB ((1 << 0) | (1 << 6))
-#define PT_INNER_WBWA (1 << 6)
-#define PT_OUTER_NC 0
-#define PT_OUTER_WT (2 << 3)
-#define PT_OUTER_WB (3 << 3)
-#define PT_OUTER_WBWA (1 << 3)
-#ifdef SMP
-#define PT_ATTR (PT_S|PT_INNER_WBWA|PT_OUTER_WBWA|PT_NOS)
-#else
-#define PT_ATTR (PT_INNER_WBWA|PT_OUTER_WBWA)
-#endif
-
-ENTRY(armv7_setttb)
- dsb
- orr r0, r0, #PT_ATTR
- mcr CP15_TTBR0(r0)
- isb
-#ifdef SMP
- mcr CP15_TLBIALLIS
-#else
- mcr CP15_TLBIALL
-#endif
- dsb
- isb
- RET
-END(armv7_setttb)
-
-#ifdef ELF_TRAMPOLINE
/* Based on algorithm from ARM Architecture Reference Manual */
ENTRY(armv7_dcache_wbinv_all)
stmdb sp!, {r4, r5, r6, r7, r8, r9}
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index d67f9c6ced68..91ccf31635f5 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <machine/smp.h>
#include <dev/fdt/fdt_common.h>
+#include <dev/fdt/fdt_intr.h>
#include <dev/ofw/ofw_bus_subr.h>
#include <arm/arm/gic.h>
@@ -821,13 +822,15 @@ gic_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp,
}
tripol = cells[2] & 0xff;
- if (tripol & 0xf0 || (tripol & 0x0a && cells[0] == 0))
+ if (tripol & 0xf0 || (tripol & FDT_INTR_LOW_MASK &&
+ cells[0] == 0))
device_printf(dev, "unsupported trigger/polarity "
"configuration 0x%02x\n", tripol);
*irqp = irq;
*polp = INTR_POLARITY_CONFORM;
- *trigp = tripol & 0x03 ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL;
+ *trigp = tripol & FDT_INTR_EDGE_MASK ?
+ INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL;
return (0);
}
return (EINVAL);
diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC
index 61b53ec35e18..dfc1b31bd021 100644
--- a/sys/arm/conf/GENERIC
+++ b/sys/arm/conf/GENERIC
@@ -59,6 +59,9 @@ device phy
device hwreset
device regulator
+# CPU frequency control
+device cpufreq
+
# Interrupt controller
options INTRNG
device gic
@@ -103,17 +106,25 @@ device psci
device iicbus
device iic
device twsi
-device rsb
+device rsb # Allwinner Reduced Serial Bus
+device p2wi # Allwinner Push-Pull Two Wire
device axp209 # AXP209 Power Management Unit
device axp81x # AXP813/818 Power Management Unit
device bcm2835_bsc
device icee
+device sy8106a # SY8106A Buck Regulator
# GPIO
device gpio
device gpioled
device gpioregulator
+# EVDEV support
+device evdev # input event device support
+options EVDEV_SUPPORT # evdev support in legacy drivers
+device uinput # install /dev/uinput cdev
+device aw_cir
+
# SPI
device spibus
device bcm2835_spi
diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h
index aa2ec2618164..e11e0f766fbb 100644
--- a/sys/arm/include/cpu-v6.h
+++ b/sys/arm/include/cpu-v6.h
@@ -347,12 +347,21 @@ tlb_flush_range_local(vm_offset_t va, vm_size_t size)
/* Broadcasting operations. */
#if __ARM_ARCH >= 7 && defined SMP
+#if defined(CPU_CORTEXA8)
+#define ARM_HAVE_MP_EXTENSIONS (cpuinfo.mp_ext != 0)
+#else
+#define ARM_HAVE_MP_EXTENSIONS 1
+#endif
+
static __inline void
tlb_flush_all(void)
{
dsb();
- _CP15_TLBIALLIS();
+ if (ARM_HAVE_MP_EXTENSIONS)
+ _CP15_TLBIALLIS();
+ else
+ _CP15_TLBIALL();
dsb();
}
@@ -361,7 +370,10 @@ tlb_flush_all_ng(void)
{
dsb();
- _CP15_TLBIASIDIS(CPU_ASID_KERNEL);
+ if (ARM_HAVE_MP_EXTENSIONS)
+ _CP15_TLBIASIDIS(CPU_ASID_KERNEL);
+ else
+ _CP15_TLBIASID(CPU_ASID_KERNEL);
dsb();
}
@@ -372,7 +384,10 @@ tlb_flush(vm_offset_t va)
KASSERT((va & PAGE_MASK) == 0, ("%s: va %#x not aligned", __func__, va));
dsb();
- _CP15_TLBIMVAAIS(va);
+ if (ARM_HAVE_MP_EXTENSIONS)
+ _CP15_TLBIMVAAIS(va);
+ else
+ _CP15_TLBIMVA(va | CPU_ASID_KERNEL);
dsb();
}
@@ -386,8 +401,13 @@ tlb_flush_range(vm_offset_t va, vm_size_t size)
size));
dsb();
- for (; va < eva; va += PAGE_SIZE)
- _CP15_TLBIMVAAIS(va);
+ if (ARM_HAVE_MP_EXTENSIONS) {
+ for (; va < eva; va += PAGE_SIZE)
+ _CP15_TLBIMVAAIS(va);
+ } else {
+ for (; va < eva; va += PAGE_SIZE)
+ _CP15_TLBIMVA(va | CPU_ASID_KERNEL);
+ }
dsb();
}
#else /* SMP */
@@ -411,19 +431,23 @@ icache_sync(vm_offset_t va, vm_size_t size)
dsb();
va &= ~cpuinfo.dcache_line_mask;
- for ( ; va < eva; va += cpuinfo.dcache_line_size) {
#if __ARM_ARCH >= 7 && defined SMP
- _CP15_DCCMVAU(va);
-#else
- _CP15_DCCMVAC(va);
+ if (ARM_HAVE_MP_EXTENSIONS) {
+ for ( ; va < eva; va += cpuinfo.dcache_line_size)
+ _CP15_DCCMVAU(va);
+ } else
#endif
+ {
+ for ( ; va < eva; va += cpuinfo.dcache_line_size)
+ _CP15_DCCMVAC(va);
}
dsb();
#if __ARM_ARCH >= 7 && defined SMP
- _CP15_ICIALLUIS();
-#else
- _CP15_ICIALLU();
+ if (ARM_HAVE_MP_EXTENSIONS)
+ _CP15_ICIALLUIS();
+ else
#endif
+ _CP15_ICIALLU();
dsb();
isb();
}
@@ -433,10 +457,11 @@ static __inline void
icache_inv_all(void)
{
#if __ARM_ARCH >= 7 && defined SMP
- _CP15_ICIALLUIS();
-#else
- _CP15_ICIALLU();
+ if (ARM_HAVE_MP_EXTENSIONS)
+ _CP15_ICIALLUIS();
+ else
#endif
+ _CP15_ICIALLU();
dsb();
isb();
}
@@ -446,10 +471,11 @@ static __inline void
bpb_inv_all(void)
{
#if __ARM_ARCH >= 7 && defined SMP
- _CP15_BPIALLIS();
-#else
- _CP15_BPIALL();
+ if (ARM_HAVE_MP_EXTENSIONS)
+ _CP15_BPIALLIS();
+ else
#endif
+ _CP15_BPIALL();
dsb();
isb();
}
@@ -462,12 +488,15 @@ dcache_wb_pou(vm_offset_t va, vm_size_t size)
dsb();
va &= ~cpuinfo.dcache_line_mask;
- for ( ; va < eva; va += cpuinfo.dcache_line_size) {
#if __ARM_ARCH >= 7 && defined SMP
- _CP15_DCCMVAU(va);
-#else
- _CP15_DCCMVAC(va);
+ if (ARM_HAVE_MP_EXTENSIONS) {
+ for ( ; va < eva; va += cpuinfo.dcache_line_size)
+ _CP15_DCCMVAU(va);
+ } else
#endif
+ {
+ for ( ; va < eva; va += cpuinfo.dcache_line_size)
+ _CP15_DCCMVAC(va);
}
dsb();
}
diff --git a/sys/arm/include/cpufunc.h b/sys/arm/include/cpufunc.h
index 7a007284a48b..a4039258455b 100644
--- a/sys/arm/include/cpufunc.h
+++ b/sys/arm/include/cpufunc.h
@@ -279,14 +279,11 @@ void armv6_idcache_wbinv_all (void);
#endif
#if defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || \
defined(CPU_MV_PJ4B) || defined(CPU_KRAIT)
-void armv7_setttb (u_int);
void armv7_idcache_wbinv_all (void);
void armv7_cpu_sleep (int);
void armv7_setup (void);
void armv7_drain_writebuf (void);
-void armadaxp_idcache_wbinv_all (void);
-
void cortexa_setup (void);
#endif
#if defined(CPU_MV_PJ4B)
@@ -297,7 +294,6 @@ void pj4bv7_setup (void);
#if defined(CPU_ARM1176)
void arm11_drain_writebuf (void);
-void arm11x6_setttb (u_int);
void arm11x6_setup (void);
void arm11x6_sleep (int); /* no ref. for errata */
#endif
diff --git a/sys/arm/include/platformvar.h b/sys/arm/include/platformvar.h
index 607e00f99aa8..a80f628c6d5c 100644
--- a/sys/arm/include/platformvar.h
+++ b/sys/arm/include/platformvar.h
@@ -93,7 +93,7 @@ extern platform_method_t fdt_platform_methods[];
#ifdef MULTIDELAY
#define FDT_PLATFORM_CTASSERT(delay) CTASSERT(delay > 0)
#else
-#define FDT_PLATFORM_CTASSERT(delay) CTASSERT(delay == 0)
+#define FDT_PLATFORM_CTASSERT(delay)
#endif
#define FDT_PLATFORM_DEF2(NAME, VAR_NAME, NAME_STR, size, compatible, \
diff --git a/sys/arm/ti/am335x/am335x_dmtimer.c b/sys/arm/ti/am335x/am335x_dmtimer.c
index dd286cfb68c3..9d28565fa1f3 100644
--- a/sys/arm/ti/am335x/am335x_dmtimer.c
+++ b/sys/arm/ti/am335x/am335x_dmtimer.c
@@ -38,6 +38,10 @@ __FBSDID("$FreeBSD$");
#include <sys/timetc.h>
#include <machine/bus.h>
+#ifdef MULTIDELAY
+#include <machine/machdep.h> /* For arm_set_delay */
+#endif
+
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
@@ -67,6 +71,8 @@ struct am335x_dmtimer_softc {
static struct am335x_dmtimer_softc *am335x_dmtimer_et_sc = NULL;
static struct am335x_dmtimer_softc *am335x_dmtimer_tc_sc = NULL;
+static void am335x_dmtimer_delay(int, void *);
+
/*
* We use dmtimer2 for eventtimer and dmtimer3 for timecounter.
*/
@@ -235,6 +241,10 @@ am335x_dmtimer_tc_init(struct am335x_dmtimer_softc *sc)
am335x_dmtimer_tc_sc = sc;
tc_init(&sc->func.tc);
+#ifdef MULTIDELAY
+ arm_set_delay(am335x_dmtimer_delay, sc);
+#endif
+
return (0);
}
@@ -328,23 +338,13 @@ static devclass_t am335x_dmtimer_devclass;
DRIVER_MODULE(am335x_dmtimer, simplebus, am335x_dmtimer_driver, am335x_dmtimer_devclass, 0, 0);
MODULE_DEPEND(am335x_dmtimer, am335x_prcm, 1, 1, 1);
-void
-DELAY(int usec)
+static void
+am335x_dmtimer_delay(int usec, void *arg)
{
- struct am335x_dmtimer_softc *sc;
+ struct am335x_dmtimer_softc *sc = arg;
int32_t counts;
uint32_t first, last;
- sc = am335x_dmtimer_tc_sc;
-
- if (sc == NULL) {
- for (; usec > 0; usec--)
- for (counts = 200; counts > 0; counts--)
- /* Prevent gcc from optimizing out the loop */
- cpufunc_nullop();
- return;
- }
-
/* Get the number of times to count */
counts = (usec + 1) * (sc->sysclk_freq / 1000000);
@@ -361,3 +361,19 @@ DELAY(int usec)
}
}
+#ifndef MULTIDELAY
+void
+DELAY(int usec)
+{
+ int32_t counts;
+
+ if (am335x_dmtimer_tc_sc == NULL) {
+ for (; usec > 0; usec--)
+ for (counts = 200; counts > 0; counts--)
+ /* Prevent gcc from optimizing out the loop */
+ cpufunc_nullop();
+ return;
+ } else
+ am335x_dmtimer_delay(usec, am335x_dmtimer_tc_sc);
+}
+#endif
diff --git a/sys/arm/ti/ti_machdep.c b/sys/arm/ti/ti_machdep.c
index 0e10f765ff15..f9d83890ba86 100644
--- a/sys/arm/ti/ti_machdep.c
+++ b/sys/arm/ti/ti_machdep.c
@@ -124,5 +124,5 @@ static platform_method_t am335x_methods[] = {
PLATFORMMETHOD_END,
};
-FDT_PLATFORM_DEF(am335x, "am335x", 0, "ti,am335x", 0);
+FDT_PLATFORM_DEF(am335x, "am335x", 0, "ti,am335x", 200);
#endif
diff --git a/sys/arm64/arm64/bcopy.c b/sys/arm64/arm64/bcopy.c
deleted file mode 100644
index 613ca97e5430..000000000000
--- a/sys/arm64/arm64/bcopy.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * 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. 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.
- *
- * From: sys/powerpc/powerpc/bcopy.c
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/param.h>
-#include <sys/systm.h>
-
-/*
- * sizeof(word) MUST BE A POWER OF TWO
- * SO THAT wmask BELOW IS ALL ONES
- */
-typedef long word; /* "word" used for optimal copy speed */
-
-#define wsize sizeof(word)
-#define wmask (wsize - 1)
-
-/*
- * Copy a block of memory, handling overlap.
- * This is the routine that actually implements
- * (the portable versions of) bcopy, memcpy, and memmove.
- */
-void *
-memcpy(void *dst0, const void *src0, size_t length)
-{
- char *dst;
- const char *src;
- size_t t;
-
- dst = dst0;
- src = src0;
-
- if (length == 0 || dst == src) { /* nothing to do */
- goto done;
- }
-
- /*
- * Macros: loop-t-times; and loop-t-times, t>0
- */
-#define TLOOP(s) if (t) TLOOP1(s)
-#define TLOOP1(s) do { s; } while (--t)
-
- if ((unsigned long)dst < (unsigned long)src) {
- /*
- * Copy forward.
- */
- t = (size_t)src; /* only need low bits */
-
- if ((t | (uintptr_t)dst) & wmask) {
- /*
- * Try to align operands. This cannot be done
- * unless the low bits match.
- */
- if ((t ^ (uintptr_t)dst) & wmask || length < wsize) {
- t = length;
- } else {
- t = wsize - (t & wmask);
- }
-
- length -= t;
- TLOOP1(*dst++ = *src++);
- }
- /*
- * Copy whole words, then mop up any trailing bytes.
- */
- t = length / wsize;
- TLOOP(*(word *)dst = *(const word *)src; src += wsize;
- dst += wsize);
- t = length & wmask;
- TLOOP(*dst++ = *src++);
- } else {
- /*
- * Copy backwards. Otherwise essentially the same.
- * Alignment works as before, except that it takes
- * (t&wmask) bytes to align, not wsize-(t&wmask).
- */
- src += length;
- dst += length;
- t = (uintptr_t)src;
-
- if ((t | (uintptr_t)dst) & wmask) {
- if ((t ^ (uintptr_t)dst) & wmask || length <= wsize) {
- t = length;
- } else {
- t &= wmask;
- }
-
- length -= t;
- TLOOP1(*--dst = *--src);
- }
- t = length / wsize;
- TLOOP(src -= wsize; dst -= wsize;
- *(word *)dst = *(const word *)src);
- t = length & wmask;
- TLOOP(*--dst = *--src);
- }
-done:
- return (dst0);
-}
-
-void
-bcopy(const void *src0, void *dst0, size_t length)
-{
-
- memcpy(dst0, src0, length);
-}
-
diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c
index 0110ebd734f2..fea4b2d42820 100644
--- a/sys/arm64/arm64/gic_v3.c
+++ b/sys/arm64/arm64/gic_v3.c
@@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#ifdef FDT
+#include <dev/fdt/fdt_intr.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
@@ -470,20 +471,20 @@ gic_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp,
return (EINVAL);
}
- switch (cells[2] & 0xf) {
- case 1:
+ switch (cells[2] & FDT_INTR_MASK) {
+ case FDT_INTR_EDGE_RISING:
*trigp = INTR_TRIGGER_EDGE;
*polp = INTR_POLARITY_HIGH;
break;
- case 2:
+ case FDT_INTR_EDGE_FALLING:
*trigp = INTR_TRIGGER_EDGE;
*polp = INTR_POLARITY_LOW;
break;
- case 4:
+ case FDT_INTR_LEVEL_HIGH:
*trigp = INTR_TRIGGER_LEVEL;
*polp = INTR_POLARITY_HIGH;
break;
- case 8:
+ case FDT_INTR_LEVEL_LOW:
*trigp = INTR_TRIGGER_LEVEL;
*polp = INTR_POLARITY_LOW;
break;
diff --git a/sys/arm64/arm64/memcpy.S b/sys/arm64/arm64/memcpy.S
new file mode 100644
index 000000000000..f98c2513fa58
--- /dev/null
+++ b/sys/arm64/arm64/memcpy.S
@@ -0,0 +1,219 @@
+/* Copyright (c) 2012, Linaro Limited
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Linaro 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 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
+ HOLDER 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) 2015 ARM Ltd
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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 <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+/* Assumptions:
+ *
+ * ARMv8-a, AArch64, unaligned accesses.
+ *
+ */
+
+#define dstin x0
+#define src x1
+#define count x2
+#define dst x3
+#define srcend x4
+#define dstend x5
+#define A_l x6
+#define A_lw w6
+#define A_h x7
+#define A_hw w7
+#define B_l x8
+#define B_lw w8
+#define B_h x9
+#define C_l x10
+#define C_h x11
+#define D_l x12
+#define D_h x13
+#define E_l src
+#define E_h count
+#define F_l srcend
+#define F_h dst
+#define tmp1 x9
+
+#define L(l) .L ## l
+
+/* Copies are split into 3 main cases: small copies of up to 16 bytes,
+ medium copies of 17..96 bytes which are fully unrolled. Large copies
+ of more than 96 bytes align the destination and use an unrolled loop
+ processing 64 bytes per iteration.
+ Small and medium copies read all data before writing, allowing any
+ kind of overlap, and memmove tailcalls memcpy for these cases as
+ well as non-overlapping copies.
+*/
+
+ENTRY(memcpy)
+ prfm PLDL1KEEP, [src]
+ add srcend, src, count
+ add dstend, dstin, count
+ cmp count, 16
+ b.ls L(copy16)
+ cmp count, 96
+ b.hi L(copy_long)
+
+ /* Medium copies: 17..96 bytes. */
+ sub tmp1, count, 1
+ ldp A_l, A_h, [src]
+ tbnz tmp1, 6, L(copy96)
+ ldp D_l, D_h, [srcend, -16]
+ tbz tmp1, 5, 1f
+ ldp B_l, B_h, [src, 16]
+ ldp C_l, C_h, [srcend, -32]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstend, -32]
+1:
+ stp A_l, A_h, [dstin]
+ stp D_l, D_h, [dstend, -16]
+ ret
+
+ .p2align 4
+ /* Small copies: 0..16 bytes. */
+L(copy16):
+ cmp count, 8
+ b.lo 1f
+ ldr A_l, [src]
+ ldr A_h, [srcend, -8]
+ str A_l, [dstin]
+ str A_h, [dstend, -8]
+ ret
+ .p2align 4
+1:
+ tbz count, 2, 1f
+ ldr A_lw, [src]
+ ldr A_hw, [srcend, -4]
+ str A_lw, [dstin]
+ str A_hw, [dstend, -4]
+ ret
+
+ /* Copy 0..3 bytes. Use a branchless sequence that copies the same
+ byte 3 times if count==1, or the 2nd byte twice if count==2. */
+1:
+ cbz count, 2f
+ lsr tmp1, count, 1
+ ldrb A_lw, [src]
+ ldrb A_hw, [srcend, -1]
+ ldrb B_lw, [src, tmp1]
+ strb A_lw, [dstin]
+ strb B_lw, [dstin, tmp1]
+ strb A_hw, [dstend, -1]
+2: ret
+
+ .p2align 4
+ /* Copy 64..96 bytes. Copy 64 bytes from the start and
+ 32 bytes from the end. */
+L(copy96):
+ ldp B_l, B_h, [src, 16]
+ ldp C_l, C_h, [src, 32]
+ ldp D_l, D_h, [src, 48]
+ ldp E_l, E_h, [srcend, -32]
+ ldp F_l, F_h, [srcend, -16]
+ stp A_l, A_h, [dstin]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstin, 32]
+ stp D_l, D_h, [dstin, 48]
+ stp E_l, E_h, [dstend, -32]
+ stp F_l, F_h, [dstend, -16]
+ ret
+
+ /* Align DST to 16 byte alignment so that we don't cross cache line
+ boundaries on both loads and stores. There are at least 96 bytes
+ to copy, so copy 16 bytes unaligned and then align. The loop
+ copies 64 bytes per iteration and prefetches one iteration ahead. */
+
+ .p2align 4
+L(copy_long):
+ and tmp1, dstin, 15
+ bic dst, dstin, 15
+ ldp D_l, D_h, [src]
+ sub src, src, tmp1
+ add count, count, tmp1 /* Count is now 16 too large. */
+ ldp A_l, A_h, [src, 16]
+ stp D_l, D_h, [dstin]
+ ldp B_l, B_h, [src, 32]
+ ldp C_l, C_h, [src, 48]
+ ldp D_l, D_h, [src, 64]!
+ subs count, count, 128 + 16 /* Test and readjust count. */
+ b.ls 2f
+1:
+ stp A_l, A_h, [dst, 16]
+ ldp A_l, A_h, [src, 16]
+ stp B_l, B_h, [dst, 32]
+ ldp B_l, B_h, [src, 32]
+ stp C_l, C_h, [dst, 48]
+ ldp C_l, C_h, [src, 48]
+ stp D_l, D_h, [dst, 64]!
+ ldp D_l, D_h, [src, 64]!
+ subs count, count, 64
+ b.hi 1b
+
+ /* Write the last full set of 64 bytes. The remainder is at most 64
+ bytes, so it is safe to always copy 64 bytes from the end even if
+ there is just 1 byte left. */
+2:
+ ldp E_l, E_h, [srcend, -64]
+ stp A_l, A_h, [dst, 16]
+ ldp A_l, A_h, [srcend, -48]
+ stp B_l, B_h, [dst, 32]
+ ldp B_l, B_h, [srcend, -32]
+ stp C_l, C_h, [dst, 48]
+ ldp C_l, C_h, [srcend, -16]
+ stp D_l, D_h, [dst, 64]
+ stp E_l, E_h, [dstend, -64]
+ stp A_l, A_h, [dstend, -48]
+ stp B_l, B_h, [dstend, -32]
+ stp C_l, C_h, [dstend, -16]
+ ret
+END(memcpy)
diff --git a/sys/arm64/arm64/memmove.S b/sys/arm64/arm64/memmove.S
new file mode 100644
index 000000000000..4b99dccc536e
--- /dev/null
+++ b/sys/arm64/arm64/memmove.S
@@ -0,0 +1,150 @@
+/* Copyright (c) 2013, Linaro Limited
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Linaro 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 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
+ HOLDER 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) 2015 ARM Ltd
+ * 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. The name of the company may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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 <machine/asm.h>
+__FBSDID("$FreeBSD$");
+
+/* Assumptions:
+ *
+ * ARMv8-a, AArch64, unaligned accesses
+ */
+
+/* Parameters and result. */
+#define dstin x0
+#define src x1
+#define count x2
+#define srcend x3
+#define dstend x4
+#define tmp1 x5
+#define A_l x6
+#define A_h x7
+#define B_l x8
+#define B_h x9
+#define C_l x10
+#define C_h x11
+#define D_l x12
+#define D_h x13
+#define E_l count
+#define E_h tmp1
+
+/* All memmoves up to 96 bytes are done by memcpy as it supports overlaps.
+ Larger backwards copies are also handled by memcpy. The only remaining
+ case is forward large copies. The destination is aligned, and an
+ unrolled loop processes 64 bytes per iteration.
+*/
+
+ENTRY(bcopy)
+ /* Switch the input pointers when called as bcopy */
+ mov x3, x1
+ mov x1, x0
+ mov x0, x3
+EENTRY(memmove)
+ sub tmp1, dstin, src
+ cmp count, 96
+ ccmp tmp1, count, 2, hi
+ b.hs memcpy
+
+ cbz tmp1, 3f
+ add dstend, dstin, count
+ add srcend, src, count
+
+ /* Align dstend to 16 byte alignment so that we don't cross cache line
+ boundaries on both loads and stores. There are at least 96 bytes
+ to copy, so copy 16 bytes unaligned and then align. The loop
+ copies 64 bytes per iteration and prefetches one iteration ahead. */
+
+ and tmp1, dstend, 15
+ ldp D_l, D_h, [srcend, -16]
+ sub srcend, srcend, tmp1
+ sub count, count, tmp1
+ ldp A_l, A_h, [srcend, -16]
+ stp D_l, D_h, [dstend, -16]
+ ldp B_l, B_h, [srcend, -32]
+ ldp C_l, C_h, [srcend, -48]
+ ldp D_l, D_h, [srcend, -64]!
+ sub dstend, dstend, tmp1
+ subs count, count, 128
+ b.ls 2f
+ nop
+1:
+ stp A_l, A_h, [dstend, -16]
+ ldp A_l, A_h, [srcend, -16]
+ stp B_l, B_h, [dstend, -32]
+ ldp B_l, B_h, [srcend, -32]
+ stp C_l, C_h, [dstend, -48]
+ ldp C_l, C_h, [srcend, -48]
+ stp D_l, D_h, [dstend, -64]!
+ ldp D_l, D_h, [srcend, -64]!
+ subs count, count, 64
+ b.hi 1b
+
+ /* Write the last full set of 64 bytes. The remainder is at most 64
+ bytes, so it is safe to always copy 64 bytes from the start even if
+ there is just 1 byte left. */
+2:
+ ldp E_l, E_h, [src, 48]
+ stp A_l, A_h, [dstend, -16]
+ ldp A_l, A_h, [src, 32]
+ stp B_l, B_h, [dstend, -32]
+ ldp B_l, B_h, [src, 16]
+ stp C_l, C_h, [dstend, -48]
+ ldp C_l, C_h, [src]
+ stp D_l, D_h, [dstend, -64]
+ stp E_l, E_h, [dstin, 48]
+ stp A_l, A_h, [dstin, 32]
+ stp B_l, B_h, [dstin, 16]
+ stp C_l, C_h, [dstin]
+3: ret
+EEND(memmove)
+END(bcopy)
diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c
index 6fbb610dd6c0..4904e6b6a4a1 100644
--- a/sys/arm64/arm64/mp_machdep.c
+++ b/sys/arm64/arm64/mp_machdep.c
@@ -203,6 +203,10 @@ release_aps(void *dummy __unused)
{
int i;
+ /* Only release CPUs if they exist */
+ if (mp_ncpus == 1)
+ return;
+
intr_pic_ipi_setup(IPI_AST, "ast", ipi_ast, NULL);
intr_pic_ipi_setup(IPI_PREEMPT, "preempt", ipi_preempt, NULL);
intr_pic_ipi_setup(IPI_RENDEZVOUS, "rendezvous", ipi_rendezvous, NULL);
@@ -461,9 +465,13 @@ cpu_init_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg)
err = psci_cpu_on(target_cpu, pa, cpuid);
if (err != PSCI_RETVAL_SUCCESS) {
- /* Panic here if INVARIANTS are enabled */
- KASSERT(0, ("Failed to start CPU %u (%lx)\n", id,
- target_cpu));
+ /*
+ * Panic here if INVARIANTS are enabled and PSCI failed to
+ * start the requested CPU. If psci_cpu_on returns PSCI_MISSING
+ * to indicate we are unable to use it to start the given CPU.
+ */
+ KASSERT(err == PSCI_MISSING,
+ ("Failed to start CPU %u (%lx)\n", id, target_cpu));
pcpu_destroy(pcpup);
kmem_free(kernel_arena, (vm_offset_t)dpcpu[cpuid - 1],
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index 07752a90e036..6ae347ef4343 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -250,7 +250,7 @@ print_registers(struct trapframe *frame)
{
u_int reg;
- for (reg = 0; reg < 31; reg++) {
+ for (reg = 0; reg < nitems(frame->tf_x); reg++) {
printf(" %sx%d: %16lx\n", (reg < 10) ? " " : "", reg,
frame->tf_x[reg]);
}
diff --git a/sys/arm64/include/param.h b/sys/arm64/include/param.h
index d4d49554ebdf..69e2c0817911 100644
--- a/sys/arm64/include/param.h
+++ b/sys/arm64/include/param.h
@@ -77,7 +77,7 @@
* CACHE_LINE_SIZE is the compile-time maximum cache line size for an
* architecture. It should be used with appropriate caution.
*/
-#define CACHE_LINE_SHIFT 6
+#define CACHE_LINE_SHIFT 7
#define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT)
#define PAGE_SHIFT 12
diff --git a/sys/boot/Makefile.ficl b/sys/boot/Makefile.ficl
new file mode 100644
index 000000000000..ef9a11de347a
--- /dev/null
+++ b/sys/boot/Makefile.ficl
@@ -0,0 +1,43 @@
+# $FreeBSD$
+
+# Common flags to build FICL related files
+
+FICLDIR?= ${SRCTOP}/sys/boot/ficl
+
+.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32)
+FICL_CPUARCH= i386
+.elif ${MACHINE_ARCH:Mmips64*} != ""
+FICL_CPUARCH= mips64
+.else
+FICL_CPUARCH= ${MACHINE_CPUARCH}
+.endif
+
+.PATH: ${FICLDIR} ${FICLDIR}/${FICL_CPUARCH}
+
+.if ${MACHINE_CPUARCH} == "amd64"
+.if defined(FICL32)
+CFLAGS+= -m32 -I.
+.else
+CFLAGS+= -fPIC
+.endif
+.endif
+
+.if ${MACHINE_ARCH} == "powerpc64"
+CFLAGS+= -m32 -mcpu=powerpc -I.
+.endif
+
+CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${FICL_CPUARCH} \
+ -I${FICLDIR}/../common
+
+.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32)
+.if !exists(machine)
+${SRCS:M*.c:R:S/$/.o/g}: machine
+
+beforedepend ${OBJS}: machine
+.endif
+
+machine: .NOMETA
+ ln -sf ${.CURDIR}/../../i386/include machine
+
+CLEANFILES+= machine
+.endif
diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc
index 480279d7c21e..a7e8ea75561b 100644
--- a/sys/boot/common/Makefile.inc
+++ b/sys/boot/common/Makefile.inc
@@ -18,7 +18,7 @@ SRCS+= load_elf32.c reloc_elf32.c
SRCS+= load_elf64.c reloc_elf64.c
.elif ${MACHINE_CPUARCH} == "sparc64"
SRCS+= load_elf64.c reloc_elf64.c
-.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el"
+.elif ${MACHINE_ARCH:Mmips64*} != ""
SRCS+= load_elf64.c reloc_elf64.c
.elif ${MACHINE} == "mips"
SRCS+= load_elf32.c reloc_elf32.c
@@ -60,6 +60,7 @@ SRCS+= pnp.c
# Forth interpreter
.if defined(BOOT_FORTH)
SRCS+= interp_forth.c
+.include "${SRCTOP}/sys/boot/Makefile.ficl"
.endif
.if defined(BOOT_PROMPT_123)
diff --git a/sys/boot/common/pnp.c b/sys/boot/common/pnp.c
index f7e1c23e5dfc..6197776a1d7d 100644
--- a/sys/boot/common/pnp.c
+++ b/sys/boot/common/pnp.c
@@ -17,7 +17,9 @@ __FBSDID("$FreeBSD$");
#include <stand.h>
#include <string.h>
#include <bootstrap.h>
+#ifdef BOOT_FORTH
#include "ficl.h"
+#endif
static struct pnpinfo_stql pnp_devices;
static int pnp_devices_initted = 0;
@@ -186,6 +188,7 @@ pnp_eisaformat(u_int8_t *data)
return(idbuf);
}
+#ifdef BOOT_FORTH
void
ficlPnpdevices(FICL_VM *pVM)
{
@@ -230,3 +233,4 @@ static void ficlCompilePnp(FICL_SYSTEM *pSys)
}
FICL_COMPILE_SET(ficlCompilePnp);
+#endif
diff --git a/sys/boot/efi/Makefile b/sys/boot/efi/Makefile
index 21da86f3aaa2..66481f8513fc 100644
--- a/sys/boot/efi/Makefile
+++ b/sys/boot/efi/Makefile
@@ -4,7 +4,7 @@
# In-tree GCC does not support __attribute__((ms_abi)), but gcc newer
# than 4.5 supports it.
-.if ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 404500
+.if ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 40500
.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
.if ${MK_FDT} != "no"
@@ -18,6 +18,6 @@ SUBDIR+= fdt
SUBDIR+= libefi loader boot1
.endif
-.endif # ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 404500
+.endif # ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 40500
.include <bsd.subdir.mk>
diff --git a/sys/boot/efi/Makefile.inc b/sys/boot/efi/Makefile.inc
index 9d457f4a1055..671033c58e80 100644
--- a/sys/boot/efi/Makefile.inc
+++ b/sys/boot/efi/Makefile.inc
@@ -20,6 +20,7 @@ CFLAGS+= -mno-aes
.if ${MACHINE_CPUARCH} == "aarch64"
CFLAGS+= -fshort-wchar
+CFLAGS+= -fPIC
.endif
.include "../Makefile.inc"
diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile
index 9ea2c3333366..d9619bef89db 100644
--- a/sys/boot/efi/libefi/Makefile
+++ b/sys/boot/efi/libefi/Makefile
@@ -1,10 +1,16 @@
# $FreeBSD$
+.include <src.opts.mk>
+
+.if ${MK_FORTH} != "no"
+.include "${.CURDIR}/../../Makefile.ficl"
+.endif
+
LIB= efi
INTERNALLIB=
WARNS?= 2
-SRCS= delay.c devpath.c efi_console.c efinet.c efipart.c env.c errno.c \
+SRCS= delay.c devpath.c efi_console.c efinet.c efipart.c errno.c \
handles.c libefi.c
.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386"
@@ -12,6 +18,9 @@ SRCS+= time.c
.elif ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm"
SRCS+= time_event.c
.endif
+.if ${MK_FORTH} != "no"
+SRCS+= env.c
+.endif
# We implement a slightly non-standard %S in that it always takes a
# CHAR16 that's common in UEFI-land instead of a wchar_t. This only
diff --git a/sys/boot/efi/libefi/env.c b/sys/boot/efi/libefi/env.c
index 6cfe491cd1b7..66b947d9b06d 100644
--- a/sys/boot/efi/libefi/env.c
+++ b/sys/boot/efi/libefi/env.c
@@ -26,8 +26,15 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <stand.h>
+#include <string.h>
#include <efi.h>
#include <efilib.h>
+#include <uuid.h>
+#include "bootstrap.h"
+#include "ficl.h"
+
+int efi_variable_support = 1;
/*
* Simple wrappers to the underlying UEFI functions.
@@ -53,3 +60,175 @@ efi_set_variable(CHAR16 *variable_name, EFI_GUID *vendor_guid, UINT32 attributes
{
return RS->SetVariable(variable_name, vendor_guid, attributes, data_size, data);
}
+
+/*
+ * FreeBSD's loader interaction words and extras
+ *
+ * efi-setenv ( value n name n guid n attr -- 0 | -1)
+ * efi-getenv ( guid n addr n -- addr' n' | -1 )
+ * efi-unsetenv ( name n guid n'' -- )
+ */
+
+/*
+ * efi-setenv
+ * efi-setenv ( value n name n guid n attr -- 0 | -1)
+ *
+ * Set environment variables using the SetVariable EFI runtime service.
+ *
+ * Value and guid are passed through in binary form (so guid needs to be
+ * converted to binary form from its string form). Name is converted from
+ * ASCII to CHAR16. Since ficl doesn't have support for internationalization,
+ * there's no native CHAR16 interface provided.
+ *
+ * attr is an int in the bitmask of the following attributes for this variable.
+ *
+ * 1 Non volatile
+ * 2 Boot service access
+ * 4 Run time access
+ * (corresponding to the same bits in the UEFI spec).
+ */
+void
+ficlEfiSetenv(FICL_VM *pVM)
+{
+#ifndef TESTMAIN
+ char *value = NULL, *guid = NULL;
+ CHAR16 *name = NULL;
+ int i;
+#endif
+ char *namep, *valuep, *guidp;
+ int names, values, guids, attr;
+ int status;
+ uuid_t u;
+ uint32_t ustatus;
+
+#if FICL_ROBUST > 1
+ vmCheckStack(pVM, 6, 0);
+#endif
+ attr = stackPopINT(pVM->pStack);
+ guids = stackPopINT(pVM->pStack);
+ guidp = (char*)stackPopPtr(pVM->pStack);
+ names = stackPopINT(pVM->pStack);
+ namep = (char*)stackPopPtr(pVM->pStack);
+ values = stackPopINT(pVM->pStack);
+ valuep = (char*)stackPopPtr(pVM->pStack);
+
+#ifndef TESTMAIN
+ guid = (char*)ficlMalloc(guids);
+ if (guid == NULL)
+ vmThrowErr(pVM, "Error: out of memory");
+ memcpy(guid, guidp, guids);
+ uuid_from_string(guid, &u, &ustatus);
+ if (ustatus != uuid_s_ok) {
+ stackPushINT(pVM->pStack, -1);
+ goto out;
+ }
+
+ name = (CHAR16 *)ficlMalloc((names + 1) * sizeof(CHAR16));
+ if (name == NULL)
+ vmThrowErr(pVM, "Error: out of memory");
+ for (i = 0; i < names; i++)
+ name[i] = namep[i];
+ name[names] = (CHAR16)0;
+
+ value = (char*)ficlMalloc(values + 1);
+ if (value == NULL)
+ vmThrowErr(pVM, "Error: out of memory");
+ memcpy(value, valuep, values);
+
+ status = efi_set_variable(name, (EFI_GUID *)&u, attr, values, value);
+ if (status == EFI_SUCCESS)
+ stackPushINT(pVM->pStack, 0);
+ else
+ stackPushINT(pVM->pStack, -1);
+out:
+ ficlFree(name);
+ ficlFree(value);
+ ficlFree(guid);
+#endif
+
+ return;
+}
+
+void
+ficlEfiGetenv(FICL_VM *pVM)
+{
+#ifndef TESTMAIN
+ char *name, *value;
+#endif
+ char *namep;
+ int names;
+
+#if FICL_ROBUST > 1
+ vmCheckStack(pVM, 2, 2);
+#endif
+ names = stackPopINT(pVM->pStack);
+ namep = (char*) stackPopPtr(pVM->pStack);
+
+#ifndef TESTMAIN
+ name = (char*) ficlMalloc(names+1);
+ if (name == NULL)
+ vmThrowErr(pVM, "Error: out of memory");
+ strncpy(name, namep, names);
+ name[names] = '\0';
+
+ value = getenv(name);
+ ficlFree(name);
+
+ if(value != NULL) {
+ stackPushPtr(pVM->pStack, value);
+ stackPushINT(pVM->pStack, strlen(value));
+ } else
+#endif
+ stackPushINT(pVM->pStack, -1);
+
+ return;
+}
+
+void
+ficlEfiUnsetenv(FICL_VM *pVM)
+{
+#ifndef TESTMAIN
+ char *name;
+#endif
+ char *namep;
+ int names;
+
+#if FICL_ROBUST > 1
+ vmCheckStack(pVM, 2, 0);
+#endif
+ names = stackPopINT(pVM->pStack);
+ namep = (char*) stackPopPtr(pVM->pStack);
+
+#ifndef TESTMAIN
+ name = (char*) ficlMalloc(names+1);
+ if (name == NULL)
+ vmThrowErr(pVM, "Error: out of memory");
+ strncpy(name, namep, names);
+ name[names] = '\0';
+
+ unsetenv(name);
+ ficlFree(name);
+#endif
+
+ return;
+}
+
+/**************************************************************************
+** Add FreeBSD UEFI platform extensions into the system dictionary
+**************************************************************************/
+void ficlEfiCompilePlatform(FICL_SYSTEM *pSys)
+{
+ FICL_DICT *dp = pSys->dp;
+ assert (dp);
+
+ dictAppendWord(dp, "efi-setenv", ficlEfiSetenv, FW_DEFAULT);
+ dictAppendWord(dp, "efi-getenv", ficlEfiGetenv, FW_DEFAULT);
+ dictAppendWord(dp, "efi-unsetenv", ficlEfiUnsetenv, FW_DEFAULT);
+
+ /* Would like to export the EFI version, but this will do for now */
+ ficlSetEnv(pSys, "efi-boot", 1);
+
+ return;
+}
+
+FICL_COMPILE_SET(ficlEfiCompilePlatform);
diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c
index b5f2fd6bcca1..8bc85d077d3e 100644
--- a/sys/boot/efi/loader/main.c
+++ b/sys/boot/efi/loader/main.c
@@ -55,6 +55,22 @@ extern char bootprog_rev[];
extern char bootprog_date[];
extern char bootprog_maker[];
+#ifdef BOOT_FORTH
+/*
+ * Normally, efi.o from libefi.a would be brought in due to a function we call
+ * there that's defined there. However, none of its functions are callable from
+ * here since it just adds words to the FORTH environment or implement those
+ * words. So, add a reference to a symbol in efi.o to force it to be be brought
+ * in so the init function there gets added to the "compile" linker set happens
+ * correctly.
+ *
+ * This assumes there's no global analysys that notices dummy1 isn't used
+ * anywhere and tries to eliminate it.
+ */
+extern int efi_variable_support;
+int *dummy1 = &efi_variable_support;
+#endif
+
struct arch_switch archsw; /* MI/MD interface boundary */
EFI_GUID acpi = ACPI_TABLE_GUID;
@@ -221,6 +237,11 @@ find_currdev(EFI_LOADED_IMAGE *img, struct devsw **dev, int *unit,
}
}
+ /* Try to fallback on first device */
+ if (devsw[0] != NULL) {
+ *dev = devsw[0];
+ return (0);
+ }
return (ENOENT);
}
@@ -906,8 +927,8 @@ command_efi_show(int argc, char *argv[])
return (rv);
}
- if (argc != 0) {
- printf("Too many args\n");
+ if (argc > 0) {
+ printf("Too many args %d\n", argc);
pager_close();
return (CMD_ERROR);
}
diff --git a/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts b/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts
index e937a93f7c00..6773792a0f2a 100644
--- a/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts
+++ b/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts
@@ -41,3 +41,7 @@
};
};
};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
diff --git a/sys/boot/ficl/Makefile b/sys/boot/ficl/Makefile
index bce9ffa78870..c16b25d8fc90 100644
--- a/sys/boot/ficl/Makefile
+++ b/sys/boot/ficl/Makefile
@@ -1,15 +1,8 @@
# $FreeBSD$
#
-FICLDIR?= ${.CURDIR}
+.include "${.CURDIR}/../Makefile.ficl"
-.if defined(FICL32)
-.PATH: ${FICLDIR}/${MACHINE_CPUARCH:S/amd64/i386/}
-.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el"
-.PATH: ${FICLDIR}/mips64
-.else
-.PATH: ${FICLDIR}/${MACHINE_CPUARCH}
-.endif
BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \
prefix.c search.c stack.c tools.c vm.c words.c
@@ -41,42 +34,6 @@ SOFTWORDS= softcore.fr jhlocal.fr marker.fr freebsd.fr ficllocal.fr \
# Optional OO extension softwords
#SOFTWORDS+= oo.fr classes.fr
-.if ${MACHINE_CPUARCH} == "amd64"
-.if defined(FICL32)
-CFLAGS+= -m32 -I.
-.else
-CFLAGS+= -fPIC
-.endif
-.endif
-
-.if ${MACHINE_ARCH} == "powerpc64"
-CFLAGS+= -m32 -mcpu=powerpc -I.
-.endif
-
-.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32)
-FICL_CPUARCH= i386
-.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el"
-FICL_CPUARCH= mips64
-.else
-FICL_CPUARCH= ${MACHINE_CPUARCH}
-.endif
-
-CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${FICL_CPUARCH} \
- -I${FICLDIR}/../common
-
softcore.c: ${SOFTWORDS} softcore.awk
(cd ${FICLDIR}/softwords; cat ${SOFTWORDS} \
| awk -f softcore.awk -v datestamp="`LC_ALL=C date`") > ${.TARGET}
-
-.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32)
-.if !exists(machine)
-${SRCS:M*.c:R:S/$/.o/g}: machine
-
-beforedepend ${OBJS}: machine
-.endif
-
-machine: .NOMETA
- ln -sf ${.CURDIR}/../../i386/include machine
-
-CLEANFILES+= machine
-.endif
diff --git a/sys/boot/ficl/efi.c b/sys/boot/ficl/efi.c
deleted file mode 100644
index 8a08f7059977..000000000000
--- a/sys/boot/ficl/efi.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/*-
- * Copyright (c) 2014 Netflix, 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$
- */
-
-/*******************************************************************
-** e f i . c
-** Additional words for EFI
-**
-*******************************************************************/
-
-#ifdef TESTMAIN
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#else
-#include <stand.h>
-#endif
-#include "bootstrap.h"
-#include <string.h>
-#include "ficl.h"
-
-/*
- * FreeBSD's loader interaction words and extras
- *
- * efi-setenv ( value n name n guid n attr -- 0 | -1)
- * efi-getenv ( guid n addr n -- addr' n' | -1 )
- * efi-unsetenv ( name n guid n'' -- )
- */
-
-/*
- * efi-setenv
- * efi-setenv ( value n name n guid n attr -- 0 | -1)
- *
- * Set environment variables using the SetVariable EFI runtime service.
- *
- * Value and guid are passed through in binary form (so guid needs to be
- * converted to binary form from its string form). Name is converted from
- * ASCII to CHAR16. Since ficl doesn't have support for internationalization,
- * there's no native CHAR16 interface provided.
- *
- * attr is an int in the bitmask of the following attributes for this variable.
- *
- * 1 Non volatile
- * 2 Boot service access
- * 4 Run time access
- * (corresponding to the same bits in the UEFI spec).
- */
-void
-ficlEfiSetenv(FICL_VM *pVM)
-{
-#ifndef TESTMAIN
- char *value, *guid;
- CHAR16 *name
- int i;
-#endif
- char *namep, *valuep, *guidp;
- int names, values, guids, attr;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 6, 0);
-#endif
- attr = stackPopINT(pVM->pStack);
- guids = stackPopINT(pVM->pStack);
- guidp = (char*)stackPopPtr(pVM->pStack);
- names = stackPopINT(pVM->pStack);
- namep = (char*)stackPopPtr(pVM->pStack);
- values = stackPopINT(pVM->pStack);
- valuep = (char*)stackPopPtr(pVM->pStack);
-
-#ifndef TESTMAIN
- guid = (char*)ficlMalloc(guids);
- if (guid != NULL)
- vmThrowErr(pVM, "Error: out of memory");
- memcpy(guid, guidp, guids);
-
- name = (char*)ficlMalloc((names + 1) * sizeof(CHAR16));
- if (name == NULL)
- vmThrowErr(pVM, "Error: out of memory");
- for (i = 0; i < names; i++)
- name[i] = namep[i];
- name[names] = (CHAR16)0;
-
- value = (char*)ficlMalloc(values + 1);
- if (value != NULL)
- vmThrowErr(pVM, "Error: out of memory");
- memcpy(value, valuep, values);
-
- status = efi_set_variable(name, guid, attr, value);
- if (status == EFI_SUCCESS)
- stackPushINT(pVM->pStack, 0);
- else
- stackPushINT(pVM->pStack, -1);
-
- ficlFree(name);
- ficlFree(value);
- ficlFree(guid);
-#endif
-
- return;
-}
-
-void
-ficlEfiGetenv(FICL_VM *pVM)
-{
-#ifndef TESTMAIN
- char *name, *value;
-#endif
- char *namep;
- int names;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 2);
-#endif
- names = stackPopINT(pVM->pStack);
- namep = (char*) stackPopPtr(pVM->pStack);
-
-#ifndef TESTMAIN
- name = (char*) ficlMalloc(names+1);
- if (!name)
- vmThrowErr(pVM, "Error: out of memory");
- strncpy(name, namep, names);
- name[names] = '\0';
-
- value = getenv(name);
- ficlFree(name);
-
- if(value != NULL) {
- stackPushPtr(pVM->pStack, value);
- stackPushINT(pVM->pStack, strlen(value));
- } else
-#endif
- stackPushINT(pVM->pStack, -1);
-
- return;
-}
-
-void
-ficlEfiUnsetenv(FICL_VM *pVM)
-{
-#ifndef TESTMAIN
- char *name;
-#endif
- char *namep;
- int names;
-
-#if FICL_ROBUST > 1
- vmCheckStack(pVM, 2, 0);
-#endif
- names = stackPopINT(pVM->pStack);
- namep = (char*) stackPopPtr(pVM->pStack);
-
-#ifndef TESTMAIN
- name = (char*) ficlMalloc(names+1);
- if (!name)
- vmThrowErr(pVM, "Error: out of memory");
- strncpy(name, namep, names);
- name[names] = '\0';
-
- unsetenv(name);
- ficlFree(name);
-#endif
-
- return;
-}
-/**************************************************************************
-
-** Build FreeBSD platform extensions into the system dictionary
-**************************************************************************/
-void ficlEfiCompilePlatform(FICL_SYSTEM *pSys)
-{
- FICL_DICT *dp = pSys->dp;
- assert (dp);
-
- dictAppendWord(dp, "efi-setenv", ficlEfiSetenv, FW_DEFAULT);
- dictAppendWord(dp, "efi-getenv", ficlEfiGetenv, FW_DEFAULT);
- dictAppendWord(dp, "efi-unsetenv", ficlEfiUnsetenv, FW_DEFAULT);
-
- return;
-}
diff --git a/sys/boot/ficl/loader.c b/sys/boot/ficl/loader.c
index 197f15bf38c3..224619065790 100644
--- a/sys/boot/ficl/loader.c
+++ b/sys/boot/ficl/loader.c
@@ -824,9 +824,8 @@ void ficlCompilePlatform(FICL_SYSTEM *pSys)
dictAppendWord(dp, "uuid-from-string", ficlUuidFromString, FW_DEFAULT);
dictAppendWord(dp, "uuid-to-string", ficlUuidToString, FW_DEFAULT);
- SET_FOREACH(fnpp, Xficl_compile_set) {
+ SET_FOREACH(fnpp, Xficl_compile_set)
(*fnpp)(pSys);
- }
#if defined(PC98)
ficlSetEnv(pSys, "arch-pc98", FICL_TRUE);
diff --git a/sys/boot/ficl32/Makefile b/sys/boot/ficl32/Makefile
index 57c44cad90af..b27a339bc2ab 100644
--- a/sys/boot/ficl32/Makefile
+++ b/sys/boot/ficl32/Makefile
@@ -1,8 +1,5 @@
# $FreeBSD$
FICL32=
-FICLDIR= ${.CURDIR}/../ficl
-.PATH: ${FICLDIR}
-
-.include "${FICLDIR}/Makefile"
+.include "${.CURDIR}/../ficl/Makefile"
diff --git a/sys/boot/forth/Makefile.inc b/sys/boot/forth/Makefile.inc
index 97ab433a1b28..d31ff3f26291 100644
--- a/sys/boot/forth/Makefile.inc
+++ b/sys/boot/forth/Makefile.inc
@@ -6,6 +6,7 @@ FILES+= brand-fbsd.4th
FILES+= check-password.4th
FILES+= color.4th
FILES+= delay.4th
+FILES+= efi.4th
FILES+= frames.4th
FILES+= loader.4th
FILES+= loader.conf
diff --git a/sys/boot/forth/efi.4th b/sys/boot/forth/efi.4th
new file mode 100644
index 000000000000..7c1bdf30b8e1
--- /dev/null
+++ b/sys/boot/forth/efi.4th
@@ -0,0 +1,30 @@
+\ Copyright (c) 2016 Netflix, 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$
+
+only forth definitions
+
+\ Place holder for more functions
+.( EFI boot environment) cr
diff --git a/sys/boot/forth/loader.4th b/sys/boot/forth/loader.4th
index 6c2f7b378f6b..013a033b1fcd 100644
--- a/sys/boot/forth/loader.4th
+++ b/sys/boot/forth/loader.4th
@@ -46,6 +46,9 @@ include /boot/support.4th
include /boot/color.4th
include /boot/delay.4th
include /boot/check-password.4th
+s" efi-boot" environment? [if] [if]
+ include /boot/efi.4th
+[then] [then]
only forth definitions
diff --git a/sys/boot/i386/Makefile.inc b/sys/boot/i386/Makefile.inc
index 312a374b9b9b..ac413b27d93d 100644
--- a/sys/boot/i386/Makefile.inc
+++ b/sys/boot/i386/Makefile.inc
@@ -30,7 +30,9 @@ BTXCRT= ${BTXDIR}/lib/crt0.o
# compact binary with no padding between text, data, bss
LDSCRIPT= ${SRCTOP}/sys/boot/i386/boot.ldscript
-LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-T,${LDSCRIPT},-S,--oformat,binary
-LD_FLAGS_BIN=-static -T ${LDSCRIPT} --gc-sections
+# LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-T,${LDSCRIPT},-S,--oformat,binary
+# LD_FLAGS_BIN=-static -T ${LDSCRIPT} --gc-sections
+LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-N,-S,--oformat,binary
+LD_FLAGS_BIN=-static -N --gc-sections
.include "../Makefile.inc"
diff --git a/sys/boot/i386/common/drv.c b/sys/boot/i386/common/drv.c
index f5133debe982..cc75d1ba6d53 100644
--- a/sys/boot/i386/common/drv.c
+++ b/sys/boot/i386/common/drv.c
@@ -91,7 +91,7 @@ drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
return (0);
}
-#ifdef GPT
+#if defined(GPT) || defined(ZFS)
int
drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
{
@@ -114,4 +114,4 @@ drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
}
return (0);
}
-#endif /* GPT */
+#endif /* GPT || ZFS */
diff --git a/sys/boot/i386/common/drv.h b/sys/boot/i386/common/drv.h
index 8ad3c9cd1542..e437cb83bf91 100644
--- a/sys/boot/i386/common/drv.h
+++ b/sys/boot/i386/common/drv.h
@@ -40,9 +40,9 @@ struct dsk {
};
int drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk);
-#ifdef GPT
+#if defined(GPT) || defined(ZFS)
int drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk);
-#endif /* GPT */
+#endif /* GPT || ZFS */
uint64_t drvsize(struct dsk *dskp);
#endif /* !_DRV_H_ */
diff --git a/sys/boot/i386/gptboot/Makefile b/sys/boot/i386/gptboot/Makefile
index 626a42a7bd81..dc447c2b9246 100644
--- a/sys/boot/i386/gptboot/Makefile
+++ b/sys/boot/i386/gptboot/Makefile
@@ -75,7 +75,7 @@ gptboot.bin: gptboot.out
${OBJCOPY} -S -O binary gptboot.out ${.TARGET}
gptboot.out: ${BTXCRT} gptboot.o sio.o crc32.o drv.o cons.o util.o ${OPENCRYPTO_XTS}
- ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBSTAND} ${LIBGELIBOOT}
+ ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBGELIBOOT} ${LIBSTAND}
gptboot.o: ${.CURDIR}/../../common/ufsread.c
diff --git a/sys/boot/i386/gptzfsboot/Makefile b/sys/boot/i386/gptzfsboot/Makefile
index 793eeff30e70..a1d2f93756e9 100644
--- a/sys/boot/i386/gptzfsboot/Makefile
+++ b/sys/boot/i386/gptzfsboot/Makefile
@@ -19,7 +19,7 @@ ORG2= 0x0
CFLAGS= -DBOOTPROG=\"gptzfsboot\" \
-O1 \
- -DGPT -DBOOT2 \
+ -DGPT -DZFS -DBOOT2 \
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
-DSIOFMT=${B2SIOFMT} \
-DSIOSPD=${BOOT_COMCONSOLE_SPEED} \
@@ -78,7 +78,7 @@ gptzfsboot.bin: gptzfsboot.out
gptzfsboot.out: ${BTXCRT} zfsboot.o sio.o gpt.o drv.o cons.o util.o \
skein.o skein_block.o ${OPENCRYPTO_XTS}
- ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBSTAND} ${LIBGELIBOOT}
+ ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBGELIBOOT} ${LIBSTAND}
zfsboot.o: ${.CURDIR}/../../zfs/zfsimpl.c
diff --git a/sys/boot/i386/libi386/biospci.c b/sys/boot/i386/libi386/biospci.c
index 331f1526617e..098e30caa5f1 100644
--- a/sys/boot/i386/libi386/biospci.c
+++ b/sys/boot/i386/libi386/biospci.c
@@ -38,7 +38,9 @@ __FBSDID("$FreeBSD$");
#include <isapnp.h>
#include <btxv86.h>
#include "libi386.h"
+#ifdef BOOT_FORTH
#include "ficl.h"
+#endif
/*
* Stupid PCI BIOS interface doesn't let you simply enumerate everything
@@ -429,6 +431,7 @@ biospci_count_device_type(uint32_t devid)
return i;
}
+#ifdef BOOT_FORTH
/*
* pcibios-device-count (devid -- count)
*
@@ -582,3 +585,4 @@ static void ficlCompilePciBios(FICL_SYSTEM *pSys)
}
FICL_COMPILE_SET(ficlCompilePciBios);
+#endif
diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile
index 233876a52687..7c6397cf5099 100644
--- a/sys/boot/i386/loader/Makefile
+++ b/sys/boot/i386/loader/Makefile
@@ -123,8 +123,8 @@ FILES+= loader.rc menu.rc
# XXX crt0.o needs to be first for pxeboot(8) to work
OBJS= ${BTXCRT}
-DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND} ${LIBGELIBOOT}
-LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND} ${LIBGELIBOOT}
+DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSTAND}
+LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSTAND}
.include <bsd.prog.mk>
diff --git a/sys/boot/i386/zfsboot/Makefile b/sys/boot/i386/zfsboot/Makefile
index 07bb7b7815d7..a4456b83bcba 100644
--- a/sys/boot/i386/zfsboot/Makefile
+++ b/sys/boot/i386/zfsboot/Makefile
@@ -18,7 +18,7 @@ ORG2= 0x2000
CFLAGS= -DBOOTPROG=\"zfsboot\" \
-O1 \
- -DBOOT2 \
+ -DZFS -DBOOT2 \
-DSIOPRT=${BOOT_COMCONSOLE_PORT} \
-DSIOFMT=${B2SIOFMT} \
-DSIOSPD=${BOOT_COMCONSOLE_SPEED} \
diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c
index e372f14e7313..bb64384fadc9 100644
--- a/sys/boot/i386/zfsboot/zfsboot.c
+++ b/sys/boot/i386/zfsboot/zfsboot.c
@@ -119,6 +119,7 @@ struct dmadat {
static struct dmadat *dmadat;
void exit(int);
+void reboot(void);
static void load(void);
static int parse(void);
static void bios_getmem(void);
@@ -175,7 +176,7 @@ zfs_read(spa_t *spa, const dnode_phys_t *dnode, off_t *offp, void *start, size_t
n = size;
if (*offp + n > zp->zp_size)
n = zp->zp_size - *offp;
-
+
rc = dnode_read(spa, dnode, *offp, start, n);
if (rc)
return (-1);
@@ -260,6 +261,35 @@ vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
}
static int
+vdev_write(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
+{
+ char *p;
+ daddr_t lba;
+ unsigned int nb;
+ struct dsk *dsk = (struct dsk *) priv;
+
+ if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1)))
+ return -1;
+
+ p = buf;
+ lba = off / DEV_BSIZE;
+ lba += dsk->start;
+ while (bytes > 0) {
+ nb = bytes / DEV_BSIZE;
+ if (nb > READ_BUF_SIZE / DEV_BSIZE)
+ nb = READ_BUF_SIZE / DEV_BSIZE;
+ memcpy(dmadat->rdbuf, p, nb * DEV_BSIZE);
+ if (drvwrite(dsk, dmadat->rdbuf, lba, nb))
+ return -1;
+ p += nb * DEV_BSIZE;
+ lba += nb;
+ bytes -= nb * DEV_BSIZE;
+ }
+
+ return 0;
+}
+
+static int
xfsread(const dnode_phys_t *dnode, off_t *offp, void *buf, size_t nbyte)
{
if ((size_t)zfs_read(spa, dnode, offp, buf, nbyte) != nbyte) {
@@ -269,6 +299,52 @@ xfsread(const dnode_phys_t *dnode, off_t *offp, void *buf, size_t nbyte)
return 0;
}
+/*
+ * Read Pad2 (formerly "Boot Block Header") area of the first
+ * vdev label of the given vdev.
+ */
+static int
+vdev_read_pad2(vdev_t *vdev, char *buf, size_t size)
+{
+ blkptr_t bp;
+ char *tmp = zap_scratch;
+ off_t off = offsetof(vdev_label_t, vl_pad2);
+
+ if (size > VDEV_PAD_SIZE)
+ size = VDEV_PAD_SIZE;
+
+ BP_ZERO(&bp);
+ BP_SET_LSIZE(&bp, VDEV_PAD_SIZE);
+ BP_SET_PSIZE(&bp, VDEV_PAD_SIZE);
+ BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL);
+ BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF);
+ DVA_SET_OFFSET(BP_IDENTITY(&bp), off);
+ if (vdev_read_phys(vdev, &bp, tmp, off, 0))
+ return (EIO);
+ memcpy(buf, tmp, size);
+ return (0);
+}
+
+static int
+vdev_clear_pad2(vdev_t *vdev)
+{
+ char *zeroes = zap_scratch;
+ uint64_t *end;
+ off_t off = offsetof(vdev_label_t, vl_pad2);
+
+ memset(zeroes, 0, VDEV_PAD_SIZE);
+ end = (uint64_t *)(zeroes + VDEV_PAD_SIZE);
+ /* ZIO_CHECKSUM_LABEL magic and pre-calcualted checksum for all zeros */
+ end[-5] = 0x0210da7ab10c7a11;
+ end[-4] = 0x97f48f807f6e2a3f;
+ end[-3] = 0xaf909f1658aacefc;
+ end[-2] = 0xcbd1ea57ff6db48b;
+ end[-1] = 0x6ec692db0d465fab;
+ if (vdev_write(vdev, vdev->v_read_priv, off, zeroes, VDEV_PAD_SIZE))
+ return (EIO);
+ return (0);
+}
+
static void
bios_getmem(void)
{
@@ -542,10 +618,12 @@ trymbr:
int
main(void)
{
- int autoboot, i;
dnode_phys_t dn;
off_t off;
struct dsk *dsk;
+ int autoboot, i;
+ int nextboot;
+ int rc;
dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base);
@@ -634,7 +712,39 @@ main(void)
primary_spa = spa;
primary_vdev = spa_get_primary_vdev(spa);
- if (zfs_spa_init(spa) != 0 || zfs_mount(spa, 0, &zfsmount) != 0) {
+ nextboot = 0;
+ rc = vdev_read_pad2(primary_vdev, cmd, sizeof(cmd));
+ if (vdev_clear_pad2(primary_vdev))
+ printf("failed to clear pad2 area of primary vdev\n");
+ if (rc == 0) {
+ if (*cmd) {
+ /*
+ * We could find an old-style ZFS Boot Block header here.
+ * Simply ignore it.
+ */
+ if (*(uint64_t *)cmd != 0x2f5b007b10c) {
+ /*
+ * Note that parse() is destructive to cmd[] and we also want
+ * to honor RBX_QUIET option that could be present in cmd[].
+ */
+ nextboot = 1;
+ memcpy(cmddup, cmd, sizeof(cmd));
+ if (parse()) {
+ printf("failed to parse pad2 area of primary vdev\n");
+ reboot();
+ }
+ if (!OPT_CHECK(RBX_QUIET))
+ printf("zfs nextboot: %s\n", cmddup);
+ }
+ /* Do not process this command twice */
+ *cmd = 0;
+ }
+ } else
+ printf("failed to read pad2 area of primary vdev\n");
+
+ /* Mount ZFS only if it's not already mounted via nextboot parsing. */
+ if (zfsmount.spa == NULL &&
+ (zfs_spa_init(spa) != 0 || zfs_mount(spa, 0, &zfsmount) != 0)) {
printf("%s: failed to mount default pool %s\n",
BOOTPROG, spa->spa_name);
autoboot = 0;
@@ -658,6 +768,10 @@ main(void)
*cmd = 0;
}
+ /* Do not risk waiting at the prompt forever. */
+ if (nextboot && !autoboot)
+ reboot();
+
/*
* Try to exec /boot/loader. If interrupted by a keypress,
* or in case of failure, try to load a kernel directly instead.
@@ -707,6 +821,13 @@ main(void)
void
exit(int x)
{
+ __exit(x);
+}
+
+void
+reboot(void)
+{
+ __exit(0);
}
static void
diff --git a/sys/boot/mips/uboot/Makefile b/sys/boot/mips/uboot/Makefile
index 6be362c86564..05761b099b6b 100644
--- a/sys/boot/mips/uboot/Makefile
+++ b/sys/boot/mips/uboot/Makefile
@@ -85,7 +85,7 @@ LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a
# Enable BootForth
BOOT_FORTH= yes
CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl
-.if ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el"
+.if ${MACHINE_ARCH:Mmips64*} != ""
CFLAGS+= -I${.CURDIR}/../../ficl/mips64
.else
CFLAGS+= -I${.CURDIR}/../../ficl/mips
diff --git a/sys/boot/powerpc/Makefile b/sys/boot/powerpc/Makefile
index 1f3a528b2f08..e3ac008fb799 100644
--- a/sys/boot/powerpc/Makefile
+++ b/sys/boot/powerpc/Makefile
@@ -1,5 +1,8 @@
# $FreeBSD$
-SUBDIR= boot1.chrp kboot ofw ps3 uboot
+SUBDIR= boot1.chrp kboot ofw uboot
+.if ${MACHINE_ARCH} != "powerpcspe"
+SUBDIR+= ps3
+.endif
.include <bsd.subdir.mk>
diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c
index 85aeb765172b..c9f8bbf43314 100644
--- a/sys/boot/zfs/zfsimpl.c
+++ b/sys/boot/zfs/zfsimpl.c
@@ -2122,8 +2122,13 @@ check_mos_features(const spa_t *spa)
&dir)) != 0)
return (rc);
if ((rc = zap_lookup(spa, &dir, DMU_POOL_FEATURES_FOR_READ,
- sizeof (objnum), 1, &objnum)) != 0)
- return (rc);
+ sizeof (objnum), 1, &objnum)) != 0) {
+ /*
+ * It is older pool without features. As we have already
+ * tested the label, just return without raising the error.
+ */
+ return (0);
+ }
if ((rc = objset_get_dnode(spa, &spa->spa_mos, objnum, &dir)) != 0)
return (rc);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h
index 13442603e02e..d07b928a310a 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h
@@ -167,6 +167,8 @@ typedef enum {
extern int vdev_label_init(vdev_t *vd, uint64_t txg, vdev_labeltype_t reason);
+extern int vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t size);
+
#ifdef __cplusplus
}
#endif
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
index 818052ba577e..2529487789e1 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
@@ -223,7 +223,7 @@ vdev_geom_attach(struct g_provider *pp, vdev_t *vd)
}
error = g_access(cp, 1, 0, 1);
if (error != 0) {
- ZFS_LOG(1, "%s(%d): g_access failed: %d\n", __func__,
+ ZFS_LOG(1, "%s(%d): g_access failed: %d", __func__,
__LINE__, error);
vdev_geom_detach(cp, B_FALSE);
return (NULL);
@@ -293,7 +293,7 @@ vdev_geom_detach(struct g_consumer *cp, boolean_t open_for_read)
g_topology_assert();
- ZFS_LOG(1, "Detaching consumer. Provider %s.",
+ ZFS_LOG(1, "Detaching from %s.",
cp->provider && cp->provider->name ? cp->provider->name : "NULL");
vd = cp->private;
@@ -307,7 +307,7 @@ vdev_geom_detach(struct g_consumer *cp, boolean_t open_for_read)
if (cp->acw > 0)
g_access(cp, 0, -cp->acw, 0);
if (cp->provider != NULL) {
- ZFS_LOG(1, "Destroying consumer to %s.",
+ ZFS_LOG(1, "Destroying consumer for %s.",
cp->provider->name ? cp->provider->name : "NULL");
g_detach(cp);
}
@@ -338,14 +338,6 @@ vdev_geom_close_locked(vdev_t *vd)
vdev_geom_detach(cp, B_TRUE);
}
-static void
-nvlist_get_guids(nvlist_t *list, uint64_t *pguid, uint64_t *vguid)
-{
-
- (void) nvlist_lookup_uint64(list, ZPOOL_CONFIG_GUID, vguid);
- (void) nvlist_lookup_uint64(list, ZPOOL_CONFIG_POOL_GUID, pguid);
-}
-
/*
* Issue one or more bios to the vdev in parallel
* cmds, datas, offsets, errors, and sizes are arrays of length ncmds. Each IO
@@ -606,58 +598,69 @@ vdev_geom_read_pool_label(const char *name,
return (*count > 0 ? 0 : ENOENT);
}
-static void
-vdev_geom_read_guids(struct g_consumer *cp, uint64_t *pguid, uint64_t *vguid)
-{
- nvlist_t *config;
-
- g_topology_assert_not();
-
- *pguid = 0;
- *vguid = 0;
- if (vdev_geom_read_config(cp, &config) == 0) {
- nvlist_get_guids(config, pguid, vguid);
- nvlist_free(config);
- }
-}
+enum match {
+ NO_MATCH,
+ TOP_MATCH,
+ FULL_MATCH
+};
-static boolean_t
+static enum match
vdev_attach_ok(vdev_t *vd, struct g_provider *pp)
{
- uint64_t pool_guid;
- uint64_t vdev_guid;
- struct g_consumer *zcp;
- boolean_t pool_ok;
- boolean_t vdev_ok;
+ nvlist_t *config;
+ uint64_t pool_guid, top_guid, vdev_guid;
+ struct g_consumer *cp;
- zcp = vdev_geom_attach(pp, NULL);
- if (zcp == NULL) {
+ cp = vdev_geom_attach(pp, NULL);
+ if (cp == NULL) {
ZFS_LOG(1, "Unable to attach tasting instance to %s.",
pp->name);
- return (B_FALSE);
+ return (NO_MATCH);
}
g_topology_unlock();
- vdev_geom_read_guids(zcp, &pool_guid, &vdev_guid);
+ if (vdev_geom_read_config(cp, &config) != 0) {
+ g_topology_lock();
+ vdev_geom_detach(cp, B_TRUE);
+ ZFS_LOG(1, "Unable to read config from %s.", pp->name);
+ return (NO_MATCH);
+ }
g_topology_lock();
- vdev_geom_detach(zcp, B_TRUE);
+ vdev_geom_detach(cp, B_TRUE);
- /*
- * Check that the label's vdev guid matches the desired guid. If the
- * label has a pool guid, check that it matches too. (Inactive spares
- * and L2ARCs do not have any pool guid in the label.)
+ pool_guid = 0;
+ (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid);
+ top_guid = 0;
+ (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_TOP_GUID, &top_guid);
+ vdev_guid = 0;
+ (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid);
+ nvlist_free(config);
+
+ /*
+ * Check that the label's pool guid matches the desired guid.
+ * Inactive spares and L2ARCs do not have any pool guid in the label.
*/
- if ((pool_guid == 0 || pool_guid == spa_guid(vd->vdev_spa)) &&
- vdev_guid == vd->vdev_guid) {
- ZFS_LOG(1, "guids match for provider %s.", vd->vdev_path);
- return (B_TRUE);
- } else {
- ZFS_LOG(1, "guid mismatch for provider %s: "
- "%ju:%ju != %ju:%ju.", vd->vdev_path,
- (uintmax_t)spa_guid(vd->vdev_spa),
- (uintmax_t)vd->vdev_guid,
- (uintmax_t)pool_guid, (uintmax_t)vdev_guid);
- return (B_FALSE);
+ if (pool_guid != 0 && pool_guid != spa_guid(vd->vdev_spa)) {
+ ZFS_LOG(1, "pool guid mismatch for provider %s: %ju != %ju.",
+ pp->name,
+ (uintmax_t)spa_guid(vd->vdev_spa), (uintmax_t)pool_guid);
+ return (NO_MATCH);
+ }
+
+ /*
+ * Check that the label's vdev guid matches the desired guid.
+ * The second condition handles possible race on vdev detach, when
+ * remaining vdev receives GUID of destroyed top level mirror vdev.
+ */
+ if (vdev_guid == vd->vdev_guid) {
+ ZFS_LOG(1, "guids match for provider %s.", pp->name);
+ return (FULL_MATCH);
+ } else if (top_guid == vd->vdev_guid && vd == vd->vdev_top) {
+ ZFS_LOG(1, "top vdev guid match for provider %s.", pp->name);
+ return (TOP_MATCH);
}
+ ZFS_LOG(1, "vdev guid mismatch for provider %s: %ju != %ju.",
+ pp->name, (uintmax_t)vd->vdev_guid, (uintmax_t)vdev_guid);
+ return (NO_MATCH);
}
static struct g_consumer *
@@ -667,6 +670,7 @@ vdev_geom_attach_by_guids(vdev_t *vd)
struct g_geom *gp;
struct g_provider *pp;
struct g_consumer *cp;
+ enum match m;
g_topology_assert();
@@ -678,23 +682,26 @@ vdev_geom_attach_by_guids(vdev_t *vd)
if (gp->flags & G_GEOM_WITHER)
continue;
LIST_FOREACH(pp, &gp->provider, provider) {
- if (!vdev_attach_ok(vd, pp))
+ m = vdev_attach_ok(vd, pp);
+ if (m == NO_MATCH)
continue;
+ if (cp != NULL) {
+ if (m == FULL_MATCH)
+ vdev_geom_detach(cp, B_TRUE);
+ else
+ continue;
+ }
cp = vdev_geom_attach(pp, vd);
if (cp == NULL) {
printf("ZFS WARNING: Unable to "
"attach to %s.\n", pp->name);
continue;
}
- break;
+ if (m == FULL_MATCH)
+ return (cp);
}
- if (cp != NULL)
- break;
}
- if (cp != NULL)
- break;
}
-end:
return (cp);
}
@@ -742,7 +749,7 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid)
pp = g_provider_by_name(vd->vdev_path + sizeof("/dev/") - 1);
if (pp != NULL) {
ZFS_LOG(1, "Found provider by name %s.", vd->vdev_path);
- if (!check_guid || vdev_attach_ok(vd, pp))
+ if (!check_guid || vdev_attach_ok(vd, pp) == FULL_MATCH)
cp = vdev_geom_attach(pp, vd);
}
@@ -769,7 +776,14 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
return (EINVAL);
}
- vd->vdev_tsd = NULL;
+ /*
+ * Reopen the device if it's not currently open. Otherwise,
+ * just update the physical size of the device.
+ */
+ if ((cp = vd->vdev_tsd) != NULL) {
+ ASSERT(vd->vdev_reopening);
+ goto skip_open;
+ }
DROP_GIANT();
g_topology_lock();
@@ -854,6 +868,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED;
return (error);
}
+skip_open:
pp = cp->provider;
/*
@@ -889,6 +904,9 @@ static void
vdev_geom_close(vdev_t *vd)
{
+ if (vd->vdev_reopening)
+ return;
+
DROP_GIANT();
g_topology_lock();
vdev_geom_close_locked(vd);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c
index 7901115264b5..7e6ff2c688ff 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c
@@ -871,6 +871,44 @@ retry:
return (error);
}
+int
+vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t size)
+{
+ spa_t *spa = vd->vdev_spa;
+ zio_t *zio;
+ char *pad2;
+ int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL;
+ int error;
+
+ if (size > VDEV_PAD_SIZE)
+ return (EINVAL);
+
+ if (!vd->vdev_ops->vdev_op_leaf)
+ return (ENODEV);
+ if (vdev_is_dead(vd))
+ return (ENXIO);
+
+ ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL);
+
+ pad2 = zio_buf_alloc(VDEV_PAD_SIZE);
+ bzero(pad2, VDEV_PAD_SIZE);
+ memcpy(pad2, buf, size);
+
+retry:
+ zio = zio_root(spa, NULL, NULL, flags);
+ vdev_label_write(zio, vd, 0, pad2,
+ offsetof(vdev_label_t, vl_pad2),
+ VDEV_PAD_SIZE, NULL, NULL, flags);
+ error = zio_wait(zio);
+ if (error != 0 && !(flags & ZIO_FLAG_TRYHARD)) {
+ flags |= ZIO_FLAG_TRYHARD;
+ goto retry;
+ }
+
+ zio_buf_free(pad2, VDEV_PAD_SIZE);
+ return (error);
+}
+
/*
* ==========================================================================
* uberblock load/sync
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
index 661e418e5ec4..36709af9c01a 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
@@ -3472,6 +3472,53 @@ zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl)
return (error);
}
+#ifdef __FreeBSD__
+static int
+zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl)
+{
+ char name[MAXNAMELEN];
+ spa_t *spa;
+ vdev_t *vd;
+ char *command;
+ uint64_t pool_guid;
+ uint64_t vdev_guid;
+ int error;
+
+ if (nvlist_lookup_uint64(innvl,
+ ZPOOL_CONFIG_POOL_GUID, &pool_guid) != 0)
+ return (EINVAL);
+ if (nvlist_lookup_uint64(innvl,
+ ZPOOL_CONFIG_GUID, &vdev_guid) != 0)
+ return (EINVAL);
+ if (nvlist_lookup_string(innvl,
+ "command", &command) != 0)
+ return (EINVAL);
+
+ mutex_enter(&spa_namespace_lock);
+ spa = spa_by_guid(pool_guid, vdev_guid);
+ if (spa != NULL)
+ strcpy(name, spa_name(spa));
+ mutex_exit(&spa_namespace_lock);
+ if (spa == NULL)
+ return (ENOENT);
+
+ if ((error = spa_open(name, &spa, FTAG)) != 0)
+ return (error);
+ spa_vdev_state_enter(spa, SCL_ALL);
+ vd = spa_lookup_by_guid(spa, vdev_guid, B_TRUE);
+ if (vd == NULL) {
+ (void) spa_vdev_state_exit(spa, NULL, ENXIO);
+ spa_close(spa, FTAG);
+ return (ENODEV);
+ }
+ error = vdev_label_write_pad2(vd, command, strlen(command));
+ (void) spa_vdev_state_exit(spa, NULL, 0);
+ txg_wait_synced(spa->spa_dsl_pool, 0);
+ spa_close(spa, FTAG);
+ return (error);
+}
+#endif
+
/*
* The dp_config_rwlock must not be held when calling this, because the
* unmount may need to write out data.
@@ -6024,6 +6071,9 @@ zfs_ioctl_init(void)
zfs_secpolicy_config, POOL_CHECK_NONE);
zfs_ioctl_register_dataset_nolog(ZFS_IOC_UNJAIL, zfs_ioc_unjail,
zfs_secpolicy_config, POOL_CHECK_NONE);
+ zfs_ioctl_register("fbsd_nextboot", ZFS_IOC_NEXTBOOT,
+ zfs_ioc_nextboot, zfs_secpolicy_config, NO_NAME,
+ POOL_CHECK_NONE, B_FALSE, B_FALSE);
#endif
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c
index 6933ccdacd16..049b958605d8 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c
@@ -454,6 +454,11 @@ zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
* Handles TX_WRITE transactions.
*/
ssize_t zfs_immediate_write_sz = 32768;
+#ifdef _KERNEL
+SYSCTL_DECL(_vfs_zfs);
+SYSCTL_LONG(_vfs_zfs, OID_AUTO, immediate_write_sz, CTLFLAG_RWTUN,
+ &zfs_immediate_write_sz, 0, "Minimal size for indirect log write");
+#endif
void
zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c
index 7f6beeed6149..ec333e54d2a8 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2015 by Delphix. All rights reserved.
+ * Copyright 2016 The MathWorks, Inc. All rights reserved.
*/
/*
@@ -71,37 +72,32 @@ zrl_destroy(zrlock_t *zrl)
void
zrl_add_impl(zrlock_t *zrl, const char *zc)
{
- uint32_t n = (uint32_t)zrl->zr_refcount;
-
- while (n != ZRL_LOCKED) {
- uint32_t cas = atomic_cas_32(
- (uint32_t *)&zrl->zr_refcount, n, n + 1);
- if (cas == n) {
- ASSERT3S((int32_t)n, >=, 0);
+ for (;;) {
+ uint32_t n = (uint32_t)zrl->zr_refcount;
+ while (n != ZRL_LOCKED) {
+ uint32_t cas = atomic_cas_32(
+ (uint32_t *)&zrl->zr_refcount, n, n + 1);
+ if (cas == n) {
+ ASSERT3S((int32_t)n, >=, 0);
#ifdef ZFS_DEBUG
- if (zrl->zr_owner == curthread) {
- DTRACE_PROBE2(zrlock__reentry,
- zrlock_t *, zrl, uint32_t, n);
- }
- zrl->zr_owner = curthread;
- zrl->zr_caller = zc;
+ if (zrl->zr_owner == curthread) {
+ DTRACE_PROBE2(zrlock__reentry,
+ zrlock_t *, zrl, uint32_t, n);
+ }
+ zrl->zr_owner = curthread;
+ zrl->zr_caller = zc;
#endif
- return;
+ return;
+ }
+ n = cas;
}
- n = cas;
- }
- mutex_enter(&zrl->zr_mtx);
- while (zrl->zr_refcount == ZRL_LOCKED) {
- cv_wait(&zrl->zr_cv, &zrl->zr_mtx);
+ mutex_enter(&zrl->zr_mtx);
+ while (zrl->zr_refcount == ZRL_LOCKED) {
+ cv_wait(&zrl->zr_cv, &zrl->zr_mtx);
+ }
+ mutex_exit(&zrl->zr_mtx);
}
- ASSERT3S(zrl->zr_refcount, >=, 0);
- zrl->zr_refcount++;
-#ifdef ZFS_DEBUG
- zrl->zr_owner = curthread;
- zrl->zr_caller = zc;
-#endif
- mutex_exit(&zrl->zr_mtx);
}
void
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
index d0c7a74c6dd7..4965dde36f43 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
@@ -782,8 +782,10 @@ zvol_remove_zv(zvol_state_t *zv)
g_topology_lock();
zvol_geom_destroy(zv);
g_topology_unlock();
- } else if (zv->zv_volmode == ZFS_VOLMODE_DEV)
- destroy_dev(zv->zv_dev);
+ } else if (zv->zv_volmode == ZFS_VOLMODE_DEV) {
+ if (zv->zv_dev != NULL)
+ destroy_dev(zv->zv_dev);
+ }
#endif
avl_destroy(&zv->zv_znode.z_range_avl);
@@ -1373,6 +1375,10 @@ zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio)
* Otherwise we will later flush the data out via dmu_sync().
*/
ssize_t zvol_immediate_write_sz = 32768;
+#ifdef _KERNEL
+SYSCTL_LONG(_vfs_zfs_vol, OID_AUTO, immediate_write_sz, CTLFLAG_RWTUN,
+ &zvol_immediate_write_sz, 0, "Minimal size for indirect log write");
+#endif
static void
zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, offset_t off, ssize_t resid,
@@ -2973,14 +2979,14 @@ zvol_rename_minor(zvol_state_t *zv, const char *newname)
} else if (zv->zv_volmode == ZFS_VOLMODE_DEV) {
struct make_dev_args args;
- dev = zv->zv_dev;
- ASSERT(dev != NULL);
- zv->zv_dev = NULL;
- destroy_dev(dev);
- if (zv->zv_total_opens > 0) {
- zv->zv_flags &= ~ZVOL_EXCL;
- zv->zv_total_opens = 0;
- zvol_last_close(zv);
+ if ((dev = zv->zv_dev) != NULL) {
+ zv->zv_dev = NULL;
+ destroy_dev(dev);
+ if (zv->zv_total_opens > 0) {
+ zv->zv_flags &= ~ZVOL_EXCL;
+ zv->zv_total_opens = 0;
+ zvol_last_close(zv);
+ }
}
make_dev_args_init(&args);
diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
index 8f5658d2e680..7c72c887d419 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
+++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
@@ -891,6 +891,7 @@ typedef enum zfs_ioc {
ZFS_IOC_BOOKMARK,
ZFS_IOC_GET_BOOKMARKS,
ZFS_IOC_DESTROY_BOOKMARKS,
+ ZFS_IOC_NEXTBOOT,
ZFS_IOC_LAST
} zfs_ioc_t;
diff --git a/sys/conf/Makefile.powerpc b/sys/conf/Makefile.powerpc
index 769b068ed5f2..e529ef7cc11d 100644
--- a/sys/conf/Makefile.powerpc
+++ b/sys/conf/Makefile.powerpc
@@ -35,6 +35,10 @@ LDSCRIPT_NAME?= ldscript.${MACHINE_ARCH}
INCLUDES+= -I$S/contrib/libfdt
+.if "${MACHINE_ARCH}" == "powerpcspe"
+# Force __SPE__, since the builtin will be removed later with -mno-spe
+CFLAGS+= -mabi=spe -D__SPE__
+.endif
CFLAGS+= -msoft-float -Wa,-many
# Build position-independent kernel
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index afc521518978..f964d256a61b 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2527,7 +2527,12 @@ device ismt
device smb
+# SMBus peripheral devices
#
+# jedec_ts Temperature Sensor compliant with JEDEC Standard 21-C
+#
+device jedec_ts
+
# I2C Bus
#
# Philips i2c bus support is provided by the `iicbus' device.
@@ -2783,7 +2788,7 @@ device rue
# Davicom DM9601E USB to fast ethernet. Supports the Corega FEther USB-TXC.
device udav
#
-# RealTek RTL8152 USB to fast ethernet.
+# RealTek RTL8152/RTL8153 USB Ethernet driver
device ure
#
# Moschip MCS7730/MCS7840 USB to fast ethernet. Supports the Sitecom LN030.
diff --git a/sys/conf/files b/sys/conf/files
index ef6ac4b6de5d..a154b803bb65 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -1273,6 +1273,7 @@ dev/cfi/cfi_bus_nexus.c optional cfi
dev/cfi/cfi_core.c optional cfi
dev/cfi/cfi_dev.c optional cfi
dev/cfi/cfi_disk.c optional cfid
+dev/chromebook_platform/chromebook_platform.c optional chromebook_platform
dev/ciss/ciss.c optional ciss
dev/cm/smc90cx6.c optional cm
dev/cmx/cmx.c optional cmx
@@ -1389,7 +1390,7 @@ t5fw.fw optional cxgbe \
dev/cy/cy.c optional cy
dev/cy/cy_isa.c optional cy isa
dev/cy/cy_pci.c optional cy pci
-dev/cyapa/cyapa.c optional cyapa smbus
+dev/cyapa/cyapa.c optional cyapa iicbus
dev/dc/if_dc.c optional dc pci
dev/dc/dcphy.c optional dc pci
dev/dc/pnphy.c optional dc pci
@@ -1631,8 +1632,8 @@ dev/hptiop/hptiop.c optional hptiop scbus
dev/hwpmc/hwpmc_logging.c optional hwpmc
dev/hwpmc/hwpmc_mod.c optional hwpmc
dev/hwpmc/hwpmc_soft.c optional hwpmc
-dev/ichiic/ig4_iic.c optional ig4 smbus
-dev/ichiic/ig4_pci.c optional ig4 pci smbus
+dev/ichiic/ig4_iic.c optional ig4 iicbus
+dev/ichiic/ig4_pci.c optional ig4 pci iicbus
dev/ichsmb/ichsmb.c optional ichsmb
dev/ichsmb/ichsmb_pci.c optional ichsmb pci
dev/ida/ida.c optional ida
@@ -1726,7 +1727,7 @@ dev/iscsi_initiator/isc_soc.c optional iscsi_initiator scbus
dev/iscsi_initiator/isc_sm.c optional iscsi_initiator scbus
dev/iscsi_initiator/isc_subr.c optional iscsi_initiator scbus
dev/ismt/ismt.c optional ismt
-dev/isl/isl.c optional isl smbus
+dev/isl/isl.c optional isl iicbus
dev/isp/isp.c optional isp
dev/isp/isp_freebsd.c optional isp
dev/isp/isp_library.c optional isp
@@ -2062,6 +2063,7 @@ dev/ixgbe/ixgbe_dcb_82598.c optional ix inet | ixv inet \
compile-with "${NORMAL_C} -I$S/dev/ixgbe"
dev/ixgbe/ixgbe_dcb_82599.c optional ix inet | ixv inet \
compile-with "${NORMAL_C} -I$S/dev/ixgbe"
+dev/jedec_ts/jedec_ts.c optional jedec_ts smbus
dev/jme/if_jme.c optional jme pci
dev/joy/joy.c optional joy
dev/joy/joy_isa.c optional joy isa
@@ -3181,6 +3183,7 @@ dev/xen/xenstore/xenstore_dev.c optional xenhvm
dev/xen/xenstore/xenstored_dev.c optional xenhvm
dev/xen/evtchn/evtchn_dev.c optional xenhvm
dev/xen/privcmd/privcmd.c optional xenhvm
+dev/xen/gntdev/gntdev.c optional xenhvm
dev/xen/debug/debug.c optional xenhvm
dev/xl/if_xl.c optional xl pci
dev/xl/xlphy.c optional xl pci
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
index be421d3d4581..5b699a08120a 100644
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -291,9 +291,9 @@ dev/hwpmc/hwpmc_uncore.c optional hwpmc
dev/hwpmc/hwpmc_piv.c optional hwpmc
dev/hwpmc/hwpmc_tsc.c optional hwpmc
dev/hwpmc/hwpmc_x86.c optional hwpmc
-dev/hyperv/netvsc/hv_net_vsc.c optional hyperv
+dev/hyperv/netvsc/hn_nvs.c optional hyperv
+dev/hyperv/netvsc/hn_rndis.c optional hyperv
dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv
-dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv
dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
dev/hyperv/utilities/hv_heartbeat.c optional hyperv
dev/hyperv/utilities/hv_kvp.c optional hyperv
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
index 2feac5041985..ea7b7d4b4431 100644
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -72,7 +72,6 @@ arm64/acpica/OsdEnvironment.c optional acpi
arm64/acpica/acpi_wakeup.c optional acpi
arm64/acpica/pci_cfgreg.c optional acpi pci
arm64/arm64/autoconf.c standard
-arm64/arm64/bcopy.c standard
arm64/arm64/bus_machdep.c standard
arm64/arm64/bus_space_asm.S standard
arm64/arm64/busdma_bounce.c standard
@@ -98,6 +97,8 @@ arm64/arm64/in_cksum.c optional inet | inet6
arm64/arm64/locore.S standard no-obj
arm64/arm64/machdep.c standard
arm64/arm64/mem.c standard
+arm64/arm64/memcpy.S standard
+arm64/arm64/memmove.S standard
arm64/arm64/minidump_machdep.c standard
arm64/arm64/mp_machdep.c optional smp
arm64/arm64/nexus.c standard
@@ -178,7 +179,6 @@ libkern/ffsll.c standard
libkern/fls.c standard
libkern/flsl.c standard
libkern/flsll.c standard
-libkern/memmove.c standard
libkern/memset.c standard
cddl/contrib/opensolaris/common/atomic/aarch64/opensolaris_atomic.S optional zfs | dtrace compile-with "${CDDL_C}"
cddl/dev/dtrace/aarch64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}"
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index cdf851a4bc3d..42962548a36a 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -248,9 +248,9 @@ dev/hwpmc/hwpmc_piv.c optional hwpmc
dev/hwpmc/hwpmc_ppro.c optional hwpmc
dev/hwpmc/hwpmc_tsc.c optional hwpmc
dev/hwpmc/hwpmc_x86.c optional hwpmc
-dev/hyperv/netvsc/hv_net_vsc.c optional hyperv
+dev/hyperv/netvsc/hn_nvs.c optional hyperv
+dev/hyperv/netvsc/hn_rndis.c optional hyperv
dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv
-dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv
dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv
dev/hyperv/utilities/hv_heartbeat.c optional hyperv
dev/hyperv/utilities/hv_kvp.c optional hyperv
diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc
index aee0a1022b9c..7ccc3a6ae2fb 100644
--- a/sys/conf/files.powerpc
+++ b/sys/conf/files.powerpc
@@ -82,25 +82,25 @@ kern/kern_clocksource.c standard
kern/subr_dummy_vdso_tc.c standard
kern/syscalls.c optional ktr
kern/subr_sfbuf.c standard
-libkern/ashldi3.c optional powerpc
-libkern/ashrdi3.c optional powerpc
+libkern/ashldi3.c optional powerpc | powerpcspe
+libkern/ashrdi3.c optional powerpc | powerpcspe
libkern/bcmp.c standard
-libkern/cmpdi2.c optional powerpc
-libkern/divdi3.c optional powerpc
+libkern/cmpdi2.c optional powerpc | powerpcspe
+libkern/divdi3.c optional powerpc | powerpcspe
libkern/ffs.c standard
libkern/ffsl.c standard
libkern/ffsll.c standard
libkern/fls.c standard
libkern/flsl.c standard
libkern/flsll.c standard
-libkern/lshrdi3.c optional powerpc
+libkern/lshrdi3.c optional powerpc | powerpcspe
libkern/memmove.c standard
libkern/memset.c standard
-libkern/moddi3.c optional powerpc
-libkern/qdivrem.c optional powerpc
-libkern/ucmpdi2.c optional powerpc
-libkern/udivdi3.c optional powerpc
-libkern/umoddi3.c optional powerpc
+libkern/moddi3.c optional powerpc | powerpcspe
+libkern/qdivrem.c optional powerpc | powerpcspe
+libkern/ucmpdi2.c optional powerpc | powerpcspe
+libkern/udivdi3.c optional powerpc | powerpcspe
+libkern/umoddi3.c optional powerpc | powerpcspe
powerpc/aim/locore.S optional aim no-obj
powerpc/aim/aim_machdep.c optional aim
powerpc/aim/mmu_oea.c optional aim powerpc
@@ -115,6 +115,7 @@ powerpc/booke/machdep_e500.c optional booke_e500
powerpc/booke/mp_cpudep.c optional booke smp
powerpc/booke/platform_bare.c optional booke
powerpc/booke/pmap.c optional booke
+powerpc/booke/spe.c optional powerpcspe
powerpc/cpufreq/dfs.c optional cpufreq
powerpc/cpufreq/pcr.c optional cpufreq aim
powerpc/cpufreq/pmufreq.c optional cpufreq aim pmu
@@ -179,7 +180,7 @@ powerpc/powermac/smusat.c optional powermac smu
powerpc/powermac/uninorth.c optional powermac
powerpc/powermac/uninorthpci.c optional powermac pci
powerpc/powermac/vcoregpio.c optional powermac
-powerpc/powerpc/altivec.c standard
+powerpc/powerpc/altivec.c optional powerpc | powerpc64
powerpc/powerpc/autoconf.c standard
powerpc/powerpc/bcopy.c standard
powerpc/powerpc/bus_machdep.c standard
@@ -193,7 +194,7 @@ powerpc/powerpc/db_hwwatch.c optional ddb
powerpc/powerpc/db_interface.c optional ddb
powerpc/powerpc/db_trace.c optional ddb
powerpc/powerpc/dump_machdep.c standard
-powerpc/powerpc/elf32_machdep.c optional powerpc | compat_freebsd32
+powerpc/powerpc/elf32_machdep.c optional powerpc | powerpcspe | compat_freebsd32
powerpc/powerpc/elf64_machdep.c optional powerpc64
powerpc/powerpc/exec_machdep.c standard
powerpc/powerpc/fpu.c standard
@@ -216,9 +217,9 @@ powerpc/powerpc/platform_if.m standard
powerpc/powerpc/ptrace_machdep.c standard
powerpc/powerpc/sc_machdep.c optional sc
powerpc/powerpc/setjmp.S standard
-powerpc/powerpc/sigcode32.S optional powerpc | compat_freebsd32
+powerpc/powerpc/sigcode32.S optional powerpc | powerpcspe | compat_freebsd32
powerpc/powerpc/sigcode64.S optional powerpc64
-powerpc/powerpc/swtch32.S optional powerpc
+powerpc/powerpc/swtch32.S optional powerpc | powerpcspe
powerpc/powerpc/swtch64.S optional powerpc64
powerpc/powerpc/stack_machdep.c optional ddb | stack
powerpc/powerpc/suswintr.c standard
diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk
index be296f7849ed..fb8ade289c8b 100644
--- a/sys/conf/kern.mk
+++ b/sys/conf/kern.mk
@@ -167,6 +167,10 @@ CFLAGS.gcc+= -msoft-float
INLINE_LIMIT?= 15000
.endif
+.if ${MACHINE_ARCH} == "powerpcspe"
+CFLAGS+= -mno-spe
+.endif
+
#
# Use dot symbols on powerpc64 to make ddb happy
#
@@ -180,6 +184,9 @@ CFLAGS.gcc+= -mcall-aixdesc
.if ${MACHINE_CPUARCH} == "mips"
CFLAGS+= -msoft-float
INLINE_LIMIT?= 8000
+.if ${TARGET_ARCH:Mmips*hf} != ""
+CFLAGS+= -DCPU_HAVEFPU
+.endif
.endif
#
@@ -261,6 +268,7 @@ LD_EMULATION_mips64el= elf64ltsmip_fbsd
LD_EMULATION_mipsn32= elf32btsmipn32_fbsd
LD_EMULATION_mipsn32el= elf32btsmipn32_fbsd # I don't think this is a thing that works
LD_EMULATION_powerpc= elf32ppc_fbsd
+LD_EMULATION_powerpcspe= elf32ppc_fbsd
LD_EMULATION_powerpc64= elf64ppc_fbsd
LD_EMULATION_riscv= elf64riscv
LD_EMULATION_sparc64= elf64_sparc_fbsd
diff --git a/sys/conf/ldscript.powerpcspe b/sys/conf/ldscript.powerpcspe
new file mode 100644
index 000000000000..b190dc193b02
--- /dev/null
+++ b/sys/conf/ldscript.powerpcspe
@@ -0,0 +1,144 @@
+/* $FreeBSD$ */
+
+OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd",
+ "elf32-powerpc-freebsd")
+OUTPUT_ARCH(powerpc)
+ENTRY(__start)
+SEARCH_DIR(/usr/lib);
+PROVIDE (__stack = 0);
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+
+ . = kernbase + SIZEOF_HEADERS;
+ PROVIDE (begin = . - SIZEOF_HEADERS);
+
+ .text :
+ {
+ *(.text)
+ *(.stub)
+ /* .gnu.warning sections are handled specially by elf32.em. */
+ *(.gnu.warning)
+ *(.gnu.linkonce.t*)
+ } =0
+ _etext = .;
+ PROVIDE (etext = .);
+
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+ .rela.text :
+ { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+ .rela.data :
+ { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+ .rela.rodata :
+ { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+ .rela.got : { *(.rela.got) }
+ .rela.got1 : { *(.rela.got1) }
+ .rela.got2 : { *(.rela.got2) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rela.init : { *(.rela.init) }
+ .rela.fini : { *(.rela.fini) }
+ .rela.bss : { *(.rela.bss) }
+ .rela.plt : { *(.rela.plt) }
+ .rela.sdata : { *(.rela.sdata) }
+ .rela.sbss : { *(.rela.sbss) }
+ .rela.sdata2 : { *(.rela.sdata2) }
+ .rela.sbss2 : { *(.rela.sbss2) }
+
+ .init : { *(.init) } =0
+ .fini : { *(.fini) } =0
+ .rodata : { *(.rodata) *(.gnu.linkonce.r*) }
+ .rodata1 : { *(.rodata1) }
+ .sdata2 : { *(.sdata2) }
+ .sbss2 : { *(.sbss2) }
+ /* Adjust the address for the data segment to the next page up. */
+ . = ((. + 0x1000) & ~(0x1000 - 1));
+ .data :
+ {
+ *(.data)
+ *(.gnu.linkonce.d*)
+ CONSTRUCTORS
+ }
+ .data1 : { *(.data1) }
+ .got1 : { *(.got1) }
+ .dynamic : { *(.dynamic) }
+ /* Put .ctors and .dtors next to the .got2 section, so that the pointers
+ get relocated with -mrelocatable. Also put in the .fixup pointers.
+ The current compiler no longer needs this, but keep it around for 2.7.2 */
+ PROVIDE (_GOT2_START_ = .);
+ .got2 : { *(.got2) }
+ PROVIDE (__CTOR_LIST__ = .);
+ .ctors : { *(.ctors) }
+ PROVIDE (__CTOR_END__ = .);
+ PROVIDE (__DTOR_LIST__ = .);
+ .dtors : { *(.dtors) }
+ PROVIDE (__DTOR_END__ = .);
+ PROVIDE (_FIXUP_START_ = .);
+ .fixup : { *(.fixup) }
+ PROVIDE (_FIXUP_END_ = .);
+ PROVIDE (_GOT2_END_ = .);
+ PROVIDE (_GOT_START_ = .);
+ .got : { *(.got) }
+ .got.plt : { *(.got.plt) }
+ PROVIDE (_GOT_END_ = .);
+ /* We want the small data sections together, so single-instruction offsets
+ can access them all, and initialized data all before uninitialized, so
+ we can shorten the on-disk segment size. */
+ .sdata : { *(.sdata) }
+ _edata = .;
+ PROVIDE (edata = .);
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ *(.sbss)
+ *(.scommon)
+ *(.dynsbss)
+ PROVIDE (__sbss_end = .);
+ }
+ .plt : { *(.plt) }
+ .bss :
+ {
+ PROVIDE (__bss_start = .);
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ /* DWARF debug sections.
+ Symbols in the DWARF debugging sections are relative to the beginning
+ of the section so we begin them at 0. */
+ /* DWARF 1 */
+ .debug 0 : { *(.debug) }
+ .line 0 : { *(.line) }
+ /* GNU DWARF 1 extensions */
+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
+ .debug_sfnames 0 : { *(.debug_sfnames) }
+ /* DWARF 1.1 and DWARF 2 */
+ .debug_aranges 0 : { *(.debug_aranges) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ /* DWARF 2 */
+ .debug_info 0 : { *(.debug_info) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_frame 0 : { *(.debug_frame) }
+ .debug_str 0 : { *(.debug_str) }
+ .debug_loc 0 : { *(.debug_loc) }
+ .debug_macinfo 0 : { *(.debug_macinfo) }
+ /* SGI/MIPS DWARF 2 extensions */
+ .debug_weaknames 0 : { *(.debug_weaknames) }
+ .debug_funcnames 0 : { *(.debug_funcnames) }
+ .debug_typenames 0 : { *(.debug_typenames) }
+ .debug_varnames 0 : { *(.debug_varnames) }
+ /* These must appear regardless of . */
+}
+
diff --git a/sys/conf/options.powerpc b/sys/conf/options.powerpc
index 4926947c7da7..3e82696983dd 100644
--- a/sys/conf/options.powerpc
+++ b/sys/conf/options.powerpc
@@ -9,6 +9,7 @@ CELL
POWERPC
POWERPC64
+POWERPCSPE
FPU_EMU
diff --git a/sys/contrib/rdma/krping/krping.c b/sys/contrib/rdma/krping/krping.c
index 3392c204b29d..8a89f80e3ea3 100644
--- a/sys/contrib/rdma/krping/krping.c
+++ b/sys/contrib/rdma/krping/krping.c
@@ -548,11 +548,11 @@ static int krping_setup_buffers(struct krping_cb *cb)
DEBUG_LOG(cb, "krping_setup_buffers called on cb %p\n", cb);
- cb->recv_dma_addr = dma_map_single(cb->pd->device->dma_device,
+ cb->recv_dma_addr = ib_dma_map_single(cb->pd->device,
&cb->recv_buf,
sizeof(cb->recv_buf), DMA_BIDIRECTIONAL);
pci_unmap_addr_set(cb, recv_mapping, cb->recv_dma_addr);
- cb->send_dma_addr = dma_map_single(cb->pd->device->dma_device,
+ cb->send_dma_addr = ib_dma_map_single(cb->pd->device,
&cb->send_buf, sizeof(cb->send_buf),
DMA_BIDIRECTIONAL);
pci_unmap_addr_set(cb, send_mapping, cb->send_dma_addr);
@@ -606,7 +606,7 @@ static int krping_setup_buffers(struct krping_cb *cb)
goto bail;
}
- cb->rdma_dma_addr = dma_map_single(cb->pd->device->dma_device,
+ cb->rdma_dma_addr = ib_dma_map_single(cb->pd->device,
cb->rdma_buf, cb->size,
DMA_BIDIRECTIONAL);
pci_unmap_addr_set(cb, rdma_mapping, cb->rdma_dma_addr);
@@ -676,7 +676,7 @@ static int krping_setup_buffers(struct krping_cb *cb)
goto bail;
}
- cb->start_dma_addr = dma_map_single(cb->pd->device->dma_device,
+ cb->start_dma_addr = ib_dma_map_single(cb->pd->device,
cb->start_buf, cb->size,
DMA_BIDIRECTIONAL);
pci_unmap_addr_set(cb, start_mapping, cb->start_dma_addr);
@@ -1707,7 +1707,7 @@ static void krping_fr_test5(struct krping_cb *cb)
goto err2;
}
DEBUG_LOG(cb, "%s buf[%u] %p\n", __func__, scnt, buf[scnt]);
- dma_addr[scnt] = dma_map_single(cb->pd->device->dma_device,
+ dma_addr[scnt] = ib_dma_map_single(cb->pd->device,
buf[scnt], cb->size,
DMA_BIDIRECTIONAL);
if (dma_mapping_error(cb->pd->device->dma_device,
@@ -2032,7 +2032,7 @@ static void krping_fr_test6(struct krping_cb *cb)
goto err2;
}
DEBUG_LOG(cb, "%s buf[%u] %p\n", __func__, scnt, buf[scnt]);
- dma_addr[scnt] = dma_map_single(cb->pd->device->dma_device,
+ dma_addr[scnt] = ib_dma_map_single(cb->pd->device,
buf[scnt], cb->size,
DMA_BIDIRECTIONAL);
if (dma_mapping_error(cb->pd->device->dma_device,
diff --git a/sys/dev/aacraid/aacraid_pci.c b/sys/dev/aacraid/aacraid_pci.c
index 46eb53c85aba..0f67c742be0b 100644
--- a/sys/dev/aacraid/aacraid_pci.c
+++ b/sys/dev/aacraid/aacraid_pci.c
@@ -102,8 +102,6 @@ struct aac_ident
"Adaptec RAID Controller"},
{0x9005, 0x028d, 0, 0, AAC_HWIF_SRCV, 0,
"Adaptec RAID Controller"},
- {0x9005, 0x028f, 0, 0, AAC_HWIF_SRCV, 0,
- "Adaptec RAID Controller"},
{0, 0, 0, 0, 0, 0, 0}
};
diff --git a/sys/dev/bfe/if_bfe.c b/sys/dev/bfe/if_bfe.c
index eaad8f0b5981..50cb173f8e73 100644
--- a/sys/dev/bfe/if_bfe.c
+++ b/sys/dev/bfe/if_bfe.c
@@ -793,6 +793,8 @@ bfe_list_newbuf(struct bfe_softc *sc, int c)
int nsegs;
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+ if (m == NULL)
+ return (ENOBUFS);
m->m_len = m->m_pkthdr.len = MCLBYTES;
if (bus_dmamap_load_mbuf_sg(sc->bfe_rxmbuf_tag, sc->bfe_rx_sparemap,
diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c
index c5daac58da56..98978da9a53f 100644
--- a/sys/dev/bxe/bxe.c
+++ b/sys/dev/bxe/bxe.c
@@ -5603,7 +5603,7 @@ bxe_tx_start(if_t ifp)
fp = &sc->fp[0];
- if (ifp->if_drv_flags & IFF_DRV_OACTIVE) {
+ if (if_getdrvflags(ifp) & IFF_DRV_OACTIVE) {
fp->eth_q_stats.tx_queue_full_return++;
return;
}
@@ -5643,7 +5643,7 @@ bxe_tx_mq_start_locked(struct bxe_softc *sc,
}
}
- if (!sc->link_vars.link_up || !(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+ if (!sc->link_vars.link_up || !(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) {
fp->eth_q_stats.tx_request_link_down_failures++;
goto bxe_tx_mq_start_locked_exit;
}
diff --git a/sys/dev/chromebook_platform/chromebook_platform.c b/sys/dev/chromebook_platform/chromebook_platform.c
new file mode 100644
index 000000000000..5cfeb9cb1e4e
--- /dev/null
+++ b/sys/dev/chromebook_platform/chromebook_platform.c
@@ -0,0 +1,102 @@
+/*-
+ * Copyright (c) 2016 The FreeBSD Project.
+ * 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 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 HOLDERS 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/systm.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/errno.h>
+#include <sys/bus.h>
+
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
+
+/*
+ * Driver that attaches I2C devices.
+ */
+static struct {
+ uint32_t pci_id;
+ const char *name;
+ uint8_t addr;
+} slaves[] = {
+ { 0x9c628086, "isl", 0x88 },
+ { 0x9c618086, "cyapa", 0xce },
+};
+
+static void
+chromebook_i2c_identify(driver_t *driver, device_t bus)
+{
+ device_t controller;
+ device_t child;
+ int i;
+
+ /*
+ * A stopgap approach to preserve the status quo.
+ * A more intelligent approach is required to correctly
+ * identify a machine model and hardware available on it.
+ * For instance, DMI could be used.
+ * See http://lxr.free-electrons.com/source/drivers/platform/chrome/chromeos_laptop.c
+ */
+ controller = device_get_parent(bus);
+ if (strcmp(device_get_name(controller), "ig4iic") != 0)
+ return;
+
+ for (i = 0; i < nitems(slaves); i++) {
+ if (device_find_child(bus, slaves[i].name, -1) != NULL)
+ continue;
+ if (slaves[i].pci_id != pci_get_devid(controller))
+ continue;
+ child = BUS_ADD_CHILD(bus, 0, slaves[i].name, -1);
+ if (child != NULL)
+ iicbus_set_addr(child, slaves[i].addr);
+ }
+}
+
+static device_method_t chromebook_i2c_methods[] = {
+ DEVMETHOD(device_identify, chromebook_i2c_identify),
+ { 0, 0 }
+};
+
+static driver_t chromebook_i2c_driver = {
+ "chromebook_i2c",
+ chromebook_i2c_methods,
+ 0 /* no softc */
+};
+
+static devclass_t chromebook_i2c_devclass;
+
+DRIVER_MODULE(chromebook_i2c, iicbus, chromebook_i2c_driver,
+ chromebook_i2c_devclass, 0, 0);
+MODULE_VERSION(chromebook_i2c, 1);
+
diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c
index 553993a66f2b..9ba4b9566518 100644
--- a/sys/dev/cxgbe/common/t4_hw.c
+++ b/sys/dev/cxgbe/common/t4_hw.c
@@ -432,6 +432,21 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
CH_ERR(adap, "command %#x in mailbox %d timed out\n",
*(const u8 *)cmd, mbox);
+ /* If DUMP_MBOX is set the mbox has already been dumped */
+ if ((adap->debug_flags & DF_DUMP_MBOX) == 0) {
+ p = cmd;
+ CH_ERR(adap, "mbox: %016llx %016llx %016llx %016llx "
+ "%016llx %016llx %016llx %016llx\n",
+ (unsigned long long)be64_to_cpu(p[0]),
+ (unsigned long long)be64_to_cpu(p[1]),
+ (unsigned long long)be64_to_cpu(p[2]),
+ (unsigned long long)be64_to_cpu(p[3]),
+ (unsigned long long)be64_to_cpu(p[4]),
+ (unsigned long long)be64_to_cpu(p[5]),
+ (unsigned long long)be64_to_cpu(p[6]),
+ (unsigned long long)be64_to_cpu(p[7]));
+ }
+
t4_report_fw_error(adap);
t4_fatal_err(adap);
return ret;
@@ -5855,10 +5870,13 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
p->tx_ppp6 = GET_STAT(TX_PORT_PPP6);
p->tx_ppp7 = GET_STAT(TX_PORT_PPP7);
- if (stat_ctl & F_COUNTPAUSESTATTX) {
- p->tx_frames -= p->tx_pause;
- p->tx_octets -= p->tx_pause * 64;
- p->tx_mcast_frames -= p->tx_pause;
+ if (chip_id(adap) >= CHELSIO_T5) {
+ if (stat_ctl & F_COUNTPAUSESTATTX) {
+ p->tx_frames -= p->tx_pause;
+ p->tx_octets -= p->tx_pause * 64;
+ }
+ if (stat_ctl & F_COUNTPAUSEMCTX)
+ p->tx_mcast_frames -= p->tx_pause;
}
p->rx_pause = GET_STAT(RX_PORT_PAUSE);
@@ -5889,10 +5907,13 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
p->rx_ppp6 = GET_STAT(RX_PORT_PPP6);
p->rx_ppp7 = GET_STAT(RX_PORT_PPP7);
- if (stat_ctl & F_COUNTPAUSESTATRX) {
- p->rx_frames -= p->rx_pause;
- p->rx_octets -= p->rx_pause * 64;
- p->rx_mcast_frames -= p->rx_pause;
+ if (chip_id(adap) >= CHELSIO_T5) {
+ if (stat_ctl & F_COUNTPAUSESTATRX) {
+ p->rx_frames -= p->rx_pause;
+ p->rx_octets -= p->rx_pause * 64;
+ }
+ if (stat_ctl & F_COUNTPAUSEMCRX)
+ p->rx_mcast_frames -= p->rx_pause;
}
p->rx_ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_DROP_FRAME) : 0;
diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c
index 3748b2bc80f7..88c2e91bc7ae 100644
--- a/sys/dev/cxgbe/t4_sge.c
+++ b/sys/dev/cxgbe/t4_sge.c
@@ -2110,24 +2110,6 @@ m_advance(struct mbuf **pm, int *poffset, int len)
return ((void *)p);
}
-static inline int
-same_paddr(char *a, char *b)
-{
-
- if (a == b)
- return (1);
- else if (a != NULL && b != NULL) {
- vm_offset_t x = (vm_offset_t)a;
- vm_offset_t y = (vm_offset_t)b;
-
- if ((x & PAGE_MASK) == (y & PAGE_MASK) &&
- pmap_kextract(x) == pmap_kextract(y))
- return (1);
- }
-
- return (0);
-}
-
/*
* Can deal with empty mbufs in the chain that have m_len = 0, but the chain
* must have at least one mbuf that's not empty.
@@ -2135,24 +2117,25 @@ same_paddr(char *a, char *b)
static inline int
count_mbuf_nsegs(struct mbuf *m)
{
- char *prev_end, *start;
+ vm_paddr_t lastb, next;
+ vm_offset_t va;
int len, nsegs;
MPASS(m != NULL);
nsegs = 0;
- prev_end = NULL;
+ lastb = 0;
for (; m; m = m->m_next) {
len = m->m_len;
if (__predict_false(len == 0))
continue;
- start = mtod(m, char *);
-
- nsegs += sglist_count(start, len);
- if (same_paddr(prev_end, start))
+ va = mtod(m, vm_offset_t);
+ next = pmap_kextract(va);
+ nsegs += sglist_count(m->m_data, len);
+ if (lastb + 1 == next)
nsegs--;
- prev_end = start + len;
+ lastb = pmap_kextract(va + len - 1);
}
MPASS(nsegs > 0);
diff --git a/sys/dev/cyapa/cyapa.c b/sys/dev/cyapa/cyapa.c
index 035121d7468b..d3a0ef18d83e 100644
--- a/sys/dev/cyapa/cyapa.c
+++ b/sys/dev/cyapa/cyapa.c
@@ -122,11 +122,11 @@ __FBSDID("$FreeBSD$");
#include <sys/uio.h>
#include <sys/vnode.h>
-#include <dev/smbus/smbconf.h>
-#include <dev/smbus/smbus.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
#include <dev/cyapa/cyapa.h>
-#include "smbus_if.h"
+#include "iicbus_if.h"
#include "bus_if.h"
#include "device_if.h"
@@ -149,7 +149,6 @@ struct cyapa_fifo {
struct cyapa_softc {
device_t dev;
int count; /* >0 if device opened */
- int addr;
struct cdev *devnode;
struct selinfo selinfo;
struct mtx mutex;
@@ -273,6 +272,30 @@ static int cyapa_reset = 0;
SYSCTL_INT(_debug, OID_AUTO, cyapa_reset, CTLFLAG_RW,
&cyapa_reset, 0, "Reset track pad");
+static int
+cyapa_read_bytes(device_t dev, uint8_t reg, uint8_t *val, int cnt)
+{
+ uint16_t addr = iicbus_get_addr(dev);
+ struct iic_msg msgs[] = {
+ { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
+ { addr, IIC_M_RD, cnt, val },
+ };
+
+ return (iicbus_transfer(dev, msgs, nitems(msgs)));
+}
+
+static int
+cyapa_write_bytes(device_t dev, uint8_t reg, const uint8_t *val, int cnt)
+{
+ uint16_t addr = iicbus_get_addr(dev);
+ struct iic_msg msgs[] = {
+ { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
+ { addr, IIC_M_WR | IIC_M_NOSTART, cnt, __DECONST(uint8_t *, val) },
+ };
+
+ return (iicbus_transfer(dev, msgs, nitems(msgs)));
+}
+
static void
cyapa_lock(struct cyapa_softc *sc)
{
@@ -318,7 +341,7 @@ cyapa_notify(struct cyapa_softc *sc)
* Initialize the device
*/
static int
-init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe)
+init_device(device_t dev, struct cyapa_cap *cap, int probe)
{
static char bl_exit[] = {
0x00, 0xff, 0xa5, 0x00, 0x01,
@@ -326,17 +349,13 @@ init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe)
static char bl_deactivate[] = {
0x00, 0xff, 0x3b, 0x00, 0x01,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
- device_t bus;
struct cyapa_boot_regs boot;
int error;
int retries;
- bus = device_get_parent(dev); /* smbus */
-
/* Get status */
- error = smbus_trans(bus, addr, CMD_BOOT_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, (void *)&boot, sizeof(boot), NULL);
+ error = cyapa_read_bytes(dev, CMD_BOOT_STATUS,
+ (void *)&boot, sizeof(boot));
if (error)
goto done;
@@ -350,25 +369,21 @@ init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe)
/* Busy, wait loop. */
} else if (boot.error & CYAPA_ERROR_BOOTLOADER) {
/* Magic */
- error = smbus_trans(bus, addr, CMD_BOOT_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- bl_deactivate, sizeof(bl_deactivate),
- NULL, 0, NULL);
+ error = cyapa_write_bytes(dev, CMD_BOOT_STATUS,
+ bl_deactivate, sizeof(bl_deactivate));
if (error)
goto done;
} else {
/* Magic */
- error = smbus_trans(bus, addr, CMD_BOOT_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- bl_exit, sizeof(bl_exit), NULL, 0, NULL);
+ error = cyapa_write_bytes(dev, CMD_BOOT_STATUS,
+ bl_exit, sizeof(bl_exit));
if (error)
goto done;
}
pause("cyapab1", (hz * 2) / 10);
--retries;
- error = smbus_trans(bus, addr, CMD_BOOT_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, (void *)&boot, sizeof(boot), NULL);
+ error = cyapa_read_bytes(dev, CMD_BOOT_STATUS,
+ (void *)&boot, sizeof(boot));
if (error)
goto done;
}
@@ -381,9 +396,8 @@ init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe)
/* Check identity */
if (cap) {
- error = smbus_trans(bus, addr, CMD_QUERY_CAPABILITIES,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, (void *)cap, sizeof(*cap), NULL);
+ error = cyapa_read_bytes(dev, CMD_QUERY_CAPABILITIES,
+ (void *)cap, sizeof(*cap));
if (strncmp(cap->prod_ida, "CYTRA", 5) != 0) {
device_printf(dev, "Product ID \"%5.5s\" mismatch\n",
@@ -391,9 +405,8 @@ init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe)
error = ENXIO;
}
}
- error = smbus_trans(bus, addr, CMD_BOOT_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, (void *)&boot, sizeof(boot), NULL);
+ error = cyapa_read_bytes(dev, CMD_BOOT_STATUS,
+ (void *)&boot, sizeof(boot));
if (probe == 0) /* official init */
device_printf(dev, "cyapa init status %02x\n", boot.stat);
@@ -452,16 +465,16 @@ cyapa_probe(device_t dev)
int addr;
int error;
- addr = smbus_get_addr(dev);
+ addr = iicbus_get_addr(dev);
/*
* 0x67 - cypress trackpad on the acer c720
* (other devices might use other ids).
*/
- if (addr != 0x67)
+ if (addr != 0xce)
return (ENXIO);
- error = init_device(dev, &cap, addr, 1);
+ error = init_device(dev, &cap, 1);
if (error != 0)
return (ENXIO);
@@ -482,15 +495,14 @@ cyapa_attach(device_t dev)
sc->reporting_mode = 1;
unit = device_get_unit(dev);
- addr = smbus_get_addr(dev);
+ addr = iicbus_get_addr(dev);
- if (init_device(dev, &cap, addr, 0))
+ if (init_device(dev, &cap, 0))
return (ENXIO);
mtx_init(&sc->mutex, "cyapa", NULL, MTX_DEF);
sc->dev = dev;
- sc->addr = addr;
knlist_init_mtx(&sc->selinfo.si_note, &sc->mutex);
@@ -1159,7 +1171,7 @@ cyapa_poll_thread(void *arg)
{
struct cyapa_softc *sc;
struct cyapa_regs regs;
- device_t bus; /* smbus */
+ device_t bus; /* iicbus */
int error;
int freq;
int isidle;
@@ -1180,12 +1192,10 @@ cyapa_poll_thread(void *arg)
while (!sc->detaching) {
cyapa_unlock(sc);
- error = smbus_request_bus(bus, sc->dev, SMB_WAIT);
+ error = iicbus_request_bus(bus, sc->dev, IIC_WAIT);
if (error == 0) {
- error = smbus_trans(bus, sc->addr, CMD_DEV_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0,
- (void *)&regs, sizeof(regs), NULL);
+ error = cyapa_read_bytes(sc->dev, CMD_DEV_STATUS,
+ (void *)&regs, sizeof(regs));
if (error == 0) {
isidle = cyapa_raw_input(sc, &regs, freq);
}
@@ -1200,9 +1210,9 @@ cyapa_poll_thread(void *arg)
(unsigned)(ticks - last_reset) > TIME_TO_RESET)) {
cyapa_reset = 0;
last_reset = ticks;
- init_device(sc->dev, NULL, sc->addr, 2);
+ init_device(sc->dev, NULL, 2);
}
- smbus_release_bus(bus, sc->dev);
+ iicbus_release_bus(bus, sc->dev);
}
pause("cyapw", hz / freq);
++sc->poll_ticks;
@@ -1531,18 +1541,16 @@ cyapa_set_power_mode(struct cyapa_softc *sc, int mode)
int error;
bus = device_get_parent(sc->dev);
- error = smbus_request_bus(bus, sc->dev, SMB_WAIT);
+ error = iicbus_request_bus(bus, sc->dev, IIC_WAIT);
if (error == 0) {
- error = smbus_trans(bus, sc->addr, CMD_POWER_MODE,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, (void *)&data, 1, NULL);
+ error = cyapa_read_bytes(sc->dev, CMD_POWER_MODE,
+ &data, 1);
data = (data & ~0xFC) | mode;
if (error == 0) {
- error = smbus_trans(bus, sc->addr, CMD_POWER_MODE,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- (void *)&data, 1, NULL, 0, NULL);
+ error = cyapa_write_bytes(sc->dev, CMD_POWER_MODE,
+ &data, 1);
}
- smbus_release_bus(bus, sc->dev);
+ iicbus_release_bus(bus, sc->dev);
}
}
@@ -1697,6 +1705,6 @@ cyapa_fuzz(int delta, int *fuzzp)
return (delta);
}
-DRIVER_MODULE(cyapa, smbus, cyapa_driver, cyapa_devclass, NULL, NULL);
-MODULE_DEPEND(cyapa, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+DRIVER_MODULE(cyapa, iicbus, cyapa_driver, cyapa_devclass, NULL, NULL);
+MODULE_DEPEND(cyapa, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
MODULE_VERSION(cyapa, 1);
diff --git a/sys/dev/dpaa/bman_fdt.c b/sys/dev/dpaa/bman_fdt.c
index 691a8dea9538..c7950270e34d 100644
--- a/sys/dev/dpaa/bman_fdt.c
+++ b/sys/dev/dpaa/bman_fdt.c
@@ -143,7 +143,7 @@ bman_portals_fdt_attach(device_t dev)
ihandle_t cpu;
int cpu_num, cpus, intr_rid;
struct dpaa_portals_devinfo di;
- struct ofw_bus_devinfo ofw_di;
+ struct ofw_bus_devinfo ofw_di = {};
cpus = 0;
sc = device_get_softc(dev);
diff --git a/sys/dev/dpaa/qman_fdt.c b/sys/dev/dpaa/qman_fdt.c
index 4df8c05b84e0..69f128cf649f 100644
--- a/sys/dev/dpaa/qman_fdt.c
+++ b/sys/dev/dpaa/qman_fdt.c
@@ -91,7 +91,7 @@ qman_fdt_probe(device_t dev)
static device_probe_t qman_portals_fdt_probe;
static device_attach_t qman_portals_fdt_attach;
-static device_method_t bm_portals_methods[] = {
+static device_method_t qm_portals_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, qman_portals_fdt_probe),
DEVMETHOD(device_attach, qman_portals_fdt_attach),
@@ -100,14 +100,14 @@ static device_method_t bm_portals_methods[] = {
{ 0, 0 }
};
-static driver_t bm_portals_driver = {
+static driver_t qm_portals_driver = {
"qman-portals",
- bm_portals_methods,
+ qm_portals_methods,
sizeof(struct dpaa_portals_softc),
};
-static devclass_t bm_portals_devclass;
-DRIVER_MODULE(qman_portals, ofwbus, bm_portals_driver, bm_portals_devclass, 0, 0);
+static devclass_t qm_portals_devclass;
+DRIVER_MODULE(qman_portals, ofwbus, qm_portals_driver, qm_portals_devclass, 0, 0);
static void
get_addr_props(phandle_t node, uint32_t *addrp, uint32_t *sizep)
@@ -143,7 +143,7 @@ qman_portals_fdt_attach(device_t dev)
ihandle_t cpu;
int cpu_num, cpus, intr_rid;
struct dpaa_portals_devinfo di;
- struct ofw_bus_devinfo ofw_di;
+ struct ofw_bus_devinfo ofw_di = {};
cpus = 0;
sc = device_get_softc(dev);
diff --git a/sys/dev/evdev/evdev.c b/sys/dev/evdev/evdev.c
index 63e04966fec9..4de5dee8db04 100644
--- a/sys/dev/evdev/evdev.c
+++ b/sys/dev/evdev/evdev.c
@@ -822,21 +822,6 @@ push:
return (ret);
}
-inline int
-evdev_sync(struct evdev_dev *evdev)
-{
-
- return (evdev_push_event(evdev, EV_SYN, SYN_REPORT, 1));
-}
-
-
-inline int
-evdev_mt_sync(struct evdev_dev *evdev)
-{
-
- return (evdev_push_event(evdev, EV_SYN, SYN_MT_REPORT, 1));
-}
-
int
evdev_register_client(struct evdev_dev *evdev, struct evdev_client *client)
{
diff --git a/sys/dev/evdev/evdev.h b/sys/dev/evdev/evdev.h
index 7287e739e832..34808b4b563c 100644
--- a/sys/dev/evdev/evdev.h
+++ b/sys/dev/evdev/evdev.h
@@ -97,8 +97,6 @@ int evdev_register(struct evdev_dev *);
int evdev_register_mtx(struct evdev_dev *, struct mtx *);
int evdev_unregister(struct evdev_dev *);
int evdev_push_event(struct evdev_dev *, uint16_t, uint16_t, int32_t);
-int evdev_sync(struct evdev_dev *);
-int evdev_mt_sync(struct evdev_dev *);
void evdev_support_prop(struct evdev_dev *, uint16_t);
void evdev_support_event(struct evdev_dev *, uint16_t);
void evdev_support_key(struct evdev_dev *, uint16_t);
@@ -129,4 +127,68 @@ void evdev_push_leds(struct evdev_dev *, int);
void evdev_push_repeats(struct evdev_dev *, keyboard_t *);
evdev_event_t evdev_ev_kbd_event;
+/* Event reporting shortcuts: */
+static __inline int
+evdev_sync(struct evdev_dev *evdev)
+{
+
+ return (evdev_push_event(evdev, EV_SYN, SYN_REPORT, 1));
+}
+
+static __inline int
+evdev_mt_sync(struct evdev_dev *evdev)
+{
+
+ return (evdev_push_event(evdev, EV_SYN, SYN_MT_REPORT, 1));
+}
+
+static __inline int
+evdev_push_key(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_KEY, code, value != 0));
+}
+
+static __inline int
+evdev_push_rel(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_REL, code, value));
+}
+
+static __inline int
+evdev_push_abs(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_ABS, code, value));
+}
+
+static __inline int
+evdev_push_msc(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_MSC, code, value));
+}
+
+static __inline int
+evdev_push_led(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_LED, code, value != 0));
+}
+
+static __inline int
+evdev_push_snd(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_SND, code, value != 0));
+}
+
+static __inline int
+evdev_push_sw(struct evdev_dev *evdev, uint16_t code, int32_t value)
+{
+
+ return (evdev_push_event(evdev, EV_SW, code, value != 0));
+}
+
#endif /* _DEV_EVDEV_EVDEV_H */
diff --git a/sys/dev/evdev/evdev_utils.c b/sys/dev/evdev/evdev_utils.c
index 47e5e64a3c42..860634299270 100644
--- a/sys/dev/evdev/evdev_utils.c
+++ b/sys/dev/evdev/evdev_utils.c
@@ -271,8 +271,8 @@ evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons)
size_t i;
for (i = 0; i < nitems(evdev_mouse_button_codes); i++)
- evdev_push_event(evdev, EV_KEY, evdev_mouse_button_codes[i],
- (buttons & (1 << i)) != 0);
+ evdev_push_key(evdev, evdev_mouse_button_codes[i],
+ buttons & (1 << i));
}
void
@@ -285,8 +285,7 @@ evdev_push_leds(struct evdev_dev *evdev, int leds)
return;
for (i = 0; i < nitems(evdev_led_codes); i++)
- evdev_push_event(evdev, EV_LED, evdev_led_codes[i],
- (leds & (1 << i)) != 0);
+ evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i));
}
void
diff --git a/sys/dev/fdt/fdt_intr.h b/sys/dev/fdt/fdt_intr.h
new file mode 100644
index 000000000000..b8568e1399f0
--- /dev/null
+++ b/sys/dev/fdt/fdt_intr.h
@@ -0,0 +1,44 @@
+/*-
+ * Copyright (c) 2016 Andrew Turner <andrew@FreeBSD.org>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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 _FDT_INTR_H_
+#define _FDT_INTR_H_
+
+#define FDT_INTR_EDGE_RISING 1
+#define FDT_INTR_EDGE_FALLING 2
+#define FDT_INTR_LEVEL_HIGH 4
+#define FDT_INTR_LEVEL_LOW 8
+#define FDT_INTR_LOW_MASK (FDT_INTR_EDGE_FALLING | FDT_INTR_LEVEL_LOW)
+#define FDT_INTR_EDGE_MASK (FDT_INTR_EDGE_RISING | FDT_INTR_EDGE_FALLING)
+#define FDT_INTR_MASK 0xf
+
+#endif /* _FDT_INTR_H_ */
diff --git a/sys/dev/gpio/gpiobusvar.h b/sys/dev/gpio/gpiobusvar.h
index 4717bf3fa32e..b6fb44cf5866 100644
--- a/sys/dev/gpio/gpiobusvar.h
+++ b/sys/dev/gpio/gpiobusvar.h
@@ -38,7 +38,6 @@
#ifdef FDT
#include <dev/ofw/ofw_bus_subr.h>
-#include <gnu/dts/include/dt-bindings/gpio/gpio.h>
#endif
#ifdef INTRNG
diff --git a/sys/dev/gpio/ofw_gpiobus.c b/sys/dev/gpio/ofw_gpiobus.c
index 96775dc0eb00..f8fcbea95078 100644
--- a/sys/dev/gpio/ofw_gpiobus.c
+++ b/sys/dev/gpio/ofw_gpiobus.c
@@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$");
#include "gpiobus_if.h"
+#define GPIO_ACTIVE_LOW 1
+
static struct ofw_gpiobus_devinfo *ofw_gpiobus_setup_devinfo(device_t,
device_t, phandle_t);
static void ofw_gpiobus_destroy_devinfo(device_t, struct ofw_gpiobus_devinfo *);
diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c
index 14d708aee949..7221071de0f8 100644
--- a/sys/dev/hwpmc/hwpmc_amd.c
+++ b/sys/dev/hwpmc/hwpmc_amd.c
@@ -689,12 +689,13 @@ amd_intr(int cpu, struct trapframe *tf)
error = pmc_process_interrupt(cpu, PMC_HR, pm, tf,
TRAPF_USERMODE(tf));
if (error == 0)
- wrmsr(evsel, config | AMD_PMC_ENABLE);
+ wrmsr(evsel, config);
}
atomic_add_int(retval ? &pmc_stats.pm_intr_processed :
&pmc_stats.pm_intr_ignored, 1);
+ PMCDBG1(MDP,INT,2, "retval=%d", retval);
return (retval);
}
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hn_nvs.c
index 2676222541e3..0d8c75cbc079 100644
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.c
+++ b/sys/dev/hyperv/netvsc/hn_nvs.c
@@ -24,49 +24,59 @@
* 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$
*/
-/**
- * HyperV vmbus network VSC (virtual services client) module
- *
+/*
+ * Network Virtualization Service.
*/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "opt_inet6.h"
+#include "opt_inet.h"
#include <sys/param.h>
#include <sys/kernel.h>
-#include <sys/socket.h>
#include <sys/limits.h>
-#include <sys/lock.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/taskqueue.h>
+
#include <net/if.h>
#include <net/if_var.h>
-#include <net/if_arp.h>
-#include <machine/bus.h>
-#include <machine/atomic.h>
+#include <net/if_media.h>
+
+#include <netinet/in.h>
+#include <netinet/tcp_lro.h>
#include <dev/hyperv/include/hyperv.h>
+#include <dev/hyperv/include/hyperv_busdma.h>
+#include <dev/hyperv/include/vmbus.h>
#include <dev/hyperv/include/vmbus_xact.h>
-#include <dev/hyperv/netvsc/hv_net_vsc.h>
-#include <dev/hyperv/netvsc/hv_rndis_filter.h>
+
+#include <dev/hyperv/netvsc/ndis.h>
#include <dev/hyperv/netvsc/if_hnreg.h>
#include <dev/hyperv/netvsc/if_hnvar.h>
-
-MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver");
-
-/*
- * Forward declarations
- */
-static int hn_nvs_conn_chim(struct hn_softc *sc);
-static int hn_nvs_conn_rxbuf(struct hn_softc *);
-static int hn_nvs_disconn_chim(struct hn_softc *sc);
-static int hn_nvs_disconn_rxbuf(struct hn_softc *sc);
-static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
- struct hn_softc *, struct vmbus_channel *chan,
- const void *, int);
-
-struct hn_send_ctx hn_send_ctx_none =
- HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
+#include <dev/hyperv/netvsc/hn_nvs.h>
+
+static int hn_nvs_conn_chim(struct hn_softc *);
+static int hn_nvs_conn_rxbuf(struct hn_softc *);
+static int hn_nvs_disconn_chim(struct hn_softc *);
+static int hn_nvs_disconn_rxbuf(struct hn_softc *);
+static int hn_nvs_conf_ndis(struct hn_softc *, int);
+static int hn_nvs_init_ndis(struct hn_softc *);
+static int hn_nvs_doinit(struct hn_softc *, uint32_t);
+static int hn_nvs_init(struct hn_softc *);
+static const void *hn_nvs_xact_execute(struct hn_softc *,
+ struct vmbus_xact *, void *, int,
+ size_t *, uint32_t);
+static void hn_nvs_sent_none(struct hn_nvs_sendctx *,
+ struct hn_softc *, struct vmbus_channel *,
+ const void *, int);
+
+struct hn_nvs_sendctx hn_nvs_sendctx_none =
+ HN_NVS_SENDCTX_INITIALIZER(hn_nvs_sent_none, NULL);
static const uint32_t hn_nvs_version[] = {
HN_NVS_VERSION_5,
@@ -75,38 +85,11 @@ static const uint32_t hn_nvs_version[] = {
HN_NVS_VERSION_1
};
-uint32_t
-hn_chim_alloc(struct hn_softc *sc)
-{
- int i, bmap_cnt = sc->hn_chim_bmap_cnt;
- u_long *bmap = sc->hn_chim_bmap;
- uint32_t ret = HN_NVS_CHIM_IDX_INVALID;
-
- for (i = 0; i < bmap_cnt; ++i) {
- int idx;
-
- idx = ffsl(~bmap[i]);
- if (idx == 0)
- continue;
-
- --idx; /* ffsl is 1-based */
- KASSERT(i * LONG_BIT + idx < sc->hn_chim_cnt,
- ("invalid i %d and idx %d", i, idx));
-
- if (atomic_testandset_long(&bmap[i], idx))
- continue;
-
- ret = i * LONG_BIT + idx;
- break;
- }
- return (ret);
-}
-
static const void *
hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact,
void *req, int reqlen, size_t *resplen0, uint32_t type)
{
- struct hn_send_ctx sndc;
+ struct hn_nvs_sendctx sndc;
size_t resplen, min_resplen = *resplen0;
const struct hn_nvs_hdr *hdr;
int error;
@@ -117,7 +100,7 @@ hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact,
/*
* Execute the xact setup by the caller.
*/
- hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
+ hn_nvs_sendctx_init(&sndc, hn_nvs_sent_xact, xact);
vmbus_xact_activate(xact);
error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
@@ -150,7 +133,7 @@ hn_nvs_req_send(struct hn_softc *sc, void *req, int reqlen)
{
return (hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE,
- req, reqlen, &hn_send_ctx_none));
+ req, reqlen, &hn_nvs_sendctx_none));
}
static int
@@ -167,9 +150,9 @@ hn_nvs_conn_rxbuf(struct hn_softc *sc)
* Limit RXBUF size for old NVS.
*/
if (sc->hn_nvs_ver <= HN_NVS_VERSION_2)
- rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
+ rxbuf_size = HN_RXBUF_SIZE_COMPAT;
else
- rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE;
+ rxbuf_size = HN_RXBUF_SIZE;
/*
* Connect the RXBUF GPADL to the primary channel.
@@ -248,8 +231,7 @@ hn_nvs_conn_chim(struct hn_softc *sc)
* Sub-channels just share this chimney sending buffer.
*/
error = vmbus_chan_gpadl_connect(sc->hn_prichan,
- sc->hn_chim_dma.hv_paddr, NETVSC_SEND_BUFFER_SIZE,
- &sc->hn_chim_gpadl);
+ sc->hn_chim_dma.hv_paddr, HN_CHIM_SIZE, &sc->hn_chim_gpadl);
if (error) {
if_printf(sc->hn_ifp, "chim gpadl conn failed: %d\n", error);
goto cleanup;
@@ -296,8 +278,8 @@ hn_nvs_conn_chim(struct hn_softc *sc)
}
sc->hn_chim_szmax = sectsz;
- sc->hn_chim_cnt = NETVSC_SEND_BUFFER_SIZE / sc->hn_chim_szmax;
- if (NETVSC_SEND_BUFFER_SIZE % sc->hn_chim_szmax != 0) {
+ sc->hn_chim_cnt = HN_CHIM_SIZE / sc->hn_chim_szmax;
+ if (HN_CHIM_SIZE % sc->hn_chim_szmax != 0) {
if_printf(sc->hn_ifp, "chimney sending sections are "
"not properly aligned\n");
}
@@ -308,7 +290,7 @@ hn_nvs_conn_chim(struct hn_softc *sc)
sc->hn_chim_bmap_cnt = sc->hn_chim_cnt / LONG_BIT;
sc->hn_chim_bmap = malloc(sc->hn_chim_bmap_cnt * sizeof(u_long),
- M_NETVSC, M_WAITOK | M_ZERO);
+ M_DEVBUF, M_WAITOK | M_ZERO);
/* Done! */
sc->hn_flags |= HN_FLAG_CHIM_CONNECTED;
@@ -427,7 +409,7 @@ hn_nvs_disconn_chim(struct hn_softc *sc)
}
if (sc->hn_chim_bmap != NULL) {
- free(sc->hn_chim_bmap, M_NETVSC);
+ free(sc->hn_chim_bmap, M_DEVBUF);
sc->hn_chim_bmap = NULL;
}
return (0);
@@ -634,7 +616,7 @@ hn_nvs_detach(struct hn_softc *sc)
}
void
-hn_nvs_sent_xact(struct hn_send_ctx *sndc,
+hn_nvs_sent_xact(struct hn_nvs_sendctx *sndc,
struct hn_softc *sc __unused, struct vmbus_channel *chan __unused,
const void *data, int dlen)
{
@@ -643,60 +625,13 @@ hn_nvs_sent_xact(struct hn_send_ctx *sndc,
}
static void
-hn_nvs_sent_none(struct hn_send_ctx *sndc __unused,
+hn_nvs_sent_none(struct hn_nvs_sendctx *sndc __unused,
struct hn_softc *sc __unused, struct vmbus_channel *chan __unused,
const void *data __unused, int dlen __unused)
{
/* EMPTY */
}
-void
-hn_chim_free(struct hn_softc *sc, uint32_t chim_idx)
-{
- u_long mask;
- uint32_t idx;
-
- idx = chim_idx / LONG_BIT;
- KASSERT(idx < sc->hn_chim_bmap_cnt,
- ("invalid chimney index 0x%x", chim_idx));
-
- mask = 1UL << (chim_idx % LONG_BIT);
- KASSERT(sc->hn_chim_bmap[idx] & mask,
- ("index bitmap 0x%lx, chimney index %u, "
- "bitmap idx %d, bitmask 0x%lx",
- sc->hn_chim_bmap[idx], chim_idx, idx, mask));
-
- atomic_clear_long(&sc->hn_chim_bmap[idx], mask);
-}
-
-/*
- * Net VSC on send
- * Sends a packet on the specified Hyper-V device.
- * Returns 0 on success, non-zero on failure.
- */
-int
-hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
- struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
-{
- struct hn_nvs_rndis rndis;
- int ret;
-
- rndis.nvs_type = HN_NVS_TYPE_RNDIS;
- rndis.nvs_rndis_mtype = rndis_mtype;
- rndis.nvs_chim_idx = sndc->hn_chim_idx;
- rndis.nvs_chim_sz = sndc->hn_chim_sz;
-
- if (gpa_cnt) {
- ret = hn_nvs_send_sglist(chan, gpa, gpa_cnt,
- &rndis, sizeof(rndis), sndc);
- } else {
- ret = hn_nvs_send(chan, VMBUS_CHANPKT_FLAG_RC,
- &rndis, sizeof(rndis), sndc);
- }
-
- return (ret);
-}
-
int
hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch0)
{
@@ -747,3 +682,12 @@ done:
vmbus_xact_put(xact);
return (error);
}
+
+int
+hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan,
+ struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
+{
+
+ return hn_nvs_send_rndis_sglist(chan, HN_NVS_RNDIS_MTYPE_CTRL,
+ sndc, gpa, gpa_cnt);
+}
diff --git a/sys/dev/hyperv/netvsc/hn_nvs.h b/sys/dev/hyperv/netvsc/hn_nvs.h
new file mode 100644
index 000000000000..49b03e09b808
--- /dev/null
+++ b/sys/dev/hyperv/netvsc/hn_nvs.h
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2009-2012,2016 Microsoft Corp.
+ * Copyright (c) 2010-2012 Citrix Inc.
+ * 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 unmodified, 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _HN_NVS_H_
+#define _HN_NVS_H_
+
+struct hn_nvs_sendctx;
+struct vmbus_channel;
+struct hn_softc;
+
+typedef void (*hn_nvs_sent_t)
+ (struct hn_nvs_sendctx *, struct hn_softc *,
+ struct vmbus_channel *, const void *, int);
+
+struct hn_nvs_sendctx {
+ hn_nvs_sent_t hn_cb;
+ void *hn_cbarg;
+};
+
+#define HN_NVS_SENDCTX_INITIALIZER(cb, cbarg) \
+{ \
+ .hn_cb = cb, \
+ .hn_cbarg = cbarg \
+}
+
+static __inline void
+hn_nvs_sendctx_init(struct hn_nvs_sendctx *sndc, hn_nvs_sent_t cb, void *cbarg)
+{
+
+ sndc->hn_cb = cb;
+ sndc->hn_cbarg = cbarg;
+}
+
+static __inline int
+hn_nvs_send(struct vmbus_channel *chan, uint16_t flags,
+ void *nvs_msg, int nvs_msglen, struct hn_nvs_sendctx *sndc)
+{
+
+ return (vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, flags,
+ nvs_msg, nvs_msglen, (uint64_t)(uintptr_t)sndc));
+}
+
+static __inline int
+hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen,
+ void *nvs_msg, int nvs_msglen, struct hn_nvs_sendctx *sndc)
+{
+
+ return (vmbus_chan_send_sglist(chan, sg, sglen, nvs_msg, nvs_msglen,
+ (uint64_t)(uintptr_t)sndc));
+}
+
+static __inline int
+hn_nvs_send_rndis_sglist(struct vmbus_channel *chan, uint32_t rndis_mtype,
+ struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
+{
+ struct hn_nvs_rndis rndis;
+
+ rndis.nvs_type = HN_NVS_TYPE_RNDIS;
+ rndis.nvs_rndis_mtype = rndis_mtype;
+ rndis.nvs_chim_idx = HN_NVS_CHIM_IDX_INVALID;
+ rndis.nvs_chim_sz = 0;
+
+ return (hn_nvs_send_sglist(chan, gpa, gpa_cnt,
+ &rndis, sizeof(rndis), sndc));
+}
+
+int hn_nvs_attach(struct hn_softc *sc, int mtu);
+void hn_nvs_detach(struct hn_softc *sc);
+int hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch);
+void hn_nvs_sent_xact(struct hn_nvs_sendctx *sndc,
+ struct hn_softc *sc, struct vmbus_channel *chan,
+ const void *data, int dlen);
+int hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan,
+ struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa,
+ int gpa_cnt);
+
+extern struct hn_nvs_sendctx hn_nvs_sendctx_none;
+
+#endif /* !_HN_NVS_H_ */
diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hn_rndis.c
index 16f292a22bba..08314a25e290 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c
+++ b/sys/dev/hyperv/netvsc/hn_rndis.c
@@ -29,41 +29,36 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_inet6.h"
+#include "opt_inet.h"
+
#include <sys/param.h>
-#include <sys/mbuf.h>
#include <sys/socket.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <sys/taskqueue.h>
+
+#include <machine/atomic.h>
+
+#include <net/ethernet.h>
#include <net/if.h>
-#include <net/if_arp.h>
#include <net/if_var.h>
-#include <net/ethernet.h>
+#include <net/if_media.h>
#include <net/rndis.h>
+
#include <netinet/in.h>
#include <netinet/ip.h>
-#include <sys/types.h>
-#include <machine/atomic.h>
-#include <sys/sema.h>
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-#include <vm/pmap.h>
+#include <netinet/tcp_lro.h>
#include <dev/hyperv/include/hyperv.h>
+#include <dev/hyperv/include/hyperv_busdma.h>
+#include <dev/hyperv/include/vmbus.h>
#include <dev/hyperv/include/vmbus_xact.h>
-#include <dev/hyperv/netvsc/hv_net_vsc.h>
-#include <dev/hyperv/netvsc/hv_rndis_filter.h>
-#include <dev/hyperv/netvsc/if_hnreg.h>
-#include <dev/hyperv/netvsc/ndis.h>
-#define HV_RF_RECVINFO_VLAN 0x1
-#define HV_RF_RECVINFO_CSUM 0x2
-#define HV_RF_RECVINFO_HASHINF 0x4
-#define HV_RF_RECVINFO_HASHVAL 0x8
-#define HV_RF_RECVINFO_ALL \
- (HV_RF_RECVINFO_VLAN | \
- HV_RF_RECVINFO_CSUM | \
- HV_RF_RECVINFO_HASHINF | \
- HV_RF_RECVINFO_HASHVAL)
+#include <dev/hyperv/netvsc/ndis.h>
+#include <dev/hyperv/netvsc/if_hnreg.h>
+#include <dev/hyperv/netvsc/if_hnvar.h>
+#include <dev/hyperv/netvsc/hn_nvs.h>
+#include <dev/hyperv/netvsc/hn_rndis.h>
#define HN_RNDIS_RID_COMPAT_MASK 0xffff
#define HN_RNDIS_RID_COMPAT_MAX HN_RNDIS_RID_COMPAT_MASK
@@ -82,24 +77,23 @@ __FBSDID("$FreeBSD$");
#define HN_NDIS_LSOV2_CAP_IP6 \
(NDIS_LSOV2_CAP_IP6EXT | NDIS_LSOV2_CAP_TCP6OPT)
-/*
- * Forward declarations
- */
-static void hv_rf_receive_indicate_status(struct hn_softc *sc,
- const void *data, int dlen);
-static void hv_rf_receive_data(struct hn_rx_ring *rxr,
- const void *data, int dlen);
-
-static int hn_rndis_query(struct hn_softc *sc, uint32_t oid,
- const void *idata, size_t idlen, void *odata, size_t *odlen0);
-static int hn_rndis_query2(struct hn_softc *sc, uint32_t oid,
- const void *idata, size_t idlen, void *odata, size_t *odlen0,
- size_t min_odlen);
-static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data,
- size_t dlen);
-static int hn_rndis_conf_offload(struct hn_softc *sc, int mtu);
-static int hn_rndis_query_hwcaps(struct hn_softc *sc,
- struct ndis_offload *caps);
+static const void *hn_rndis_xact_exec1(struct hn_softc *,
+ struct vmbus_xact *, size_t,
+ struct hn_nvs_sendctx *, size_t *);
+static const void *hn_rndis_xact_execute(struct hn_softc *,
+ struct vmbus_xact *, uint32_t, size_t, size_t *,
+ uint32_t);
+static int hn_rndis_query(struct hn_softc *, uint32_t,
+ const void *, size_t, void *, size_t *);
+static int hn_rndis_query2(struct hn_softc *, uint32_t,
+ const void *, size_t, void *, size_t *, size_t);
+static int hn_rndis_set(struct hn_softc *, uint32_t,
+ const void *, size_t);
+static int hn_rndis_init(struct hn_softc *);
+static int hn_rndis_halt(struct hn_softc *);
+static int hn_rndis_conf_offload(struct hn_softc *, int);
+static int hn_rndis_query_hwcaps(struct hn_softc *,
+ struct ndis_offload *);
static __inline uint32_t
hn_rndis_rid(struct hn_softc *sc)
@@ -115,371 +109,22 @@ again:
return ((rid & 0xffff) << 16);
}
-void *
-hn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize,
- size_t pi_dlen, uint32_t pi_type)
-{
- const size_t pi_size = HN_RNDIS_PKTINFO_SIZE(pi_dlen);
- struct rndis_pktinfo *pi;
-
- KASSERT((pi_size & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK) == 0,
- ("unaligned pktinfo size %zu, pktinfo dlen %zu", pi_size, pi_dlen));
-
- /*
- * Per-packet-info does not move; it only grows.
- *
- * NOTE:
- * rm_pktinfooffset in this phase counts from the beginning
- * of rndis_packet_msg.
- */
- KASSERT(pkt->rm_pktinfooffset + pkt->rm_pktinfolen + pi_size <= pktsize,
- ("%u pktinfo overflows RNDIS packet msg", pi_type));
- pi = (struct rndis_pktinfo *)((uint8_t *)pkt + pkt->rm_pktinfooffset +
- pkt->rm_pktinfolen);
- pkt->rm_pktinfolen += pi_size;
-
- pi->rm_size = pi_size;
- pi->rm_type = pi_type;
- pi->rm_pktinfooffset = RNDIS_PKTINFO_OFFSET;
-
- /* Data immediately follow per-packet-info. */
- pkt->rm_dataoffset += pi_size;
-
- /* Update RNDIS packet msg length */
- pkt->rm_len += pi_size;
-
- return (pi->rm_data);
-}
-
-/*
- * RNDIS filter receive indicate status
- */
-static void
-hv_rf_receive_indicate_status(struct hn_softc *sc, const void *data, int dlen)
-{
- const struct rndis_status_msg *msg;
- int ofs;
-
- if (dlen < sizeof(*msg)) {
- if_printf(sc->hn_ifp, "invalid RNDIS status\n");
- return;
- }
- msg = data;
-
- switch (msg->rm_status) {
- case RNDIS_STATUS_MEDIA_CONNECT:
- case RNDIS_STATUS_MEDIA_DISCONNECT:
- hn_link_status_update(sc);
- break;
-
- case RNDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG:
- /* Not really useful; ignore. */
- break;
-
- case RNDIS_STATUS_NETWORK_CHANGE:
- ofs = RNDIS_STBUFOFFSET_ABS(msg->rm_stbufoffset);
- if (dlen < ofs + msg->rm_stbuflen ||
- msg->rm_stbuflen < sizeof(uint32_t)) {
- if_printf(sc->hn_ifp, "network changed\n");
- } else {
- uint32_t change;
-
- memcpy(&change, ((const uint8_t *)msg) + ofs,
- sizeof(change));
- if_printf(sc->hn_ifp, "network changed, change %u\n",
- change);
- }
- hn_network_change(sc);
- break;
-
- default:
- /* TODO: */
- if_printf(sc->hn_ifp, "unknown RNDIS status 0x%08x\n",
- msg->rm_status);
- break;
- }
-}
-
-static int
-hn_rndis_rxinfo(const void *info_data, int info_dlen, struct hn_recvinfo *info)
-{
- const struct rndis_pktinfo *pi = info_data;
- uint32_t mask = 0;
-
- while (info_dlen != 0) {
- const void *data;
- uint32_t dlen;
-
- if (__predict_false(info_dlen < sizeof(*pi)))
- return (EINVAL);
- if (__predict_false(info_dlen < pi->rm_size))
- return (EINVAL);
- info_dlen -= pi->rm_size;
-
- if (__predict_false(pi->rm_size & RNDIS_PKTINFO_SIZE_ALIGNMASK))
- return (EINVAL);
- if (__predict_false(pi->rm_size < pi->rm_pktinfooffset))
- return (EINVAL);
- dlen = pi->rm_size - pi->rm_pktinfooffset;
- data = pi->rm_data;
-
- switch (pi->rm_type) {
- case NDIS_PKTINFO_TYPE_VLAN:
- if (__predict_false(dlen < NDIS_VLAN_INFO_SIZE))
- return (EINVAL);
- info->vlan_info = *((const uint32_t *)data);
- mask |= HV_RF_RECVINFO_VLAN;
- break;
-
- case NDIS_PKTINFO_TYPE_CSUM:
- if (__predict_false(dlen < NDIS_RXCSUM_INFO_SIZE))
- return (EINVAL);
- info->csum_info = *((const uint32_t *)data);
- mask |= HV_RF_RECVINFO_CSUM;
- break;
-
- case HN_NDIS_PKTINFO_TYPE_HASHVAL:
- if (__predict_false(dlen < HN_NDIS_HASH_VALUE_SIZE))
- return (EINVAL);
- info->hash_value = *((const uint32_t *)data);
- mask |= HV_RF_RECVINFO_HASHVAL;
- break;
-
- case HN_NDIS_PKTINFO_TYPE_HASHINF:
- if (__predict_false(dlen < HN_NDIS_HASH_INFO_SIZE))
- return (EINVAL);
- info->hash_info = *((const uint32_t *)data);
- mask |= HV_RF_RECVINFO_HASHINF;
- break;
-
- default:
- goto next;
- }
-
- if (mask == HV_RF_RECVINFO_ALL) {
- /* All found; done */
- break;
- }
-next:
- pi = (const struct rndis_pktinfo *)
- ((const uint8_t *)pi + pi->rm_size);
- }
-
- /*
- * Final fixup.
- * - If there is no hash value, invalidate the hash info.
- */
- if ((mask & HV_RF_RECVINFO_HASHVAL) == 0)
- info->hash_info = HN_NDIS_HASH_INFO_INVALID;
- return (0);
-}
-
-static __inline bool
-hn_rndis_check_overlap(int off, int len, int check_off, int check_len)
-{
-
- if (off < check_off) {
- if (__predict_true(off + len <= check_off))
- return (false);
- } else if (off > check_off) {
- if (__predict_true(check_off + check_len <= off))
- return (false);
- }
- return (true);
-}
-
-/*
- * RNDIS filter receive data
- */
-static void
-hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen)
-{
- const struct rndis_packet_msg *pkt;
- struct hn_recvinfo info;
- int data_off, pktinfo_off, data_len, pktinfo_len;
-
- /*
- * Check length.
- */
- if (__predict_false(dlen < sizeof(*pkt))) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg\n");
- return;
- }
- pkt = data;
-
- if (__predict_false(dlen < pkt->rm_len)) {
- if_printf(rxr->hn_ifp, "truncated RNDIS packet msg, "
- "dlen %d, msglen %u\n", dlen, pkt->rm_len);
- return;
- }
- if (__predict_false(pkt->rm_len <
- pkt->rm_datalen + pkt->rm_oobdatalen + pkt->rm_pktinfolen)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msglen, "
- "msglen %u, data %u, oob %u, pktinfo %u\n",
- pkt->rm_len, pkt->rm_datalen, pkt->rm_oobdatalen,
- pkt->rm_pktinfolen);
- return;
- }
- if (__predict_false(pkt->rm_datalen == 0)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, no data\n");
- return;
- }
-
- /*
- * Check offests.
- */
-#define IS_OFFSET_INVALID(ofs) \
- ((ofs) < RNDIS_PACKET_MSG_OFFSET_MIN || \
- ((ofs) & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK))
-
- /* XXX Hyper-V does not meet data offset alignment requirement */
- if (__predict_false(pkt->rm_dataoffset < RNDIS_PACKET_MSG_OFFSET_MIN)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
- "data offset %u\n", pkt->rm_dataoffset);
- return;
- }
- if (__predict_false(pkt->rm_oobdataoffset > 0 &&
- IS_OFFSET_INVALID(pkt->rm_oobdataoffset))) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
- "oob offset %u\n", pkt->rm_oobdataoffset);
- return;
- }
- if (__predict_true(pkt->rm_pktinfooffset > 0) &&
- __predict_false(IS_OFFSET_INVALID(pkt->rm_pktinfooffset))) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
- "pktinfo offset %u\n", pkt->rm_pktinfooffset);
- return;
- }
-
-#undef IS_OFFSET_INVALID
-
- data_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_dataoffset);
- data_len = pkt->rm_datalen;
- pktinfo_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_pktinfooffset);
- pktinfo_len = pkt->rm_pktinfolen;
-
- /*
- * Check OOB coverage.
- */
- if (__predict_false(pkt->rm_oobdatalen != 0)) {
- int oob_off, oob_len;
-
- if_printf(rxr->hn_ifp, "got oobdata\n");
- oob_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_oobdataoffset);
- oob_len = pkt->rm_oobdatalen;
-
- if (__predict_false(oob_off + oob_len > pkt->rm_len)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
- "oob overflow, msglen %u, oob abs %d len %d\n",
- pkt->rm_len, oob_off, oob_len);
- return;
- }
-
- /*
- * Check against data.
- */
- if (hn_rndis_check_overlap(oob_off, oob_len,
- data_off, data_len)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
- "oob overlaps data, oob abs %d len %d, "
- "data abs %d len %d\n",
- oob_off, oob_len, data_off, data_len);
- return;
- }
-
- /*
- * Check against pktinfo.
- */
- if (pktinfo_len != 0 &&
- hn_rndis_check_overlap(oob_off, oob_len,
- pktinfo_off, pktinfo_len)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
- "oob overlaps pktinfo, oob abs %d len %d, "
- "pktinfo abs %d len %d\n",
- oob_off, oob_len, pktinfo_off, pktinfo_len);
- return;
- }
- }
-
- /*
- * Check per-packet-info coverage and find useful per-packet-info.
- */
- info.vlan_info = HN_NDIS_VLAN_INFO_INVALID;
- info.csum_info = HN_NDIS_RXCSUM_INFO_INVALID;
- info.hash_info = HN_NDIS_HASH_INFO_INVALID;
- if (__predict_true(pktinfo_len != 0)) {
- bool overlap;
- int error;
-
- if (__predict_false(pktinfo_off + pktinfo_len > pkt->rm_len)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
- "pktinfo overflow, msglen %u, "
- "pktinfo abs %d len %d\n",
- pkt->rm_len, pktinfo_off, pktinfo_len);
- return;
- }
-
- /*
- * Check packet info coverage.
- */
- overlap = hn_rndis_check_overlap(pktinfo_off, pktinfo_len,
- data_off, data_len);
- if (__predict_false(overlap)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
- "pktinfo overlap data, pktinfo abs %d len %d, "
- "data abs %d len %d\n",
- pktinfo_off, pktinfo_len, data_off, data_len);
- return;
- }
-
- /*
- * Find useful per-packet-info.
- */
- error = hn_rndis_rxinfo(((const uint8_t *)pkt) + pktinfo_off,
- pktinfo_len, &info);
- if (__predict_false(error)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg "
- "pktinfo\n");
- return;
- }
- }
-
- if (__predict_false(data_off + data_len > pkt->rm_len)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
- "data overflow, msglen %u, data abs %d len %d\n",
- pkt->rm_len, data_off, data_len);
- return;
- }
- hn_rxpkt(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info);
-}
-
-/*
- * RNDIS filter on receive
- */
void
-hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
- const void *data, int dlen)
+hn_rndis_rx_ctrl(struct hn_softc *sc, const void *data, int dlen)
{
const struct rndis_comp_hdr *comp;
const struct rndis_msghdr *hdr;
- if (__predict_false(dlen < sizeof(*hdr))) {
- if_printf(rxr->hn_ifp, "invalid RNDIS msg\n");
- return;
- }
+ KASSERT(dlen >= sizeof(*hdr), ("invalid RNDIS msg\n"));
hdr = data;
switch (hdr->rm_type) {
- case REMOTE_NDIS_PACKET_MSG:
- hv_rf_receive_data(rxr, data, dlen);
- break;
-
case REMOTE_NDIS_INITIALIZE_CMPLT:
case REMOTE_NDIS_QUERY_CMPLT:
case REMOTE_NDIS_SET_CMPLT:
case REMOTE_NDIS_KEEPALIVE_CMPLT: /* unused */
if (dlen < sizeof(*comp)) {
- if_printf(rxr->hn_ifp, "invalid RNDIS cmplt\n");
+ if_printf(sc->hn_ifp, "invalid RNDIS cmplt\n");
return;
}
comp = data;
@@ -489,10 +134,6 @@ hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
vmbus_xact_ctx_wakeup(sc->hn_xact, comp, dlen);
break;
- case REMOTE_NDIS_INDICATE_STATUS_MSG:
- hv_rf_receive_indicate_status(sc, data, dlen);
- break;
-
case REMOTE_NDIS_RESET_CMPLT:
/*
* Reset completed, no rid.
@@ -501,11 +142,11 @@ hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
* RESET is not issued by hn(4), so this message should
* _not_ be observed.
*/
- if_printf(rxr->hn_ifp, "RESET cmplt received\n");
+ if_printf(sc->hn_ifp, "RESET cmplt received\n");
break;
default:
- if_printf(rxr->hn_ifp, "unknown RNDIS msg 0x%x\n",
+ if_printf(sc->hn_ifp, "unknown RNDIS msg 0x%x\n",
hdr->rm_type);
break;
}
@@ -549,7 +190,7 @@ hn_rndis_get_linkstatus(struct hn_softc *sc, uint32_t *link_status)
static const void *
hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen,
- struct hn_send_ctx *sndc, size_t *comp_len)
+ struct hn_nvs_sendctx *sndc, size_t *comp_len)
{
struct vmbus_gpa gpa[HN_XACT_REQ_PGCNT];
int gpa_cnt, error;
@@ -585,8 +226,7 @@ hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen,
* message.
*/
vmbus_xact_activate(xact);
- error = hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL, sndc,
- gpa, gpa_cnt);
+ error = hn_nvs_send_rndis_ctrl(sc->hn_prichan, sndc, gpa, gpa_cnt);
if (error) {
vmbus_xact_deactivate(xact);
if_printf(sc->hn_ifp, "RNDIS ctrl send failed: %d\n", error);
@@ -609,7 +249,7 @@ hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid
/*
* Execute the xact setup by the caller.
*/
- comp = hn_rndis_xact_exec1(sc, xact, reqlen, &hn_send_ctx_none,
+ comp = hn_rndis_xact_exec1(sc, xact, reqlen, &hn_nvs_sendctx_none,
&comp_len);
if (comp == NULL)
return (NULL);
@@ -748,13 +388,14 @@ done:
}
int
-hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt)
+hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt0)
{
struct ndis_rss_caps in, caps;
size_t caps_len;
- int error;
+ int error, indsz, rxr_cnt, hash_fnidx;
+ uint32_t hash_func = 0, hash_types = 0;
- *rxr_cnt = 0;
+ *rxr_cnt0 = 0;
if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_20)
return (EOPNOTSUPP);
@@ -793,18 +434,73 @@ hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt)
return (EINVAL);
}
+ /*
+ * Save information for later RSS configuration.
+ */
if (caps.ndis_nrxr == 0) {
if_printf(sc->hn_ifp, "0 RX rings!?\n");
return (EINVAL);
}
- *rxr_cnt = caps.ndis_nrxr;
+ if (bootverbose)
+ if_printf(sc->hn_ifp, "%u RX rings\n", caps.ndis_nrxr);
+ rxr_cnt = caps.ndis_nrxr;
+
+ if (caps.ndis_hdr.ndis_size == NDIS_RSS_CAPS_SIZE &&
+ caps.ndis_hdr.ndis_rev >= NDIS_RSS_CAPS_REV_2) {
+ if (caps.ndis_nind > NDIS_HASH_INDCNT) {
+ if_printf(sc->hn_ifp,
+ "too many RSS indirect table entries %u\n",
+ caps.ndis_nind);
+ return (EOPNOTSUPP);
+ }
+ if (!powerof2(caps.ndis_nind)) {
+ if_printf(sc->hn_ifp, "RSS indirect table size is not "
+ "power-of-2 %u\n", caps.ndis_nind);
+ }
- if (caps.ndis_hdr.ndis_size == NDIS_RSS_CAPS_SIZE) {
if (bootverbose) {
if_printf(sc->hn_ifp, "RSS indirect table size %u\n",
caps.ndis_nind);
}
+ indsz = caps.ndis_nind;
+ } else {
+ indsz = NDIS_HASH_INDCNT;
}
+ if (indsz < rxr_cnt) {
+ if_printf(sc->hn_ifp, "# of RX rings (%d) > "
+ "RSS indirect table size %d\n", rxr_cnt, indsz);
+ rxr_cnt = indsz;
+ }
+
+ /*
+ * NOTE:
+ * Toeplitz is at the lowest bit, and it is prefered; so ffs(),
+ * instead of fls(), is used here.
+ */
+ hash_fnidx = ffs(caps.ndis_caps & NDIS_RSS_CAP_HASHFUNC_MASK);
+ if (hash_fnidx == 0) {
+ if_printf(sc->hn_ifp, "no hash functions, caps 0x%08x\n",
+ caps.ndis_caps);
+ return (EOPNOTSUPP);
+ }
+ hash_func = 1 << (hash_fnidx - 1); /* ffs is 1-based */
+
+ if (caps.ndis_caps & NDIS_RSS_CAP_IPV4)
+ hash_types |= NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4;
+ if (caps.ndis_caps & NDIS_RSS_CAP_IPV6)
+ hash_types |= NDIS_HASH_IPV6 | NDIS_HASH_TCP_IPV6;
+ if (caps.ndis_caps & NDIS_RSS_CAP_IPV6_EX)
+ hash_types |= NDIS_HASH_IPV6_EX | NDIS_HASH_TCP_IPV6_EX;
+ if (hash_types == 0) {
+ if_printf(sc->hn_ifp, "no hash types, caps 0x%08x\n",
+ caps.ndis_caps);
+ return (EOPNOTSUPP);
+ }
+
+ /* Commit! */
+ sc->hn_rss_ind_size = indsz;
+ sc->hn_rss_hash = hash_func | hash_types;
+ *rxr_cnt0 = rxr_cnt;
return (0);
}
@@ -1034,7 +730,7 @@ hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags)
{
struct ndis_rssprm_toeplitz *rss = &sc->hn_rss;
struct ndis_rss_params *prm = &rss->rss_params;
- int error;
+ int error, rss_size;
/*
* Only NDIS 6.20+ is supported:
@@ -1044,21 +740,29 @@ hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags)
KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_20,
("NDIS 6.20+ is required, NDIS version 0x%08x", sc->hn_ndis_ver));
+ /* XXX only one can be specified through, popcnt? */
+ KASSERT((sc->hn_rss_hash & NDIS_HASH_FUNCTION_MASK), ("no hash func"));
+ KASSERT((sc->hn_rss_hash & NDIS_HASH_TYPE_MASK), ("no hash types"));
+ KASSERT(sc->hn_rss_ind_size > 0, ("no indirect table size"));
+
+ if (bootverbose) {
+ if_printf(sc->hn_ifp, "RSS indirect table size %d, "
+ "hash 0x%08x\n", sc->hn_rss_ind_size, sc->hn_rss_hash);
+ }
+
/*
* NOTE:
* DO NOT whack rss_key and rss_ind, which are setup by the caller.
*/
memset(prm, 0, sizeof(*prm));
+ rss_size = NDIS_RSSPRM_TOEPLITZ_SIZE(sc->hn_rss_ind_size);
prm->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS;
prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2;
- prm->ndis_hdr.ndis_size = sizeof(*rss);
+ prm->ndis_hdr.ndis_size = rss_size;
prm->ndis_flags = flags;
- prm->ndis_hash = NDIS_HASH_FUNCTION_TOEPLITZ |
- NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4 |
- NDIS_HASH_IPV6 | NDIS_HASH_TCP_IPV6;
- /* TODO: Take ndis_rss_caps.ndis_nind into account */
- prm->ndis_indsize = sizeof(rss->rss_ind);
+ prm->ndis_hash = sc->hn_rss_hash;
+ prm->ndis_indsize = sizeof(rss->rss_ind[0]) * sc->hn_rss_ind_size;
prm->ndis_indoffset =
__offsetof(struct ndis_rssprm_toeplitz, rss_ind[0]);
prm->ndis_keysize = sizeof(rss->rss_key);
@@ -1066,7 +770,7 @@ hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags)
__offsetof(struct ndis_rssprm_toeplitz, rss_key[0]);
error = hn_rndis_set(sc, OID_GEN_RECEIVE_SCALE_PARAMETERS,
- rss, sizeof(*rss));
+ rss, rss_size);
if (error) {
if_printf(sc->hn_ifp, "RSS config failed: %d\n", error);
} else {
@@ -1151,7 +855,7 @@ hn_rndis_halt(struct hn_softc *sc)
{
struct vmbus_xact *xact;
struct rndis_halt_req *halt;
- struct hn_send_ctx sndc;
+ struct hn_nvs_sendctx sndc;
size_t comp_len;
xact = vmbus_xact_get(sc->hn_xact, sizeof(*halt));
@@ -1165,7 +869,7 @@ hn_rndis_halt(struct hn_softc *sc)
halt->rm_rid = hn_rndis_rid(sc);
/* No RNDIS completion; rely on NVS message send completion */
- hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
+ hn_nvs_sendctx_init(&sndc, hn_nvs_sent_xact, xact);
hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len);
vmbus_xact_put(xact);
@@ -1285,10 +989,3 @@ hn_rndis_detach(struct hn_softc *sc)
/* Halt the RNDIS. */
hn_rndis_halt(sc);
}
-
-void
-hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr)
-{
-
- hn_chan_rollup(rxr, txr);
-}
diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.h b/sys/dev/hyperv/netvsc/hn_rndis.h
index 3ecda3b80d03..736df341f642 100644
--- a/sys/dev/hyperv/netvsc/hv_rndis_filter.h
+++ b/sys/dev/hyperv/netvsc/hn_rndis.h
@@ -28,21 +28,22 @@
* $FreeBSD$
*/
-#ifndef __HV_RNDIS_FILTER_H__
-#define __HV_RNDIS_FILTER_H__
+#ifndef _HN_RNDIS_H_
+#define _HN_RNDIS_H_
-#include <sys/param.h>
-#include <net/ethernet.h>
-#include <dev/hyperv/netvsc/if_hnvar.h>
+struct hn_softc;
-/*
- * Externs
- */
-struct hn_rx_ring;
-
-void hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr,
- const void *data, int dlen);
-void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr);
-
-#endif /* __HV_RNDIS_FILTER_H__ */
+int hn_rndis_attach(struct hn_softc *sc, int mtu);
+void hn_rndis_detach(struct hn_softc *sc);
+int hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags);
+int hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt);
+int hn_rndis_get_eaddr(struct hn_softc *sc, uint8_t *eaddr);
+/* link_status: NDIS_MEDIA_STATE_ */
+int hn_rndis_get_linkstatus(struct hn_softc *sc,
+ uint32_t *link_status);
+/* filter: NDIS_PACKET_TYPE_. */
+int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter);
+void hn_rndis_rx_ctrl(struct hn_softc *sc, const void *data,
+ int dlen);
+#endif /* !_HN_RNDIS_H_ */
diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h
deleted file mode 100644
index 06a6dfe8c98b..000000000000
--- a/sys/dev/hyperv/netvsc/hv_net_vsc.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/*-
- * Copyright (c) 2009-2012,2016 Microsoft Corp.
- * Copyright (c) 2010-2012 Citrix Inc.
- * 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 unmodified, 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.
- *
- * $FreeBSD$
- */
-
-/*
- * HyperV vmbus (virtual machine bus) network VSC (virtual services client)
- * header file
- *
- * (Updated from unencumbered NvspProtocol.h)
- */
-
-#ifndef __HV_NET_VSC_H__
-#define __HV_NET_VSC_H__
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/queue.h>
-#include <sys/taskqueue.h>
-#include <sys/sema.h>
-#include <sys/sx.h>
-
-#include <machine/bus.h>
-#include <sys/bus.h>
-#include <sys/bus_dma.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp_lro.h>
-
-#include <net/ethernet.h>
-#include <net/if.h>
-#include <net/if_media.h>
-
-#include <dev/hyperv/include/hyperv.h>
-#include <dev/hyperv/include/hyperv_busdma.h>
-#include <dev/hyperv/include/vmbus.h>
-
-#include <dev/hyperv/netvsc/ndis.h>
-
-#define HN_USE_TXDESC_BUFRING
-
-MALLOC_DECLARE(M_NETVSC);
-
-/*
- * The following arguably belongs in a separate header file
- */
-
-/*
- * Defines
- */
-
-#define NETVSC_SEND_BUFFER_SIZE (1024*1024*15) /* 15M */
-
-#define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */
-#define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */
-
-/*
- * Maximum MTU we permit to be configured for a netvsc interface.
- * When the code was developed, a max MTU of 12232 was tested and
- * proven to work. 9K is a reasonable maximum for an Ethernet.
- */
-#define NETVSC_MAX_CONFIGURABLE_MTU (9 * 1024)
-
-#define NETVSC_PACKET_SIZE PAGE_SIZE
-
-/*
- * Data types
- */
-
-struct vmbus_channel;
-
-#define NETVSC_DEVICE_RING_BUFFER_SIZE (128 * PAGE_SIZE)
-#define NETVSC_PACKET_MAXPAGE 32
-
-#define HN_XACT_REQ_PGCNT 2
-#define HN_XACT_RESP_PGCNT 2
-#define HN_XACT_REQ_SIZE (HN_XACT_REQ_PGCNT * PAGE_SIZE)
-#define HN_XACT_RESP_SIZE (HN_XACT_RESP_PGCNT * PAGE_SIZE)
-
-#ifndef HN_USE_TXDESC_BUFRING
-struct hn_txdesc;
-SLIST_HEAD(hn_txdesc_list, hn_txdesc);
-#else
-struct buf_ring;
-#endif
-
-struct hn_tx_ring;
-
-struct hn_rx_ring {
- struct ifnet *hn_ifp;
- struct hn_tx_ring *hn_txr;
- void *hn_rdbuf;
- uint8_t *hn_rxbuf; /* shadow sc->hn_rxbuf */
- int hn_rx_idx;
-
- /* Trust csum verification on host side */
- int hn_trust_hcsum; /* HN_TRUST_HCSUM_ */
- struct lro_ctrl hn_lro;
-
- u_long hn_csum_ip;
- u_long hn_csum_tcp;
- u_long hn_csum_udp;
- u_long hn_csum_trusted;
- u_long hn_lro_tried;
- u_long hn_small_pkts;
- u_long hn_pkts;
- u_long hn_rss_pkts;
-
- /* Rarely used stuffs */
- struct sysctl_oid *hn_rx_sysctl_tree;
- int hn_rx_flags;
-
- void *hn_br; /* TX/RX bufring */
- struct hyperv_dma hn_br_dma;
-} __aligned(CACHE_LINE_SIZE);
-
-#define HN_TRUST_HCSUM_IP 0x0001
-#define HN_TRUST_HCSUM_TCP 0x0002
-#define HN_TRUST_HCSUM_UDP 0x0004
-
-#define HN_RX_FLAG_ATTACHED 0x1
-
-struct hn_tx_ring {
-#ifndef HN_USE_TXDESC_BUFRING
- struct mtx hn_txlist_spin;
- struct hn_txdesc_list hn_txlist;
-#else
- struct buf_ring *hn_txdesc_br;
-#endif
- int hn_txdesc_cnt;
- int hn_txdesc_avail;
- u_short hn_has_txeof;
- u_short hn_txdone_cnt;
-
- int hn_sched_tx;
- void (*hn_txeof)(struct hn_tx_ring *);
- struct taskqueue *hn_tx_taskq;
- struct task hn_tx_task;
- struct task hn_txeof_task;
-
- struct buf_ring *hn_mbuf_br;
- int hn_oactive;
- int hn_tx_idx;
- int hn_tx_flags;
-
- struct mtx hn_tx_lock;
- struct hn_softc *hn_sc;
- struct vmbus_channel *hn_chan;
-
- int hn_direct_tx_size;
- int hn_chim_size;
- bus_dma_tag_t hn_tx_data_dtag;
- uint64_t hn_csum_assist;
-
- int hn_suspended;
- int hn_gpa_cnt;
- struct vmbus_gpa hn_gpa[NETVSC_PACKET_MAXPAGE];
-
- u_long hn_no_txdescs;
- u_long hn_send_failed;
- u_long hn_txdma_failed;
- u_long hn_tx_collapsed;
- u_long hn_tx_chimney_tried;
- u_long hn_tx_chimney;
- u_long hn_pkts;
-
- /* Rarely used stuffs */
- struct hn_txdesc *hn_txdesc;
- bus_dma_tag_t hn_tx_rndis_dtag;
- struct sysctl_oid *hn_tx_sysctl_tree;
-} __aligned(CACHE_LINE_SIZE);
-
-#define HN_TX_FLAG_ATTACHED 0x1
-#define HN_TX_FLAG_HASHVAL 0x2 /* support HASHVAL pktinfo */
-
-/*
- * Device-specific softc structure
- */
-struct hn_softc {
- struct ifnet *hn_ifp;
- struct ifmedia hn_media;
- device_t hn_dev;
- int hn_if_flags;
- struct sx hn_lock;
- struct vmbus_channel *hn_prichan;
-
- int hn_rx_ring_cnt;
- int hn_rx_ring_inuse;
- struct hn_rx_ring *hn_rx_ring;
-
- int hn_tx_ring_cnt;
- int hn_tx_ring_inuse;
- struct hn_tx_ring *hn_tx_ring;
-
- uint8_t *hn_chim;
- u_long *hn_chim_bmap;
- int hn_chim_bmap_cnt;
- int hn_chim_cnt;
- int hn_chim_szmax;
-
- int hn_cpu;
- struct taskqueue *hn_tx_taskq;
- struct sysctl_oid *hn_tx_sysctl_tree;
- struct sysctl_oid *hn_rx_sysctl_tree;
- struct vmbus_xact_ctx *hn_xact;
- uint32_t hn_nvs_ver;
-
- struct taskqueue *hn_mgmt_taskq;
- struct taskqueue *hn_mgmt_taskq0;
- struct task hn_link_task;
- struct task hn_netchg_init;
- struct timeout_task hn_netchg_status;
- uint32_t hn_link_flags; /* HN_LINK_FLAG_ */
-
- uint32_t hn_caps; /* HN_CAP_ */
- uint32_t hn_flags; /* HN_FLAG_ */
- void *hn_rxbuf;
- uint32_t hn_rxbuf_gpadl;
- struct hyperv_dma hn_rxbuf_dma;
-
- uint32_t hn_chim_gpadl;
- struct hyperv_dma hn_chim_dma;
-
- uint32_t hn_rndis_rid;
- uint32_t hn_ndis_ver;
- int hn_ndis_tso_szmax;
- int hn_ndis_tso_sgmin;
-
- struct ndis_rssprm_toeplitz hn_rss;
-};
-
-#define HN_FLAG_RXBUF_CONNECTED 0x0001
-#define HN_FLAG_CHIM_CONNECTED 0x0002
-#define HN_FLAG_HAS_RSSKEY 0x0004
-#define HN_FLAG_HAS_RSSIND 0x0008
-#define HN_FLAG_SYNTH_ATTACHED 0x0010
-
-#define HN_CAP_VLAN 0x0001
-#define HN_CAP_MTU 0x0002
-#define HN_CAP_IPCS 0x0004
-#define HN_CAP_TCP4CS 0x0008
-#define HN_CAP_TCP6CS 0x0010
-#define HN_CAP_UDP4CS 0x0020
-#define HN_CAP_UDP6CS 0x0040
-#define HN_CAP_TSO4 0x0080
-#define HN_CAP_TSO6 0x0100
-#define HN_CAP_HASHVAL 0x0200
-
-#define HN_LINK_FLAG_LINKUP 0x0001
-#define HN_LINK_FLAG_NETCHG 0x0002
-
-/*
- * Externs
- */
-struct hn_send_ctx;
-
-int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
- struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt);
-
-#endif /* __HV_NET_VSC_H__ */
-
diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
index 336fee8b3b4e..6e2fb28ab380 100644
--- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
+++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sockio.h>
+#include <sys/limits.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/module.h>
@@ -72,6 +73,7 @@ __FBSDID("$FreeBSD$");
#include <sys/smp.h>
#include <sys/sysctl.h>
#include <sys/buf_ring.h>
+#include <sys/taskqueue.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -90,6 +92,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/ip.h>
#include <netinet/if_ether.h>
#include <netinet/tcp.h>
+#include <netinet/tcp_lro.h>
#include <netinet/udp.h>
#include <netinet/ip6.h>
@@ -115,11 +118,14 @@ __FBSDID("$FreeBSD$");
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/include/hyperv_busdma.h>
+#include <dev/hyperv/include/vmbus.h>
#include <dev/hyperv/include/vmbus_xact.h>
-#include <dev/hyperv/netvsc/hv_net_vsc.h>
-#include <dev/hyperv/netvsc/hv_rndis_filter.h>
#include <dev/hyperv/netvsc/ndis.h>
+#include <dev/hyperv/netvsc/if_hnreg.h>
+#include <dev/hyperv/netvsc/if_hnvar.h>
+#include <dev/hyperv/netvsc/hn_nvs.h>
+#include <dev/hyperv/netvsc/hn_rndis.h>
#include "vmbus_if.h"
@@ -154,12 +160,24 @@ __FBSDID("$FreeBSD$");
#define HN_TX_DATA_MAXSIZE IP_MAXPACKET
#define HN_TX_DATA_SEGSIZE PAGE_SIZE
/* -1 for RNDIS packet message */
-#define HN_TX_DATA_SEGCNT_MAX (NETVSC_PACKET_MAXPAGE - 1)
+#define HN_TX_DATA_SEGCNT_MAX (HN_GPACNT_MAX - 1)
#define HN_DIRECT_TX_SIZE_DEF 128
#define HN_EARLY_TXEOF_THRESH 8
+#define HN_RXINFO_VLAN 0x0001
+#define HN_RXINFO_CSUM 0x0002
+#define HN_RXINFO_HASHINF 0x0004
+#define HN_RXINFO_HASHVAL 0x0008
+#define HN_RXINFO_ALL \
+ (HN_RXINFO_VLAN | \
+ HN_RXINFO_CSUM | \
+ HN_RXINFO_HASHINF | \
+ HN_RXINFO_HASHVAL)
+
+#define HN_PKTBUF_LEN_DEF (16 * 1024)
+
struct hn_txdesc {
#ifndef HN_USE_TXDESC_BUFRING
SLIST_ENTRY(hn_txdesc) link;
@@ -168,7 +186,9 @@ struct hn_txdesc {
struct hn_tx_ring *txr;
int refs;
uint32_t flags; /* HN_TXD_FLAG_ */
- struct hn_send_ctx send_ctx;
+ struct hn_nvs_sendctx send_ctx;
+ uint32_t chim_index;
+ int chim_size;
bus_dmamap_t data_dmap;
@@ -180,6 +200,17 @@ struct hn_txdesc {
#define HN_TXD_FLAG_ONLIST 0x1
#define HN_TXD_FLAG_DMAMAP 0x2
+#define HN_NDIS_VLAN_INFO_INVALID 0xffffffff
+#define HN_NDIS_RXCSUM_INFO_INVALID 0
+#define HN_NDIS_HASH_INFO_INVALID 0
+
+struct hn_rxinfo {
+ uint32_t vlan_info;
+ uint32_t csum_info;
+ uint32_t hash_info;
+ uint32_t hash_value;
+};
+
#define HN_LRO_LENLIM_MULTIRX_DEF (12 * ETHERMTU)
#define HN_LRO_LENLIM_DEF (25 * ETHERMTU)
/* YYY 2*MTU is a bit rough, but should be good enough. */
@@ -324,8 +355,10 @@ static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_caps_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_hwassist_sysctl(SYSCTL_HANDLER_ARGS);
+static int hn_rxfilter_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS);
+static int hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS);
static int hn_check_iplen(const struct mbuf *, int);
static int hn_create_tx_ring(struct hn_softc *, int);
static void hn_destroy_tx_ring(struct hn_tx_ring *);
@@ -348,6 +381,7 @@ static void hn_chan_detach(struct hn_softc *, struct vmbus_channel *);
static int hn_attach_subchans(struct hn_softc *);
static void hn_detach_allchans(struct hn_softc *);
static void hn_chan_callback(struct vmbus_channel *chan, void *xrxr);
+static void hn_chan_rollup(struct hn_rx_ring *, struct hn_tx_ring *);
static void hn_set_ring_inuse(struct hn_softc *, int);
static int hn_synth_attach(struct hn_softc *, int);
static void hn_synth_detach(struct hn_softc *);
@@ -363,15 +397,25 @@ static void hn_tx_resume(struct hn_softc *, int);
static void hn_tx_ring_qflush(struct hn_tx_ring *);
static int netvsc_detach(device_t dev);
static void hn_link_status(struct hn_softc *);
+static int hn_sendpkt_rndis_sglist(struct hn_tx_ring *, struct hn_txdesc *);
+static int hn_sendpkt_rndis_chim(struct hn_tx_ring *, struct hn_txdesc *);
+static int hn_set_rxfilter(struct hn_softc *);
+static void hn_link_status_update(struct hn_softc *);
+static void hn_network_change(struct hn_softc *);
+
+static int hn_rndis_rxinfo(const void *, int, struct hn_rxinfo *);
+static void hn_rndis_rx_data(struct hn_rx_ring *, const void *, int);
+static void hn_rndis_rx_status(struct hn_softc *, const void *, int);
static void hn_nvs_handle_notify(struct hn_softc *sc,
const struct vmbus_chanpkt_hdr *pkt);
static void hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkt);
-static void hn_nvs_handle_rxbuf(struct hn_softc *sc, struct hn_rx_ring *rxr,
+static void hn_nvs_handle_rxbuf(struct hn_rx_ring *rxr,
struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkthdr);
-static void hn_nvs_ack_rxbuf(struct vmbus_channel *chan, uint64_t tid);
+static void hn_nvs_ack_rxbuf(struct hn_rx_ring *, struct vmbus_channel *,
+ uint64_t);
static int hn_transmit(struct ifnet *, struct mbuf *);
static void hn_xmit_qflush(struct ifnet *);
@@ -400,6 +444,116 @@ hn_set_lro_lenlim(struct hn_softc *sc, int lenlim)
#endif
static int
+hn_sendpkt_rndis_sglist(struct hn_tx_ring *txr, struct hn_txdesc *txd)
+{
+
+ KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID &&
+ txd->chim_size == 0, ("invalid rndis sglist txd"));
+ return (hn_nvs_send_rndis_sglist(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA,
+ &txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt));
+}
+
+static int
+hn_sendpkt_rndis_chim(struct hn_tx_ring *txr, struct hn_txdesc *txd)
+{
+ struct hn_nvs_rndis rndis;
+
+ KASSERT(txd->chim_index != HN_NVS_CHIM_IDX_INVALID &&
+ txd->chim_size > 0, ("invalid rndis chim txd"));
+
+ rndis.nvs_type = HN_NVS_TYPE_RNDIS;
+ rndis.nvs_rndis_mtype = HN_NVS_RNDIS_MTYPE_DATA;
+ rndis.nvs_chim_idx = txd->chim_index;
+ rndis.nvs_chim_sz = txd->chim_size;
+
+ return (hn_nvs_send(txr->hn_chan, VMBUS_CHANPKT_FLAG_RC,
+ &rndis, sizeof(rndis), &txd->send_ctx));
+}
+
+static __inline uint32_t
+hn_chim_alloc(struct hn_softc *sc)
+{
+ int i, bmap_cnt = sc->hn_chim_bmap_cnt;
+ u_long *bmap = sc->hn_chim_bmap;
+ uint32_t ret = HN_NVS_CHIM_IDX_INVALID;
+
+ for (i = 0; i < bmap_cnt; ++i) {
+ int idx;
+
+ idx = ffsl(~bmap[i]);
+ if (idx == 0)
+ continue;
+
+ --idx; /* ffsl is 1-based */
+ KASSERT(i * LONG_BIT + idx < sc->hn_chim_cnt,
+ ("invalid i %d and idx %d", i, idx));
+
+ if (atomic_testandset_long(&bmap[i], idx))
+ continue;
+
+ ret = i * LONG_BIT + idx;
+ break;
+ }
+ return (ret);
+}
+
+static __inline void
+hn_chim_free(struct hn_softc *sc, uint32_t chim_idx)
+{
+ u_long mask;
+ uint32_t idx;
+
+ idx = chim_idx / LONG_BIT;
+ KASSERT(idx < sc->hn_chim_bmap_cnt,
+ ("invalid chimney index 0x%x", chim_idx));
+
+ mask = 1UL << (chim_idx % LONG_BIT);
+ KASSERT(sc->hn_chim_bmap[idx] & mask,
+ ("index bitmap 0x%lx, chimney index %u, "
+ "bitmap idx %d, bitmask 0x%lx",
+ sc->hn_chim_bmap[idx], chim_idx, idx, mask));
+
+ atomic_clear_long(&sc->hn_chim_bmap[idx], mask);
+}
+
+static int
+hn_set_rxfilter(struct hn_softc *sc)
+{
+ struct ifnet *ifp = sc->hn_ifp;
+ uint32_t filter;
+ int error = 0;
+
+ HN_LOCK_ASSERT(sc);
+
+ if (ifp->if_flags & IFF_PROMISC) {
+ filter = NDIS_PACKET_TYPE_PROMISCUOUS;
+ } else {
+ filter = NDIS_PACKET_TYPE_DIRECTED;
+ if (ifp->if_flags & IFF_BROADCAST)
+ filter |= NDIS_PACKET_TYPE_BROADCAST;
+#ifdef notyet
+ /*
+ * See the comment in SIOCADDMULTI/SIOCDELMULTI.
+ */
+ /* TODO: support multicast list */
+ if ((ifp->if_flags & IFF_ALLMULTI) ||
+ !TAILQ_EMPTY(&ifp->if_multiaddrs))
+ filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
+#else
+ /* Always enable ALLMULTI */
+ filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
+#endif
+ }
+
+ if (sc->hn_rx_filter != filter) {
+ error = hn_rndis_set_rxfilter(sc, filter);
+ if (!error)
+ sc->hn_rx_filter = filter;
+ }
+ return (error);
+}
+
+static int
hn_get_txswq_depth(const struct hn_tx_ring *txr)
{
@@ -673,6 +827,14 @@ netvsc_attach(device_t dev)
SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "hwassist",
CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
hn_hwassist_sysctl, "A", "hwassist");
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rxfilter",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+ hn_rxfilter_sysctl, "A", "rxfilter");
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_hash",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+ hn_rss_hash_sysctl, "A", "RSS hash");
+ SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rss_ind_size",
+ CTLFLAG_RD, &sc->hn_rss_ind_size, 0, "RSS indirect entry count");
SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_key",
CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0,
hn_rss_key_sysctl, "IU", "RSS key");
@@ -692,6 +854,7 @@ netvsc_attach(device_t dev)
* Setup the ifnet for this interface.
*/
+ ifp->if_baudrate = IF_Gbps(10);
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = hn_ioctl;
ifp->if_init = hn_init;
@@ -873,7 +1036,7 @@ hn_netchg_status_taskfunc(void *xsc, int pending __unused)
hn_link_status(sc);
}
-void
+static void
hn_link_status_update(struct hn_softc *sc)
{
@@ -881,7 +1044,7 @@ hn_link_status_update(struct hn_softc *sc)
taskqueue_enqueue(sc->hn_mgmt_taskq, &sc->hn_link_task);
}
-void
+static void
hn_network_change(struct hn_softc *sc)
{
@@ -896,6 +1059,8 @@ hn_txdesc_dmamap_load(struct hn_tx_ring *txr, struct hn_txdesc *txd,
struct mbuf *m = *m_head;
int error;
+ KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID, ("txd uses chim"));
+
error = bus_dmamap_load_mbuf_sg(txr->hn_tx_data_dtag, txd->data_dmap,
m, segs, nsegs, BUS_DMA_NOWAIT);
if (error == EFBIG) {
@@ -919,19 +1084,6 @@ hn_txdesc_dmamap_load(struct hn_tx_ring *txr, struct hn_txdesc *txd,
return error;
}
-static __inline void
-hn_txdesc_dmamap_unload(struct hn_tx_ring *txr, struct hn_txdesc *txd)
-{
-
- if (txd->flags & HN_TXD_FLAG_DMAMAP) {
- bus_dmamap_sync(txr->hn_tx_data_dtag,
- txd->data_dmap, BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(txr->hn_tx_data_dtag,
- txd->data_dmap);
- txd->flags &= ~HN_TXD_FLAG_DMAMAP;
- }
-}
-
static __inline int
hn_txdesc_put(struct hn_tx_ring *txr, struct hn_txdesc *txd)
{
@@ -943,14 +1095,25 @@ hn_txdesc_put(struct hn_tx_ring *txr, struct hn_txdesc *txd)
if (atomic_fetchadd_int(&txd->refs, -1) != 1)
return 0;
- hn_txdesc_dmamap_unload(txr, txd);
+ if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) {
+ KASSERT((txd->flags & HN_TXD_FLAG_DMAMAP) == 0,
+ ("chim txd uses dmamap"));
+ hn_chim_free(txr->hn_sc, txd->chim_index);
+ txd->chim_index = HN_NVS_CHIM_IDX_INVALID;
+ } else if (txd->flags & HN_TXD_FLAG_DMAMAP) {
+ bus_dmamap_sync(txr->hn_tx_data_dtag,
+ txd->data_dmap, BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(txr->hn_tx_data_dtag,
+ txd->data_dmap);
+ txd->flags &= ~HN_TXD_FLAG_DMAMAP;
+ }
+
if (txd->m != NULL) {
m_freem(txd->m);
txd->m = NULL;
}
txd->flags |= HN_TXD_FLAG_ONLIST;
-
#ifndef HN_USE_TXDESC_BUFRING
mtx_lock_spin(&txr->hn_txlist_spin);
KASSERT(txr->hn_txdesc_avail >= 0 &&
@@ -991,7 +1154,9 @@ hn_txdesc_get(struct hn_tx_ring *txr)
atomic_subtract_int(&txr->hn_txdesc_avail, 1);
#endif
KASSERT(txd->m == NULL && txd->refs == 0 &&
- (txd->flags & HN_TXD_FLAG_ONLIST), ("invalid txd"));
+ txd->chim_index == HN_NVS_CHIM_IDX_INVALID &&
+ (txd->flags & HN_TXD_FLAG_ONLIST) &&
+ (txd->flags & HN_TXD_FLAG_DMAMAP) == 0, ("invalid txd"));
txd->flags &= ~HN_TXD_FLAG_ONLIST;
txd->refs = 1;
}
@@ -1032,15 +1197,12 @@ hn_txeof(struct hn_tx_ring *txr)
}
static void
-hn_tx_done(struct hn_send_ctx *sndc, struct hn_softc *sc,
+hn_tx_done(struct hn_nvs_sendctx *sndc, struct hn_softc *sc,
struct vmbus_channel *chan, const void *data __unused, int dlen __unused)
{
struct hn_txdesc *txd = sndc->hn_cbarg;
struct hn_tx_ring *txr;
- if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
- hn_chim_free(sc, sndc->hn_chim_idx);
-
txr = txd->txr;
KASSERT(txr->hn_chan == chan,
("channel mismatch, on chan%u, should be chan%u",
@@ -1057,7 +1219,7 @@ hn_tx_done(struct hn_send_ctx *sndc, struct hn_softc *sc,
}
}
-void
+static void
hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr)
{
#if defined(INET) || defined(INET6)
@@ -1085,6 +1247,42 @@ hn_rndis_pktmsg_offset(uint32_t ofs)
return (ofs - __offsetof(struct rndis_packet_msg, rm_dataoffset));
}
+static __inline void *
+hn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize,
+ size_t pi_dlen, uint32_t pi_type)
+{
+ const size_t pi_size = HN_RNDIS_PKTINFO_SIZE(pi_dlen);
+ struct rndis_pktinfo *pi;
+
+ KASSERT((pi_size & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK) == 0,
+ ("unaligned pktinfo size %zu, pktinfo dlen %zu", pi_size, pi_dlen));
+
+ /*
+ * Per-packet-info does not move; it only grows.
+ *
+ * NOTE:
+ * rm_pktinfooffset in this phase counts from the beginning
+ * of rndis_packet_msg.
+ */
+ KASSERT(pkt->rm_pktinfooffset + pkt->rm_pktinfolen + pi_size <= pktsize,
+ ("%u pktinfo overflows RNDIS packet msg", pi_type));
+ pi = (struct rndis_pktinfo *)((uint8_t *)pkt + pkt->rm_pktinfooffset +
+ pkt->rm_pktinfolen);
+ pkt->rm_pktinfolen += pi_size;
+
+ pi->rm_size = pi_size;
+ pi->rm_type = pi_type;
+ pi->rm_pktinfooffset = RNDIS_PKTINFO_OFFSET;
+
+ /* Data immediately follow per-packet-info. */
+ pkt->rm_dataoffset += pi_size;
+
+ /* Update RNDIS packet msg length */
+ pkt->rm_len += pi_size;
+
+ return (pi->rm_data);
+}
+
/*
* NOTE:
* If this function fails, then both txd and m_head0 will be freed.
@@ -1096,9 +1294,8 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
int error, nsegs, i;
struct mbuf *m_head = *m_head0;
struct rndis_packet_msg *pkt;
- uint32_t send_buf_section_idx;
- int send_buf_section_size, pktlen;
uint32_t *pi_data;
+ int pktlen;
/*
* extension points to the area reserved for the
@@ -1211,18 +1408,19 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
*/
if (pkt->rm_len < txr->hn_chim_size) {
txr->hn_tx_chimney_tried++;
- send_buf_section_idx = hn_chim_alloc(txr->hn_sc);
- if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) {
+ txd->chim_index = hn_chim_alloc(txr->hn_sc);
+ if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) {
uint8_t *dest = txr->hn_sc->hn_chim +
- (send_buf_section_idx * txr->hn_sc->hn_chim_szmax);
+ (txd->chim_index * txr->hn_sc->hn_chim_szmax);
memcpy(dest, pkt, pktlen);
dest += pktlen;
m_copydata(m_head, 0, m_head->m_pkthdr.len, dest);
- send_buf_section_size = pkt->rm_len;
+ txd->chim_size = pkt->rm_len;
txr->hn_gpa_cnt = 0;
txr->hn_tx_chimney++;
+ txr->hn_sendpkt = hn_sendpkt_rndis_chim;
goto done;
}
}
@@ -1267,14 +1465,14 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
gpa->gpa_len = segs[i].ds_len;
}
- send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID;
- send_buf_section_size = 0;
+ txd->chim_index = HN_NVS_CHIM_IDX_INVALID;
+ txd->chim_size = 0;
+ txr->hn_sendpkt = hn_sendpkt_rndis_sglist;
done:
txd->m = m_head;
/* Set the completion routine */
- hn_send_ctx_init(&txd->send_ctx, hn_tx_done, txd,
- send_buf_section_idx, send_buf_section_size);
+ hn_nvs_sendctx_init(&txd->send_ctx, hn_tx_done, txd);
return 0;
}
@@ -1294,8 +1492,7 @@ again:
* Make sure that txd is not freed before ETHER_BPF_MTAP.
*/
hn_txdesc_hold(txd);
- error = hv_nv_on_send(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA,
- &txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt);
+ error = txr->hn_sendpkt(txr, txd);
if (!error) {
ETHER_BPF_MTAP(ifp, txd->m);
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
@@ -1484,15 +1681,9 @@ hn_lro_rx(struct lro_ctrl *lc, struct mbuf *m)
}
#endif
-/*
- * Called when we receive a data packet from the "wire" on the
- * specified device
- *
- * Note: This is no longer used as a callback
- */
-int
+static int
hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
- const struct hn_recvinfo *info)
+ const struct hn_rxinfo *info)
{
struct ifnet *ifp = rxr->hn_ifp;
struct mbuf *m_new;
@@ -1563,6 +1754,13 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
rxr->hn_csum_udp++;
}
+ /*
+ * XXX
+ * As of this write (Oct 28th, 2016), host side will turn
+ * on only TCPCS_OK and IPCS_OK even for UDP datagrams, so
+ * the do_lro setting here is actually _not_ accurate. We
+ * depend on the RSS hash type check to reset do_lro.
+ */
if ((info->csum_info &
(NDIS_RXCSUM_INFO_TCPCS_OK | NDIS_RXCSUM_INFO_IPCS_OK)) ==
(NDIS_RXCSUM_INFO_TCPCS_OK | NDIS_RXCSUM_INFO_IPCS_OK))
@@ -1637,9 +1835,16 @@ skip:
NDIS_HASH_FUNCTION_TOEPLITZ) {
uint32_t type = (info->hash_info & NDIS_HASH_TYPE_MASK);
+ /*
+ * NOTE:
+ * do_lro is resetted, if the hash types are not TCP
+ * related. See the comment in the above csum_flags
+ * setup section.
+ */
switch (type) {
case NDIS_HASH_IPV4:
hash_type = M_HASHTYPE_RSS_IPV4;
+ do_lro = 0;
break;
case NDIS_HASH_TCP_IPV4:
@@ -1648,10 +1853,12 @@ skip:
case NDIS_HASH_IPV6:
hash_type = M_HASHTYPE_RSS_IPV6;
+ do_lro = 0;
break;
case NDIS_HASH_IPV6_EX:
hash_type = M_HASHTYPE_RSS_IPV6_EX;
+ do_lro = 0;
break;
case NDIS_HASH_TCP_IPV6:
@@ -1706,7 +1913,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
switch (cmd) {
case SIOCSIFMTU:
- if (ifr->ifr_mtu > NETVSC_MAX_CONFIGURABLE_MTU) {
+ if (ifr->ifr_mtu > HN_MTU_MAX) {
error = EINVAL;
break;
}
@@ -1730,19 +1937,6 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
break;
}
- /* Obtain and record requested MTU */
- ifp->if_mtu = ifr->ifr_mtu;
-
-#if __FreeBSD_version >= 1100099
- /*
- * Make sure that LRO aggregation length limit is still
- * valid, after the MTU change.
- */
- if (sc->hn_rx_ring[0].hn_lro.lro_length_lim <
- HN_LRO_LENLIM_MIN(ifp))
- hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MIN(ifp));
-#endif
-
/*
* Suspend this interface before the synthetic parts
* are ripped.
@@ -1757,13 +1951,31 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
/*
* Reattach the synthetic parts, i.e. NVS and RNDIS,
* with the new MTU setting.
- * XXX check error.
*/
- hn_synth_attach(sc, ifr->ifr_mtu);
+ error = hn_synth_attach(sc, ifr->ifr_mtu);
+ if (error) {
+ HN_UNLOCK(sc);
+ break;
+ }
+
+ /*
+ * Commit the requested MTU, after the synthetic parts
+ * have been successfully attached.
+ */
+ ifp->if_mtu = ifr->ifr_mtu;
+ /*
+ * Make sure that various parameters based on MTU are
+ * still valid, after the MTU change.
+ */
if (sc->hn_tx_ring[0].hn_chim_size > sc->hn_chim_szmax)
hn_set_chim_size(sc, sc->hn_chim_szmax);
- hn_set_tso_maxsize(sc, hn_tso_maxlen, ifr->ifr_mtu);
+ hn_set_tso_maxsize(sc, hn_tso_maxlen, ifp->if_mtu);
+#if __FreeBSD_version >= 1100099
+ if (sc->hn_rx_ring[0].hn_lro.lro_length_lim <
+ HN_LRO_LENLIM_MIN(ifp))
+ hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MIN(ifp));
+#endif
/*
* All done! Resume the interface now.
@@ -1782,31 +1994,13 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
if (ifp->if_flags & IFF_UP) {
- /*
- * If only the state of the PROMISC flag changed,
- * then just use the 'set promisc mode' command
- * instead of reinitializing the entire NIC. Doing
- * a full re-init means reloading the firmware and
- * waiting for it to start up, which may take a
- * second or two.
- */
-#ifdef notyet
- /* Fixme: Promiscuous mode? */
- if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- ifp->if_flags & IFF_PROMISC &&
- !(sc->hn_if_flags & IFF_PROMISC)) {
- /* do something here for Hyper-V */
- } else if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
- !(ifp->if_flags & IFF_PROMISC) &&
- sc->hn_if_flags & IFF_PROMISC) {
- /* do something here for Hyper-V */
- } else
-#endif
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ hn_set_rxfilter(sc);
+ else
hn_init_locked(sc);
} else {
- if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
hn_stop(sc);
- }
}
sc->hn_if_flags = ifp->if_flags;
@@ -1864,12 +2058,27 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
case SIOCADDMULTI:
case SIOCDELMULTI:
- /* Always all-multi */
+#ifdef notyet
/*
- * TODO:
- * Enable/disable all-multi according to the emptiness of
- * the mcast address list.
+ * XXX
+ * Multicast uses mutex, while RNDIS RX filter setting
+ * sleeps. We workaround this by always enabling
+ * ALLMULTI. ALLMULTI would actually always be on, even
+ * if we supported the SIOCADDMULTI/SIOCDELMULTI, since
+ * we don't support multicast address list configuration
+ * for this driver.
*/
+ HN_LOCK(sc);
+
+ if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0) {
+ HN_UNLOCK(sc);
+ break;
+ }
+ if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+ hn_set_rxfilter(sc);
+
+ HN_UNLOCK(sc);
+#endif
break;
case SIOCSIFMEDIA:
@@ -1977,8 +2186,8 @@ hn_init_locked(struct hn_softc *sc)
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
return;
- /* TODO: add hn_rx_filter */
- hn_rndis_set_rxfilter(sc, NDIS_PACKET_TYPE_PROMISCUOUS);
+ /* Configure RX filter */
+ hn_set_rxfilter(sc);
/* Clear OACTIVE bit. */
atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE);
@@ -2275,18 +2484,7 @@ hn_caps_sysctl(SYSCTL_HANDLER_ARGS)
HN_LOCK(sc);
caps = sc->hn_caps;
HN_UNLOCK(sc);
- snprintf(caps_str, sizeof(caps_str), "%b", caps,
- "\020"
- "\001VLAN"
- "\002MTU"
- "\003IPCS"
- "\004TCP4CS"
- "\005TCP6CS"
- "\006UDP4CS"
- "\007UDP6CS"
- "\010TSO4"
- "\011TSO6"
- "\012HASHVAL");
+ snprintf(caps_str, sizeof(caps_str), "%b", caps, HN_CAP_BITS);
return sysctl_handle_string(oidp, caps_str, sizeof(caps_str), req);
}
@@ -2305,6 +2503,21 @@ hn_hwassist_sysctl(SYSCTL_HANDLER_ARGS)
}
static int
+hn_rxfilter_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct hn_softc *sc = arg1;
+ char filter_str[128];
+ uint32_t filter;
+
+ HN_LOCK(sc);
+ filter = sc->hn_rx_filter;
+ HN_UNLOCK(sc);
+ snprintf(filter_str, sizeof(filter_str), "%b", filter,
+ NDIS_PACKET_TYPES);
+ return sysctl_handle_string(oidp, filter_str, sizeof(filter_str), req);
+}
+
+static int
hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS)
{
struct hn_softc *sc = arg1;
@@ -2366,6 +2579,20 @@ back:
}
static int
+hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct hn_softc *sc = arg1;
+ char hash_str[128];
+ uint32_t hash;
+
+ HN_LOCK(sc);
+ hash = sc->hn_rss_hash;
+ HN_UNLOCK(sc);
+ snprintf(hash_str, sizeof(hash_str), "%b", hash, NDIS_HASH_BITS);
+ return sysctl_handle_string(oidp, hash_str, sizeof(hash_str), req);
+}
+
+static int
hn_check_iplen(const struct mbuf *m, int hoff)
{
const struct ip *ip;
@@ -2462,7 +2689,7 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt)
* may further limit the usable space.
*/
sc->hn_rxbuf = hyperv_dmamem_alloc(bus_get_dma_tag(dev),
- PAGE_SIZE, 0, NETVSC_RECEIVE_BUFFER_SIZE, &sc->hn_rxbuf_dma,
+ PAGE_SIZE, 0, HN_RXBUF_SIZE, &sc->hn_rxbuf_dma,
BUS_DMA_WAITOK | BUS_DMA_ZERO);
if (sc->hn_rxbuf == NULL) {
device_printf(sc->hn_dev, "allocate rxbuf failed\n");
@@ -2473,7 +2700,7 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt)
sc->hn_rx_ring_inuse = sc->hn_rx_ring_cnt;
sc->hn_rx_ring = malloc(sizeof(struct hn_rx_ring) * sc->hn_rx_ring_cnt,
- M_NETVSC, M_WAITOK | M_ZERO);
+ M_DEVBUF, M_WAITOK | M_ZERO);
#if defined(INET) || defined(INET6)
#if __FreeBSD_version >= 1100095
@@ -2496,9 +2723,7 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt)
struct hn_rx_ring *rxr = &sc->hn_rx_ring[i];
rxr->hn_br = hyperv_dmamem_alloc(bus_get_dma_tag(dev),
- PAGE_SIZE, 0,
- NETVSC_DEVICE_RING_BUFFER_SIZE +
- NETVSC_DEVICE_RING_BUFFER_SIZE,
+ PAGE_SIZE, 0, HN_TXBR_SIZE + HN_RXBR_SIZE,
&rxr->hn_br_dma, BUS_DMA_WAITOK);
if (rxr->hn_br == NULL) {
device_printf(dev, "allocate bufring failed\n");
@@ -2514,7 +2739,8 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt)
rxr->hn_ifp = sc->hn_ifp;
if (i < sc->hn_tx_ring_cnt)
rxr->hn_txr = &sc->hn_tx_ring[i];
- rxr->hn_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK);
+ rxr->hn_pktbuf_len = HN_PKTBUF_LEN_DEF;
+ rxr->hn_pktbuf = malloc(rxr->hn_pktbuf_len, M_DEVBUF, M_WAITOK);
rxr->hn_rx_idx = i;
rxr->hn_rxbuf = sc->hn_rxbuf;
@@ -2557,6 +2783,11 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt)
OID_AUTO, "rss_pkts", CTLFLAG_RW,
&rxr->hn_rss_pkts,
"# of packets w/ RSS info received");
+ SYSCTL_ADD_INT(ctx,
+ SYSCTL_CHILDREN(rxr->hn_rx_sysctl_tree),
+ OID_AUTO, "pktbuf_len", CTLFLAG_RD,
+ &rxr->hn_pktbuf_len, 0,
+ "Temporary channel packet buffer length");
}
}
}
@@ -2629,6 +2860,10 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt)
CTLTYPE_ULONG | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
__offsetof(struct hn_rx_ring, hn_small_pkts),
hn_rx_stat_ulong_sysctl, "LU", "# of small packets received");
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_ack_failed",
+ CTLTYPE_ULONG | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
+ __offsetof(struct hn_rx_ring, hn_ack_failed),
+ hn_rx_stat_ulong_sysctl, "LU", "# of RXBUF ack failures");
SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rx_ring_cnt",
CTLFLAG_RD, &sc->hn_rx_ring_cnt, 0, "# created RX rings");
SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rx_ring_inuse",
@@ -2661,9 +2896,9 @@ hn_destroy_rx_data(struct hn_softc *sc)
#if defined(INET) || defined(INET6)
tcp_lro_free(&rxr->hn_lro);
#endif
- free(rxr->hn_rdbuf, M_NETVSC);
+ free(rxr->hn_pktbuf, M_DEVBUF);
}
- free(sc->hn_rx_ring, M_NETVSC);
+ free(sc->hn_rx_ring, M_DEVBUF);
sc->hn_rx_ring = NULL;
sc->hn_rx_ring_cnt = 0;
@@ -2688,11 +2923,11 @@ hn_create_tx_ring(struct hn_softc *sc, int id)
txr->hn_txdesc_cnt = HN_TX_DESC_CNT;
txr->hn_txdesc = malloc(sizeof(struct hn_txdesc) * txr->hn_txdesc_cnt,
- M_NETVSC, M_WAITOK | M_ZERO);
+ M_DEVBUF, M_WAITOK | M_ZERO);
#ifndef HN_USE_TXDESC_BUFRING
SLIST_INIT(&txr->hn_txlist);
#else
- txr->hn_txdesc_br = buf_ring_alloc(txr->hn_txdesc_cnt, M_NETVSC,
+ txr->hn_txdesc_br = buf_ring_alloc(txr->hn_txdesc_cnt, M_DEVBUF,
M_WAITOK, &txr->hn_tx_lock);
#endif
@@ -2710,7 +2945,7 @@ hn_create_tx_ring(struct hn_softc *sc, int id)
TASK_INIT(&txr->hn_txeof_task, 0, hn_xmit_txeof_taskfunc, txr);
br_depth = hn_get_txswq_depth(txr);
- txr->hn_mbuf_br = buf_ring_alloc(br_depth, M_NETVSC,
+ txr->hn_mbuf_br = buf_ring_alloc(br_depth, M_DEVBUF,
M_WAITOK, &txr->hn_tx_lock);
}
@@ -2766,6 +3001,7 @@ hn_create_tx_ring(struct hn_softc *sc, int id)
struct hn_txdesc *txd = &txr->hn_txdesc[i];
txd->txr = txr;
+ txd->chim_index = HN_NVS_CHIM_IDX_INVALID;
/*
* Allocate and load RNDIS packet message.
@@ -2892,14 +3128,14 @@ hn_destroy_tx_ring(struct hn_tx_ring *txr)
bus_dma_tag_destroy(txr->hn_tx_rndis_dtag);
#ifdef HN_USE_TXDESC_BUFRING
- buf_ring_free(txr->hn_txdesc_br, M_NETVSC);
+ buf_ring_free(txr->hn_txdesc_br, M_DEVBUF);
#endif
- free(txr->hn_txdesc, M_NETVSC);
+ free(txr->hn_txdesc, M_DEVBUF);
txr->hn_txdesc = NULL;
if (txr->hn_mbuf_br != NULL)
- buf_ring_free(txr->hn_mbuf_br, M_NETVSC);
+ buf_ring_free(txr->hn_mbuf_br, M_DEVBUF);
#ifndef HN_USE_TXDESC_BUFRING
mtx_destroy(&txr->hn_txlist_spin);
@@ -2920,7 +3156,7 @@ hn_create_tx_data(struct hn_softc *sc, int ring_cnt)
* NOTE: It is shared by all channels.
*/
sc->hn_chim = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev),
- PAGE_SIZE, 0, NETVSC_SEND_BUFFER_SIZE, &sc->hn_chim_dma,
+ PAGE_SIZE, 0, HN_CHIM_SIZE, &sc->hn_chim_dma,
BUS_DMA_WAITOK | BUS_DMA_ZERO);
if (sc->hn_chim == NULL) {
device_printf(sc->hn_dev, "allocate txbuf failed\n");
@@ -2931,7 +3167,7 @@ hn_create_tx_data(struct hn_softc *sc, int ring_cnt)
sc->hn_tx_ring_inuse = sc->hn_tx_ring_cnt;
sc->hn_tx_ring = malloc(sizeof(struct hn_tx_ring) * sc->hn_tx_ring_cnt,
- M_NETVSC, M_WAITOK | M_ZERO);
+ M_DEVBUF, M_WAITOK | M_ZERO);
ctx = device_get_sysctl_ctx(sc->hn_dev);
child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->hn_dev));
@@ -3091,7 +3327,7 @@ hn_destroy_tx_data(struct hn_softc *sc)
for (i = 0; i < sc->hn_tx_ring_cnt; ++i)
hn_destroy_tx_ring(&sc->hn_tx_ring[i]);
- free(sc->hn_tx_ring, M_NETVSC);
+ free(sc->hn_tx_ring, M_DEVBUF);
sc->hn_tx_ring = NULL;
sc->hn_tx_ring_cnt = 0;
@@ -3338,8 +3574,8 @@ hn_chan_attach(struct hn_softc *sc, struct vmbus_channel *chan)
*/
cbr.cbr = rxr->hn_br;
cbr.cbr_paddr = rxr->hn_br_dma.hv_paddr;
- cbr.cbr_txsz = NETVSC_DEVICE_RING_BUFFER_SIZE;
- cbr.cbr_rxsz = NETVSC_DEVICE_RING_BUFFER_SIZE;
+ cbr.cbr_txsz = HN_TXBR_SIZE;
+ cbr.cbr_rxsz = HN_RXBR_SIZE;
error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr);
if (error) {
if_printf(sc->hn_ifp, "open chan%u failed: %d\n",
@@ -3528,6 +3764,10 @@ hn_synth_attach(struct hn_softc *sc, int mtu)
old_caps = sc->hn_caps;
sc->hn_caps = 0;
+ /* Clear RSS stuffs. */
+ sc->hn_rss_ind_size = 0;
+ sc->hn_rss_hash = 0;
+
/*
* Attach the primary channel _before_ attaching NVS and RNDIS.
*/
@@ -3602,7 +3842,6 @@ hn_synth_attach(struct hn_softc *sc, int mtu)
if_printf(sc->hn_ifp, "setup default RSS indirect "
"table\n");
}
- /* TODO: Take ndis_rss_caps.ndis_nind into account. */
for (i = 0; i < NDIS_HASH_INDCNT; ++i)
rss->rss_ind[i] = i % nchan;
sc->hn_flags |= HN_FLAG_HAS_RSSIND;
@@ -3723,7 +3962,8 @@ hn_suspend_data(struct hn_softc *sc)
/*
* Disable RX by clearing RX filter.
*/
- hn_rndis_set_rxfilter(sc, 0);
+ sc->hn_rx_filter = NDIS_PACKET_TYPE_NONE;
+ hn_rndis_set_rxfilter(sc, sc->hn_rx_filter);
/*
* Give RNDIS enough time to flush all pending data packets.
@@ -3811,9 +4051,8 @@ hn_resume_data(struct hn_softc *sc)
/*
* Re-enable RX.
- * TODO: add hn_rx_filter.
*/
- hn_rndis_set_rxfilter(sc, NDIS_PACKET_TYPE_PROMISCUOUS);
+ hn_set_rxfilter(sc);
/*
* Make sure to clear suspend status on "all" TX rings,
@@ -3849,12 +4088,18 @@ static void
hn_resume_mgmt(struct hn_softc *sc)
{
+ sc->hn_mgmt_taskq = sc->hn_mgmt_taskq0;
+
/*
- * Kick off network change detection, which will
- * do link status check too.
+ * Kick off network change detection, if it was pending.
+ * If no network change was pending, start link status
+ * checks, which is more lightweight than network change
+ * detection.
*/
- sc->hn_mgmt_taskq = sc->hn_mgmt_taskq0;
- hn_network_change(sc);
+ if (sc->hn_link_flags & HN_LINK_FLAG_NETCHG)
+ hn_network_change(sc);
+ else
+ hn_link_status_update(sc);
}
static void
@@ -3866,6 +4111,325 @@ hn_resume(struct hn_softc *sc)
hn_resume_mgmt(sc);
}
+static void
+hn_rndis_rx_status(struct hn_softc *sc, const void *data, int dlen)
+{
+ const struct rndis_status_msg *msg;
+ int ofs;
+
+ if (dlen < sizeof(*msg)) {
+ if_printf(sc->hn_ifp, "invalid RNDIS status\n");
+ return;
+ }
+ msg = data;
+
+ switch (msg->rm_status) {
+ case RNDIS_STATUS_MEDIA_CONNECT:
+ case RNDIS_STATUS_MEDIA_DISCONNECT:
+ hn_link_status_update(sc);
+ break;
+
+ case RNDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG:
+ /* Not really useful; ignore. */
+ break;
+
+ case RNDIS_STATUS_NETWORK_CHANGE:
+ ofs = RNDIS_STBUFOFFSET_ABS(msg->rm_stbufoffset);
+ if (dlen < ofs + msg->rm_stbuflen ||
+ msg->rm_stbuflen < sizeof(uint32_t)) {
+ if_printf(sc->hn_ifp, "network changed\n");
+ } else {
+ uint32_t change;
+
+ memcpy(&change, ((const uint8_t *)msg) + ofs,
+ sizeof(change));
+ if_printf(sc->hn_ifp, "network changed, change %u\n",
+ change);
+ }
+ hn_network_change(sc);
+ break;
+
+ default:
+ if_printf(sc->hn_ifp, "unknown RNDIS status 0x%08x\n",
+ msg->rm_status);
+ break;
+ }
+}
+
+static int
+hn_rndis_rxinfo(const void *info_data, int info_dlen, struct hn_rxinfo *info)
+{
+ const struct rndis_pktinfo *pi = info_data;
+ uint32_t mask = 0;
+
+ while (info_dlen != 0) {
+ const void *data;
+ uint32_t dlen;
+
+ if (__predict_false(info_dlen < sizeof(*pi)))
+ return (EINVAL);
+ if (__predict_false(info_dlen < pi->rm_size))
+ return (EINVAL);
+ info_dlen -= pi->rm_size;
+
+ if (__predict_false(pi->rm_size & RNDIS_PKTINFO_SIZE_ALIGNMASK))
+ return (EINVAL);
+ if (__predict_false(pi->rm_size < pi->rm_pktinfooffset))
+ return (EINVAL);
+ dlen = pi->rm_size - pi->rm_pktinfooffset;
+ data = pi->rm_data;
+
+ switch (pi->rm_type) {
+ case NDIS_PKTINFO_TYPE_VLAN:
+ if (__predict_false(dlen < NDIS_VLAN_INFO_SIZE))
+ return (EINVAL);
+ info->vlan_info = *((const uint32_t *)data);
+ mask |= HN_RXINFO_VLAN;
+ break;
+
+ case NDIS_PKTINFO_TYPE_CSUM:
+ if (__predict_false(dlen < NDIS_RXCSUM_INFO_SIZE))
+ return (EINVAL);
+ info->csum_info = *((const uint32_t *)data);
+ mask |= HN_RXINFO_CSUM;
+ break;
+
+ case HN_NDIS_PKTINFO_TYPE_HASHVAL:
+ if (__predict_false(dlen < HN_NDIS_HASH_VALUE_SIZE))
+ return (EINVAL);
+ info->hash_value = *((const uint32_t *)data);
+ mask |= HN_RXINFO_HASHVAL;
+ break;
+
+ case HN_NDIS_PKTINFO_TYPE_HASHINF:
+ if (__predict_false(dlen < HN_NDIS_HASH_INFO_SIZE))
+ return (EINVAL);
+ info->hash_info = *((const uint32_t *)data);
+ mask |= HN_RXINFO_HASHINF;
+ break;
+
+ default:
+ goto next;
+ }
+
+ if (mask == HN_RXINFO_ALL) {
+ /* All found; done */
+ break;
+ }
+next:
+ pi = (const struct rndis_pktinfo *)
+ ((const uint8_t *)pi + pi->rm_size);
+ }
+
+ /*
+ * Final fixup.
+ * - If there is no hash value, invalidate the hash info.
+ */
+ if ((mask & HN_RXINFO_HASHVAL) == 0)
+ info->hash_info = HN_NDIS_HASH_INFO_INVALID;
+ return (0);
+}
+
+static __inline bool
+hn_rndis_check_overlap(int off, int len, int check_off, int check_len)
+{
+
+ if (off < check_off) {
+ if (__predict_true(off + len <= check_off))
+ return (false);
+ } else if (off > check_off) {
+ if (__predict_true(check_off + check_len <= off))
+ return (false);
+ }
+ return (true);
+}
+
+static void
+hn_rndis_rx_data(struct hn_rx_ring *rxr, const void *data, int dlen)
+{
+ const struct rndis_packet_msg *pkt;
+ struct hn_rxinfo info;
+ int data_off, pktinfo_off, data_len, pktinfo_len;
+
+ /*
+ * Check length.
+ */
+ if (__predict_false(dlen < sizeof(*pkt))) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg\n");
+ return;
+ }
+ pkt = data;
+
+ if (__predict_false(dlen < pkt->rm_len)) {
+ if_printf(rxr->hn_ifp, "truncated RNDIS packet msg, "
+ "dlen %d, msglen %u\n", dlen, pkt->rm_len);
+ return;
+ }
+ if (__predict_false(pkt->rm_len <
+ pkt->rm_datalen + pkt->rm_oobdatalen + pkt->rm_pktinfolen)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msglen, "
+ "msglen %u, data %u, oob %u, pktinfo %u\n",
+ pkt->rm_len, pkt->rm_datalen, pkt->rm_oobdatalen,
+ pkt->rm_pktinfolen);
+ return;
+ }
+ if (__predict_false(pkt->rm_datalen == 0)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, no data\n");
+ return;
+ }
+
+ /*
+ * Check offests.
+ */
+#define IS_OFFSET_INVALID(ofs) \
+ ((ofs) < RNDIS_PACKET_MSG_OFFSET_MIN || \
+ ((ofs) & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK))
+
+ /* XXX Hyper-V does not meet data offset alignment requirement */
+ if (__predict_false(pkt->rm_dataoffset < RNDIS_PACKET_MSG_OFFSET_MIN)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "data offset %u\n", pkt->rm_dataoffset);
+ return;
+ }
+ if (__predict_false(pkt->rm_oobdataoffset > 0 &&
+ IS_OFFSET_INVALID(pkt->rm_oobdataoffset))) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "oob offset %u\n", pkt->rm_oobdataoffset);
+ return;
+ }
+ if (__predict_true(pkt->rm_pktinfooffset > 0) &&
+ __predict_false(IS_OFFSET_INVALID(pkt->rm_pktinfooffset))) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "pktinfo offset %u\n", pkt->rm_pktinfooffset);
+ return;
+ }
+
+#undef IS_OFFSET_INVALID
+
+ data_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_dataoffset);
+ data_len = pkt->rm_datalen;
+ pktinfo_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_pktinfooffset);
+ pktinfo_len = pkt->rm_pktinfolen;
+
+ /*
+ * Check OOB coverage.
+ */
+ if (__predict_false(pkt->rm_oobdatalen != 0)) {
+ int oob_off, oob_len;
+
+ if_printf(rxr->hn_ifp, "got oobdata\n");
+ oob_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_oobdataoffset);
+ oob_len = pkt->rm_oobdatalen;
+
+ if (__predict_false(oob_off + oob_len > pkt->rm_len)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "oob overflow, msglen %u, oob abs %d len %d\n",
+ pkt->rm_len, oob_off, oob_len);
+ return;
+ }
+
+ /*
+ * Check against data.
+ */
+ if (hn_rndis_check_overlap(oob_off, oob_len,
+ data_off, data_len)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "oob overlaps data, oob abs %d len %d, "
+ "data abs %d len %d\n",
+ oob_off, oob_len, data_off, data_len);
+ return;
+ }
+
+ /*
+ * Check against pktinfo.
+ */
+ if (pktinfo_len != 0 &&
+ hn_rndis_check_overlap(oob_off, oob_len,
+ pktinfo_off, pktinfo_len)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "oob overlaps pktinfo, oob abs %d len %d, "
+ "pktinfo abs %d len %d\n",
+ oob_off, oob_len, pktinfo_off, pktinfo_len);
+ return;
+ }
+ }
+
+ /*
+ * Check per-packet-info coverage and find useful per-packet-info.
+ */
+ info.vlan_info = HN_NDIS_VLAN_INFO_INVALID;
+ info.csum_info = HN_NDIS_RXCSUM_INFO_INVALID;
+ info.hash_info = HN_NDIS_HASH_INFO_INVALID;
+ if (__predict_true(pktinfo_len != 0)) {
+ bool overlap;
+ int error;
+
+ if (__predict_false(pktinfo_off + pktinfo_len > pkt->rm_len)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "pktinfo overflow, msglen %u, "
+ "pktinfo abs %d len %d\n",
+ pkt->rm_len, pktinfo_off, pktinfo_len);
+ return;
+ }
+
+ /*
+ * Check packet info coverage.
+ */
+ overlap = hn_rndis_check_overlap(pktinfo_off, pktinfo_len,
+ data_off, data_len);
+ if (__predict_false(overlap)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "pktinfo overlap data, pktinfo abs %d len %d, "
+ "data abs %d len %d\n",
+ pktinfo_off, pktinfo_len, data_off, data_len);
+ return;
+ }
+
+ /*
+ * Find useful per-packet-info.
+ */
+ error = hn_rndis_rxinfo(((const uint8_t *)pkt) + pktinfo_off,
+ pktinfo_len, &info);
+ if (__predict_false(error)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg "
+ "pktinfo\n");
+ return;
+ }
+ }
+
+ if (__predict_false(data_off + data_len > pkt->rm_len)) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, "
+ "data overflow, msglen %u, data abs %d len %d\n",
+ pkt->rm_len, data_off, data_len);
+ return;
+ }
+ hn_rxpkt(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info);
+}
+
+static __inline void
+hn_rndis_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen)
+{
+ const struct rndis_msghdr *hdr;
+
+ if (__predict_false(dlen < sizeof(*hdr))) {
+ if_printf(rxr->hn_ifp, "invalid RNDIS msg\n");
+ return;
+ }
+ hdr = data;
+
+ if (__predict_true(hdr->rm_type == REMOTE_NDIS_PACKET_MSG)) {
+ /* Hot data path. */
+ hn_rndis_rx_data(rxr, data, dlen);
+ /* Done! */
+ return;
+ }
+
+ if (hdr->rm_type == REMOTE_NDIS_INDICATE_STATUS_MSG)
+ hn_rndis_rx_status(rxr->hn_ifp->if_softc, data, dlen);
+ else
+ hn_rndis_rx_ctrl(rxr->hn_ifp->if_softc, data, dlen);
+}
+
static void
hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt)
{
@@ -3888,9 +4452,9 @@ static void
hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan,
const struct vmbus_chanpkt_hdr *pkt)
{
- struct hn_send_ctx *sndc;
+ struct hn_nvs_sendctx *sndc;
- sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid;
+ sndc = (struct hn_nvs_sendctx *)(uintptr_t)pkt->cph_xactid;
sndc->hn_cb(sndc, sc, chan, VMBUS_CHANPKT_CONST_DATA(pkt),
VMBUS_CHANPKT_DATALEN(pkt));
/*
@@ -3901,8 +4465,8 @@ hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan,
}
static void
-hn_nvs_handle_rxbuf(struct hn_softc *sc, struct hn_rx_ring *rxr,
- struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr)
+hn_nvs_handle_rxbuf(struct hn_rx_ring *rxr, struct vmbus_channel *chan,
+ const struct vmbus_chanpkt_hdr *pkthdr)
{
const struct vmbus_chanpkt_rxbuf *pkt;
const struct hn_nvs_hdr *nvs_hdr;
@@ -3947,52 +4511,52 @@ hn_nvs_handle_rxbuf(struct hn_softc *sc, struct hn_rx_ring *rxr,
ofs = pkt->cp_rxbuf[i].rb_ofs;
len = pkt->cp_rxbuf[i].rb_len;
- if (__predict_false(ofs + len > NETVSC_RECEIVE_BUFFER_SIZE)) {
+ if (__predict_false(ofs + len > HN_RXBUF_SIZE)) {
if_printf(rxr->hn_ifp, "%dth RNDIS msg overflow rxbuf, "
"ofs %d, len %d\n", i, ofs, len);
continue;
}
- hv_rf_on_receive(sc, rxr, rxr->hn_rxbuf + ofs, len);
+ hn_rndis_rxpkt(rxr, rxr->hn_rxbuf + ofs, len);
}
-
+
/*
- * Moved completion call back here so that all received
- * messages (not just data messages) will trigger a response
- * message back to the host.
+ * Ack the consumed RXBUF associated w/ this channel packet,
+ * so that this RXBUF can be recycled by the hypervisor.
*/
- hn_nvs_ack_rxbuf(chan, pkt->cp_hdr.cph_xactid);
+ hn_nvs_ack_rxbuf(rxr, chan, pkt->cp_hdr.cph_xactid);
}
-/*
- * Net VSC on receive completion
- *
- * Send a receive completion packet to RNDIS device (ie NetVsp)
- */
static void
-hn_nvs_ack_rxbuf(struct vmbus_channel *chan, uint64_t tid)
+hn_nvs_ack_rxbuf(struct hn_rx_ring *rxr, struct vmbus_channel *chan,
+ uint64_t tid)
{
struct hn_nvs_rndis_ack ack;
- int retries = 0;
- int ret = 0;
+ int retries, error;
ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK;
ack.nvs_status = HN_NVS_STATUS_OK;
-retry_send_cmplt:
- /* Send the completion */
- ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP,
+ retries = 0;
+again:
+ error = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP,
VMBUS_CHANPKT_FLAG_NONE, &ack, sizeof(ack), tid);
- if (ret == 0) {
- /* success */
- /* no-op */
- } else if (ret == EAGAIN) {
- /* no more room... wait a bit and attempt to retry 3 times */
+ if (__predict_false(error == EAGAIN)) {
+ /*
+ * NOTE:
+ * This should _not_ happen in real world, since the
+ * consumption of the TX bufring from the TX path is
+ * controlled.
+ */
+ if (rxr->hn_ack_failed == 0)
+ if_printf(rxr->hn_ifp, "RXBUF ack retry\n");
+ rxr->hn_ack_failed++;
retries++;
-
- if (retries < 4) {
+ if (retries < 10) {
DELAY(100);
- goto retry_send_cmplt;
+ goto again;
}
+ /* RXBUF leaks! */
+ if_printf(rxr->hn_ifp, "RXBUF ack failed\n");
}
}
@@ -4001,66 +4565,72 @@ hn_chan_callback(struct vmbus_channel *chan, void *xrxr)
{
struct hn_rx_ring *rxr = xrxr;
struct hn_softc *sc = rxr->hn_ifp->if_softc;
- void *buffer;
- int bufferlen = NETVSC_PACKET_SIZE;
-
- buffer = rxr->hn_rdbuf;
- do {
- struct vmbus_chanpkt_hdr *pkt = buffer;
- uint32_t bytes_rxed;
- int ret;
-
- bytes_rxed = bufferlen;
- ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed);
- if (ret == 0) {
- switch (pkt->cph_type) {
- case VMBUS_CHANPKT_TYPE_COMP:
- hn_nvs_handle_comp(sc, chan, pkt);
- break;
- case VMBUS_CHANPKT_TYPE_RXBUF:
- hn_nvs_handle_rxbuf(sc, rxr, chan, pkt);
- break;
- case VMBUS_CHANPKT_TYPE_INBAND:
- hn_nvs_handle_notify(sc, pkt);
- break;
- default:
- if_printf(rxr->hn_ifp,
- "unknown chan pkt %u\n",
- pkt->cph_type);
- break;
- }
- } else if (ret == ENOBUFS) {
- /* Handle large packet */
- if (bufferlen > NETVSC_PACKET_SIZE) {
- free(buffer, M_NETVSC);
- buffer = NULL;
- }
- /* alloc new buffer */
- buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT);
- if (buffer == NULL) {
- if_printf(rxr->hn_ifp,
- "hv_cb malloc buffer failed, len=%u\n",
- bytes_rxed);
- bufferlen = 0;
- break;
- }
- bufferlen = bytes_rxed;
- } else {
- /* No more packets */
+ for (;;) {
+ struct vmbus_chanpkt_hdr *pkt = rxr->hn_pktbuf;
+ int error, pktlen;
+
+ pktlen = rxr->hn_pktbuf_len;
+ error = vmbus_chan_recv_pkt(chan, pkt, &pktlen);
+ if (__predict_false(error == ENOBUFS)) {
+ void *nbuf;
+ int nlen;
+
+ /*
+ * Expand channel packet buffer.
+ *
+ * XXX
+ * Use M_WAITOK here, since allocation failure
+ * is fatal.
+ */
+ nlen = rxr->hn_pktbuf_len * 2;
+ while (nlen < pktlen)
+ nlen *= 2;
+ nbuf = malloc(nlen, M_DEVBUF, M_WAITOK);
+
+ if_printf(rxr->hn_ifp, "expand pktbuf %d -> %d\n",
+ rxr->hn_pktbuf_len, nlen);
+
+ free(rxr->hn_pktbuf, M_DEVBUF);
+ rxr->hn_pktbuf = nbuf;
+ rxr->hn_pktbuf_len = nlen;
+ /* Retry! */
+ continue;
+ } else if (__predict_false(error == EAGAIN)) {
+ /* No more channel packets; done! */
break;
}
- } while (1);
+ KASSERT(!error, ("vmbus_chan_recv_pkt failed: %d", error));
+
+ switch (pkt->cph_type) {
+ case VMBUS_CHANPKT_TYPE_COMP:
+ hn_nvs_handle_comp(sc, chan, pkt);
+ break;
- if (bufferlen > NETVSC_PACKET_SIZE)
- free(buffer, M_NETVSC);
+ case VMBUS_CHANPKT_TYPE_RXBUF:
+ hn_nvs_handle_rxbuf(rxr, chan, pkt);
+ break;
+
+ case VMBUS_CHANPKT_TYPE_INBAND:
+ hn_nvs_handle_notify(sc, pkt);
+ break;
- hv_rf_channel_rollup(rxr, rxr->hn_txr);
+ default:
+ if_printf(rxr->hn_ifp, "unknown chan pkt %u\n",
+ pkt->cph_type);
+ break;
+ }
+ }
+ hn_chan_rollup(rxr, rxr->hn_txr);
}
static void
hn_tx_taskq_create(void *arg __unused)
{
+
+ if (vm_guest != VM_GUEST_HV)
+ return;
+
if (!hn_share_tx_taskq)
return;
@@ -4079,16 +4649,17 @@ hn_tx_taskq_create(void *arg __unused)
taskqueue_start_threads(&hn_tx_taskq, 1, PI_NET, "hn tx");
}
}
-SYSINIT(hn_txtq_create, SI_SUB_DRIVERS, SI_ORDER_FIRST,
+SYSINIT(hn_txtq_create, SI_SUB_DRIVERS, SI_ORDER_SECOND,
hn_tx_taskq_create, NULL);
static void
hn_tx_taskq_destroy(void *arg __unused)
{
+
if (hn_tx_taskq != NULL)
taskqueue_free(hn_tx_taskq);
}
-SYSUNINIT(hn_txtq_destroy, SI_SUB_DRIVERS, SI_ORDER_FIRST,
+SYSUNINIT(hn_txtq_destroy, SI_SUB_DRIVERS, SI_ORDER_SECOND,
hn_tx_taskq_destroy, NULL);
static device_method_t netvsc_methods[] = {
diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h
index d25d5f2b7d53..ea47be85848a 100644
--- a/sys/dev/hyperv/netvsc/if_hnvar.h
+++ b/sys/dev/hyperv/netvsc/if_hnvar.h
@@ -29,118 +29,206 @@
#ifndef _IF_HNVAR_H_
#define _IF_HNVAR_H_
-#include <sys/param.h>
-
-#include <dev/hyperv/include/vmbus.h>
-#include <dev/hyperv/netvsc/if_hnreg.h>
-
-struct hn_softc;
-
-struct vmbus_channel;
-struct hn_send_ctx;
-
-typedef void (*hn_sent_callback_t)
- (struct hn_send_ctx *, struct hn_softc *,
- struct vmbus_channel *, const void *, int);
-
-struct hn_send_ctx {
- hn_sent_callback_t hn_cb;
- void *hn_cbarg;
- uint32_t hn_chim_idx;
- int hn_chim_sz;
-};
-
-struct rndis_hash_info;
-struct rndix_hash_value;
-struct ndis_8021q_info_;
-struct rndis_tcp_ip_csum_info_;
-
-#define HN_NDIS_VLAN_INFO_INVALID 0xffffffff
-#define HN_NDIS_RXCSUM_INFO_INVALID 0
-#define HN_NDIS_HASH_INFO_INVALID 0
-
-struct hn_recvinfo {
- uint32_t vlan_info;
- uint32_t csum_info;
- uint32_t hash_info;
- uint32_t hash_value;
+#define HN_USE_TXDESC_BUFRING
+
+#define HN_CHIM_SIZE (15 * 1024 * 1024)
+
+#define HN_RXBUF_SIZE (16 * 1024 * 1024)
+#define HN_RXBUF_SIZE_COMPAT (15 * 1024 * 1024)
+
+/* Claimed to be 12232B */
+#define HN_MTU_MAX (9 * 1024)
+
+#define HN_TXBR_SIZE (128 * PAGE_SIZE)
+#define HN_RXBR_SIZE (128 * PAGE_SIZE)
+
+#define HN_XACT_REQ_PGCNT 2
+#define HN_XACT_RESP_PGCNT 2
+#define HN_XACT_REQ_SIZE (HN_XACT_REQ_PGCNT * PAGE_SIZE)
+#define HN_XACT_RESP_SIZE (HN_XACT_RESP_PGCNT * PAGE_SIZE)
+
+#define HN_GPACNT_MAX 32
+
+struct hn_txdesc;
+#ifndef HN_USE_TXDESC_BUFRING
+SLIST_HEAD(hn_txdesc_list, hn_txdesc);
+#else
+struct buf_ring;
+#endif
+struct hn_tx_ring;
+
+struct hn_rx_ring {
+ struct ifnet *hn_ifp;
+ struct hn_tx_ring *hn_txr;
+ void *hn_pktbuf;
+ int hn_pktbuf_len;
+ uint8_t *hn_rxbuf; /* shadow sc->hn_rxbuf */
+ int hn_rx_idx;
+
+ /* Trust csum verification on host side */
+ int hn_trust_hcsum; /* HN_TRUST_HCSUM_ */
+ struct lro_ctrl hn_lro;
+
+ u_long hn_csum_ip;
+ u_long hn_csum_tcp;
+ u_long hn_csum_udp;
+ u_long hn_csum_trusted;
+ u_long hn_lro_tried;
+ u_long hn_small_pkts;
+ u_long hn_pkts;
+ u_long hn_rss_pkts;
+ u_long hn_ack_failed;
+
+ /* Rarely used stuffs */
+ struct sysctl_oid *hn_rx_sysctl_tree;
+ int hn_rx_flags;
+
+ void *hn_br; /* TX/RX bufring */
+ struct hyperv_dma hn_br_dma;
+} __aligned(CACHE_LINE_SIZE);
+
+#define HN_TRUST_HCSUM_IP 0x0001
+#define HN_TRUST_HCSUM_TCP 0x0002
+#define HN_TRUST_HCSUM_UDP 0x0004
+
+#define HN_RX_FLAG_ATTACHED 0x1
+
+struct hn_tx_ring {
+#ifndef HN_USE_TXDESC_BUFRING
+ struct mtx hn_txlist_spin;
+ struct hn_txdesc_list hn_txlist;
+#else
+ struct buf_ring *hn_txdesc_br;
+#endif
+ int hn_txdesc_cnt;
+ int hn_txdesc_avail;
+ u_short hn_has_txeof;
+ u_short hn_txdone_cnt;
+
+ int hn_sched_tx;
+ void (*hn_txeof)(struct hn_tx_ring *);
+ struct taskqueue *hn_tx_taskq;
+ struct task hn_tx_task;
+ struct task hn_txeof_task;
+
+ struct buf_ring *hn_mbuf_br;
+ int hn_oactive;
+ int hn_tx_idx;
+ int hn_tx_flags;
+
+ struct mtx hn_tx_lock;
+ struct hn_softc *hn_sc;
+ struct vmbus_channel *hn_chan;
+
+ int hn_direct_tx_size;
+ int hn_chim_size;
+ bus_dma_tag_t hn_tx_data_dtag;
+ uint64_t hn_csum_assist;
+
+ int (*hn_sendpkt)(struct hn_tx_ring *, struct hn_txdesc *);
+ int hn_suspended;
+ int hn_gpa_cnt;
+ struct vmbus_gpa hn_gpa[HN_GPACNT_MAX];
+
+ u_long hn_no_txdescs;
+ u_long hn_send_failed;
+ u_long hn_txdma_failed;
+ u_long hn_tx_collapsed;
+ u_long hn_tx_chimney_tried;
+ u_long hn_tx_chimney;
+ u_long hn_pkts;
+
+ /* Rarely used stuffs */
+ struct hn_txdesc *hn_txdesc;
+ bus_dma_tag_t hn_tx_rndis_dtag;
+ struct sysctl_oid *hn_tx_sysctl_tree;
+} __aligned(CACHE_LINE_SIZE);
+
+#define HN_TX_FLAG_ATTACHED 0x1
+#define HN_TX_FLAG_HASHVAL 0x2 /* support HASHVAL pktinfo */
+
+/*
+ * Device-specific softc structure
+ */
+struct hn_softc {
+ struct ifnet *hn_ifp;
+ struct ifmedia hn_media;
+ device_t hn_dev;
+ int hn_if_flags;
+ struct sx hn_lock;
+ struct vmbus_channel *hn_prichan;
+
+ int hn_rx_ring_cnt;
+ int hn_rx_ring_inuse;
+ struct hn_rx_ring *hn_rx_ring;
+
+ int hn_tx_ring_cnt;
+ int hn_tx_ring_inuse;
+ struct hn_tx_ring *hn_tx_ring;
+
+ uint8_t *hn_chim;
+ u_long *hn_chim_bmap;
+ int hn_chim_bmap_cnt;
+ int hn_chim_cnt;
+ int hn_chim_szmax;
+
+ int hn_cpu;
+ struct taskqueue *hn_tx_taskq;
+ struct sysctl_oid *hn_tx_sysctl_tree;
+ struct sysctl_oid *hn_rx_sysctl_tree;
+ struct vmbus_xact_ctx *hn_xact;
+ uint32_t hn_nvs_ver;
+ uint32_t hn_rx_filter;
+
+ struct taskqueue *hn_mgmt_taskq;
+ struct taskqueue *hn_mgmt_taskq0;
+ struct task hn_link_task;
+ struct task hn_netchg_init;
+ struct timeout_task hn_netchg_status;
+ uint32_t hn_link_flags; /* HN_LINK_FLAG_ */
+
+ uint32_t hn_caps; /* HN_CAP_ */
+ uint32_t hn_flags; /* HN_FLAG_ */
+ void *hn_rxbuf;
+ uint32_t hn_rxbuf_gpadl;
+ struct hyperv_dma hn_rxbuf_dma;
+
+ uint32_t hn_chim_gpadl;
+ struct hyperv_dma hn_chim_dma;
+
+ uint32_t hn_rndis_rid;
+ uint32_t hn_ndis_ver;
+ int hn_ndis_tso_szmax;
+ int hn_ndis_tso_sgmin;
+
+ int hn_rss_ind_size;
+ uint32_t hn_rss_hash; /* NDIS_HASH_ */
+ struct ndis_rssprm_toeplitz hn_rss;
};
-#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
-{ \
- .hn_cb = cb, \
- .hn_cbarg = cbarg, \
- .hn_chim_idx = HN_NVS_CHIM_IDX_INVALID, \
- .hn_chim_sz = 0 \
-}
-
-static __inline void
-hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
- void *cbarg, uint32_t chim_idx, int chim_sz)
-{
-
- sndc->hn_cb = cb;
- sndc->hn_cbarg = cbarg;
- sndc->hn_chim_idx = chim_idx;
- sndc->hn_chim_sz = chim_sz;
-}
-
-static __inline void
-hn_send_ctx_init_simple(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
- void *cbarg)
-{
-
- hn_send_ctx_init(sndc, cb, cbarg, HN_NVS_CHIM_IDX_INVALID, 0);
-}
-
-static __inline int
-hn_nvs_send(struct vmbus_channel *chan, uint16_t flags,
- void *nvs_msg, int nvs_msglen, struct hn_send_ctx *sndc)
-{
-
- return (vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, flags,
- nvs_msg, nvs_msglen, (uint64_t)(uintptr_t)sndc));
-}
-
-static __inline int
-hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen,
- void *nvs_msg, int nvs_msglen, struct hn_send_ctx *sndc)
-{
-
- return (vmbus_chan_send_sglist(chan, sg, sglen, nvs_msg, nvs_msglen,
- (uint64_t)(uintptr_t)sndc));
-}
-
-struct vmbus_xact;
-struct rndis_packet_msg;
-
-uint32_t hn_chim_alloc(struct hn_softc *sc);
-void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx);
-
-int hn_rndis_attach(struct hn_softc *sc, int mtu);
-void hn_rndis_detach(struct hn_softc *sc);
-int hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags);
-void *hn_rndis_pktinfo_append(struct rndis_packet_msg *,
- size_t pktsize, size_t pi_dlen, uint32_t pi_type);
-int hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt);
-int hn_rndis_get_eaddr(struct hn_softc *sc, uint8_t *eaddr);
-int hn_rndis_get_linkstatus(struct hn_softc *sc,
- uint32_t *link_status);
-/* filter: NDIS_PACKET_TYPE_ or 0. */
-int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter);
-
-int hn_nvs_attach(struct hn_softc *sc, int mtu);
-void hn_nvs_detach(struct hn_softc *sc);
-int hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch);
-void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc,
- struct vmbus_channel *chan, const void *data, int dlen);
-
-int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen,
- const struct hn_recvinfo *info);
-void hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr);
-void hn_link_status_update(struct hn_softc *sc);
-void hn_network_change(struct hn_softc *sc);
-
-extern struct hn_send_ctx hn_send_ctx_none;
+#define HN_FLAG_RXBUF_CONNECTED 0x0001
+#define HN_FLAG_CHIM_CONNECTED 0x0002
+#define HN_FLAG_HAS_RSSKEY 0x0004
+#define HN_FLAG_HAS_RSSIND 0x0008
+#define HN_FLAG_SYNTH_ATTACHED 0x0010
+
+#define HN_CAP_VLAN 0x0001
+#define HN_CAP_MTU 0x0002
+#define HN_CAP_IPCS 0x0004
+#define HN_CAP_TCP4CS 0x0008
+#define HN_CAP_TCP6CS 0x0010
+#define HN_CAP_UDP4CS 0x0020
+#define HN_CAP_UDP6CS 0x0040
+#define HN_CAP_TSO4 0x0080
+#define HN_CAP_TSO6 0x0100
+#define HN_CAP_HASHVAL 0x0200
+
+/* Capability description for use with printf(9) %b identifier. */
+#define HN_CAP_BITS \
+ "\020\1VLAN\2MTU\3IPCS\4TCP4CS\5TCP6CS" \
+ "\6UDP4CS\7UDP6CS\10TSO4\11TSO6\12HASHVAL"
+
+#define HN_LINK_FLAG_LINKUP 0x0001
+#define HN_LINK_FLAG_NETCHG 0x0002
#endif /* !_IF_HNVAR_H_ */
diff --git a/sys/dev/hyperv/netvsc/ndis.h b/sys/dev/hyperv/netvsc/ndis.h
index 5c741c6db330..9d01471553c6 100644
--- a/sys/dev/hyperv/netvsc/ndis.h
+++ b/sys/dev/hyperv/netvsc/ndis.h
@@ -57,6 +57,10 @@
#define NDIS_HASH_TCP_IPV6 0x00001000
#define NDIS_HASH_TCP_IPV6_EX 0x00002000
+/* Hash description for use with printf(9) %b identifier. */
+#define NDIS_HASH_BITS \
+ "\20\1TOEPLITZ\11IP4\12TCP4\13IP6\14IP6EX\15TCP6\16TCP6EX"
+
#define NDIS_HASH_KEYSIZE_TOEPLITZ 40
#define NDIS_HASH_INDCNT 128
@@ -142,7 +146,7 @@ struct ndis_offload_params {
*/
struct ndis_rss_caps {
struct ndis_object_hdr ndis_hdr;
- uint32_t ndis_flags; /* NDIS_RSS_CAP_ */
+ uint32_t ndis_caps; /* NDIS_RSS_CAP_ */
uint32_t ndis_nmsi; /* # of MSIs */
uint32_t ndis_nrxr; /* # of RX rings */
/* NDIS >= 6.30 */
@@ -165,7 +169,8 @@ struct ndis_rss_caps {
#define NDIS_RSS_CAP_IPV4 0x00000100
#define NDIS_RSS_CAP_IPV6 0x00000200
#define NDIS_RSS_CAP_IPV6_EX 0x00000400
-#define NDIS_RSS_CAP_HASH_TOEPLITZ 0x00000001
+#define NDIS_RSS_CAP_HASH_TOEPLITZ NDIS_HASH_FUNCTION_TOEPLITZ
+#define NDIS_RSS_CAP_HASHFUNC_MASK NDIS_HASH_FUNCTION_MASK
/*
* OID_GEN_RECEIVE_SCALE_PARAMETERS
@@ -209,6 +214,9 @@ struct ndis_rssprm_toeplitz {
uint32_t rss_ind[NDIS_HASH_INDCNT];
};
+#define NDIS_RSSPRM_TOEPLITZ_SIZE(nind) \
+ __offsetof(struct ndis_rssprm_toeplitz, rss_ind[nind])
+
/*
* OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES
* ndis_type: NDIS_OBJTYPE_OFFLOAD
diff --git a/sys/dev/hyperv/utilities/hv_heartbeat.c b/sys/dev/hyperv/utilities/hv_heartbeat.c
index 37867148b538..8fc7a0944eaf 100644
--- a/sys/dev/hyperv/utilities/hv_heartbeat.c
+++ b/sys/dev/hyperv/utilities/hv_heartbeat.c
@@ -40,6 +40,14 @@ __FBSDID("$FreeBSD$");
#include "vmbus_if.h"
+#define VMBUS_HEARTBEAT_FWVER_MAJOR 3
+#define VMBUS_HEARTBEAT_FWVER \
+ VMBUS_IC_VERSION(VMBUS_HEARTBEAT_FWVER_MAJOR, 0)
+
+#define VMBUS_HEARTBEAT_MSGVER_MAJOR 3
+#define VMBUS_HEARTBEAT_MSGVER \
+ VMBUS_IC_VERSION(VMBUS_HEARTBEAT_MSGVER_MAJOR, 0)
+
static const struct vmbus_ic_desc vmbus_heartbeat_descs[] = {
{
.ic_guid = { .hv_guid = {
@@ -80,7 +88,8 @@ vmbus_heartbeat_cb(struct vmbus_channel *chan, void *xsc)
*/
switch (hdr->ic_type) {
case VMBUS_ICMSG_TYPE_NEGOTIATE:
- error = vmbus_ic_negomsg(sc, data, &dlen);
+ error = vmbus_ic_negomsg(sc, data, &dlen,
+ VMBUS_HEARTBEAT_FWVER, VMBUS_HEARTBEAT_MSGVER);
if (error)
return;
break;
diff --git a/sys/dev/hyperv/utilities/hv_kvp.c b/sys/dev/hyperv/utilities/hv_kvp.c
index 9d1abb4c42b9..593b4226bc52 100644
--- a/sys/dev/hyperv/utilities/hv_kvp.c
+++ b/sys/dev/hyperv/utilities/hv_kvp.c
@@ -61,7 +61,9 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <dev/hyperv/include/hyperv.h>
+#include <dev/hyperv/include/vmbus.h>
#include <dev/hyperv/utilities/hv_utilreg.h>
+#include <dev/hyperv/utilities/vmbus_icreg.h>
#include "hv_util.h"
#include "unicode.h"
@@ -74,6 +76,12 @@ __FBSDID("$FreeBSD$");
#define KVP_ERROR 1
#define kvp_hdr hdr.kvp_hdr
+#define KVP_FWVER_MAJOR 3
+#define KVP_FWVER VMBUS_IC_VERSION(KVP_FWVER_MAJOR, 0)
+
+#define KVP_MSGVER_MAJOR 4
+#define KVP_MSGVER VMBUS_IC_VERSION(KVP_MSGVER_MAJOR, 0)
+
/* hv_kvp debug control */
static int hv_kvp_log = 0;
@@ -208,52 +216,10 @@ hv_kvp_transaction_init(hv_kvp_sc *sc, uint32_t rcv_len,
sc->host_msg_id = request_id;
sc->rcv_buf = rcv_buf;
sc->host_kvp_msg = (struct hv_kvp_msg *)&rcv_buf[
- sizeof(struct hv_vmbus_pipe_hdr) +
- sizeof(struct hv_vmbus_icmsg_hdr)];
+ sizeof(struct hv_vmbus_pipe_hdr) +
+ sizeof(struct hv_vmbus_icmsg_hdr)];
}
-
-/*
- * hv_kvp - version neogtiation function
- */
-static void
-hv_kvp_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, uint8_t *buf)
-{
- struct hv_vmbus_icmsg_negotiate *negop;
- int icframe_vercnt;
- int icmsg_vercnt;
-
- icmsghdrp->icmsgsize = 0x10;
-
- negop = (struct hv_vmbus_icmsg_negotiate *)&buf[
- sizeof(struct hv_vmbus_pipe_hdr) +
- sizeof(struct hv_vmbus_icmsg_hdr)];
- icframe_vercnt = negop->icframe_vercnt;
- icmsg_vercnt = negop->icmsg_vercnt;
-
- /*
- * Select the framework version number we will support
- */
- if ((icframe_vercnt >= 2) && (negop->icversion_data[1].major == 3)) {
- icframe_vercnt = 3;
- if (icmsg_vercnt > 2)
- icmsg_vercnt = 4;
- else
- icmsg_vercnt = 3;
- } else {
- icframe_vercnt = 1;
- icmsg_vercnt = 1;
- }
-
- negop->icframe_vercnt = 1;
- negop->icmsg_vercnt = 1;
- negop->icversion_data[0].major = icframe_vercnt;
- negop->icversion_data[0].minor = 0;
- negop->icversion_data[1].major = icmsg_vercnt;
- negop->icversion_data[1].minor = 0;
-}
-
-
/*
* Convert ip related info in umsg from utf8 to utf16 and store in hmsg
*/
@@ -578,7 +544,8 @@ hv_kvp_respond_host(hv_kvp_sc *sc, int error)
error = HV_KVP_E_FAIL;
hv_icmsg_hdrp->status = error;
- hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE;
+ hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION |
+ HV_ICMSGHDRFLAG_RESPONSE;
error = vmbus_chan_send(vmbus_get_channel(sc->dev),
VMBUS_CHANPKT_TYPE_INBAND, 0, sc->rcv_buf, sc->host_msg_len,
@@ -622,8 +589,8 @@ hv_kvp_process_request(void *context, int pending)
uint32_t recvlen = 0;
uint64_t requestid;
struct hv_vmbus_icmsg_hdr *icmsghdrp;
- int ret = 0;
- hv_kvp_sc *sc;
+ int ret = 0, error;
+ hv_kvp_sc *sc;
hv_kvp_log_info("%s: entering hv_kvp_process_request\n", __func__);
@@ -637,14 +604,15 @@ hv_kvp_process_request(void *context, int pending)
/* XXX check recvlen to make sure that it contains enough data */
while ((ret == 0) && (recvlen > 0)) {
-
icmsghdrp = (struct hv_vmbus_icmsg_hdr *)
- &kvp_buf[sizeof(struct hv_vmbus_pipe_hdr)];
+ &kvp_buf[sizeof(struct hv_vmbus_pipe_hdr)];
hv_kvp_transaction_init(sc, recvlen, requestid, kvp_buf);
if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
- hv_kvp_negotiate_version(icmsghdrp, kvp_buf);
- hv_kvp_respond_host(sc, ret);
+ error = vmbus_ic_negomsg(&sc->util_sc,
+ kvp_buf, &recvlen, KVP_FWVER, KVP_MSGVER);
+ /* XXX handle vmbus_ic_negomsg failure. */
+ hv_kvp_respond_host(sc, error);
/*
* It is ok to not acquire the mutex before setting
diff --git a/sys/dev/hyperv/utilities/hv_kvp.h b/sys/dev/hyperv/utilities/hv_kvp.h
index 6474e1825677..c391da0d5a5d 100644
--- a/sys/dev/hyperv/utilities/hv_kvp.h
+++ b/sys/dev/hyperv/utilities/hv_kvp.h
@@ -28,7 +28,6 @@
#ifndef _KVP_H
#define _KVP_H
-
/*
* An implementation of HyperV key value pair (KVP) functionality for FreeBSD
*
@@ -178,9 +177,9 @@ struct hv_kvp_ipaddr_value {
}__attribute__((packed));
struct hv_kvp_hdr {
- uint8_t operation;
- uint8_t pool;
- uint16_t pad;
+ uint8_t operation;
+ uint8_t pool;
+ uint16_t pad;
} __attribute__((packed));
struct hv_kvp_exchg_msg_value {
diff --git a/sys/dev/hyperv/utilities/hv_shutdown.c b/sys/dev/hyperv/utilities/hv_shutdown.c
index 458009381b27..e511b21a070c 100644
--- a/sys/dev/hyperv/utilities/hv_shutdown.c
+++ b/sys/dev/hyperv/utilities/hv_shutdown.c
@@ -41,6 +41,14 @@ __FBSDID("$FreeBSD$");
#include "vmbus_if.h"
+#define VMBUS_SHUTDOWN_FWVER_MAJOR 3
+#define VMBUS_SHUTDOWN_FWVER \
+ VMBUS_IC_VERSION(VMBUS_SHUTDOWN_FWVER_MAJOR, 0)
+
+#define VMBUS_SHUTDOWN_MSGVER_MAJOR 3
+#define VMBUS_SHUTDOWN_MSGVER \
+ VMBUS_IC_VERSION(VMBUS_SHUTDOWN_MSGVER_MAJOR, 0)
+
static const struct vmbus_ic_desc vmbus_shutdown_descs[] = {
{
.ic_guid = { .hv_guid = {
@@ -82,7 +90,8 @@ vmbus_shutdown_cb(struct vmbus_channel *chan, void *xsc)
*/
switch (hdr->ic_type) {
case VMBUS_ICMSG_TYPE_NEGOTIATE:
- error = vmbus_ic_negomsg(sc, data, &dlen);
+ error = vmbus_ic_negomsg(sc, data, &dlen,
+ VMBUS_SHUTDOWN_FWVER, VMBUS_SHUTDOWN_MSGVER);
if (error)
return;
break;
diff --git a/sys/dev/hyperv/utilities/hv_timesync.c b/sys/dev/hyperv/utilities/hv_timesync.c
index 2d440263ec0c..5bd51b08a91f 100644
--- a/sys/dev/hyperv/utilities/hv_timesync.c
+++ b/sys/dev/hyperv/utilities/hv_timesync.c
@@ -42,6 +42,14 @@ __FBSDID("$FreeBSD$");
#include "vmbus_if.h"
+#define VMBUS_TIMESYNC_FWVER_MAJOR 3
+#define VMBUS_TIMESYNC_FWVER \
+ VMBUS_IC_VERSION(VMBUS_TIMESYNC_FWVER_MAJOR, 0)
+
+#define VMBUS_TIMESYNC_MSGVER_MAJOR 3
+#define VMBUS_TIMESYNC_MSGVER \
+ VMBUS_IC_VERSION(VMBUS_TIMESYNC_MSGVER_MAJOR, 0)
+
static const struct vmbus_ic_desc vmbus_timesync_descs[] = {
{
.ic_guid = { .hv_guid = {
@@ -162,7 +170,8 @@ vmbus_timesync_cb(struct vmbus_channel *chan, void *xsc)
*/
switch (hdr->ic_type) {
case VMBUS_ICMSG_TYPE_NEGOTIATE:
- error = vmbus_ic_negomsg(sc, data, &dlen);
+ error = vmbus_ic_negomsg(sc, data, &dlen,
+ VMBUS_TIMESYNC_FWVER, VMBUS_TIMESYNC_MSGVER);
if (error)
return;
break;
diff --git a/sys/dev/hyperv/utilities/hv_util.c b/sys/dev/hyperv/utilities/hv_util.c
index 3fc16c951d4a..20b8f84da94f 100644
--- a/sys/dev/hyperv/utilities/hv_util.c
+++ b/sys/dev/hyperv/utilities/hv_util.c
@@ -37,6 +37,7 @@
#include <sys/module.h>
#include <sys/reboot.h>
#include <sys/systm.h>
+#include <sys/sysctl.h>
#include <sys/timetc.h>
#include <dev/hyperv/include/hyperv.h>
@@ -53,52 +54,145 @@
__offsetof(struct vmbus_icmsg_negotiate, ic_ver[VMBUS_IC_VERCNT])
CTASSERT(VMBUS_IC_NEGOSZ < VMBUS_IC_BRSIZE);
+static int vmbus_ic_fwver_sysctl(SYSCTL_HANDLER_ARGS);
+static int vmbus_ic_msgver_sysctl(SYSCTL_HANDLER_ARGS);
+
int
-vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen0)
+vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen0,
+ uint32_t fw_ver, uint32_t msg_ver)
{
struct vmbus_icmsg_negotiate *nego;
- int cnt, major, dlen = *dlen0;
+ int i, cnt, dlen = *dlen0, error;
+ uint32_t sel_fw_ver, sel_msg_ver;
+ bool has_fw_ver, has_msg_ver;
/*
- * Preliminary message size verification
+ * Preliminary message verification.
*/
if (dlen < sizeof(*nego)) {
device_printf(sc->ic_dev, "truncated ic negotiate, len %d\n",
dlen);
- return EINVAL;
+ return (EINVAL);
}
nego = data;
+ if (nego->ic_fwver_cnt == 0) {
+ device_printf(sc->ic_dev, "ic negotiate does not contain "
+ "framework version %u\n", nego->ic_fwver_cnt);
+ return (EINVAL);
+ }
+ if (nego->ic_msgver_cnt == 0) {
+ device_printf(sc->ic_dev, "ic negotiate does not contain "
+ "message version %u\n", nego->ic_msgver_cnt);
+ return (EINVAL);
+ }
+
cnt = nego->ic_fwver_cnt + nego->ic_msgver_cnt;
if (dlen < __offsetof(struct vmbus_icmsg_negotiate, ic_ver[cnt])) {
device_printf(sc->ic_dev, "ic negotiate does not contain "
"versions %d\n", dlen);
- return EINVAL;
+ return (EINVAL);
+ }
+
+ error = EOPNOTSUPP;
+
+ /*
+ * Find the best match framework version.
+ */
+ has_fw_ver = false;
+ for (i = 0; i < nego->ic_fwver_cnt; ++i) {
+ if (VMBUS_ICVER_LE(nego->ic_ver[i], fw_ver)) {
+ if (!has_fw_ver) {
+ sel_fw_ver = nego->ic_ver[i];
+ has_fw_ver = true;
+ } else if (VMBUS_ICVER_GT(nego->ic_ver[i],
+ sel_fw_ver)) {
+ sel_fw_ver = nego->ic_ver[i];
+ }
+ }
+ }
+ if (!has_fw_ver) {
+ device_printf(sc->ic_dev, "failed to select framework "
+ "version\n");
+ goto done;
+ }
+
+ /*
+ * Fine the best match message version.
+ */
+ has_msg_ver = false;
+ for (i = nego->ic_fwver_cnt;
+ i < nego->ic_fwver_cnt + nego->ic_msgver_cnt; ++i) {
+ if (VMBUS_ICVER_LE(nego->ic_ver[i], msg_ver)) {
+ if (!has_msg_ver) {
+ sel_msg_ver = nego->ic_ver[i];
+ has_msg_ver = true;
+ } else if (VMBUS_ICVER_GT(nego->ic_ver[i],
+ sel_msg_ver)) {
+ sel_msg_ver = nego->ic_ver[i];
+ }
+ }
+ }
+ if (!has_msg_ver) {
+ device_printf(sc->ic_dev, "failed to select message "
+ "version\n");
+ goto done;
}
- /* Select major version; XXX looks wrong. */
- if (nego->ic_fwver_cnt >= 2 && VMBUS_ICVER_MAJOR(nego->ic_ver[1]) == 3)
- major = 3;
- else
- major = 1;
+ error = 0;
+done:
+ if (bootverbose || !has_fw_ver || !has_msg_ver) {
+ if (has_fw_ver) {
+ device_printf(sc->ic_dev, "sel framework version: "
+ "%u.%u\n",
+ VMBUS_ICVER_MAJOR(sel_fw_ver),
+ VMBUS_ICVER_MINOR(sel_fw_ver));
+ }
+ for (i = 0; i < nego->ic_fwver_cnt; i++) {
+ device_printf(sc->ic_dev, "supp framework version: "
+ "%u.%u\n",
+ VMBUS_ICVER_MAJOR(nego->ic_ver[i]),
+ VMBUS_ICVER_MINOR(nego->ic_ver[i]));
+ }
+
+ if (has_msg_ver) {
+ device_printf(sc->ic_dev, "sel message version: "
+ "%u.%u\n",
+ VMBUS_ICVER_MAJOR(sel_msg_ver),
+ VMBUS_ICVER_MINOR(sel_msg_ver));
+ }
+ for (i = nego->ic_fwver_cnt;
+ i < nego->ic_fwver_cnt + nego->ic_msgver_cnt; i++) {
+ device_printf(sc->ic_dev, "supp message version: "
+ "%u.%u\n",
+ VMBUS_ICVER_MAJOR(nego->ic_ver[i]),
+ VMBUS_ICVER_MINOR(nego->ic_ver[i]));
+ }
+ }
+ if (error)
+ return (error);
+
+ /* Record the selected versions. */
+ sc->ic_fwver = sel_fw_ver;
+ sc->ic_msgver = sel_msg_ver;
- /* One framework version */
+ /* One framework version. */
nego->ic_fwver_cnt = 1;
- nego->ic_ver[0] = VMBUS_IC_VERSION(major, 0);
+ nego->ic_ver[0] = sel_fw_ver;
- /* One message version */
+ /* One message version. */
nego->ic_msgver_cnt = 1;
- nego->ic_ver[1] = VMBUS_IC_VERSION(major, 0);
+ nego->ic_ver[1] = sel_msg_ver;
- /* Update data size */
+ /* Update data size. */
nego->ic_hdr.ic_dsize = VMBUS_IC_NEGOSZ -
sizeof(struct vmbus_icmsg_hdr);
- /* Update total size, if necessary */
+ /* Update total size, if necessary. */
if (dlen < VMBUS_IC_NEGOSZ)
*dlen0 = VMBUS_IC_NEGOSZ;
- return 0;
+ return (0);
}
int
@@ -124,6 +218,8 @@ hv_util_attach(device_t dev, vmbus_chan_callback_t cb)
{
struct hv_util_sc *sc = device_get_softc(dev);
struct vmbus_channel *chan = vmbus_get_channel(dev);
+ struct sysctl_oid_list *child;
+ struct sysctl_ctx_list *ctx;
int error;
sc->ic_dev = dev;
@@ -146,9 +242,41 @@ hv_util_attach(device_t dev, vmbus_chan_callback_t cb)
free(sc->receive_buffer, M_DEVBUF);
return (error);
}
+
+ ctx = device_get_sysctl_ctx(dev);
+ child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fw_version",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+ vmbus_ic_fwver_sysctl, "A", "framework version");
+ SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "msg_version",
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0,
+ vmbus_ic_msgver_sysctl, "A", "message version");
+
return (0);
}
+static int
+vmbus_ic_fwver_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct hv_util_sc *sc = arg1;
+ char verstr[16];
+
+ snprintf(verstr, sizeof(verstr), "%u.%u",
+ VMBUS_ICVER_MAJOR(sc->ic_fwver), VMBUS_ICVER_MINOR(sc->ic_fwver));
+ return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
+}
+
+static int
+vmbus_ic_msgver_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct hv_util_sc *sc = arg1;
+ char verstr[16];
+
+ snprintf(verstr, sizeof(verstr), "%u.%u",
+ VMBUS_ICVER_MAJOR(sc->ic_msgver), VMBUS_ICVER_MINOR(sc->ic_msgver));
+ return sysctl_handle_string(oidp, verstr, sizeof(verstr), req);
+}
+
int
hv_util_detach(device_t dev)
{
diff --git a/sys/dev/hyperv/utilities/hv_util.h b/sys/dev/hyperv/utilities/hv_util.h
index 012cdeec3ed6..7cf8d3171826 100644
--- a/sys/dev/hyperv/utilities/hv_util.h
+++ b/sys/dev/hyperv/utilities/hv_util.h
@@ -42,6 +42,8 @@ typedef struct hv_util_sc {
device_t ic_dev;
uint8_t *receive_buffer;
int ic_buflen;
+ uint32_t ic_fwver; /* framework version */
+ uint32_t ic_msgver; /* message version */
} hv_util_sc;
struct vmbus_ic_desc {
@@ -54,6 +56,7 @@ struct vmbus_ic_desc {
int hv_util_attach(device_t dev, vmbus_chan_callback_t cb);
int hv_util_detach(device_t dev);
int vmbus_ic_probe(device_t dev, const struct vmbus_ic_desc descs[]);
-int vmbus_ic_negomsg(struct hv_util_sc *, void *data, int *dlen);
+int vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen,
+ uint32_t fw_ver, uint32_t msg_ver);
#endif
diff --git a/sys/dev/hyperv/utilities/hv_utilreg.h b/sys/dev/hyperv/utilities/hv_utilreg.h
index 124de412e95f..9358776409ee 100644
--- a/sys/dev/hyperv/utilities/hv_utilreg.h
+++ b/sys/dev/hyperv/utilities/hv_utilreg.h
@@ -76,16 +76,4 @@ typedef struct hv_vmbus_icmsg_negotiate {
hv_vmbus_ic_version icversion_data[1]; /* any size array */
} __packed hv_vmbus_icmsg_negotiate;
-typedef struct hv_vmbus_shutdown_msg_data {
- uint32_t reason_code;
- uint32_t timeout_seconds;
- uint32_t flags;
- uint8_t display_message[2048];
-} __packed hv_vmbus_shutdown_msg_data;
-
-typedef struct hv_vmbus_heartbeat_msg_data {
- uint64_t seq_num;
- uint32_t reserved[8];
-} __packed hv_vmbus_heartbeat_msg_data;
-
#endif /* !_HV_UTILREG_H_ */
diff --git a/sys/dev/hyperv/utilities/vmbus_icreg.h b/sys/dev/hyperv/utilities/vmbus_icreg.h
index 683e2f83b591..34359622b6c2 100644
--- a/sys/dev/hyperv/utilities/vmbus_icreg.h
+++ b/sys/dev/hyperv/utilities/vmbus_icreg.h
@@ -42,6 +42,12 @@
#define VMBUS_IC_VERSION(major, minor) ((major) | (((uint32_t)(minor)) << 16))
#define VMBUS_ICVER_MAJOR(ver) ((ver) & 0xffff)
#define VMBUS_ICVER_MINOR(ver) (((ver) & 0xffff0000) >> 16)
+#define VMBUS_ICVER_SWAP(ver) \
+ ((VMBUS_ICVER_MAJOR((ver)) << 16) | VMBUS_ICVER_MINOR((ver)))
+#define VMBUS_ICVER_LE(v1, v2) \
+ (VMBUS_ICVER_SWAP((v1)) <= VMBUS_ICVER_SWAP((v2)))
+#define VMBUS_ICVER_GT(v1, v2) \
+ (VMBUS_ICVER_SWAP((v1)) > VMBUS_ICVER_SWAP((v2)))
struct vmbus_pipe_hdr {
uint32_t ph_flags;
diff --git a/sys/dev/hyperv/vmbus/vmbus.c b/sys/dev/hyperv/vmbus/vmbus.c
index d9cb81ba3f66..6c153335c57c 100644
--- a/sys/dev/hyperv/vmbus/vmbus.c
+++ b/sys/dev/hyperv/vmbus/vmbus.c
@@ -863,7 +863,7 @@ vmbus_intr_setup(struct vmbus_softc *sc)
device_printf(sc->vmbus_dev, "cannot find free IDT vector\n");
return ENXIO;
}
- if(bootverbose) {
+ if (bootverbose) {
device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n",
sc->vmbus_idtvec);
}
diff --git a/sys/dev/hyperv/vmbus/vmbus_chan.c b/sys/dev/hyperv/vmbus/vmbus_chan.c
index a889962b0b49..1a86efdaf09e 100644
--- a/sys/dev/hyperv/vmbus/vmbus_chan.c
+++ b/sys/dev/hyperv/vmbus/vmbus_chan.c
@@ -30,6 +30,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -39,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <machine/atomic.h>
+#include <machine/stdarg.h>
#include <dev/hyperv/include/hyperv_busdma.h>
#include <dev/hyperv/vmbus/hyperv_var.h>
@@ -90,6 +92,9 @@ static void vmbus_chan_msgproc_chrescind(
struct vmbus_softc *,
const struct vmbus_message *);
+static int vmbus_chan_printf(const struct vmbus_channel *,
+ const char *, ...) __printflike(2, 3);
+
/*
* Vmbus channel message processing.
*/
@@ -304,7 +309,7 @@ vmbus_chan_open(struct vmbus_channel *chan, int txbr_size, int rxbr_size,
PAGE_SIZE, 0, txbr_size + rxbr_size, &chan->ch_bufring_dma,
BUS_DMA_WAITOK);
if (chan->ch_bufring == NULL) {
- device_printf(chan->ch_dev, "bufring allocation failed\n");
+ vmbus_chan_printf(chan, "bufring allocation failed\n");
return (ENOMEM);
}
@@ -336,7 +341,7 @@ vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr,
uint8_t *br;
if (udlen > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) {
- device_printf(sc->vmbus_dev,
+ vmbus_chan_printf(chan,
"invalid udata len %d for chan%u\n", udlen, chan->ch_id);
return EINVAL;
}
@@ -386,7 +391,7 @@ vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr,
error = vmbus_chan_gpadl_connect(chan, cbr->cbr_paddr,
txbr_size + rxbr_size, &chan->ch_bufring_gpadl);
if (error) {
- device_printf(sc->vmbus_dev,
+ vmbus_chan_printf(chan,
"failed to connect bufring GPADL to chan%u\n", chan->ch_id);
goto failed;
}
@@ -402,7 +407,7 @@ vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr,
*/
mh = vmbus_msghc_get(sc, sizeof(*req));
if (mh == NULL) {
- device_printf(sc->vmbus_dev,
+ vmbus_chan_printf(chan,
"can not get msg hypercall for chopen(chan%u)\n",
chan->ch_id);
error = ENXIO;
@@ -421,7 +426,7 @@ vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr,
error = vmbus_msghc_exec(sc, mh);
if (error) {
- device_printf(sc->vmbus_dev,
+ vmbus_chan_printf(chan,
"chopen(chan%u) msg hypercall exec failed: %d\n",
chan->ch_id, error);
vmbus_msghc_put(sc, mh);
@@ -436,13 +441,12 @@ vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr,
if (status == 0) {
if (bootverbose) {
- device_printf(sc->vmbus_dev, "chan%u opened\n",
- chan->ch_id);
+ vmbus_chan_printf(chan, "chan%u opened\n", chan->ch_id);
}
return 0;
}
- device_printf(sc->vmbus_dev, "failed to open chan%u\n", chan->ch_id);
+ vmbus_chan_printf(chan, "failed to open chan%u\n", chan->ch_id);
error = ENXIO;
failed:
@@ -485,7 +489,7 @@ vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr,
* We don't support multiple GPA ranges.
*/
if (range_len > UINT16_MAX) {
- device_printf(sc->vmbus_dev, "GPA too large, %d pages\n",
+ vmbus_chan_printf(chan, "GPA too large, %d pages\n",
page_count);
return EOPNOTSUPP;
}
@@ -514,8 +518,8 @@ vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr,
chm_range.gpa_page[cnt]);
mh = vmbus_msghc_get(sc, reqsz);
if (mh == NULL) {
- device_printf(sc->vmbus_dev,
- "can not get msg hypercall for gpadl->chan%u\n",
+ vmbus_chan_printf(chan,
+ "can not get msg hypercall for gpadl_conn(chan%u)\n",
chan->ch_id);
return EIO;
}
@@ -533,8 +537,8 @@ vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr,
error = vmbus_msghc_exec(sc, mh);
if (error) {
- device_printf(sc->vmbus_dev,
- "gpadl->chan%u msg hypercall exec failed: %d\n",
+ vmbus_chan_printf(chan,
+ "gpadl_conn(chan%u) msg hypercall exec failed: %d\n",
chan->ch_id, error);
vmbus_msghc_put(sc, mh);
return error;
@@ -570,13 +574,13 @@ vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr,
vmbus_msghc_put(sc, mh);
if (status != 0) {
- device_printf(sc->vmbus_dev, "gpadl->chan%u failed: "
- "status %u\n", chan->ch_id, status);
+ vmbus_chan_printf(chan, "gpadl_conn(chan%u) failed: %u\n",
+ chan->ch_id, status);
return EIO;
} else {
if (bootverbose) {
- device_printf(sc->vmbus_dev, "gpadl->chan%u "
- "succeeded\n", chan->ch_id);
+ vmbus_chan_printf(chan,
+ "gpadl_conn(chan%u) succeeded\n", chan->ch_id);
}
}
return 0;
@@ -595,8 +599,8 @@ vmbus_chan_gpadl_disconnect(struct vmbus_channel *chan, uint32_t gpadl)
mh = vmbus_msghc_get(sc, sizeof(*req));
if (mh == NULL) {
- device_printf(sc->vmbus_dev,
- "can not get msg hypercall for gpa x->chan%u\n",
+ vmbus_chan_printf(chan,
+ "can not get msg hypercall for gpadl_disconn(chan%u)\n",
chan->ch_id);
return EBUSY;
}
@@ -608,8 +612,8 @@ vmbus_chan_gpadl_disconnect(struct vmbus_channel *chan, uint32_t gpadl)
error = vmbus_msghc_exec(sc, mh);
if (error) {
- device_printf(sc->vmbus_dev,
- "gpa x->chan%u msg hypercall exec failed: %d\n",
+ vmbus_chan_printf(chan,
+ "gpadl_disconn(chan%u) msg hypercall exec failed: %d\n",
chan->ch_id, error);
vmbus_msghc_put(sc, mh);
return error;
@@ -681,7 +685,7 @@ vmbus_chan_close_internal(struct vmbus_channel *chan)
*/
mh = vmbus_msghc_get(sc, sizeof(*req));
if (mh == NULL) {
- device_printf(sc->vmbus_dev,
+ vmbus_chan_printf(chan,
"can not get msg hypercall for chclose(chan%u)\n",
chan->ch_id);
return;
@@ -695,12 +699,12 @@ vmbus_chan_close_internal(struct vmbus_channel *chan)
vmbus_msghc_put(sc, mh);
if (error) {
- device_printf(sc->vmbus_dev,
+ vmbus_chan_printf(chan,
"chclose(chan%u) msg hypercall exec failed: %d\n",
chan->ch_id, error);
return;
} else if (bootverbose) {
- device_printf(sc->vmbus_dev, "close chan%u\n", chan->ch_id);
+ vmbus_chan_printf(chan, "close chan%u\n", chan->ch_id);
}
/*
@@ -890,13 +894,12 @@ vmbus_chan_recv(struct vmbus_channel *chan, void *data, int *dlen0,
return (error);
if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) {
- device_printf(chan->ch_dev, "invalid hlen %u\n",
- pkt.cph_hlen);
+ vmbus_chan_printf(chan, "invalid hlen %u\n", pkt.cph_hlen);
/* XXX this channel is dead actually. */
return (EIO);
}
if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) {
- device_printf(chan->ch_dev, "invalid hlen %u and tlen %u\n",
+ vmbus_chan_printf(chan, "invalid hlen %u and tlen %u\n",
pkt.cph_hlen, pkt.cph_tlen);
/* XXX this channel is dead actually. */
return (EIO);
@@ -933,13 +936,12 @@ vmbus_chan_recv_pkt(struct vmbus_channel *chan,
return (error);
if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) {
- device_printf(chan->ch_dev, "invalid hlen %u\n",
- pkt.cph_hlen);
+ vmbus_chan_printf(chan, "invalid hlen %u\n", pkt.cph_hlen);
/* XXX this channel is dead actually. */
return (EIO);
}
if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) {
- device_printf(chan->ch_dev, "invalid hlen %u and tlen %u\n",
+ vmbus_chan_printf(chan, "invalid hlen %u and tlen %u\n",
pkt.cph_hlen, pkt.cph_tlen);
/* XXX this channel is dead actually. */
return (EIO);
@@ -1082,8 +1084,8 @@ vmbus_chan_update_evtflagcnt(struct vmbus_softc *sc,
break;
if (atomic_cmpset_int(flag_cnt_ptr, old_flag_cnt, flag_cnt)) {
if (bootverbose) {
- device_printf(sc->vmbus_dev,
- "channel%u update cpu%d flag_cnt to %d\n",
+ vmbus_chan_printf(chan,
+ "chan%u update cpu%d flag_cnt to %d\n",
chan->ch_id, chan->ch_cpuid, flag_cnt);
}
break;
@@ -1154,11 +1156,6 @@ vmbus_chan_add(struct vmbus_channel *newchan)
return EINVAL;
}
- if (bootverbose) {
- device_printf(sc->vmbus_dev, "chan%u subidx%u offer\n",
- newchan->ch_id, newchan->ch_subidx);
- }
-
mtx_lock(&sc->vmbus_prichan_lock);
TAILQ_FOREACH(prichan, &sc->vmbus_prichans, ch_prilink) {
/*
@@ -1179,15 +1176,15 @@ vmbus_chan_add(struct vmbus_channel *newchan)
goto done;
} else {
mtx_unlock(&sc->vmbus_prichan_lock);
- device_printf(sc->vmbus_dev, "duplicated primary "
- "chan%u\n", newchan->ch_id);
+ device_printf(sc->vmbus_dev,
+ "duplicated primary chan%u\n", newchan->ch_id);
return EINVAL;
}
} else { /* Sub-channel */
if (prichan == NULL) {
mtx_unlock(&sc->vmbus_prichan_lock);
- device_printf(sc->vmbus_dev, "no primary chan for "
- "chan%u\n", newchan->ch_id);
+ device_printf(sc->vmbus_dev,
+ "no primary chan for chan%u\n", newchan->ch_id);
return EINVAL;
}
/*
@@ -1224,6 +1221,15 @@ done:
mtx_lock(&sc->vmbus_chan_lock);
vmbus_chan_ins_list(sc, newchan);
mtx_unlock(&sc->vmbus_chan_lock);
+
+ if (bootverbose) {
+ vmbus_chan_printf(newchan, "chan%u subidx%u offer\n",
+ newchan->ch_id, newchan->ch_subidx);
+ }
+
+ /* Select default cpu for this channel. */
+ vmbus_chan_cpu_default(newchan);
+
return 0;
}
@@ -1242,7 +1248,8 @@ vmbus_chan_cpu_set(struct vmbus_channel *chan, int cpu)
chan->ch_vcpuid = VMBUS_PCPU_GET(chan->ch_vmbus, vcpuid, cpu);
if (bootverbose) {
- printf("vmbus_chan%u: assigned to cpu%u [vcpu%u]\n",
+ vmbus_chan_printf(chan,
+ "chan%u assigned to cpu%u [vcpu%u]\n",
chan->ch_id, chan->ch_cpuid, chan->ch_vcpuid);
}
}
@@ -1338,9 +1345,6 @@ vmbus_chan_msgproc_choffer(struct vmbus_softc *sc,
TASK_INIT(&chan->ch_attach_task, 0, attach_fn, chan);
TASK_INIT(&chan->ch_detach_task, 0, detach_fn, chan);
- /* Select default cpu for this channel. */
- vmbus_chan_cpu_default(chan);
-
error = vmbus_chan_add(chan);
if (error) {
device_printf(sc->vmbus_dev, "add chan%u failed: %d\n",
@@ -1365,11 +1369,6 @@ vmbus_chan_msgproc_chrescind(struct vmbus_softc *sc,
return;
}
- if (bootverbose) {
- device_printf(sc->vmbus_dev, "chan%u rescinded\n",
- note->chm_chanid);
- }
-
/*
* Find and remove the target channel from the channel list.
*/
@@ -1400,6 +1399,9 @@ vmbus_chan_msgproc_chrescind(struct vmbus_softc *sc,
mtx_unlock(&sc->vmbus_prichan_lock);
}
+ if (bootverbose)
+ vmbus_chan_printf(chan, "chan%u rescinded\n", note->chm_chanid);
+
/* Detach the target channel. */
taskqueue_enqueue(chan->ch_mgmt_tq, &chan->ch_detach_task);
}
@@ -1414,8 +1416,9 @@ vmbus_chan_release(struct vmbus_channel *chan)
mh = vmbus_msghc_get(sc, sizeof(*req));
if (mh == NULL) {
- device_printf(sc->vmbus_dev, "can not get msg hypercall for "
- "chfree(chan%u)\n", chan->ch_id);
+ vmbus_chan_printf(chan,
+ "can not get msg hypercall for chfree(chan%u)\n",
+ chan->ch_id);
return (ENXIO);
}
@@ -1427,13 +1430,12 @@ vmbus_chan_release(struct vmbus_channel *chan)
vmbus_msghc_put(sc, mh);
if (error) {
- device_printf(sc->vmbus_dev, "chfree(chan%u) failed: %d",
+ vmbus_chan_printf(chan,
+ "chfree(chan%u) msg hypercall exec failed: %d\n",
chan->ch_id, error);
} else {
- if (bootverbose) {
- device_printf(sc->vmbus_dev, "chan%u freed\n",
- chan->ch_id);
- }
+ if (bootverbose)
+ vmbus_chan_printf(chan, "chan%u freed\n", chan->ch_id);
}
return (error);
}
@@ -1714,6 +1716,26 @@ vmbus_chan_rx_empty(const struct vmbus_channel *chan)
return (vmbus_rxbr_empty(&chan->ch_rxbr));
}
+static int
+vmbus_chan_printf(const struct vmbus_channel *chan, const char *fmt, ...)
+{
+ va_list ap;
+ device_t dev;
+ int retval;
+
+ if (chan->ch_dev == NULL || !device_is_alive(chan->ch_dev))
+ dev = chan->ch_vmbus->vmbus_dev;
+ else
+ dev = chan->ch_dev;
+
+ retval = device_print_prettyname(dev);
+ va_start(ap, fmt);
+ retval += vprintf(fmt, ap);
+ va_end(ap);
+
+ return (retval);
+}
+
void
vmbus_chan_run_task(struct vmbus_channel *chan, struct task *task)
{
diff --git a/sys/dev/ichiic/ig4_iic.c b/sys/dev/ichiic/ig4_iic.c
index 44bc64ead3e9..87eee02ebe33 100644
--- a/sys/dev/ichiic/ig4_iic.c
+++ b/sys/dev/ichiic/ig4_iic.c
@@ -61,6 +61,8 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/smbus/smbconf.h>
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
#include <dev/ichiic/ig4_reg.h>
#include <dev/ichiic/ig4_var.h>
@@ -120,7 +122,7 @@ set_controller(ig4iic_softc_t *sc, uint32_t ctl)
reg_write(sc, IG4_REG_INTR_MASK, 0);
reg_write(sc, IG4_REG_I2C_EN, ctl);
- error = SMB_ETIMEOUT;
+ error = IIC_ETIMEOUT;
for (retry = 100; retry > 0; --retry) {
v = reg_read(sc, IG4_REG_ENABLE_STATUS);
@@ -148,7 +150,7 @@ wait_status(ig4iic_softc_t *sc, uint32_t status)
u_int count_us = 0;
u_int limit_us = 25000; /* 25ms */
- error = SMB_ETIMEOUT;
+ error = IIC_ETIMEOUT;
for (;;) {
/*
@@ -484,6 +486,236 @@ done:
}
/*
+ * IICBUS API FUNCTIONS
+ */
+static int
+ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave)
+{
+ /* XXX 10-bit address support? */
+ set_slave_addr(sc, slave >> 1, 0);
+ return (0);
+}
+
+static int
+ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
+ bool repeated_start, bool stop)
+{
+ uint32_t cmd;
+ uint16_t i;
+ int error;
+
+ if (len == 0)
+ return (0);
+
+ cmd = IG4_DATA_COMMAND_RD;
+ cmd |= repeated_start ? IG4_DATA_RESTART : 0;
+ cmd |= stop && len == 1 ? IG4_DATA_STOP : 0;
+
+ /* Issue request for the first byte (could be last as well). */
+ reg_write(sc, IG4_REG_DATA_CMD, cmd);
+
+ for (i = 0; i < len; i++) {
+ /*
+ * Maintain a pipeline by queueing the allowance for the next
+ * read before waiting for the current read.
+ */
+ cmd = IG4_DATA_COMMAND_RD;
+ if (i < len - 1) {
+ cmd = IG4_DATA_COMMAND_RD;
+ cmd |= stop && i == len - 2 ? IG4_DATA_STOP : 0;
+ reg_write(sc, IG4_REG_DATA_CMD, cmd);
+ }
+ error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY);
+ if (error)
+ break;
+ buf[i] = data_read(sc);
+ }
+
+ (void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
+ return (error);
+}
+
+static int
+ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
+ bool repeated_start, bool stop)
+{
+ uint32_t cmd;
+ uint16_t i;
+ int error;
+
+ if (len == 0)
+ return (0);
+
+ cmd = repeated_start ? IG4_DATA_RESTART : 0;
+ for (i = 0; i < len; i++) {
+ error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
+ if (error)
+ break;
+ cmd |= buf[i];
+ cmd |= stop && i == len - 1 ? IG4_DATA_STOP : 0;
+ reg_write(sc, IG4_REG_DATA_CMD, cmd);
+ cmd = 0;
+ }
+
+ (void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
+ return (error);
+}
+
+int
+ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ const char *reason = NULL;
+ uint32_t i;
+ int error;
+ int unit;
+ bool rpstart;
+ bool stop;
+
+ /*
+ * The hardware interface imposes limits on allowed I2C messages.
+ * It is not possible to explicitly send a start or stop.
+ * They are automatically sent (or not sent, depending on the
+ * configuration) when a data byte is transferred.
+ * For this reason it's impossible to send a message with no data
+ * at all (like an SMBus quick message).
+ * The start condition is automatically generated after the stop
+ * condition, so it's impossible to not have a start after a stop.
+ * The repeated start condition is automatically sent if a change
+ * of the transfer direction happens, so it's impossible to have
+ * a change of direction without a (repeated) start.
+ * The repeated start can be forced even without the change of
+ * direction.
+ * Changing the target slave address requires resetting the hardware
+ * state, so it's impossible to do that without the stop followed
+ * by the start.
+ */
+ for (i = 0; i < nmsgs; i++) {
+#if 0
+ if (i == 0 && (msgs[i].flags & IIC_M_NOSTART) != 0) {
+ reason = "first message without start";
+ break;
+ }
+ if (i == nmsgs - 1 && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
+ reason = "last message without stop";
+ break;
+ }
+#endif
+ if (msgs[i].len == 0) {
+ reason = "message with no data";
+ break;
+ }
+ if (i > 0) {
+ if ((msgs[i].flags & IIC_M_NOSTART) != 0 &&
+ (msgs[i - 1].flags & IIC_M_NOSTOP) == 0) {
+ reason = "stop not followed by start";
+ break;
+ }
+ if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 &&
+ msgs[i].slave != msgs[i - 1].slave) {
+ reason = "change of slave without stop";
+ break;
+ }
+ if ((msgs[i].flags & IIC_M_NOSTART) != 0 &&
+ (msgs[i].flags & IIC_M_RD) !=
+ (msgs[i - 1].flags & IIC_M_RD)) {
+ reason = "change of direction without repeated"
+ " start";
+ break;
+ }
+ }
+ }
+ if (reason != NULL) {
+ if (bootverbose)
+ device_printf(dev, "%s\n", reason);
+ return (IIC_ENOTSUPP);
+ }
+
+ sx_xlock(&sc->call_lock);
+ mtx_lock(&sc->io_lock);
+
+ /* Debugging - dump registers. */
+ if (ig4_dump) {
+ unit = device_get_unit(dev);
+ if (ig4_dump & (1 << unit)) {
+ ig4_dump &= ~(1 << unit);
+ ig4iic_dump(sc);
+ }
+ }
+
+ /*
+ * Clear any previous abort condition that may have been holding
+ * the txfifo in reset.
+ */
+ reg_read(sc, IG4_REG_CLR_TX_ABORT);
+
+ /*
+ * Clean out any previously received data.
+ */
+ if (sc->rpos != sc->rnext && bootverbose) {
+ device_printf(sc->dev, "discarding %d bytes of spurious data\n",
+ sc->rnext - sc->rpos);
+ }
+ sc->rpos = 0;
+ sc->rnext = 0;
+
+ rpstart = false;
+ error = 0;
+ for (i = 0; i < nmsgs; i++) {
+ if ((msgs[i].flags & IIC_M_NOSTART) == 0) {
+ error = ig4iic_xfer_start(sc, msgs[i].slave);
+ } else {
+ if (!sc->slave_valid ||
+ (msgs[i].slave >> 1) != sc->last_slave) {
+ device_printf(dev, "start condition suppressed"
+ "but slave address is not set up");
+ error = EINVAL;
+ break;
+ }
+ rpstart = false;
+ }
+ if (error != 0)
+ break;
+
+ stop = (msgs[i].flags & IIC_M_NOSTOP) == 0;
+ if (msgs[i].flags & IIC_M_RD)
+ error = ig4iic_read(sc, msgs[i].buf, msgs[i].len,
+ rpstart, stop);
+ else
+ error = ig4iic_write(sc, msgs[i].buf, msgs[i].len,
+ rpstart, stop);
+ if (error != 0)
+ break;
+
+ rpstart = !stop;
+ }
+
+ mtx_unlock(&sc->io_lock);
+ sx_unlock(&sc->call_lock);
+ return (error);
+}
+
+int
+ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+
+ sx_xlock(&sc->call_lock);
+ mtx_lock(&sc->io_lock);
+
+ /* TODO handle speed configuration? */
+ if (oldaddr != NULL)
+ *oldaddr = sc->last_slave << 1;
+ set_slave_addr(sc, addr >> 1, 0);
+ if (addr == IIC_UNKNOWN)
+ sc->slave_valid = false;
+
+ mtx_unlock(&sc->io_lock);
+ sx_unlock(&sc->call_lock);
+ return (0);
+}
+
+/*
* SMBUS API FUNCTIONS
*
* Called from ig4iic_pci_attach/detach()
@@ -549,9 +781,9 @@ ig4iic_attach(ig4iic_softc_t *sc)
IG4_CTL_RESTARTEN |
IG4_CTL_SPEED_STD);
- sc->smb = device_add_child(sc->dev, "smbus", -1);
- if (sc->smb == NULL) {
- device_printf(sc->dev, "smbus driver not found\n");
+ sc->iicbus = device_add_child(sc->dev, "iicbus", -1);
+ if (sc->iicbus == NULL) {
+ device_printf(sc->dev, "iicbus driver not found\n");
error = ENXIO;
goto done;
}
@@ -624,15 +856,15 @@ ig4iic_detach(ig4iic_softc_t *sc)
if (error)
return (error);
}
- if (sc->smb)
- device_delete_child(sc->dev, sc->smb);
+ if (sc->iicbus)
+ device_delete_child(sc->dev, sc->iicbus);
if (sc->intr_handle)
bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);
sx_xlock(&sc->call_lock);
mtx_lock(&sc->io_lock);
- sc->smb = NULL;
+ sc->iicbus = NULL;
sc->intr_handle = NULL;
reg_write(sc, IG4_REG_INTR_MASK, 0);
set_controller(sc, 0);
@@ -976,4 +1208,4 @@ ig4iic_dump(ig4iic_softc_t *sc)
}
#undef REGDUMP
-DRIVER_MODULE(smbus, ig4iic, smbus_driver, smbus_devclass, NULL, NULL);
+DRIVER_MODULE(iicbus, ig4iic, iicbus_driver, iicbus_devclass, NULL, NULL);
diff --git a/sys/dev/ichiic/ig4_pci.c b/sys/dev/ichiic/ig4_pci.c
index 7038cae6478f..0d796e5980d7 100644
--- a/sys/dev/ichiic/ig4_pci.c
+++ b/sys/dev/ichiic/ig4_pci.c
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/smbus/smbconf.h>
+#include <dev/iicbus/iiconf.h>
#include "smbus_if.h"
@@ -180,6 +181,10 @@ static device_method_t ig4iic_pci_methods[] = {
DEVMETHOD(smbus_bread, ig4iic_smb_bread),
DEVMETHOD(smbus_trans, ig4iic_smb_trans),
+ DEVMETHOD(iicbus_transfer, ig4iic_transfer),
+ DEVMETHOD(iicbus_reset, ig4iic_reset),
+ DEVMETHOD(iicbus_callback, iicbus_null_callback),
+
DEVMETHOD_END
};
@@ -191,7 +196,9 @@ static driver_t ig4iic_pci_driver = {
static devclass_t ig4iic_pci_devclass;
-DRIVER_MODULE(ig4iic, pci, ig4iic_pci_driver, ig4iic_pci_devclass, 0, 0);
+DRIVER_MODULE_ORDERED(ig4iic, pci, ig4iic_pci_driver, ig4iic_pci_devclass, 0, 0,
+ SI_ORDER_ANY);
MODULE_DEPEND(ig4iic, pci, 1, 1, 1);
MODULE_DEPEND(ig4iic, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_DEPEND(ig4iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
MODULE_VERSION(ig4iic, 1);
diff --git a/sys/dev/ichiic/ig4_var.h b/sys/dev/ichiic/ig4_var.h
index bb1a357e2c32..b35f2f97296f 100644
--- a/sys/dev/ichiic/ig4_var.h
+++ b/sys/dev/ichiic/ig4_var.h
@@ -42,6 +42,7 @@
#include "device_if.h"
#include "pci_if.h"
#include "smbus_if.h"
+#include "iicbus_if.h"
#define IG4_RBUFSIZE 128
#define IG4_RBUFMASK (IG4_RBUFSIZE - 1)
@@ -51,7 +52,7 @@ enum ig4_op { IG4_IDLE, IG4_READ, IG4_WRITE };
struct ig4iic_softc {
device_t dev;
struct intr_config_hook enum_hook;
- device_t smb;
+ device_t iicbus;
struct resource *regs_res;
int regs_rid;
struct resource *intr_res;
@@ -115,5 +116,7 @@ extern smbus_pcall_t ig4iic_smb_pcall;
extern smbus_bwrite_t ig4iic_smb_bwrite;
extern smbus_bread_t ig4iic_smb_bread;
extern smbus_trans_t ig4iic_smb_trans;
+extern iicbus_transfer_t ig4iic_transfer;
+extern iicbus_reset_t ig4iic_reset;
#endif
diff --git a/sys/dev/iicbus/iicbus.c b/sys/dev/iicbus/iicbus.c
index 0e529fd2499b..8cb7383df243 100644
--- a/sys/dev/iicbus/iicbus.c
+++ b/sys/dev/iicbus/iicbus.c
@@ -208,7 +208,9 @@ iicbus_write_ivar(device_t bus, device_t child, int which, uintptr_t value)
default:
return (EINVAL);
case IICBUS_IVAR_ADDR:
- return (EINVAL);
+ if (devi->addr != 0)
+ return (EINVAL);
+ devi->addr = value;
case IICBUS_IVAR_NOSTOP:
devi->nostop = value;
break;
diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c
index ccf9166f8abb..21723b28f471 100644
--- a/sys/dev/ioat/ioat.c
+++ b/sys/dev/ioat/ioat.c
@@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/conf.h>
+#include <sys/fail.h>
#include <sys/ioccom.h>
#include <sys/kernel.h>
#include <sys/lock.h>
@@ -676,7 +677,7 @@ ioat_process_events(struct ioat_softc *ioat)
}
completed = 0;
- comp_update = ioat_get_chansts(ioat);
+ comp_update = *ioat->comp_update;
status = comp_update & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK;
if (status == ioat->last_seen) {
@@ -690,11 +691,11 @@ ioat_process_events(struct ioat_softc *ioat)
__func__, ioat->chan_idx, comp_update, ioat->last_seen);
desc = ioat_get_ring_entry(ioat, ioat->tail - 1);
- while (desc->hw_desc_bus_addr != status && ioat_get_active(ioat) > 0) {
+ while (desc->hw_desc_bus_addr != status) {
desc = ioat_get_ring_entry(ioat, ioat->tail);
dmadesc = &desc->bus_dmadesc;
- CTR4(KTR_IOAT, "channel=%u completing desc %u ok cb %p(%p)",
- ioat->chan_idx, ioat->tail, dmadesc->callback_fn,
+ CTR5(KTR_IOAT, "channel=%u completing desc idx %u (%p) ok cb %p(%p)",
+ ioat->chan_idx, ioat->tail, dmadesc, dmadesc->callback_fn,
dmadesc->callback_arg);
if (dmadesc->callback_fn != NULL)
@@ -703,6 +704,8 @@ ioat_process_events(struct ioat_softc *ioat)
completed++;
ioat->tail++;
}
+ CTR5(KTR_IOAT, "%s channel=%u head=%u tail=%u active=%u", __func__,
+ ioat->chan_idx, ioat->head, ioat->tail, ioat_get_active(ioat));
if (completed != 0) {
ioat->last_seen = desc->hw_desc_bus_addr;
@@ -760,8 +763,8 @@ out:
while (ioat_get_active(ioat) > 0) {
desc = ioat_get_ring_entry(ioat, ioat->tail);
dmadesc = &desc->bus_dmadesc;
- CTR4(KTR_IOAT, "channel=%u completing desc %u err cb %p(%p)",
- ioat->chan_idx, ioat->tail, dmadesc->callback_fn,
+ CTR5(KTR_IOAT, "channel=%u completing desc idx %u (%p) err cb %p(%p)",
+ ioat->chan_idx, ioat->tail, dmadesc, dmadesc->callback_fn,
dmadesc->callback_arg);
if (dmadesc->callback_fn != NULL)
@@ -773,6 +776,8 @@ out:
ioat->stats.descriptors_processed++;
ioat->stats.descriptors_error++;
}
+ CTR5(KTR_IOAT, "%s channel=%u head=%u tail=%u active=%u", __func__,
+ ioat->chan_idx, ioat->head, ioat->tail, ioat_get_active(ioat));
if (ioat->is_completion_pending) {
ioat->is_completion_pending = FALSE;
@@ -947,7 +952,12 @@ ioat_release(bus_dmaengine_t dmaengine)
struct ioat_softc *ioat;
ioat = to_ioat_softc(dmaengine);
- CTR2(KTR_IOAT, "%s channel=%u", __func__, ioat->chan_idx);
+ CTR4(KTR_IOAT, "%s channel=%u dispatch1 hw_head=%u head=%u", __func__,
+ ioat->chan_idx, ioat->hw_head & UINT16_MAX, ioat->head);
+ KFAIL_POINT_CODE(DEBUG_FP, ioat_release, /* do nothing */);
+ CTR4(KTR_IOAT, "%s channel=%u dispatch2 hw_head=%u head=%u", __func__,
+ ioat->chan_idx, ioat->hw_head & UINT16_MAX, ioat->head);
+
ioat_write_2(ioat, IOAT_DMACOUNT_OFFSET, (uint16_t)ioat->hw_head);
if (!ioat->is_completion_pending) {
@@ -1040,7 +1050,6 @@ ioat_copy(bus_dmaengine_t dmaengine, bus_addr_t dst,
struct ioat_softc *ioat;
ioat = to_ioat_softc(dmaengine);
- CTR2(KTR_IOAT, "%s channel=%u", __func__, ioat->chan_idx);
if (((src | dst) & (0xffffull << 48)) != 0) {
ioat_log_message(0, "%s: High 16 bits of src/dst invalid\n",
@@ -1058,6 +1067,8 @@ ioat_copy(bus_dmaengine_t dmaengine, bus_addr_t dst,
dump_descriptor(hw_desc);
ioat_submit_single(ioat);
+ CTR6(KTR_IOAT, "%s channel=%u desc=%p dest=%lx src=%lx len=%lx",
+ __func__, ioat->chan_idx, &desc->bus_dmadesc, dst, src, len);
return (&desc->bus_dmadesc);
}
@@ -1414,11 +1425,16 @@ ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags)
if (ioat_get_ring_space(ioat) >= num_descs)
goto out;
+ CTR3(KTR_IOAT, "%s channel=%u starved (%u)", __func__,
+ ioat->chan_idx, num_descs);
+
if (!dug && !ioat->is_submitter_processing &&
(1 << ioat->ring_size_order) > num_descs) {
ioat->is_submitter_processing = TRUE;
mtx_unlock(&ioat->submit_lock);
+ CTR2(KTR_IOAT, "%s channel=%u attempting to process events",
+ __func__, ioat->chan_idx);
ioat_process_events(ioat);
mtx_lock(&ioat->submit_lock);
@@ -1433,6 +1449,8 @@ ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags)
order = ioat->ring_size_order;
if (ioat->is_resize_pending || order == IOAT_MAX_ORDER) {
if ((mflags & M_WAITOK) != 0) {
+ CTR2(KTR_IOAT, "%s channel=%u blocking on completions",
+ __func__, ioat->chan_idx);
msleep(&ioat->tail, &ioat->submit_lock, 0,
"ioat_rsz", 0);
continue;
@@ -1791,9 +1809,14 @@ static void
ioat_submit_single(struct ioat_softc *ioat)
{
+ mtx_assert(&ioat->submit_lock, MA_OWNED);
+
ioat_get(ioat, IOAT_ACTIVE_DESCR_REF);
atomic_add_rel_int(&ioat->head, 1);
atomic_add_rel_int(&ioat->hw_head, 1);
+ CTR5(KTR_IOAT, "%s channel=%u head=%u hw_head=%u tail=%u", __func__,
+ ioat->chan_idx, ioat->head, ioat->hw_head & UINT16_MAX,
+ ioat->tail);
ioat->stats.descriptors_submitted++;
}
diff --git a/sys/dev/ioat/ioat_internal.h b/sys/dev/ioat/ioat_internal.h
index a8507609c11d..419b1fdba270 100644
--- a/sys/dev/ioat/ioat_internal.h
+++ b/sys/dev/ioat/ioat_internal.h
@@ -523,6 +523,15 @@ struct ioat_softc {
void ioat_test_attach(void);
void ioat_test_detach(void);
+/*
+ * XXX DO NOT USE this routine for obtaining the current completed descriptor.
+ *
+ * The double_4 read on ioat<3.3 appears to result in torn reads. And v3.2
+ * hardware is still commonplace (Broadwell Xeon has it). Instead, use the
+ * device-pushed *comp_update.
+ *
+ * It is safe to use ioat_get_chansts() for the low status bits.
+ */
static inline uint64_t
ioat_get_chansts(struct ioat_softc *ioat)
{
diff --git a/sys/dev/isl/isl.c b/sys/dev/isl/isl.c
index 5531ee948125..ef77985df19c 100644
--- a/sys/dev/isl/isl.c
+++ b/sys/dev/isl/isl.c
@@ -52,14 +52,12 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/systm.h>
-#include <sys/uio.h>
-#include <sys/vnode.h>
-#include <dev/smbus/smbconf.h>
-#include <dev/smbus/smbus.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
#include <dev/isl/isl.h>
-#include "smbus_if.h"
+#include "iicbus_if.h"
#include "bus_if.h"
#include "device_if.h"
@@ -71,46 +69,58 @@ __FBSDID("$FreeBSD$");
struct isl_softc {
device_t dev;
- int addr;
-
struct sx isl_sx;
};
/* Returns < 0 on problem. */
-static int isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask);
+static int isl_read_sensor(device_t dev, uint8_t cmd_mask);
+
+static int
+isl_read_byte(device_t dev, uint8_t reg, uint8_t *val)
+{
+ uint16_t addr = iicbus_get_addr(dev);
+ struct iic_msg msgs[] = {
+ { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
+ { addr, IIC_M_RD, 1, val },
+ };
+
+ return (iicbus_transfer(dev, msgs, nitems(msgs)));
+}
+
+static int
+isl_write_byte(device_t dev, uint8_t reg, uint8_t val)
+{
+ uint16_t addr = iicbus_get_addr(dev);
+ uint8_t bytes[] = { reg, val };
+ struct iic_msg msgs[] = {
+ { addr, IIC_M_WR, nitems(bytes), bytes },
+ };
+
+ return (iicbus_transfer(dev, msgs, nitems(msgs)));
+}
/*
* Initialize the device
*/
static int
-init_device(device_t dev, int addr, int probe)
+init_device(device_t dev, int probe)
{
- static char bl_init[] = { 0x00 };
-
- device_t bus;
int error;
- bus = device_get_parent(dev); /* smbus */
-
/*
* init procedure: send 0x00 to test ref and cmd reg 1
*/
- error = smbus_trans(bus, addr, REG_TEST,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- bl_init, sizeof(bl_init), NULL, 0, NULL);
+ error = isl_write_byte(dev, REG_TEST, 0);
if (error)
goto done;
-
- error = smbus_trans(bus, addr, REG_CMD1,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- bl_init, sizeof(bl_init), NULL, 0, NULL);
+ error = isl_write_byte(dev, REG_CMD1, 0);
if (error)
goto done;
pause("islinit", hz/100);
done:
- if (error)
+ if (error && !probe)
device_printf(dev, "Unable to initialize\n");
return (error);
}
@@ -138,27 +148,33 @@ static driver_t isl_driver = {
sizeof(struct isl_softc),
};
+#if 0
+static void
+isl_identify(driver_t *driver, device_t parent)
+{
+
+ if (device_find_child(parent, "asl", -1)) {
+ if (bootverbose)
+ printf("asl: device(s) already created\n");
+ return;
+ }
+
+ /* Check if we can communicate to our slave. */
+ if (init_device(dev, 0x88, 1) == 0)
+ BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "isl", -1);
+}
+#endif
+
static int
isl_probe(device_t dev)
{
- int addr;
- int error;
-
- addr = smbus_get_addr(dev);
+ uint32_t addr = iicbus_get_addr(dev);
- /*
- * 0x44 - isl ambient light sensor on the acer c720.
- * (other devices might use other ids).
- */
- if (addr != 0x44)
+ if (addr != 0x88)
return (ENXIO);
-
- error = init_device(dev, addr, 1);
- if (error)
+ if (init_device(dev, 1) != 0)
return (ENXIO);
-
device_set_desc(dev, "ISL Digital Ambient Light Sensor");
-
return (BUS_PROBE_VENDOR);
}
@@ -168,36 +184,28 @@ isl_attach(device_t dev)
struct isl_softc *sc;
struct sysctl_ctx_list *sysctl_ctx;
struct sysctl_oid *sysctl_tree;
- int addr;
int use_als;
int use_ir;
int use_prox;
sc = device_get_softc(dev);
+ sc->dev = dev;
- if (!sc)
- return (ENOMEM);
-
- addr = smbus_get_addr(dev);
-
- if (init_device(dev, addr, 0))
+ if (init_device(dev, 0) != 0)
return (ENXIO);
sx_init(&sc->isl_sx, "ISL read lock");
- sc->dev = dev;
- sc->addr = addr;
-
sysctl_ctx = device_get_sysctl_ctx(dev);
sysctl_tree = device_get_sysctl_tree(dev);
- use_als = isl_read_sensor(dev, addr, CMD1_MASK_ALS_ONCE) >= 0;
- use_ir = isl_read_sensor(dev, addr, CMD1_MASK_IR_ONCE) >= 0;
- use_prox = isl_read_sensor(dev, addr, CMD1_MASK_PROX_ONCE) >= 0;
+ use_als = isl_read_sensor(dev, CMD1_MASK_ALS_ONCE) >= 0;
+ use_ir = isl_read_sensor(dev, CMD1_MASK_IR_ONCE) >= 0;
+ use_prox = isl_read_sensor(dev, CMD1_MASK_PROX_ONCE) >= 0;
if (use_als) {
SYSCTL_ADD_PROC(sysctl_ctx,
- SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
+ SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
"als", CTLTYPE_INT | CTLFLAG_RD,
sc, ISL_METHOD_ALS, isl_sysctl, "I",
"Current ALS sensor read-out");
@@ -252,7 +260,6 @@ isl_sysctl(SYSCTL_HANDLER_ARGS)
static int ranges[] = { 1000, 4000, 16000, 64000};
struct isl_softc *sc;
- device_t bus;
uint8_t rbyte;
int arg;
int resolution;
@@ -262,10 +269,7 @@ isl_sysctl(SYSCTL_HANDLER_ARGS)
arg = -1;
sx_xlock(&sc->isl_sx);
- bus = device_get_parent(sc->dev); /* smbus */
- if (smbus_trans(bus, sc->addr, REG_CMD2,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ if (isl_read_byte(sc->dev, REG_CMD2, &rbyte) != 0) {
sx_xunlock(&sc->isl_sx);
return (-1);
}
@@ -275,16 +279,14 @@ isl_sysctl(SYSCTL_HANDLER_ARGS)
switch (oidp->oid_arg2) {
case ISL_METHOD_ALS:
- arg = (isl_read_sensor(sc->dev, sc->addr,
+ arg = (isl_read_sensor(sc->dev,
CMD1_MASK_ALS_ONCE) * range) >> resolution;
break;
case ISL_METHOD_IR:
- arg = isl_read_sensor(sc->dev, sc->addr,
- CMD1_MASK_IR_ONCE);
+ arg = isl_read_sensor(sc->dev, CMD1_MASK_IR_ONCE);
break;
case ISL_METHOD_PROX:
- arg = isl_read_sensor(sc->dev, sc->addr,
- CMD1_MASK_PROX_ONCE);
+ arg = isl_read_sensor(sc->dev, CMD1_MASK_PROX_ONCE);
break;
case ISL_METHOD_RESOLUTION:
arg = (1 << resolution);
@@ -300,18 +302,13 @@ isl_sysctl(SYSCTL_HANDLER_ARGS)
}
static int
-isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask)
+isl_read_sensor(device_t dev, uint8_t cmd_mask)
{
- device_t bus;
uint8_t rbyte;
uint8_t cmd;
int ret;
- bus = device_get_parent(dev); /* smbus */
-
- if (smbus_trans(bus, addr, REG_CMD1,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ if (isl_read_byte(dev, REG_CMD1, &rbyte) != 0) {
device_printf(dev,
"Couldn't read first byte before issuing command %d\n",
cmd_mask);
@@ -319,27 +316,21 @@ isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask)
}
cmd = (rbyte & 0x1f) | cmd_mask;
- if (smbus_trans(bus, addr, REG_CMD1,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- &cmd, sizeof(cmd), NULL, 0, NULL)) {
+ if (isl_write_byte(dev, REG_CMD1, cmd) != 0) {
device_printf(dev, "Couldn't write command %d\n", cmd_mask);
return (-1);
}
pause("islconv", hz/10);
- if (smbus_trans(bus, addr, REG_DATA1,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ if (isl_read_byte(dev, REG_DATA1, &rbyte) != 0) {
device_printf(dev,
"Couldn't read first byte after command %d\n", cmd_mask);
return (-1);
}
ret = rbyte;
- if (smbus_trans(bus, addr, REG_DATA2,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ if (isl_read_byte(dev, REG_DATA2, &rbyte) != 0) {
device_printf(dev, "Couldn't read second byte after command %d\n", cmd_mask);
return (-1);
}
@@ -348,6 +339,6 @@ isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask)
return (ret);
}
-DRIVER_MODULE(isl, smbus, isl_driver, isl_devclass, NULL, NULL);
-MODULE_DEPEND(isl, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+DRIVER_MODULE(isl, iicbus, isl_driver, isl_devclass, NULL, NULL);
+MODULE_DEPEND(isl, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
MODULE_VERSION(isl, 1);
diff --git a/sys/dev/jedec_ts/jedec_ts.c b/sys/dev/jedec_ts/jedec_ts.c
new file mode 100644
index 000000000000..b65ef789173f
--- /dev/null
+++ b/sys/dev/jedec_ts/jedec_ts.c
@@ -0,0 +1,179 @@
+/*-
+ * Copyright (c) 2016 Andriy Gapon <avg@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 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/kernel.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/module.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+#include <sys/systm.h>
+
+#include <dev/smbus/smbconf.h>
+#include <dev/smbus/smbus.h>
+
+#include "smbus_if.h"
+
+
+/*
+ * SMBus specification defines little-endian byte order,
+ * but it seems that the JEDEC devices expect it to
+ * be big-endian.
+ */
+static int
+ts_readw_be(device_t dev, uint8_t reg, uint16_t *val)
+{
+ device_t bus = device_get_parent(dev);
+ uint8_t addr = smbus_get_addr(dev);
+ int err;
+
+ err = smbus_readw(bus, addr, reg, val);
+ if (err != 0)
+ return (err);
+ *val = be16toh(*val);
+ return (0);
+}
+
+static int
+ts_temp_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ device_t dev = arg1;
+ int err;
+ int temp;
+ uint16_t val;
+
+ err = ts_readw_be(dev, 5, &val);
+ if (err != 0)
+ return (EIO);
+
+ /*
+ * Convert the reading to temperature in 0.0001 Kelvins.
+ * Three most significant bits are flags, the next
+ * most significant bit is a sign bit.
+ * Each step is 0.0625 degrees.
+ */
+ temp = val & 0xfff;
+ if ((val & 0x1000) != 0)
+ temp = -temp;
+ temp = temp * 625 + 2731500;
+ err = sysctl_handle_int(oidp, &temp, 0, req);
+ return (err);
+}
+
+static int
+ts_probe(device_t dev)
+{
+ device_set_desc(dev, "DIMM memory sensor");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+ts_attach(device_t dev)
+{
+ struct sysctl_ctx_list *ctx;
+ struct sysctl_oid_list *tree;
+ int err;
+ uint16_t vendorid;
+ uint16_t devid;
+ uint8_t addr;
+
+ addr = smbus_get_addr(dev);
+ if ((addr & 0x30) != 0x30) {
+ /* Up to 8 slave devices starting at 0x30. */
+ return (ENXIO);
+ }
+
+ err = ts_readw_be(dev, 6, &vendorid);
+ if (err != 0) {
+ device_printf(dev, "failed to read Manufacturer ID\n");
+ return (ENXIO);
+ }
+ err = ts_readw_be(dev, 6, &devid);
+ if (err != 0) {
+ device_printf(dev, "failed to read Device ID\n");
+ return (ENXIO);
+ }
+ if ((devid & 0xff00) == 0x2200) {
+ /*
+ * Defined by JEDEC Standard No. 21-C, Release 26,
+ * Page 4.1.6 – 24
+ */
+ } else if (vendorid == 0x104a) {
+ /*
+ * STMicroelectronics datasheets say that
+ * device ID and revision can vary.
+ * E.g. STT424E02, Doc ID 13448 Rev 8,
+ * section 4.6, page 26.
+ */
+ } else {
+ if (bootverbose) {
+ device_printf(dev, "Unknown Manufacturer and Device IDs"
+ ", 0x%x and 0x%x\n", vendorid, devid);
+ }
+ return (ENXIO);
+ }
+
+ ctx = device_get_sysctl_ctx(dev);
+ tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev));
+
+ SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temp",
+ CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, dev, 0,
+ ts_temp_sysctl, "IK4", "Current temperature");
+
+ return (0);
+}
+
+static int
+ts_detach(device_t dev)
+{
+ return (0);
+}
+
+
+static device_method_t jedec_ts_methods[] = {
+ /* Methods from the device interface */
+ DEVMETHOD(device_probe, ts_probe),
+ DEVMETHOD(device_attach, ts_attach),
+ DEVMETHOD(device_detach, ts_detach),
+
+ /* Terminate method list */
+ { 0, 0 }
+};
+
+static driver_t jedec_ts_driver = {
+ "jedec_ts",
+ jedec_ts_methods,
+ 0 /* no softc */
+};
+
+static devclass_t jedec_ts_devclass;
+
+DRIVER_MODULE(jedec_ts, smbus, jedec_ts_driver, jedec_ts_devclass, 0, 0);
+MODULE_DEPEND(jedec_ts, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(jedec_ts, 1);
diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
index cdb02894192e..64818be60f19 100644
--- a/sys/dev/mii/miidevs
+++ b/sys/dev/mii/miidevs
@@ -316,7 +316,7 @@ model yyREALTEK RTL8201L 0x0020 RTL8201L 10/100 media interface
model xxREALTEK RTL8169S 0x0011 RTL8169S/8110S/8211 1000BASE-T media interface
model REALTEK RTL8305SC 0x0005 RTL8305SC 10/100 802.1q switch
model REALTEK RTL8201E 0x0008 RTL8201E 10/100 media interface
-model REALTEK RTL8251 0x0000 RTL8251 1000BASE-T media interface
+model REALTEK RTL8251 0x0000 RTL8251/8153 1000BASE-T media interface
model REALTEK RTL8169S 0x0011 RTL8169S/8110S/8211 1000BASE-T media interface
/* Seeq Seeq PHYs */
diff --git a/sys/dev/mii/rgephy.c b/sys/dev/mii/rgephy.c
index bb60fa92fe17..25cea3abdbaf 100644
--- a/sys/dev/mii/rgephy.c
+++ b/sys/dev/mii/rgephy.c
@@ -121,6 +121,8 @@ rgephy_attach(device_t dev)
flags = 0;
if (mii_dev_mac_match(dev, "re"))
flags |= MIIF_PHYPRIV0;
+ else if (mii_dev_mac_match(dev, "ure"))
+ flags |= MIIF_PHYPRIV1;
mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0);
/* RTL8169S do not report auto-sense; add manually. */
@@ -293,7 +295,10 @@ rgephy_linkup(struct mii_softc *sc)
linkup++;
}
} else {
- reg = PHY_READ(sc, RL_GMEDIASTAT);
+ if (sc->mii_flags & MIIF_PHYPRIV1)
+ reg = PHY_READ(sc, URE_GMEDIASTAT);
+ else
+ reg = PHY_READ(sc, RL_GMEDIASTAT);
if (reg & RL_GMEDIASTAT_LINK)
linkup++;
}
@@ -378,7 +383,10 @@ rgephy_status(struct mii_softc *sc)
mii->mii_media_active |= IFM_HDX;
}
} else {
- bmsr = PHY_READ(sc, RL_GMEDIASTAT);
+ if (sc->mii_flags & MIIF_PHYPRIV1)
+ bmsr = PHY_READ(sc, URE_GMEDIASTAT);
+ else
+ bmsr = PHY_READ(sc, RL_GMEDIASTAT);
if (bmsr & RL_GMEDIASTAT_1000MBPS)
mii->mii_media_active |= IFM_1000_T;
else if (bmsr & RL_GMEDIASTAT_100MBPS)
diff --git a/sys/dev/mii/rgephyreg.h b/sys/dev/mii/rgephyreg.h
index 7c24a1f7cbb5..35917daa69c9 100644
--- a/sys/dev/mii/rgephyreg.h
+++ b/sys/dev/mii/rgephyreg.h
@@ -199,4 +199,7 @@
#define EEELPAR_1000T 0x0004 /* link partner 1000baseT EEE capable */
#define EEELPAR_100TX 0x0002 /* link partner 100baseTX EEE capable */
+/* RTL8153 */
+#define URE_GMEDIASTAT 0xe908 /* media status register */
+
#endif /* _DEV_RGEPHY_MIIREG_H_ */
diff --git a/sys/dev/mlx4/mlx4_en/mlx4_en_tx.c b/sys/dev/mlx4/mlx4_en/mlx4_en_tx.c
index d415ab65f790..9f83500314ac 100644
--- a/sys/dev/mlx4/mlx4_en/mlx4_en_tx.c
+++ b/sys/dev/mlx4/mlx4_en/mlx4_en_tx.c
@@ -707,20 +707,19 @@ static int mlx4_en_xmit(struct mlx4_en_priv *priv, int tx_ind, struct mbuf **mbp
/* check if TX ring is full */
if (unlikely(mlx4_en_tx_ring_is_full(ring))) {
- /* every full native Tx ring stops queue */
- if (ring->blocked == 0)
- atomic_add_int(&priv->blocked, 1);
- /* Set HW-queue-is-full flag */
- atomic_set_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE);
- priv->port_stats.queue_stopped++;
- ring->blocked = 1;
+ /* every full native Tx ring stops queue */
+ if (ring->blocked == 0)
+ atomic_add_int(&priv->blocked, 1);
+ /* Set HW-queue-is-full flag */
+ atomic_set_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE);
priv->port_stats.queue_stopped++;
+ ring->blocked = 1;
ring->queue_stopped++;
/* Use interrupts to find out when queue opened */
mlx4_en_arm_cq(priv, priv->tx_cq[tx_ind]);
return (ENOBUFS);
- }
+ }
/* sanity check we are not wrapping around */
KASSERT(((~ring->prod) & ring->size_mask) >=
diff --git a/sys/dev/netmap/if_em_netmap.h b/sys/dev/netmap/if_em_netmap.h
index 28f2dd4bbc64..1fe7563348c6 100644
--- a/sys/dev/netmap/if_em_netmap.h
+++ b/sys/dev/netmap/if_em_netmap.h
@@ -277,9 +277,9 @@ em_netmap_rxsync(struct netmap_kring *kring, int flags)
if (addr == NETMAP_BUF_BASE(na)) /* bad buf */
goto ring_reset;
+ curr->read.buffer_addr = htole64(paddr);
if (slot->flags & NS_BUF_CHANGED) {
/* buffer has changed, reload map */
- curr->read.buffer_addr = htole64(paddr);
netmap_reload_map(na, rxr->rxtag, rxbuf->map, addr);
slot->flags &= ~NS_BUF_CHANGED;
}
diff --git a/sys/dev/netmap/if_ptnet.c b/sys/dev/netmap/if_ptnet.c
index 90a90e984a5a..4c7072774df4 100644
--- a/sys/dev/netmap/if_ptnet.c
+++ b/sys/dev/netmap/if_ptnet.c
@@ -291,7 +291,7 @@ static inline void ptnet_kick(struct ptnet_queue *pq)
static int
ptnet_attach(device_t dev)
{
- uint32_t ptfeatures = PTNETMAP_F_BASE;
+ uint32_t ptfeatures = 0;
unsigned int num_rx_rings, num_tx_rings;
struct netmap_adapter na_arg;
unsigned int nifp_offset;
@@ -315,19 +315,12 @@ ptnet_attach(device_t dev)
return (ENXIO);
}
- /* Check if we are supported by the hypervisor. If not,
- * bail out immediately. */
+ /* Negotiate features with the hypervisor. */
if (ptnet_vnet_hdr) {
ptfeatures |= PTNETMAP_F_VNET_HDR;
}
bus_write_4(sc->iomem, PTNET_IO_PTFEAT, ptfeatures); /* wanted */
ptfeatures = bus_read_4(sc->iomem, PTNET_IO_PTFEAT); /* acked */
- if (!(ptfeatures & PTNETMAP_F_BASE)) {
- device_printf(dev, "Hypervisor does not support netmap "
- "passthorugh\n");
- err = ENXIO;
- goto err_path;
- }
sc->ptfeatures = ptfeatures;
/* Allocate CSB and carry out CSB allocation protocol (CSBBAH first,
@@ -474,7 +467,8 @@ ptnet_attach(device_t dev)
na_arg.nm_txsync = ptnet_nm_txsync;
na_arg.nm_rxsync = ptnet_nm_rxsync;
- netmap_pt_guest_attach(&na_arg, sc->csb, nifp_offset, ptnet_nm_ptctl);
+ netmap_pt_guest_attach(&na_arg, sc->csb, nifp_offset,
+ bus_read_4(sc->iomem, PTNET_IO_HOSTMEMID));
/* Now a netmap adapter for this ifp has been allocated, and it
* can be accessed through NA(ifp). We also have to initialize the CSB
@@ -1082,13 +1076,12 @@ static uint32_t
ptnet_nm_ptctl(if_t ifp, uint32_t cmd)
{
struct ptnet_softc *sc = if_getsoftc(ifp);
- int ret;
-
+ /*
+ * Write a command and read back error status,
+ * with zero meaning success.
+ */
bus_write_4(sc->iomem, PTNET_IO_PTCTL, cmd);
- ret = bus_read_4(sc->iomem, PTNET_IO_PTSTS);
- device_printf(sc->dev, "PTCTL %u, ret %u\n", cmd, ret);
-
- return ret;
+ return bus_read_4(sc->iomem, PTNET_IO_PTCTL);
}
static int
@@ -1196,7 +1189,7 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff)
/* Make sure the host adapter passed through is ready
* for txsync/rxsync. */
- ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_REGIF);
+ ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_CREATE);
if (ret) {
return ret;
}
@@ -1246,7 +1239,7 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff)
}
if (sc->ptna->backend_regifs == 0) {
- ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_UNREGIF);
+ ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_DELETE);
}
}
diff --git a/sys/dev/netmap/netmap.c b/sys/dev/netmap/netmap.c
index 46aca2eab5e2..15e44815accc 100644
--- a/sys/dev/netmap/netmap.c
+++ b/sys/dev/netmap/netmap.c
@@ -2186,7 +2186,11 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread
break;
case NIOCREGIF:
- /* possibly attach/detach NIC and VALE switch */
+ /*
+ * If nmr->nr_cmd is not zero, this NIOCREGIF is not really
+ * a regif operation, but a different one, specified by the
+ * value of nmr->nr_cmd.
+ */
i = nmr->nr_cmd;
if (i == NETMAP_BDG_ATTACH || i == NETMAP_BDG_DETACH
|| i == NETMAP_BDG_VNET_HDR
@@ -2194,12 +2198,15 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread
|| i == NETMAP_BDG_DELIF
|| i == NETMAP_BDG_POLLING_ON
|| i == NETMAP_BDG_POLLING_OFF) {
+ /* possibly attach/detach NIC and VALE switch */
error = netmap_bdg_ctl(nmr, NULL);
break;
} else if (i == NETMAP_PT_HOST_CREATE || i == NETMAP_PT_HOST_DELETE) {
+ /* forward the command to the ptnetmap subsystem */
error = ptnetmap_ctl(nmr, priv->np_na);
break;
} else if (i == NETMAP_VNET_HDR_GET) {
+ /* get vnet-header length for this netmap port */
struct ifnet *ifp;
NMG_LOCK();
@@ -2210,6 +2217,10 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread
netmap_unget_na(na, ifp);
NMG_UNLOCK();
break;
+ } else if (i == NETMAP_POOLS_INFO_GET) {
+ /* get information from the memory allocator */
+ error = netmap_mem_pools_info_get(nmr, priv->np_na);
+ break;
} else if (i != 0) {
D("nr_cmd must be 0 not %d", i);
error = EINVAL;
@@ -2873,17 +2884,15 @@ netmap_attach(struct netmap_adapter *arg)
#ifdef WITH_PTNETMAP_GUEST
int
-netmap_pt_guest_attach(struct netmap_adapter *arg,
- void *csb,
- unsigned int nifp_offset,
- nm_pt_guest_ptctl_t ptctl)
+netmap_pt_guest_attach(struct netmap_adapter *arg, void *csb,
+ unsigned int nifp_offset, unsigned int memid)
{
struct netmap_pt_guest_adapter *ptna;
struct ifnet *ifp = arg ? arg->ifp : NULL;
int error;
/* get allocator */
- arg->nm_mem = netmap_mem_pt_guest_new(ifp, nifp_offset, ptctl);
+ arg->nm_mem = netmap_mem_pt_guest_new(ifp, nifp_offset, memid);
if (arg->nm_mem == NULL)
return ENOMEM;
arg->na_flags |= NAF_MEM_OWNER;
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c
index d83f21e255ec..2aecb53b47e4 100644
--- a/sys/dev/netmap/netmap_freebsd.c
+++ b/sys/dev/netmap/netmap_freebsd.c
@@ -626,38 +626,26 @@ DRIVER_MODULE_ORDERED(ptn_memdev, pci, ptn_memdev_driver, ptnetmap_devclass,
NULL, NULL, SI_ORDER_MIDDLE + 1);
/*
- * I/O port read/write wrappers.
- * Some are not used, so we keep them commented out until needed
- */
-#define ptn_ioread16(ptn_dev, reg) bus_read_2((ptn_dev)->pci_io, (reg))
-#define ptn_ioread32(ptn_dev, reg) bus_read_4((ptn_dev)->pci_io, (reg))
-#if 0
-#define ptn_ioread8(ptn_dev, reg) bus_read_1((ptn_dev)->pci_io, (reg))
-#define ptn_iowrite8(ptn_dev, reg, val) bus_write_1((ptn_dev)->pci_io, (reg), (val))
-#define ptn_iowrite16(ptn_dev, reg, val) bus_write_2((ptn_dev)->pci_io, (reg), (val))
-#define ptn_iowrite32(ptn_dev, reg, val) bus_write_4((ptn_dev)->pci_io, (reg), (val))
-#endif /* unused */
-
-/*
* Map host netmap memory through PCI-BAR in the guest OS,
* returning physical (nm_paddr) and virtual (nm_addr) addresses
* of the netmap memory mapped in the guest.
*/
int
nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr,
- void **nm_addr)
+ void **nm_addr, uint64_t *mem_size)
{
- uint32_t mem_size;
int rid;
D("ptn_memdev_driver iomap");
rid = PCIR_BAR(PTNETMAP_MEM_PCI_BAR);
- mem_size = ptn_ioread32(ptn_dev, PTNETMAP_IO_PCI_MEMSIZE);
+ *mem_size = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMSIZE_HI);
+ *mem_size = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMSIZE_LO) |
+ (*mem_size << 32);
/* map memory allocator */
ptn_dev->pci_mem = bus_alloc_resource(ptn_dev->dev, SYS_RES_MEMORY,
- &rid, 0, ~0, mem_size, RF_ACTIVE);
+ &rid, 0, ~0, *mem_size, RF_ACTIVE);
if (ptn_dev->pci_mem == NULL) {
*nm_paddr = 0;
*nm_addr = 0;
@@ -667,14 +655,20 @@ nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr,
*nm_paddr = rman_get_start(ptn_dev->pci_mem);
*nm_addr = rman_get_virtual(ptn_dev->pci_mem);
- D("=== BAR %d start %lx len %lx mem_size %x ===",
+ D("=== BAR %d start %lx len %lx mem_size %lx ===",
PTNETMAP_MEM_PCI_BAR,
(unsigned long)(*nm_paddr),
(unsigned long)rman_get_size(ptn_dev->pci_mem),
- mem_size);
+ (unsigned long)*mem_size);
return (0);
}
+uint32_t
+nm_os_pt_memdev_ioread(struct ptnetmap_memdev *ptn_dev, unsigned int reg)
+{
+ return bus_read_4(ptn_dev->pci_io, reg);
+}
+
/* Unmap host netmap memory. */
void
nm_os_pt_memdev_iounmap(struct ptnetmap_memdev *ptn_dev)
@@ -730,7 +724,7 @@ ptn_memdev_attach(device_t dev)
return (ENXIO);
}
- mem_id = ptn_ioread16(ptn_dev, PTNETMAP_IO_PCI_HOSTID);
+ mem_id = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMID);
/* create guest allocator */
ptn_dev->nm_mem = netmap_mem_pt_guest_attach(ptn_dev, mem_id);
@@ -740,7 +734,7 @@ ptn_memdev_attach(device_t dev)
}
netmap_mem_get(ptn_dev->nm_mem);
- D("ptn_memdev_driver probe OK - host_id: %d", mem_id);
+ D("ptn_memdev_driver probe OK - host_mem_id: %d", mem_id);
return (0);
}
@@ -993,12 +987,7 @@ nm_os_ncpus(void)
struct nm_kthread_ctx {
struct thread *user_td; /* thread user-space (kthread creator) to send ioctl */
- /* notification to guest (interrupt) */
- int irq_fd; /* ioctl fd */
- struct nm_kth_ioctl irq_ioctl; /* ioctl arguments */
-
- /* notification from guest */
- void *ioevent_file; /* tsleep() argument */
+ struct ptnetmap_cfgentry_bhyve cfg;
/* worker function and parameter */
nm_kthread_worker_fn_t worker_fn;
@@ -1034,8 +1023,8 @@ nm_os_kthread_wakeup_worker(struct nm_kthread *nmk)
*/
mtx_lock(&nmk->worker_lock);
nmk->scheduled++;
- if (nmk->worker_ctx.ioevent_file) {
- wakeup(nmk->worker_ctx.ioevent_file);
+ if (nmk->worker_ctx.cfg.wchan) {
+ wakeup((void *)nmk->worker_ctx.cfg.wchan);
}
mtx_unlock(&nmk->worker_lock);
}
@@ -1046,11 +1035,13 @@ nm_os_kthread_send_irq(struct nm_kthread *nmk)
struct nm_kthread_ctx *ctx = &nmk->worker_ctx;
int err;
- if (ctx->user_td && ctx->irq_fd > 0) {
- err = kern_ioctl(ctx->user_td, ctx->irq_fd, ctx->irq_ioctl.com, (caddr_t)&ctx->irq_ioctl.data.msix);
+ if (ctx->user_td && ctx->cfg.ioctl_fd > 0) {
+ err = kern_ioctl(ctx->user_td, ctx->cfg.ioctl_fd, ctx->cfg.ioctl_cmd,
+ (caddr_t)&ctx->cfg.ioctl_data);
if (err) {
- D("kern_ioctl error: %d ioctl parameters: fd %d com %ju data %p",
- err, ctx->irq_fd, (uintmax_t)ctx->irq_ioctl.com, &ctx->irq_ioctl.data);
+ D("kern_ioctl error: %d ioctl parameters: fd %d com %lu data %p",
+ err, ctx->cfg.ioctl_fd, (unsigned long)ctx->cfg.ioctl_cmd,
+ &ctx->cfg.ioctl_data);
}
}
}
@@ -1082,10 +1073,10 @@ nm_kthread_worker(void *data)
}
/*
- * if ioevent_file is not defined, we don't have notification
+ * if wchan is not defined, we don't have notification
* mechanism and we continually execute worker_fn()
*/
- if (!ctx->ioevent_file) {
+ if (!ctx->cfg.wchan) {
ctx->worker_fn(ctx->worker_private); /* worker body */
} else {
/* checks if there is a pending notification */
@@ -1099,7 +1090,7 @@ nm_kthread_worker(void *data)
continue;
} else if (nmk->run) {
/* wait on event with one second timeout */
- msleep_spin(ctx->ioevent_file, &nmk->worker_lock,
+ msleep_spin((void *)ctx->cfg.wchan, &nmk->worker_lock,
"nmk_ev", hz);
nmk->scheduled++;
}
@@ -1110,29 +1101,6 @@ nm_kthread_worker(void *data)
kthread_exit();
}
-static int
-nm_kthread_open_files(struct nm_kthread *nmk, struct nm_kthread_cfg *cfg)
-{
- /* send irq through ioctl to bhyve (vmm.ko) */
- if (cfg->event.irqfd) {
- nmk->worker_ctx.irq_fd = cfg->event.irqfd;
- nmk->worker_ctx.irq_ioctl = cfg->event.ioctl;
- }
- /* ring.ioeventfd contains the chan where do tsleep to wait events */
- if (cfg->event.ioeventfd) {
- nmk->worker_ctx.ioevent_file = (void *)cfg->event.ioeventfd;
- }
-
- return 0;
-}
-
-static void
-nm_kthread_close_files(struct nm_kthread *nmk)
-{
- nmk->worker_ctx.irq_fd = 0;
- nmk->worker_ctx.ioevent_file = NULL;
-}
-
void
nm_os_kthread_set_affinity(struct nm_kthread *nmk, int affinity)
{
@@ -1140,10 +1108,15 @@ nm_os_kthread_set_affinity(struct nm_kthread *nmk, int affinity)
}
struct nm_kthread *
-nm_os_kthread_create(struct nm_kthread_cfg *cfg)
+nm_os_kthread_create(struct nm_kthread_cfg *cfg, unsigned int cfgtype,
+ void *opaque)
{
struct nm_kthread *nmk = NULL;
- int error;
+
+ if (cfgtype != PTNETMAP_CFGTYPE_BHYVE) {
+ D("Unsupported cfgtype %u", cfgtype);
+ return NULL;
+ }
nmk = malloc(sizeof(*nmk), M_DEVBUF, M_NOWAIT | M_ZERO);
if (!nmk)
@@ -1158,15 +1131,12 @@ nm_os_kthread_create(struct nm_kthread_cfg *cfg)
/* attach kthread to user process (ptnetmap) */
nmk->attach_user = cfg->attach_user;
- /* open event fd */
- error = nm_kthread_open_files(nmk, cfg);
- if (error)
- goto err;
+ /* store kick/interrupt configuration */
+ if (opaque) {
+ nmk->worker_ctx.cfg = *((struct ptnetmap_cfgentry_bhyve *)opaque);
+ }
return nmk;
-err:
- free(nmk, M_DEVBUF);
- return NULL;
}
int
@@ -1194,7 +1164,7 @@ nm_os_kthread_start(struct nm_kthread *nmk)
goto err;
}
- D("nm_kthread started td 0x%p", nmk->worker);
+ D("nm_kthread started td %p", nmk->worker);
return 0;
err:
@@ -1228,7 +1198,7 @@ nm_os_kthread_delete(struct nm_kthread *nmk)
nm_os_kthread_stop(nmk);
}
- nm_kthread_close_files(nmk);
+ memset(&nmk->worker_ctx.cfg, 0, sizeof(nmk->worker_ctx.cfg));
free(nmk, M_DEVBUF);
}
diff --git a/sys/dev/netmap/netmap_kern.h b/sys/dev/netmap/netmap_kern.h
index 28e69d7ab093..f904476721ba 100644
--- a/sys/dev/netmap/netmap_kern.h
+++ b/sys/dev/netmap/netmap_kern.h
@@ -2009,13 +2009,14 @@ typedef void (*nm_kthread_worker_fn_t)(void *data);
/* kthread configuration */
struct nm_kthread_cfg {
long type; /* kthread type/identifier */
- struct ptnet_ring_cfg event; /* event/ioctl fd */
nm_kthread_worker_fn_t worker_fn; /* worker function */
void *worker_private;/* worker parameter */
int attach_user; /* attach kthread to user process */
};
/* kthread configuration */
-struct nm_kthread *nm_os_kthread_create(struct nm_kthread_cfg *cfg);
+struct nm_kthread *nm_os_kthread_create(struct nm_kthread_cfg *cfg,
+ unsigned int cfgtype,
+ void *opaque);
int nm_os_kthread_start(struct nm_kthread *);
void nm_os_kthread_stop(struct nm_kthread *);
void nm_os_kthread_delete(struct nm_kthread *);
@@ -2053,8 +2054,6 @@ nm_ptnetmap_host_on(struct netmap_adapter *na)
#ifdef WITH_PTNETMAP_GUEST
/* ptnetmap GUEST routines */
-typedef uint32_t (*nm_pt_guest_ptctl_t)(struct ifnet *, uint32_t);
-
/*
* netmap adapter for guest ptnetmap ports
*/
@@ -2076,8 +2075,8 @@ struct netmap_pt_guest_adapter {
};
-int netmap_pt_guest_attach(struct netmap_adapter *, void *,
- unsigned int, nm_pt_guest_ptctl_t);
+int netmap_pt_guest_attach(struct netmap_adapter *na, void *csb,
+ unsigned int nifp_offset, unsigned int memid);
struct ptnet_ring;
bool netmap_pt_guest_txsync(struct ptnet_ring *ptring, struct netmap_kring *kring,
int flags);
diff --git a/sys/dev/netmap/netmap_mem2.c b/sys/dev/netmap/netmap_mem2.c
index bb0f9c8b6f39..ab89d3af65a5 100644
--- a/sys/dev/netmap/netmap_mem2.c
+++ b/sys/dev/netmap/netmap_mem2.c
@@ -147,39 +147,6 @@ struct netmap_mem_ops {
typedef uint16_t nm_memid_t;
-/*
- * Shared info for netmap allocator
- *
- * Each allocator contains this structur as first netmap_if.
- * In this way, we can share same details about allocator
- * to the VM.
- * Used in ptnetmap.
- */
-struct netmap_mem_shared_info {
-#ifndef _WIN32
- struct netmap_if up; /* ends with a 0-sized array, which VSC does not like */
-#else /* !_WIN32 */
- char up[sizeof(struct netmap_if)];
-#endif /* !_WIN32 */
- uint64_t features;
-#define NMS_FEAT_BUF_POOL 0x0001
-#define NMS_FEAT_MEMSIZE 0x0002
-
- uint32_t buf_pool_offset;
- uint32_t buf_pool_objtotal;
- uint32_t buf_pool_objsize;
- uint32_t totalsize;
-};
-
-#define NMS_NAME "nms_info"
-#define NMS_VERSION 1
-static const struct netmap_if nms_if_blueprint = {
- .ni_name = NMS_NAME,
- .ni_version = NMS_VERSION,
- .ni_tx_rings = 0,
- .ni_rx_rings = 0
-};
-
struct netmap_mem_d {
NMA_LOCK_T nm_mtx; /* protect the allocator */
u_int nm_totalsize; /* shorthand */
@@ -312,8 +279,6 @@ netmap_mem_finalize(struct netmap_mem_d *nmd, struct netmap_adapter *na)
return nmd->lasterr;
}
-static int netmap_mem_init_shared_info(struct netmap_mem_d *nmd);
-
void
netmap_mem_deref(struct netmap_mem_d *nmd, struct netmap_adapter *na)
{
@@ -362,13 +327,9 @@ netmap_mem_deref(struct netmap_mem_d *nmd, struct netmap_adapter *na)
if (nmd->pools[NETMAP_BUF_POOL].bitmap) {
/* XXX This check is a workaround that prevents a
* NULL pointer crash which currently happens only
- * with ptnetmap guests. Also,
- * netmap_mem_init_shared_info must not be called
- * by ptnetmap guest. */
+ * with ptnetmap guests.
+ * Removed shared-info --> is the bug still there? */
nmd->pools[NETMAP_BUF_POOL].bitmap[0] = ~3;
-
- /* expose info to the ptnetmap guest */
- netmap_mem_init_shared_info(nmd);
}
}
nmd->ops->nmd_deref(nmd);
@@ -1391,30 +1352,6 @@ netmap_mem_map(struct netmap_obj_pool *p, struct netmap_adapter *na)
}
static int
-netmap_mem_init_shared_info(struct netmap_mem_d *nmd)
-{
- struct netmap_mem_shared_info *nms_info;
- ssize_t base;
-
- /* Use the first slot in IF_POOL */
- nms_info = netmap_if_malloc(nmd, sizeof(*nms_info));
- if (nms_info == NULL) {
- return ENOMEM;
- }
-
- base = netmap_if_offset(nmd, nms_info);
-
- memcpy(&nms_info->up, &nms_if_blueprint, sizeof(nms_if_blueprint));
- nms_info->buf_pool_offset = nmd->pools[NETMAP_IF_POOL].memtotal + nmd->pools[NETMAP_RING_POOL].memtotal;
- nms_info->buf_pool_objtotal = nmd->pools[NETMAP_BUF_POOL].objtotal;
- nms_info->buf_pool_objsize = nmd->pools[NETMAP_BUF_POOL]._objsize;
- nms_info->totalsize = nmd->nm_totalsize;
- nms_info->features = NMS_FEAT_BUF_POOL | NMS_FEAT_MEMSIZE;
-
- return 0;
-}
-
-static int
netmap_mem_finalize_all(struct netmap_mem_d *nmd)
{
int i;
@@ -1433,11 +1370,6 @@ netmap_mem_finalize_all(struct netmap_mem_d *nmd)
nmd->pools[NETMAP_BUF_POOL].bitmap[0] = ~3;
nmd->flags |= NETMAP_MEM_FINALIZED;
- /* expose info to the ptnetmap guest */
- nmd->lasterr = netmap_mem_init_shared_info(nmd);
- if (nmd->lasterr)
- goto error;
-
if (netmap_verbose)
D("interfaces %d KB, rings %d KB, buffers %d MB",
nmd->pools[NETMAP_IF_POOL].memtotal >> 10,
@@ -1929,12 +1861,54 @@ struct netmap_mem_ops netmap_mem_private_ops = {
.nmd_rings_delete = netmap_mem2_rings_delete
};
+int
+netmap_mem_pools_info_get(struct nmreq *nmr, struct netmap_adapter *na)
+{
+ uintptr_t *pp = (uintptr_t *)&nmr->nr_arg1;
+ struct netmap_pools_info *upi = (struct netmap_pools_info *)(*pp);
+ struct netmap_mem_d *nmd = na->nm_mem;
+ struct netmap_pools_info pi;
+ unsigned int memsize;
+ uint16_t memid;
+ int ret;
+
+ if (!nmd) {
+ return -1;
+ }
+
+ ret = netmap_mem_get_info(nmd, &memsize, NULL, &memid);
+ if (ret) {
+ return ret;
+ }
+
+ pi.memsize = memsize;
+ pi.memid = memid;
+ pi.if_pool_offset = 0;
+ pi.if_pool_objtotal = nmd->pools[NETMAP_IF_POOL].objtotal;
+ pi.if_pool_objsize = nmd->pools[NETMAP_IF_POOL]._objsize;
+
+ pi.ring_pool_offset = nmd->pools[NETMAP_IF_POOL].memtotal;
+ pi.ring_pool_objtotal = nmd->pools[NETMAP_RING_POOL].objtotal;
+ pi.ring_pool_objsize = nmd->pools[NETMAP_RING_POOL]._objsize;
+
+ pi.buf_pool_offset = nmd->pools[NETMAP_IF_POOL].memtotal +
+ nmd->pools[NETMAP_RING_POOL].memtotal;
+ pi.buf_pool_objtotal = nmd->pools[NETMAP_BUF_POOL].objtotal;
+ pi.buf_pool_objsize = nmd->pools[NETMAP_BUF_POOL]._objsize;
+
+ ret = copyout(&pi, upi, sizeof(pi));
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
#ifdef WITH_PTNETMAP_GUEST
struct mem_pt_if {
struct mem_pt_if *next;
struct ifnet *ifp;
unsigned int nifp_offset;
- nm_pt_guest_ptctl_t ptctl;
};
/* Netmap allocator for ptnetmap guests. */
@@ -1944,16 +1918,15 @@ struct netmap_mem_ptg {
vm_paddr_t nm_paddr; /* physical address in the guest */
void *nm_addr; /* virtual address in the guest */
struct netmap_lut buf_lut; /* lookup table for BUF pool in the guest */
- nm_memid_t nm_host_id; /* allocator identifier in the host */
- struct ptnetmap_memdev *ptn_dev;
+ nm_memid_t host_mem_id; /* allocator identifier in the host */
+ struct ptnetmap_memdev *ptn_dev;/* ptnetmap memdev */
struct mem_pt_if *pt_ifs; /* list of interfaces in passthrough */
};
/* Link a passthrough interface to a passthrough netmap allocator. */
static int
netmap_mem_pt_guest_ifp_add(struct netmap_mem_d *nmd, struct ifnet *ifp,
- unsigned int nifp_offset,
- nm_pt_guest_ptctl_t ptctl)
+ unsigned int nifp_offset)
{
struct netmap_mem_ptg *ptnmd = (struct netmap_mem_ptg *)nmd;
struct mem_pt_if *ptif = malloc(sizeof(*ptif), M_NETMAP,
@@ -1967,7 +1940,6 @@ netmap_mem_pt_guest_ifp_add(struct netmap_mem_d *nmd, struct ifnet *ifp,
ptif->ifp = ifp;
ptif->nifp_offset = nifp_offset;
- ptif->ptctl = ptctl;
if (ptnmd->pt_ifs) {
ptif->next = ptnmd->pt_ifs;
@@ -2029,62 +2001,6 @@ netmap_mem_pt_guest_ifp_del(struct netmap_mem_d *nmd, struct ifnet *ifp)
return ret;
}
-/* Read allocator info from the first netmap_if (only on finalize) */
-static int
-netmap_mem_pt_guest_read_shared_info(struct netmap_mem_d *nmd)
-{
- struct netmap_mem_ptg *ptnmd = (struct netmap_mem_ptg *)nmd;
- struct netmap_mem_shared_info *nms_info;
- uint32_t bufsize;
- uint32_t nbuffers;
- char *vaddr;
- vm_paddr_t paddr;
- int i;
-
- nms_info = (struct netmap_mem_shared_info *)ptnmd->nm_addr;
- if (strncmp(nms_info->up.ni_name, NMS_NAME, sizeof(NMS_NAME)) != 0) {
- D("error, the first slot does not contain shared info");
- return EINVAL;
- }
- /* check features mem_shared info */
- if ((nms_info->features & (NMS_FEAT_BUF_POOL | NMS_FEAT_MEMSIZE)) !=
- (NMS_FEAT_BUF_POOL | NMS_FEAT_MEMSIZE)) {
- D("error, the shared info does not contain BUF_POOL and MEMSIZE");
- return EINVAL;
- }
-
- bufsize = nms_info->buf_pool_objsize;
- nbuffers = nms_info->buf_pool_objtotal;
-
- /* allocate the lut */
- if (ptnmd->buf_lut.lut == NULL) {
- D("allocating lut");
- ptnmd->buf_lut.lut = nm_alloc_lut(nbuffers);
- if (ptnmd->buf_lut.lut == NULL) {
- D("lut allocation failed");
- return ENOMEM;
- }
- }
-
- /* we have physically contiguous memory mapped through PCI BAR */
- vaddr = (char *)(ptnmd->nm_addr) + nms_info->buf_pool_offset;
- paddr = ptnmd->nm_paddr + nms_info->buf_pool_offset;
-
- for (i = 0; i < nbuffers; i++) {
- ptnmd->buf_lut.lut[i].vaddr = vaddr;
- ptnmd->buf_lut.lut[i].paddr = paddr;
- vaddr += bufsize;
- paddr += bufsize;
- }
-
- ptnmd->buf_lut.objtotal = nbuffers;
- ptnmd->buf_lut.objsize = bufsize;
-
- nmd->nm_totalsize = nms_info->totalsize;
-
- return 0;
-}
-
static int
netmap_mem_pt_guest_get_lut(struct netmap_mem_d *nmd, struct netmap_lut *lut)
{
@@ -2147,6 +2063,13 @@ static int
netmap_mem_pt_guest_finalize(struct netmap_mem_d *nmd)
{
struct netmap_mem_ptg *ptnmd = (struct netmap_mem_ptg *)nmd;
+ uint64_t mem_size;
+ uint32_t bufsize;
+ uint32_t nbuffers;
+ uint32_t poolofs;
+ vm_paddr_t paddr;
+ char *vaddr;
+ int i;
int error = 0;
nmd->active++;
@@ -2159,16 +2082,45 @@ netmap_mem_pt_guest_finalize(struct netmap_mem_d *nmd)
error = ENOMEM;
goto err;
}
- /* map memory through ptnetmap-memdev BAR */
+ /* Map memory through ptnetmap-memdev BAR. */
error = nm_os_pt_memdev_iomap(ptnmd->ptn_dev, &ptnmd->nm_paddr,
- &ptnmd->nm_addr);
+ &ptnmd->nm_addr, &mem_size);
if (error)
goto err;
- /* read allcator info and create lut */
- error = netmap_mem_pt_guest_read_shared_info(nmd);
- if (error)
- goto err;
+ /* Initialize the lut using the information contained in the
+ * ptnetmap memory device. */
+ bufsize = nm_os_pt_memdev_ioread(ptnmd->ptn_dev,
+ PTNET_MDEV_IO_BUF_POOL_OBJSZ);
+ nbuffers = nm_os_pt_memdev_ioread(ptnmd->ptn_dev,
+ PTNET_MDEV_IO_BUF_POOL_OBJNUM);
+
+ /* allocate the lut */
+ if (ptnmd->buf_lut.lut == NULL) {
+ D("allocating lut");
+ ptnmd->buf_lut.lut = nm_alloc_lut(nbuffers);
+ if (ptnmd->buf_lut.lut == NULL) {
+ D("lut allocation failed");
+ return ENOMEM;
+ }
+ }
+
+ /* we have physically contiguous memory mapped through PCI BAR */
+ poolofs = nm_os_pt_memdev_ioread(ptnmd->ptn_dev,
+ PTNET_MDEV_IO_BUF_POOL_OFS);
+ vaddr = (char *)(ptnmd->nm_addr) + poolofs;
+ paddr = ptnmd->nm_paddr + poolofs;
+
+ for (i = 0; i < nbuffers; i++) {
+ ptnmd->buf_lut.lut[i].vaddr = vaddr;
+ ptnmd->buf_lut.lut[i].paddr = paddr;
+ vaddr += bufsize;
+ paddr += bufsize;
+ }
+
+ ptnmd->buf_lut.objtotal = nbuffers;
+ ptnmd->buf_lut.objsize = bufsize;
+ nmd->nm_totalsize = (unsigned int)mem_size;
nmd->flags |= NETMAP_MEM_FINALIZED;
out:
@@ -2248,15 +2200,10 @@ netmap_mem_pt_guest_if_delete(struct netmap_adapter *na, struct netmap_if *nifp)
struct mem_pt_if *ptif;
NMA_LOCK(na->nm_mem);
-
ptif = netmap_mem_pt_guest_ifp_lookup(na->nm_mem, na->ifp);
if (ptif == NULL) {
D("Error: interface %p is not in passthrough", na->ifp);
- goto out;
}
-
- ptif->ptctl(na->ifp, PTNETMAP_PTCTL_IFDELETE);
-out:
NMA_UNLOCK(na->nm_mem);
}
@@ -2295,7 +2242,6 @@ netmap_mem_pt_guest_rings_create(struct netmap_adapter *na)
nifp->ring_ofs[i + na->num_tx_rings + 1]);
}
- //error = ptif->ptctl->nm_ptctl(ifp, PTNETMAP_PTCTL_RINGSCREATE);
error = 0;
out:
NMA_UNLOCK(na->nm_mem);
@@ -2331,7 +2277,7 @@ static struct netmap_mem_ops netmap_mem_pt_guest_ops = {
/* Called with NMA_LOCK(&nm_mem) held. */
static struct netmap_mem_d *
-netmap_mem_pt_guest_find_hostid(nm_memid_t host_id)
+netmap_mem_pt_guest_find_memid(nm_memid_t mem_id)
{
struct netmap_mem_d *mem = NULL;
struct netmap_mem_d *scan = netmap_last_mem_d;
@@ -2339,7 +2285,7 @@ netmap_mem_pt_guest_find_hostid(nm_memid_t host_id)
do {
/* find ptnetmap allocator through host ID */
if (scan->ops->nmd_deref == netmap_mem_pt_guest_deref &&
- ((struct netmap_mem_ptg *)(scan))->nm_host_id == host_id) {
+ ((struct netmap_mem_ptg *)(scan))->host_mem_id == mem_id) {
mem = scan;
break;
}
@@ -2351,7 +2297,7 @@ netmap_mem_pt_guest_find_hostid(nm_memid_t host_id)
/* Called with NMA_LOCK(&nm_mem) held. */
static struct netmap_mem_d *
-netmap_mem_pt_guest_create(nm_memid_t host_id)
+netmap_mem_pt_guest_create(nm_memid_t mem_id)
{
struct netmap_mem_ptg *ptnmd;
int err = 0;
@@ -2364,7 +2310,7 @@ netmap_mem_pt_guest_create(nm_memid_t host_id)
}
ptnmd->up.ops = &netmap_mem_pt_guest_ops;
- ptnmd->nm_host_id = host_id;
+ ptnmd->host_mem_id = mem_id;
ptnmd->pt_ifs = NULL;
/* Assign new id in the guest (We have the lock) */
@@ -2388,14 +2334,14 @@ error:
* if it is not there
*/
static struct netmap_mem_d *
-netmap_mem_pt_guest_get(nm_memid_t host_id)
+netmap_mem_pt_guest_get(nm_memid_t mem_id)
{
struct netmap_mem_d *nmd;
NMA_LOCK(&nm_mem);
- nmd = netmap_mem_pt_guest_find_hostid(host_id);
+ nmd = netmap_mem_pt_guest_find_memid(mem_id);
if (nmd == NULL) {
- nmd = netmap_mem_pt_guest_create(host_id);
+ nmd = netmap_mem_pt_guest_create(mem_id);
}
NMA_UNLOCK(&nm_mem);
@@ -2404,7 +2350,7 @@ netmap_mem_pt_guest_get(nm_memid_t host_id)
/*
* The guest allocator can be created by ptnetmap_memdev (during the device
- * attach) or by ptnetmap device (e1000/virtio), during the netmap_attach.
+ * attach) or by ptnetmap device (ptnet), during the netmap_attach.
*
* The order is not important (we have different order in LINUX and FreeBSD).
* The first one, creates the device, and the second one simply attaches it.
@@ -2413,12 +2359,12 @@ netmap_mem_pt_guest_get(nm_memid_t host_id)
/* Called when ptnetmap_memdev is attaching, to attach a new allocator in
* the guest */
struct netmap_mem_d *
-netmap_mem_pt_guest_attach(struct ptnetmap_memdev *ptn_dev, nm_memid_t host_id)
+netmap_mem_pt_guest_attach(struct ptnetmap_memdev *ptn_dev, nm_memid_t mem_id)
{
struct netmap_mem_d *nmd;
struct netmap_mem_ptg *ptnmd;
- nmd = netmap_mem_pt_guest_get(host_id);
+ nmd = netmap_mem_pt_guest_get(mem_id);
/* assign this device to the guest allocator */
if (nmd) {
@@ -2429,27 +2375,22 @@ netmap_mem_pt_guest_attach(struct ptnetmap_memdev *ptn_dev, nm_memid_t host_id)
return nmd;
}
-/* Called when ptnetmap device (virtio/e1000) is attaching */
+/* Called when ptnet device is attaching */
struct netmap_mem_d *
netmap_mem_pt_guest_new(struct ifnet *ifp,
unsigned int nifp_offset,
- nm_pt_guest_ptctl_t ptctl)
+ unsigned int memid)
{
struct netmap_mem_d *nmd;
- nm_memid_t host_id;
- if (ifp == NULL || ptctl == NULL) {
+ if (ifp == NULL) {
return NULL;
}
- /* Get the host id allocator. */
- host_id = ptctl(ifp, PTNETMAP_PTCTL_HOSTMEMID);
-
- nmd = netmap_mem_pt_guest_get(host_id);
+ nmd = netmap_mem_pt_guest_get((nm_memid_t)memid);
if (nmd) {
- netmap_mem_pt_guest_ifp_add(nmd, ifp, nifp_offset,
- ptctl);
+ netmap_mem_pt_guest_ifp_add(nmd, ifp, nifp_offset);
}
return nmd;
diff --git a/sys/dev/netmap/netmap_mem2.h b/sys/dev/netmap/netmap_mem2.h
index 7f4c5e9e9624..f170df9d5490 100644
--- a/sys/dev/netmap/netmap_mem2.h
+++ b/sys/dev/netmap/netmap_mem2.h
@@ -167,12 +167,14 @@ void netmap_mem_put(struct netmap_mem_d *);
#ifdef WITH_PTNETMAP_GUEST
struct netmap_mem_d* netmap_mem_pt_guest_new(struct ifnet *,
unsigned int nifp_offset,
- nm_pt_guest_ptctl_t);
+ unsigned int memid);
struct ptnetmap_memdev;
struct netmap_mem_d* netmap_mem_pt_guest_attach(struct ptnetmap_memdev *, uint16_t);
int netmap_mem_pt_guest_ifp_del(struct netmap_mem_d *, struct ifnet *);
#endif /* WITH_PTNETMAP_GUEST */
+int netmap_mem_pools_info_get(struct nmreq *, struct netmap_adapter *);
+
#define NETMAP_MEM_PRIVATE 0x2 /* allocator uses private address space */
#define NETMAP_MEM_IO 0x4 /* the underlying memory is mmapped I/O */
diff --git a/sys/dev/netmap/netmap_pt.c b/sys/dev/netmap/netmap_pt.c
index 56434a236145..3913f4b957fd 100644
--- a/sys/dev/netmap/netmap_pt.c
+++ b/sys/dev/netmap/netmap_pt.c
@@ -560,13 +560,34 @@ ptnetmap_print_configuration(struct ptnetmap_cfg *cfg)
{
int k;
- D("[PTN] configuration:");
- D(" CSB ptrings @%p, num_rings=%u, features %08x", cfg->ptrings,
- cfg->num_rings, cfg->features);
+ D("ptnetmap configuration:");
+ D(" CSB ptrings @%p, num_rings=%u, cfgtype %08x", cfg->ptrings,
+ cfg->num_rings, cfg->cfgtype);
for (k = 0; k < cfg->num_rings; k++) {
- D(" ring #%d: iofd=%llu, irqfd=%llu", k,
- (unsigned long long)cfg->entries[k].ioeventfd,
- (unsigned long long)cfg->entries[k].irqfd);
+ switch (cfg->cfgtype) {
+ case PTNETMAP_CFGTYPE_QEMU: {
+ struct ptnetmap_cfgentry_qemu *e =
+ (struct ptnetmap_cfgentry_qemu *)(cfg+1) + k;
+ D(" ring #%d: ioeventfd=%lu, irqfd=%lu", k,
+ (unsigned long)e->ioeventfd,
+ (unsigned long)e->irqfd);
+ break;
+ }
+
+ case PTNETMAP_CFGTYPE_BHYVE:
+ {
+ struct ptnetmap_cfgentry_bhyve *e =
+ (struct ptnetmap_cfgentry_bhyve *)(cfg+1) + k;
+ D(" ring #%d: wchan=%lu, ioctl_fd=%lu, "
+ "ioctl_cmd=%lu, msix_msg_data=%lu, msix_addr=%lu",
+ k, (unsigned long)e->wchan,
+ (unsigned long)e->ioctl_fd,
+ (unsigned long)e->ioctl_cmd,
+ (unsigned long)e->ioctl_data.msg_data,
+ (unsigned long)e->ioctl_data.addr);
+ break;
+ }
+ }
}
}
@@ -632,6 +653,7 @@ ptnetmap_create_kthreads(struct netmap_pt_host_adapter *pth_na,
struct ptnetmap_state *ptns = pth_na->ptns;
struct nm_kthread_cfg nmk_cfg;
unsigned int num_rings;
+ uint8_t *cfg_entries = (uint8_t *)(cfg + 1);
int k;
num_rings = pth_na->up.num_tx_rings +
@@ -640,7 +662,6 @@ ptnetmap_create_kthreads(struct netmap_pt_host_adapter *pth_na,
for (k = 0; k < num_rings; k++) {
nmk_cfg.attach_user = 1; /* attach kthread to user process */
nmk_cfg.worker_private = ptnetmap_kring(pth_na, k);
- nmk_cfg.event = *(cfg->entries + k);
nmk_cfg.type = k;
if (k < pth_na->up.num_tx_rings) {
nmk_cfg.worker_fn = ptnetmap_tx_handler;
@@ -648,7 +669,8 @@ ptnetmap_create_kthreads(struct netmap_pt_host_adapter *pth_na,
nmk_cfg.worker_fn = ptnetmap_rx_handler;
}
- ptns->kthreads[k] = nm_os_kthread_create(&nmk_cfg);
+ ptns->kthreads[k] = nm_os_kthread_create(&nmk_cfg,
+ cfg->cfgtype, cfg_entries + k * cfg->entry_size);
if (ptns->kthreads[k] == NULL) {
goto err;
}
@@ -727,7 +749,7 @@ ptnetmap_read_cfg(struct nmreq *nmr)
return NULL;
}
- cfglen = sizeof(tmp) + tmp.num_rings * sizeof(struct ptnet_ring_cfg);
+ cfglen = sizeof(tmp) + tmp.num_rings * tmp.entry_size;
cfg = malloc(cfglen, M_DEVBUF, M_NOWAIT | M_ZERO);
if (!cfg) {
return NULL;
@@ -750,7 +772,6 @@ static int
ptnetmap_create(struct netmap_pt_host_adapter *pth_na,
struct ptnetmap_cfg *cfg)
{
- unsigned ft_mask = (PTNETMAP_CFG_FEAT_CSB | PTNETMAP_CFG_FEAT_EVENTFD);
struct ptnetmap_state *ptns;
unsigned int num_rings;
int ret, i;
@@ -761,12 +782,6 @@ ptnetmap_create(struct netmap_pt_host_adapter *pth_na,
return EINVAL;
}
- if ((cfg->features & ft_mask) != ft_mask) {
- D("ERROR ptnetmap_cfg(%x) does not contain CSB and EVENTFD",
- cfg->features);
- return EINVAL;
- }
-
num_rings = pth_na->up.num_tx_rings + pth_na->up.num_rx_rings;
if (num_rings != cfg->num_rings) {
@@ -1240,9 +1255,9 @@ put_out_noputparent:
#ifdef WITH_PTNETMAP_GUEST
/*
- * GUEST ptnetmap generic txsync()/rxsync() used in e1000/virtio-net device
- * driver notify is set when we need to send notification to the host
- * (driver-specific)
+ * Guest ptnetmap txsync()/rxsync() routines, used in ptnet device drivers.
+ * These routines are reused across the different operating systems supported
+ * by netmap.
*/
/*
diff --git a/sys/dev/netmap/netmap_vale.c b/sys/dev/netmap/netmap_vale.c
index 78c53409c0b3..71b3aedddd46 100644
--- a/sys/dev/netmap/netmap_vale.c
+++ b/sys/dev/netmap/netmap_vale.c
@@ -913,7 +913,7 @@ nm_bdg_create_kthreads(struct nm_bdg_polling_state *bps)
kcfg.type = i;
kcfg.worker_private = t;
- t->nmk = nm_os_kthread_create(&kcfg);
+ t->nmk = nm_os_kthread_create(&kcfg, 0, NULL);
if (t->nmk == NULL) {
goto cleanup;
}
diff --git a/sys/dev/psci/psci.c b/sys/dev/psci/psci.c
index c5fe0fbc443e..f7050976c8c6 100644
--- a/sys/dev/psci/psci.c
+++ b/sys/dev/psci/psci.c
@@ -189,12 +189,12 @@ psci_cpu_on(unsigned long cpu, unsigned long entry, unsigned long context_id)
node = ofw_bus_find_compatible(OF_peer(0), "arm,psci-0.2");
if (node == 0)
/* TODO: Handle psci 0.1 */
- return (PSCI_RETVAL_INTERNAL_FAILURE);
+ return (PSCI_MISSING);
fnid = PSCI_FNID_CPU_ON;
callfn = psci_get_callfn(node);
if (callfn == NULL)
- return (PSCI_RETVAL_INTERNAL_FAILURE);
+ return (PSCI_MISSING);
} else {
callfn = psci_softc->psci_call;
fnid = psci_softc->psci_fnids[PSCI_FN_CPU_ON];
diff --git a/sys/dev/psci/psci.h b/sys/dev/psci/psci.h
index 58f1e791d0c0..7f447abaf444 100644
--- a/sys/dev/psci/psci.h
+++ b/sys/dev/psci/psci.h
@@ -54,6 +54,10 @@ int psci_smc_despatch(register_t, register_t, register_t, register_t);
#define PSCI_RETVAL_INTERNAL_FAILURE -6
#define PSCI_RETVAL_NOT_PRESENT -7
#define PSCI_RETVAL_DISABLED -8
+/*
+ * Used to signal PSCI is not available, e.g. to start a CPU.
+ */
+#define PSCI_MISSING 1
/*
* PSCI function codes (as per PSCI v0.2).
diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c
index 071b55b10146..00c27642b568 100644
--- a/sys/dev/re/if_re.c
+++ b/sys/dev/re/if_re.c
@@ -1358,15 +1358,17 @@ re_attach(device_t dev)
CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF);
}
- /* Disable ASPM L0S/L1. */
+ /* Disable ASPM L0S/L1 and CLKREQ. */
if (sc->rl_expcap != 0) {
cap = pci_read_config(dev, sc->rl_expcap +
PCIER_LINK_CAP, 2);
if ((cap & PCIEM_LINK_CAP_ASPM) != 0) {
ctl = pci_read_config(dev, sc->rl_expcap +
PCIER_LINK_CTL, 2);
- if ((ctl & PCIEM_LINK_CTL_ASPMC) != 0) {
- ctl &= ~PCIEM_LINK_CTL_ASPMC;
+ if ((ctl & (PCIEM_LINK_CTL_ECPM |
+ PCIEM_LINK_CTL_ASPMC))!= 0) {
+ ctl &= ~(PCIEM_LINK_CTL_ECPM |
+ PCIEM_LINK_CTL_ASPMC);
pci_write_config(dev, sc->rl_expcap +
PCIER_LINK_CTL, ctl, 2);
device_printf(dev, "ASPM disabled\n");
diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c
index 4d60517e1b50..757a96a8b831 100644
--- a/sys/dev/usb/input/ums.c
+++ b/sys/dev/usb/input/ums.c
@@ -173,6 +173,8 @@ static usb_fifo_ioctl_t ums_fifo_ioctl;
#ifdef EVDEV_SUPPORT
static evdev_open_t ums_ev_open;
static evdev_close_t ums_ev_close;
+static void ums_evdev_push(struct ums_softc *, int32_t, int32_t,
+ int32_t, int32_t, int32_t);
#endif
static void ums_start_rx(struct ums_softc *);
@@ -205,6 +207,9 @@ ums_put_queue_timeout(void *__sc)
mtx_assert(&sc->sc_mtx, MA_OWNED);
ums_put_queue(sc, 0, 0, 0, 0, 0);
+#ifdef EVDEV_SUPPORT
+ ums_evdev_push(sc, 0, 0, 0, 0, 0);
+#endif
}
static void
@@ -216,6 +221,9 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
uint8_t *buf = sc->sc_temp;
int32_t buttons = 0;
int32_t buttons_found = 0;
+#ifdef EVDEV_SUPPORT
+ int32_t buttons_reported = 0;
+#endif
int32_t dw = 0;
int32_t dx = 0;
int32_t dy = 0;
@@ -287,8 +295,11 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
}
if ((info->sc_flags & UMS_FLAG_T_AXIS) &&
- (id == info->sc_iid_t))
+ (id == info->sc_iid_t)) {
dt -= hid_get_data(buf, len, &info->sc_loc_t);
+ /* T-axis is translated into button presses */
+ buttons_found |= (1UL << 5) | (1UL << 6);
+ }
for (i = 0; i < info->sc_buttons; i++) {
uint32_t mask;
@@ -306,6 +317,9 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
if (++info != &sc->sc_info[UMS_INFO_MAX])
goto repeat;
+#ifdef EVDEV_SUPPORT
+ buttons_reported = buttons;
+#endif
/* keep old button value(s) for non-detected buttons */
buttons |= sc->sc_status.button & ~buttons_found;
@@ -351,6 +365,11 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error)
usb_callout_stop(&sc->sc_callout);
ums_put_queue(sc, dx, dy, dz, dt, buttons);
+#ifdef EVDEV_SUPPORT
+ ums_evdev_push(sc, dx, dy, dz, dt,
+ buttons_reported);
+#endif
+
}
}
case USB_ST_SETUP:
@@ -720,7 +739,7 @@ ums_attach(device_t dev)
for (i = 0; i < info->sc_buttons; i++)
evdev_support_key(sc->sc_evdev, BTN_MOUSE + i);
- err = evdev_register(sc->sc_evdev);
+ err = evdev_register_mtx(sc->sc_evdev, &sc->sc_mtx);
if (err)
goto detach;
#endif
@@ -891,27 +910,32 @@ ums_put_queue(struct ums_softc *sc, int32_t dx, int32_t dy,
}
usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf,
sc->sc_mode.packetsize, 1);
-
-#ifdef EVDEV_SUPPORT
- if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
- /* Push evdev event */
- evdev_push_event(sc->sc_evdev, EV_REL, REL_X, dx);
- evdev_push_event(sc->sc_evdev, EV_REL, REL_Y, -dy);
- evdev_push_event(sc->sc_evdev, EV_REL, REL_WHEEL, -dz);
- evdev_push_event(sc->sc_evdev, EV_REL, REL_HWHEEL, dt);
- evdev_push_mouse_btn(sc->sc_evdev,
- (buttons & ~MOUSE_STDBUTTONS) |
- (buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) |
- (buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) |
- (buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0));
- evdev_sync(sc->sc_evdev);
- }
-#endif
} else {
DPRINTF("Buffer full, discarded packet\n");
}
}
+#ifdef EVDEV_SUPPORT
+static void
+ums_evdev_push(struct ums_softc *sc, int32_t dx, int32_t dy,
+ int32_t dz, int32_t dt, int32_t buttons)
+{
+ if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
+ /* Push evdev event */
+ evdev_push_rel(sc->sc_evdev, REL_X, dx);
+ evdev_push_rel(sc->sc_evdev, REL_Y, -dy);
+ evdev_push_rel(sc->sc_evdev, REL_WHEEL, -dz);
+ evdev_push_rel(sc->sc_evdev, REL_HWHEEL, dt);
+ evdev_push_mouse_btn(sc->sc_evdev,
+ (buttons & ~MOUSE_STDBUTTONS) |
+ (buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) |
+ (buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) |
+ (buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0));
+ evdev_sync(sc->sc_evdev);
+ }
+}
+#endif
+
static void
ums_reset_buf(struct ums_softc *sc)
{
@@ -925,7 +949,7 @@ ums_ev_open(struct evdev_dev *evdev, void *ev_softc)
{
struct ums_softc *sc = (struct ums_softc *)ev_softc;
- mtx_lock(&sc->sc_mtx);
+ mtx_assert(&sc->sc_mtx, MA_OWNED);
sc->sc_evflags = UMS_EVDEV_OPENED;
@@ -934,8 +958,6 @@ ums_ev_open(struct evdev_dev *evdev, void *ev_softc)
ums_start_rx(sc);
}
- mtx_unlock(&sc->sc_mtx);
-
return (0);
}
@@ -944,14 +966,12 @@ ums_ev_close(struct evdev_dev *evdev, void *ev_softc)
{
struct ums_softc *sc = (struct ums_softc *)ev_softc;
- mtx_lock(&sc->sc_mtx);
+ mtx_assert(&sc->sc_mtx, MA_OWNED);
sc->sc_evflags = 0;
if (sc->sc_fflags == 0)
ums_stop_rx(sc);
-
- mtx_unlock(&sc->sc_mtx);
}
#endif
diff --git a/sys/dev/usb/net/if_ure.c b/sys/dev/usb/net/if_ure.c
index 9d7f47a576ee..59fa71f215d6 100644
--- a/sys/dev/usb/net/if_ure.c
+++ b/sys/dev/usb/net/if_ure.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,8 +66,9 @@ SYSCTL_INT(_hw_usb_ure, OID_AUTO, debug, CTLFLAG_RWTUN, &ure_debug, 0,
* Various supported device vendors/products.
*/
static const STRUCT_USB_HOST_ID ure_devs[] = {
-#define URE_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) }
- URE_DEV(REALTEK, RTL8152),
+#define URE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) }
+ URE_DEV(REALTEK, RTL8152, URE_FLAG_8152),
+ URE_DEV(REALTEK, RTL8153, 0),
#undef URE_DEV
};
@@ -87,8 +88,7 @@ static uether_fn_t ure_init;
static uether_fn_t ure_stop;
static uether_fn_t ure_start;
static uether_fn_t ure_tick;
-static uether_fn_t ure_setmulti;
-static uether_fn_t ure_setpromisc;
+static uether_fn_t ure_rxfilter;
static int ure_ctl(struct ure_softc *, uint8_t, uint16_t, uint16_t,
void *, int);
@@ -112,6 +112,7 @@ static int ure_ifmedia_upd(struct ifnet *);
static void ure_ifmedia_sts(struct ifnet *, struct ifmediareq *);
static int ure_ioctl(struct ifnet *, u_long, caddr_t);
static void ure_rtl8152_init(struct ure_softc *);
+static void ure_rtl8153_init(struct ure_softc *);
static void ure_disable_teredo(struct ure_softc *);
static void ure_init_fifo(struct ure_softc *);
@@ -129,7 +130,7 @@ static const struct usb_config ure_config[URE_N_TRANSFER] = {
.type = UE_BULK,
.endpoint = UE_ADDR_ANY,
.direction = UE_DIR_IN,
- .bufsize = MCLBYTES,
+ .bufsize = 16384,
.flags = {.pipe_bof = 1,.short_xfer_ok = 1,},
.callback = ure_bulk_read_callback,
.timeout = 0, /* no timeout */
@@ -173,8 +174,8 @@ static const struct usb_ether_methods ure_ue_methods = {
.ue_init = ure_init,
.ue_stop = ure_stop,
.ue_tick = ure_tick,
- .ue_setmulti = ure_setmulti,
- .ue_setpromisc = ure_setpromisc,
+ .ue_setmulti = ure_rxfilter,
+ .ue_setpromisc = ure_rxfilter,
.ue_mii_upd = ure_ifmedia_upd,
.ue_mii_sts = ure_ifmedia_sts,
};
@@ -343,6 +344,13 @@ ure_miibus_readreg(device_t dev, int phy, int reg)
if (!locked)
URE_LOCK(sc);
+ /* Let the rgephy driver read the URE_GMEDIASTAT register. */
+ if (reg == URE_GMEDIASTAT) {
+ if (!locked)
+ URE_UNLOCK(sc);
+ return (ure_read_1(sc, URE_GMEDIASTAT, URE_MCU_TYPE_PLA));
+ }
+
val = ure_ocp_reg_read(sc, URE_OCP_BASE_MII + reg * 2);
if (!locked)
@@ -398,6 +406,11 @@ ure_miibus_statchg(device_t dev)
case IFM_100_TX:
sc->sc_flags |= URE_FLAG_LINK;
break;
+ case IFM_1000_T:
+ if ((sc->sc_flags & URE_FLAG_8152) != 0)
+ break;
+ sc->sc_flags |= URE_FLAG_LINK;
+ break;
default:
break;
}
@@ -412,7 +425,7 @@ done:
}
/*
- * Probe for a RTL8152 chip.
+ * Probe for a RTL8152/RTL8153 chip.
*/
static int
ure_probe(device_t dev)
@@ -443,6 +456,7 @@ ure_attach(device_t dev)
uint8_t iface_index;
int error;
+ sc->sc_flags = USB_GET_DRIVER_INFO(uaa);
device_set_usb_desc(dev);
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF);
@@ -617,6 +631,18 @@ ure_read_chipver(struct ure_softc *sc)
case 0x4c10:
sc->sc_chip |= URE_CHIP_VER_4C10;
break;
+ case 0x5c00:
+ sc->sc_chip |= URE_CHIP_VER_5C00;
+ break;
+ case 0x5c10:
+ sc->sc_chip |= URE_CHIP_VER_5C10;
+ break;
+ case 0x5c20:
+ sc->sc_chip |= URE_CHIP_VER_5C20;
+ break;
+ case 0x5c30:
+ sc->sc_chip |= URE_CHIP_VER_5C30;
+ break;
default:
device_printf(sc->sc_ue.ue_dev,
"unknown version 0x%04x\n", ver);
@@ -635,7 +661,10 @@ ure_attach_post(struct usb_ether *ue)
ure_read_chipver(sc);
/* Initialize controller and get station address. */
- ure_rtl8152_init(sc);
+ if (sc->sc_flags & URE_FLAG_8152)
+ ure_rtl8152_init(sc);
+ else
+ ure_rtl8153_init(sc);
if (sc->sc_chip & URE_CHIP_VER_4C00)
ure_read_mem(sc, URE_PLA_IDR, URE_MCU_TYPE_PLA,
@@ -676,7 +705,6 @@ ure_init(struct usb_ether *ue)
{
struct ure_softc *sc = uether_getsc(ue);
struct ifnet *ifp = uether_getifp(ue);
- uint32_t rxmode;
URE_LOCK_ASSERT(sc, MA_OWNED);
@@ -709,20 +737,8 @@ ure_init(struct usb_ether *ue)
ure_read_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) &
~URE_RXDY_GATED_EN);
- /* Set Rx mode. */
- rxmode = URE_RCR_APM;
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- rxmode |= URE_RCR_AAP;
-
- if (ifp->if_flags & IFF_BROADCAST)
- rxmode |= URE_RCR_AB;
-
- ure_write_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode);
-
- /* Load the multicast filter. */
- ure_setmulti(ue);
+ /* Configure RX filters. */
+ ure_rxfilter(ue);
usbd_xfer_set_stall(sc->sc_xfer[URE_BULK_DT_WR]);
@@ -750,30 +766,11 @@ ure_tick(struct usb_ether *ue)
}
}
-static void
-ure_setpromisc(struct usb_ether *ue)
-{
- struct ure_softc *sc = uether_getsc(ue);
- struct ifnet *ifp = uether_getifp(ue);
- uint32_t rxmode;
-
- rxmode = ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA);
-
- if (ifp->if_flags & IFF_PROMISC)
- rxmode |= URE_RCR_AAP;
- else
- rxmode &= ~URE_RCR_AAP;
-
- ure_write_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode);
-
- ure_setmulti(ue);
-}
-
/*
* Program the 64-bit multicast hash filter.
*/
static void
-ure_setmulti(struct usb_ether *ue)
+ure_rxfilter(struct usb_ether *ue)
{
struct ure_softc *sc = uether_getsc(ue);
struct ifnet *ifp = uether_getifp(ue);
@@ -783,7 +780,9 @@ ure_setmulti(struct usb_ether *ue)
URE_LOCK_ASSERT(sc, MA_OWNED);
- rxmode = ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA);
+ rxmode = URE_RCR_APM;
+ if (ifp->if_flags & IFF_BROADCAST)
+ rxmode |= URE_RCR_AB;
if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
if (ifp->if_flags & IFF_PROMISC)
rxmode |= URE_RCR_AAP;
@@ -792,6 +791,7 @@ ure_setmulti(struct usb_ether *ue)
goto done;
}
+ rxmode |= URE_RCR_AM;
if_maddr_rlock(ifp);
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
if (ifma->ifma_addr->sa_family != AF_LINK)
@@ -965,6 +965,156 @@ ure_rtl8152_init(struct ure_softc *sc)
}
static void
+ure_rtl8153_init(struct ure_softc *sc)
+{
+ uint16_t val;
+ uint8_t u1u2[8];
+ int i;
+
+ /* Disable ALDPS. */
+ ure_ocp_reg_write(sc, URE_OCP_POWER_CFG,
+ ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS);
+ uether_pause(&sc->sc_ue, hz / 50);
+
+ memset(u1u2, 0x00, sizeof(u1u2));
+ ure_write_mem(sc, URE_USB_TOLERANCE,
+ URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
+
+ for (i = 0; i < URE_TIMEOUT; i++) {
+ if (ure_read_2(sc, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) &
+ URE_AUTOLOAD_DONE)
+ break;
+ uether_pause(&sc->sc_ue, hz / 100);
+ }
+ if (i == URE_TIMEOUT)
+ device_printf(sc->sc_ue.ue_dev,
+ "timeout waiting for chip autoload\n");
+
+ for (i = 0; i < URE_TIMEOUT; i++) {
+ val = ure_ocp_reg_read(sc, URE_OCP_PHY_STATUS) &
+ URE_PHY_STAT_MASK;
+ if (val == URE_PHY_STAT_LAN_ON || val == URE_PHY_STAT_PWRDN)
+ break;
+ uether_pause(&sc->sc_ue, hz / 100);
+ }
+ if (i == URE_TIMEOUT)
+ device_printf(sc->sc_ue.ue_dev,
+ "timeout waiting for phy to stabilize\n");
+
+ ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB,
+ ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB) &
+ ~URE_U2P3_ENABLE);
+
+ if (sc->sc_chip & URE_CHIP_VER_5C10) {
+ val = ure_read_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB);
+ val &= ~URE_PWD_DN_SCALE_MASK;
+ val |= URE_PWD_DN_SCALE(96);
+ ure_write_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB, val);
+
+ ure_write_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB,
+ ure_read_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB) |
+ URE_USB2PHY_L1 | URE_USB2PHY_SUSPEND);
+ } else if (sc->sc_chip & URE_CHIP_VER_5C20) {
+ ure_write_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA,
+ ure_read_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA) &
+ ~URE_ECM_ALDPS);
+ }
+ if (sc->sc_chip & (URE_CHIP_VER_5C20 | URE_CHIP_VER_5C30)) {
+ val = ure_read_1(sc, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB);
+ if (ure_read_2(sc, URE_USB_BURST_SIZE, URE_MCU_TYPE_USB) ==
+ 0)
+ val &= ~URE_DYNAMIC_BURST;
+ else
+ val |= URE_DYNAMIC_BURST;
+ ure_write_1(sc, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB, val);
+ }
+
+ ure_write_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB,
+ ure_read_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB) |
+ URE_EP4_FULL_FC);
+
+ ure_write_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB,
+ ure_read_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB) &
+ ~URE_TIMER11_EN);
+
+ ure_write_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA,
+ ure_read_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) &
+ ~URE_LED_MODE_MASK);
+
+ if ((sc->sc_chip & URE_CHIP_VER_5C10) &&
+ usbd_get_speed(sc->sc_ue.ue_udev) != USB_SPEED_SUPER)
+ val = URE_LPM_TIMER_500MS;
+ else
+ val = URE_LPM_TIMER_500US;
+ ure_write_1(sc, URE_USB_LPM_CTRL, URE_MCU_TYPE_USB,
+ val | URE_FIFO_EMPTY_1FB | URE_ROK_EXIT_LPM);
+
+ val = ure_read_2(sc, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB);
+ val &= ~URE_SEN_VAL_MASK;
+ val |= URE_SEN_VAL_NORMAL | URE_SEL_RXIDLE;
+ ure_write_2(sc, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB, val);
+
+ ure_write_2(sc, URE_USB_CONNECT_TIMER, URE_MCU_TYPE_USB, 0x0001);
+
+ ure_write_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB,
+ ure_read_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB) &
+ ~(URE_PWR_EN | URE_PHASE2_EN));
+ ure_write_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB,
+ ure_read_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB) &
+ ~URE_PCUT_STATUS);
+
+ memset(u1u2, 0xff, sizeof(u1u2));
+ ure_write_mem(sc, URE_USB_TOLERANCE,
+ URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
+
+ ure_write_2(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA,
+ URE_ALDPS_SPDWN_RATIO);
+ ure_write_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA,
+ URE_EEE_SPDWN_RATIO);
+ ure_write_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA,
+ URE_PKT_AVAIL_SPDWN_EN | URE_SUSPEND_SPDWN_EN |
+ URE_U1U2_SPDWN_EN | URE_L1_SPDWN_EN);
+ ure_write_2(sc, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA,
+ URE_PWRSAVE_SPDWN_EN | URE_RXDV_SPDWN_EN | URE_TX10MIDLE_EN |
+ URE_TP100_SPDWN_EN | URE_TP500_SPDWN_EN | URE_TP1000_SPDWN_EN |
+ URE_EEE_SPDWN_EN);
+
+ val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB);
+ if (!(sc->sc_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10)))
+ val |= URE_U2P3_ENABLE;
+ else
+ val &= ~URE_U2P3_ENABLE;
+ ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val);
+
+ memset(u1u2, 0x00, sizeof(u1u2));
+ ure_write_mem(sc, URE_USB_TOLERANCE,
+ URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
+
+ /* Disable ALDPS. */
+ ure_ocp_reg_write(sc, URE_OCP_POWER_CFG,
+ ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS);
+ uether_pause(&sc->sc_ue, hz / 50);
+
+ ure_init_fifo(sc);
+
+ /* Disable Rx aggregation. */
+ ure_write_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB,
+ ure_read_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) |
+ URE_RX_AGG_DISABLE);
+
+ val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB);
+ if (!(sc->sc_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10)))
+ val |= URE_U2P3_ENABLE;
+ else
+ val &= ~URE_U2P3_ENABLE;
+ ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val);
+
+ memset(u1u2, 0xff, sizeof(u1u2));
+ ure_write_mem(sc, URE_USB_TOLERANCE,
+ URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2));
+}
+
+static void
ure_stop(struct usb_ether *ue)
{
struct ure_softc *sc = uether_getsc(ue);
@@ -1011,6 +1161,43 @@ ure_init_fifo(struct ure_softc *sc)
ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA) &
~URE_RCR_ACPT_ALL);
+ if (!(sc->sc_flags & URE_FLAG_8152)) {
+ if (sc->sc_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10 |
+ URE_CHIP_VER_5C20)) {
+ ure_ocp_reg_write(sc, URE_OCP_ADC_CFG,
+ URE_CKADSEL_L | URE_ADC_EN | URE_EN_EMI_L);
+ }
+ if (sc->sc_chip & URE_CHIP_VER_5C00) {
+ ure_ocp_reg_write(sc, URE_OCP_EEE_CFG,
+ ure_ocp_reg_read(sc, URE_OCP_EEE_CFG) &
+ ~URE_CTAP_SHORT_EN);
+ }
+ ure_ocp_reg_write(sc, URE_OCP_POWER_CFG,
+ ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) |
+ URE_EEE_CLKDIV_EN);
+ ure_ocp_reg_write(sc, URE_OCP_DOWN_SPEED,
+ ure_ocp_reg_read(sc, URE_OCP_DOWN_SPEED) |
+ URE_EN_10M_BGOFF);
+ ure_ocp_reg_write(sc, URE_OCP_POWER_CFG,
+ ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) |
+ URE_EN_10M_PLLOFF);
+ ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_IMPEDANCE);
+ ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x0b13);
+ ure_write_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA,
+ ure_read_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) |
+ URE_PFM_PWM_SWITCH);
+
+ /* Enable LPF corner auto tune. */
+ ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_LPF_CFG);
+ ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0xf70f);
+
+ /* Adjust 10M amplitude. */
+ ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP1);
+ ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x00af);
+ ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP2);
+ ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x0208);
+ }
+
ure_reset(sc);
ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, 0);
diff --git a/sys/dev/usb/net/if_urereg.h b/sys/dev/usb/net/if_urereg.h
index 89c34f5a64ca..8eff1c25db4f 100644
--- a/sys/dev/usb/net/if_urereg.h
+++ b/sys/dev/usb/net/if_urereg.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015 Kevin Lo <kevlo@FreeBSD.org>
+ * Copyright (c) 2015-2016 Kevin Lo <kevlo@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -86,7 +86,7 @@
#define URE_PLA_OCP_GPHY_BASE 0xe86c
#define URE_PLA_TELLYCNT 0xe890
#define URE_PLA_SFF_STS_7 0xe8de
-#define URE_PLA_PHYSTATUS 0xe908
+#define URE_GMEDIASTAT 0xe908
#define URE_USB_USB2PHY 0xb41e
#define URE_USB_SSPHYLINK2 0xb428
@@ -424,10 +424,15 @@ struct ure_softc {
u_int sc_flags;
#define URE_FLAG_LINK 0x0001
+#define URE_FLAG_8152 0x1000 /* RTL8152 */
u_int sc_chip;
#define URE_CHIP_VER_4C00 0x01
#define URE_CHIP_VER_4C10 0x02
+#define URE_CHIP_VER_5C00 0x04
+#define URE_CHIP_VER_5C10 0x08
+#define URE_CHIP_VER_5C20 0x10
+#define URE_CHIP_VER_5C30 0x20
};
#define URE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
diff --git a/sys/dev/usb/net/uhso.c b/sys/dev/usb/net/uhso.c
index c94e67625a94..d8db44986b53 100644
--- a/sys/dev/usb/net/uhso.c
+++ b/sys/dev/usb/net/uhso.c
@@ -1752,7 +1752,7 @@ uhso_if_rxflush(void *arg)
* Allocate a new mbuf for this IP packet and
* copy the IP-packet into it.
*/
- m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+ m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR);
memcpy(mtod(m, uint8_t *), mtod(m0, uint8_t *), iplen);
m->m_pkthdr.len = m->m_len = iplen;
diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c
index bc0f50e5ead3..56a6095a16e9 100644
--- a/sys/dev/usb/usb_device.c
+++ b/sys/dev/usb/usb_device.c
@@ -1938,8 +1938,8 @@ config_done:
udev->ugen_symlink = usb_alloc_symlink(udev->ugen_name);
/* Announce device */
- printf("%s: <%s> at %s\n", udev->ugen_name,
- usb_get_manufacturer(udev),
+ printf("%s: <%s %s> at %s\n", udev->ugen_name,
+ usb_get_manufacturer(udev), usb_get_product(udev),
device_get_nameunit(udev->bus->bdev));
#endif
@@ -2148,8 +2148,9 @@ usb_free_device(struct usb_device *udev, uint8_t flag)
#if USB_HAVE_UGEN
if (!rebooting) {
- printf("%s: <%s> at %s (disconnected)\n", udev->ugen_name,
- usb_get_manufacturer(udev), device_get_nameunit(bus->bdev));
+ printf("%s: <%s %s> at %s (disconnected)\n", udev->ugen_name,
+ usb_get_manufacturer(udev), usb_get_product(udev),
+ device_get_nameunit(bus->bdev));
}
/* Destroy UGEN symlink, if any */
diff --git a/sys/dev/xen/gntdev/gntdev.c b/sys/dev/xen/gntdev/gntdev.c
new file mode 100644
index 000000000000..467a0c05df85
--- /dev/null
+++ b/sys/dev/xen/gntdev/gntdev.c
@@ -0,0 +1,1275 @@
+/*-
+ * Copyright (c) 2016 Akshay Jaggi <jaggi@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.
+ *
+ * gntdev.c
+ *
+ * Interface to /dev/xen/gntdev.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/uio.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/rwlock.h>
+#include <sys/selinfo.h>
+#include <sys/poll.h>
+#include <sys/conf.h>
+#include <sys/fcntl.h>
+#include <sys/ioccom.h>
+#include <sys/rman.h>
+#include <sys/tree.h>
+#include <sys/module.h>
+#include <sys/proc.h>
+#include <sys/bitset.h>
+#include <sys/queue.h>
+#include <sys/mman.h>
+#include <sys/syslog.h>
+#include <sys/taskqueue.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_pager.h>
+#include <vm/vm_phys.h>
+
+#include <machine/md_var.h>
+
+#include <xen/xen-os.h>
+#include <xen/hypervisor.h>
+#include <xen/error.h>
+#include <xen/xen_intr.h>
+#include <xen/gnttab.h>
+#include <xen/gntdev.h>
+
+MALLOC_DEFINE(M_GNTDEV, "gntdev", "Xen grant-table user-space device");
+
+#define MAX_OFFSET_COUNT ((0xffffffffffffffffull >> PAGE_SHIFT) + 1)
+
+static d_open_t gntdev_open;
+static d_ioctl_t gntdev_ioctl;
+static d_mmap_single_t gntdev_mmap_single;
+
+static struct cdevsw gntdev_devsw = {
+ .d_version = D_VERSION,
+ .d_open = gntdev_open,
+ .d_ioctl = gntdev_ioctl,
+ .d_mmap_single = gntdev_mmap_single,
+ .d_name = "gntdev",
+};
+
+static device_t gntdev_dev = NULL;
+
+struct gntdev_gref;
+struct gntdev_gmap;
+STAILQ_HEAD(gref_list_head, gntdev_gref);
+STAILQ_HEAD(gmap_list_head, gntdev_gmap);
+RB_HEAD(gref_tree_head, gntdev_gref);
+RB_HEAD(gmap_tree_head, gntdev_gmap);
+
+struct file_offset_struct {
+ RB_ENTRY(file_offset_struct) next;
+ uint64_t file_offset;
+ uint64_t count;
+};
+
+static int
+offset_cmp(struct file_offset_struct *f1, struct file_offset_struct *f2)
+{
+ return (f1->file_offset - f2->file_offset);
+}
+
+RB_HEAD(file_offset_head, file_offset_struct);
+RB_GENERATE_STATIC(file_offset_head, file_offset_struct, next, offset_cmp);
+
+struct per_user_data {
+ struct mtx user_data_lock;
+ struct gref_tree_head gref_tree;
+ struct gmap_tree_head gmap_tree;
+ struct file_offset_head file_offset;
+};
+
+/*
+ * Get offset into the file which will be used while mmapping the
+ * appropriate pages by the userspace program.
+ */
+static int
+get_file_offset(struct per_user_data *priv_user, uint32_t count,
+ uint64_t *file_offset)
+{
+ struct file_offset_struct *offset, *offset_tmp;
+
+ if (count == 0)
+ return (EINVAL);
+ mtx_lock(&priv_user->user_data_lock);
+ RB_FOREACH_SAFE(offset, file_offset_head, &priv_user->file_offset,
+ offset_tmp) {
+ if (offset->count >= count) {
+ offset->count -= count;
+ *file_offset = offset->file_offset + offset->count *
+ PAGE_SIZE;
+ if (offset->count == 0) {
+ RB_REMOVE(file_offset_head,
+ &priv_user->file_offset, offset);
+ free(offset, M_GNTDEV);
+ }
+ mtx_unlock(&priv_user->user_data_lock);
+ return (0);
+ }
+ }
+ mtx_unlock(&priv_user->user_data_lock);
+
+ return (ENOSPC);
+}
+
+static void
+put_file_offset(struct per_user_data *priv_user, uint32_t count,
+ uint64_t file_offset)
+{
+ struct file_offset_struct *offset, *offset_nxt, *offset_prv;
+
+ offset = malloc(sizeof(*offset), M_GNTDEV, M_WAITOK | M_ZERO);
+ offset->file_offset = file_offset;
+ offset->count = count;
+
+ mtx_lock(&priv_user->user_data_lock);
+ RB_INSERT(file_offset_head, &priv_user->file_offset, offset);
+ offset_nxt = RB_NEXT(file_offset_head, &priv_user->file_offset, offset);
+ offset_prv = RB_PREV(file_offset_head, &priv_user->file_offset, offset);
+ if (offset_nxt != NULL &&
+ offset_nxt->file_offset == offset->file_offset + offset->count *
+ PAGE_SIZE) {
+ offset->count += offset_nxt->count;
+ RB_REMOVE(file_offset_head, &priv_user->file_offset,
+ offset_nxt);
+ free(offset_nxt, M_GNTDEV);
+ }
+ if (offset_prv != NULL &&
+ offset->file_offset == offset_prv->file_offset + offset_prv->count *
+ PAGE_SIZE) {
+ offset_prv->count += offset->count;
+ RB_REMOVE(file_offset_head, &priv_user->file_offset, offset);
+ free(offset, M_GNTDEV);
+ }
+ mtx_unlock(&priv_user->user_data_lock);
+}
+
+static int gntdev_gmap_pg_ctor(void *handle, vm_ooffset_t size,
+ vm_prot_t prot, vm_ooffset_t foff, struct ucred *cred, u_short *color);
+static void gntdev_gmap_pg_dtor(void *handle);
+static int gntdev_gmap_pg_fault(vm_object_t object, vm_ooffset_t offset,
+ int prot, vm_page_t *mres);
+
+static struct cdev_pager_ops gntdev_gmap_pg_ops = {
+ .cdev_pg_fault = gntdev_gmap_pg_fault,
+ .cdev_pg_ctor = gntdev_gmap_pg_ctor,
+ .cdev_pg_dtor = gntdev_gmap_pg_dtor,
+};
+
+struct cleanup_data_struct {
+ struct mtx to_kill_grefs_mtx;
+ struct mtx to_kill_gmaps_mtx;
+ struct gref_list_head to_kill_grefs;
+ struct gmap_list_head to_kill_gmaps;
+};
+
+static struct cleanup_data_struct cleanup_data = {
+ .to_kill_grefs = STAILQ_HEAD_INITIALIZER(cleanup_data.to_kill_grefs),
+ .to_kill_gmaps = STAILQ_HEAD_INITIALIZER(cleanup_data.to_kill_gmaps),
+};
+MTX_SYSINIT(to_kill_grefs_mtx, &cleanup_data.to_kill_grefs_mtx,
+ "gntdev to_kill_grefs mutex", MTX_DEF);
+MTX_SYSINIT(to_kill_gmaps_mtx, &cleanup_data.to_kill_gmaps_mtx,
+ "gntdev to_kill_gmaps mutex", MTX_DEF);
+
+static void cleanup_function(void *arg, __unused int pending);
+static struct task cleanup_task = TASK_INITIALIZER(0, cleanup_function,
+ &cleanup_data);
+
+struct notify_data {
+ uint64_t index;
+ uint32_t action;
+ uint32_t event_channel_port;
+ xen_intr_handle_t notify_evtchn_handle;
+};
+
+static void notify(struct notify_data *notify, vm_page_t page);
+
+/*-------------------- Grant Allocation Methods -----------------------------*/
+
+struct gntdev_gref {
+ union gref_next_union {
+ STAILQ_ENTRY(gntdev_gref) list;
+ RB_ENTRY(gntdev_gref) tree;
+ } gref_next;
+ uint64_t file_index;
+ grant_ref_t gref_id;
+ vm_page_t page;
+ struct notify_data *notify;
+};
+
+static int
+gref_cmp(struct gntdev_gref *g1, struct gntdev_gref *g2)
+{
+ return (g1->file_index - g2->file_index);
+}
+
+RB_GENERATE_STATIC(gref_tree_head, gntdev_gref, gref_next.tree, gref_cmp);
+
+/*
+ * Traverse over the device-list of to-be-deleted grants allocated, and
+ * if all accesses, both local mmaps and foreign maps, to them have ended,
+ * destroy them.
+ */
+static void
+gref_list_dtor(struct cleanup_data_struct *cleanup_data)
+{
+ struct gref_list_head tmp_grefs;
+ struct gntdev_gref *gref, *gref_tmp, *gref_previous;
+
+ STAILQ_INIT(&tmp_grefs);
+ mtx_lock(&cleanup_data->to_kill_grefs_mtx);
+ STAILQ_SWAP(&cleanup_data->to_kill_grefs, &tmp_grefs, gntdev_gref);
+ mtx_unlock(&cleanup_data->to_kill_grefs_mtx);
+
+ gref_previous = NULL;
+ STAILQ_FOREACH_SAFE(gref, &tmp_grefs, gref_next.list, gref_tmp) {
+ if (gref->page && gref->page->object == NULL) {
+ if (gref->notify) {
+ notify(gref->notify, gref->page);
+ }
+ if (gref->gref_id != GRANT_REF_INVALID) {
+ if (gnttab_query_foreign_access(gref->gref_id))
+ continue;
+ if (gnttab_end_foreign_access_ref(gref->gref_id)
+ == 0)
+ continue;
+ gnttab_free_grant_reference(gref->gref_id);
+ }
+ vm_page_unwire(gref->page, PQ_NONE);
+ vm_page_free(gref->page);
+ gref->page = NULL;
+ }
+ if (gref->page == NULL) {
+ if (gref_previous == NULL)
+ STAILQ_REMOVE_HEAD(&tmp_grefs, gref_next.list);
+ else
+ STAILQ_REMOVE_AFTER(&tmp_grefs, gref_previous,
+ gref_next.list);
+ if (gref->notify)
+ free(gref->notify, M_GNTDEV);
+ free(gref, M_GNTDEV);
+ }
+ else
+ gref_previous = gref;
+ }
+
+ if (!STAILQ_EMPTY(&tmp_grefs)) {
+ mtx_lock(&cleanup_data->to_kill_grefs_mtx);
+ STAILQ_CONCAT(&cleanup_data->to_kill_grefs, &tmp_grefs);
+ mtx_unlock(&cleanup_data->to_kill_grefs_mtx);
+ }
+}
+
+/*
+ * Find count number of contiguous allocated grants for a given userspace
+ * program by file-offset (index).
+ */
+static struct gntdev_gref*
+gntdev_find_grefs(struct per_user_data *priv_user,
+ uint64_t index, uint32_t count)
+{
+ struct gntdev_gref find_gref, *gref, *gref_start = NULL;
+
+ find_gref.file_index = index;
+
+ mtx_lock(&priv_user->user_data_lock);
+ gref_start = RB_FIND(gref_tree_head, &priv_user->gref_tree, &find_gref);
+ for (gref = gref_start; gref != NULL && count > 0; gref =
+ RB_NEXT(gref_tree_head, &priv_user->gref_tree, gref)) {
+ if (index != gref->file_index)
+ break;
+ index += PAGE_SIZE;
+ count--;
+ }
+ mtx_unlock(&priv_user->user_data_lock);
+
+ if (count)
+ return (NULL);
+ return (gref_start);
+}
+
+/*
+ * IOCTL_GNTDEV_ALLOC_GREF
+ * Allocate required number of wired pages for the request, grant foreign
+ * access to the physical frames for these pages, and add details about
+ * this allocation to the per user private data, so that these pages can
+ * be mmapped by the userspace program.
+ */
+static int
+gntdev_alloc_gref(struct ioctl_gntdev_alloc_gref *arg)
+{
+ uint32_t i;
+ int error, readonly;
+ uint64_t file_offset;
+ struct gntdev_gref *grefs;
+ struct per_user_data *priv_user;
+
+ readonly = !(arg->flags & GNTDEV_ALLOC_FLAG_WRITABLE);
+
+ error = devfs_get_cdevpriv((void**) &priv_user);
+ if (error != 0)
+ return (EINVAL);
+
+ /* Cleanup grefs and free pages. */
+ taskqueue_enqueue(taskqueue_thread, &cleanup_task);
+
+ /* Get file offset for this request. */
+ error = get_file_offset(priv_user, arg->count, &file_offset);
+ if (error != 0)
+ return (error);
+
+ /* Allocate grefs. */
+ grefs = malloc(sizeof(*grefs) * arg->count, M_GNTDEV, M_WAITOK);
+
+ for (i = 0; i < arg->count; i++) {
+ grefs[i].file_index = file_offset + i * PAGE_SIZE;
+ grefs[i].gref_id = GRANT_REF_INVALID;
+ grefs[i].notify = NULL;
+ grefs[i].page = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL
+ | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO);
+ if (grefs[i].page == NULL) {
+ log(LOG_ERR, "Page allocation failed.");
+ error = ENOMEM;
+ break;
+ }
+ if ((grefs[i].page->flags & PG_ZERO) == 0) {
+ /*
+ * Zero the allocated page, as we don't want to
+ * leak our memory to other domains.
+ */
+ pmap_zero_page(grefs[i].page);
+ }
+ grefs[i].page->valid = VM_PAGE_BITS_ALL;
+
+ error = gnttab_grant_foreign_access(arg->domid,
+ (VM_PAGE_TO_PHYS(grefs[i].page) >> PAGE_SHIFT),
+ readonly, &grefs[i].gref_id);
+ if (error != 0) {
+ log(LOG_ERR, "Grant Table Hypercall failed.");
+ break;
+ }
+ }
+
+ if (error != 0) {
+ /*
+ * If target domain maps the gref (by guessing the gref-id),
+ * then we can't clean it up yet and we have to leave the
+ * page in place so as to not leak our memory to that domain.
+ * Add it to a global list to be cleaned up later.
+ */
+ mtx_lock(&cleanup_data.to_kill_grefs_mtx);
+ for (i = 0; i < arg->count; i++)
+ STAILQ_INSERT_TAIL(&cleanup_data.to_kill_grefs,
+ &grefs[i], gref_next.list);
+ mtx_unlock(&cleanup_data.to_kill_grefs_mtx);
+
+ taskqueue_enqueue(taskqueue_thread, &cleanup_task);
+
+ return (error);
+ }
+
+ /* Copy the output values. */
+ arg->index = file_offset;
+ for (i = 0; i < arg->count; i++)
+ arg->gref_ids[i] = grefs[i].gref_id;
+
+ /* Modify the per user private data. */
+ mtx_lock(&priv_user->user_data_lock);
+ for (i = 0; i < arg->count; i++)
+ RB_INSERT(gref_tree_head, &priv_user->gref_tree, &grefs[i]);
+ mtx_unlock(&priv_user->user_data_lock);
+
+ return (error);
+}
+
+/*
+ * IOCTL_GNTDEV_DEALLOC_GREF
+ * Remove grant allocation information from the per user private data, so
+ * that it can't be mmapped anymore by the userspace program, and add it
+ * to the to-be-deleted grants global device-list.
+ */
+static int
+gntdev_dealloc_gref(struct ioctl_gntdev_dealloc_gref *arg)
+{
+ int error;
+ uint32_t count;
+ struct gntdev_gref *gref, *gref_tmp;
+ struct per_user_data *priv_user;
+
+ error = devfs_get_cdevpriv((void**) &priv_user);
+ if (error != 0)
+ return (EINVAL);
+
+ gref = gntdev_find_grefs(priv_user, arg->index, arg->count);
+ if (gref == NULL) {
+ log(LOG_ERR, "Can't find requested grant-refs.");
+ return (EINVAL);
+ }
+
+ /* Remove the grefs from user private data. */
+ count = arg->count;
+ mtx_lock(&priv_user->user_data_lock);
+ mtx_lock(&cleanup_data.to_kill_grefs_mtx);
+ for (; gref != NULL && count > 0; gref = gref_tmp) {
+ gref_tmp = RB_NEXT(gref_tree_head, &priv_user->gref_tree, gref);
+ RB_REMOVE(gref_tree_head, &priv_user->gref_tree, gref);
+ STAILQ_INSERT_TAIL(&cleanup_data.to_kill_grefs, gref,
+ gref_next.list);
+ count--;
+ }
+ mtx_unlock(&cleanup_data.to_kill_grefs_mtx);
+ mtx_unlock(&priv_user->user_data_lock);
+
+ taskqueue_enqueue(taskqueue_thread, &cleanup_task);
+ put_file_offset(priv_user, arg->count, arg->index);
+
+ return (0);
+}
+
+/*-------------------- Grant Mapping Methods --------------------------------*/
+
+struct gntdev_gmap_map {
+ vm_object_t mem;
+ struct resource *pseudo_phys_res;
+ int pseudo_phys_res_id;
+ vm_paddr_t phys_base_addr;
+};
+
+struct gntdev_gmap {
+ union gmap_next_union {
+ STAILQ_ENTRY(gntdev_gmap) list;
+ RB_ENTRY(gntdev_gmap) tree;
+ } gmap_next;
+ uint64_t file_index;
+ uint32_t count;
+ struct gnttab_map_grant_ref *grant_map_ops;
+ struct gntdev_gmap_map *map;
+ struct notify_data *notify;
+};
+
+static int
+gmap_cmp(struct gntdev_gmap *g1, struct gntdev_gmap *g2)
+{
+ return (g1->file_index - g2->file_index);
+}
+
+RB_GENERATE_STATIC(gmap_tree_head, gntdev_gmap, gmap_next.tree, gmap_cmp);
+
+/*
+ * Traverse over the device-list of to-be-deleted grant mappings, and if
+ * the region is no longer mmapped by anyone, free the memory used to
+ * store information about the mapping.
+ */
+static void
+gmap_list_dtor(struct cleanup_data_struct *cleanup_data)
+{
+ struct gmap_list_head tmp_gmaps;
+ struct gntdev_gmap *gmap, *gmap_tmp, *gmap_previous;
+
+ STAILQ_INIT(&tmp_gmaps);
+ mtx_lock(&cleanup_data->to_kill_gmaps_mtx);
+ STAILQ_SWAP(&cleanup_data->to_kill_gmaps, &tmp_gmaps, gntdev_gmap);
+ mtx_unlock(&cleanup_data->to_kill_gmaps_mtx);
+
+ gmap_previous = NULL;
+ STAILQ_FOREACH_SAFE(gmap, &tmp_gmaps, gmap_next.list, gmap_tmp) {
+ if (gmap->map == NULL) {
+ if (gmap_previous == NULL)
+ STAILQ_REMOVE_HEAD(&tmp_gmaps, gmap_next.list);
+ else
+ STAILQ_REMOVE_AFTER(&tmp_gmaps, gmap_previous,
+ gmap_next.list);
+
+ if (gmap->notify)
+ free(gmap->notify, M_GNTDEV);
+ free(gmap->grant_map_ops, M_GNTDEV);
+ free(gmap, M_GNTDEV);
+ }
+ else
+ gmap_previous = gmap;
+ }
+
+ if (!STAILQ_EMPTY(&tmp_gmaps)) {
+ mtx_lock(&cleanup_data->to_kill_gmaps_mtx);
+ STAILQ_CONCAT(&cleanup_data->to_kill_gmaps, &tmp_gmaps);
+ mtx_unlock(&cleanup_data->to_kill_gmaps_mtx);
+ }
+}
+
+/*
+ * Find mapped grants for a given userspace program, by file-offset (index)
+ * and count, as supplied during the map-ioctl.
+ */
+static struct gntdev_gmap*
+gntdev_find_gmap(struct per_user_data *priv_user,
+ uint64_t index, uint32_t count)
+{
+ struct gntdev_gmap find_gmap, *gmap;
+
+ find_gmap.file_index = index;
+
+ mtx_lock(&priv_user->user_data_lock);
+ gmap = RB_FIND(gmap_tree_head, &priv_user->gmap_tree, &find_gmap);
+ mtx_unlock(&priv_user->user_data_lock);
+
+ if (gmap != NULL && gmap->count == count)
+ return (gmap);
+ return (NULL);
+}
+
+/*
+ * Remove the pages from the mgtdevice pager, call the unmap hypercall,
+ * free the xenmem resource. This function is called during the
+ * destruction of the mgtdevice pager, which happens when all mmaps to
+ * it have been removed, and the unmap-ioctl has been performed.
+ */
+static int
+notify_unmap_cleanup(struct gntdev_gmap *gmap)
+{
+ uint32_t i;
+ int error, count;
+ vm_page_t m;
+ struct gnttab_unmap_grant_ref *unmap_ops;
+
+ unmap_ops = malloc(sizeof(struct gnttab_unmap_grant_ref) * gmap->count,
+ M_GNTDEV, M_WAITOK);
+
+ /* Enumerate freeable maps. */
+ count = 0;
+ for (i = 0; i < gmap->count; i++) {
+ if (gmap->grant_map_ops[i].handle != -1) {
+ unmap_ops[count].handle = gmap->grant_map_ops[i].handle;
+ unmap_ops[count].host_addr =
+ gmap->grant_map_ops[i].host_addr;
+ unmap_ops[count].dev_bus_addr = 0;
+ count++;
+ }
+ }
+
+ /* Perform notification. */
+ if (count > 0 && gmap->notify) {
+ vm_page_t page;
+ uint64_t page_offset;
+
+ page_offset = gmap->notify->index - gmap->file_index;
+ page = PHYS_TO_VM_PAGE(gmap->map->phys_base_addr + page_offset);
+ notify(gmap->notify, page);
+ }
+
+ /* Free the pages. */
+ VM_OBJECT_WLOCK(gmap->map->mem);
+retry:
+ for (i = 0; i < gmap->count; i++) {
+ m = vm_page_lookup(gmap->map->mem, i);
+ if (m == NULL)
+ continue;
+ if (vm_page_sleep_if_busy(m, "pcmdum"))
+ goto retry;
+ cdev_pager_free_page(gmap->map->mem, m);
+ }
+ VM_OBJECT_WUNLOCK(gmap->map->mem);
+
+ /* Perform unmap hypercall. */
+ error = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref,
+ unmap_ops, count);
+
+ for (i = 0; i < gmap->count; i++) {
+ gmap->grant_map_ops[i].handle = -1;
+ gmap->grant_map_ops[i].host_addr = 0;
+ }
+
+ if (gmap->map) {
+ error = xenmem_free(gntdev_dev, gmap->map->pseudo_phys_res_id,
+ gmap->map->pseudo_phys_res);
+ KASSERT(error == 0,
+ ("Unable to release memory resource: %d", error));
+
+ free(gmap->map, M_GNTDEV);
+ gmap->map = NULL;
+ }
+
+ free(unmap_ops, M_GNTDEV);
+
+ return (error);
+}
+
+/*
+ * IOCTL_GNTDEV_MAP_GRANT_REF
+ * Populate structures for mapping the grant reference in the per user
+ * private data. Actual resource allocation and map hypercall is performed
+ * during the mmap.
+ */
+static int
+gntdev_map_grant_ref(struct ioctl_gntdev_map_grant_ref *arg)
+{
+ uint32_t i;
+ int error;
+ struct gntdev_gmap *gmap;
+ struct per_user_data *priv_user;
+
+ error = devfs_get_cdevpriv((void**) &priv_user);
+ if (error != 0)
+ return (EINVAL);
+
+ gmap = malloc(sizeof(*gmap), M_GNTDEV, M_WAITOK | M_ZERO);
+ gmap->count = arg->count;
+ gmap->grant_map_ops =
+ malloc(sizeof(struct gnttab_map_grant_ref) * arg->count,
+ M_GNTDEV, M_WAITOK | M_ZERO);
+
+ error = get_file_offset(priv_user, arg->count, &gmap->file_index);
+ if (error != 0)
+ return (error);
+
+ for (i = 0; i < arg->count; i++) {
+ gmap->grant_map_ops[i].dom = arg->refs[i].domid;
+ gmap->grant_map_ops[i].ref = arg->refs[i].ref;
+ gmap->grant_map_ops[i].handle = -1;
+ gmap->grant_map_ops[i].flags = GNTMAP_host_map;
+ }
+
+ mtx_lock(&priv_user->user_data_lock);
+ RB_INSERT(gmap_tree_head, &priv_user->gmap_tree, gmap);
+ mtx_unlock(&priv_user->user_data_lock);
+
+ arg->index = gmap->file_index;
+
+ return (error);
+}
+
+/*
+ * IOCTL_GNTDEV_UNMAP_GRANT_REF
+ * Remove the map information from the per user private data and add it
+ * to the global device-list of mappings to be deleted. A reference to
+ * the mgtdevice pager is also decreased, the reason for which is
+ * explained in mmap_gmap().
+ */
+static int
+gntdev_unmap_grant_ref(struct ioctl_gntdev_unmap_grant_ref *arg)
+{
+ int error;
+ struct gntdev_gmap *gmap;
+ struct per_user_data *priv_user;
+
+ error = devfs_get_cdevpriv((void**) &priv_user);
+ if (error != 0)
+ return (EINVAL);
+
+ gmap = gntdev_find_gmap(priv_user, arg->index, arg->count);
+ if (gmap == NULL) {
+ log(LOG_ERR, "Can't find requested grant-map.");
+ return (EINVAL);
+ }
+
+ mtx_lock(&priv_user->user_data_lock);
+ mtx_lock(&cleanup_data.to_kill_gmaps_mtx);
+ RB_REMOVE(gmap_tree_head, &priv_user->gmap_tree, gmap);
+ STAILQ_INSERT_TAIL(&cleanup_data.to_kill_gmaps, gmap, gmap_next.list);
+ mtx_unlock(&cleanup_data.to_kill_gmaps_mtx);
+ mtx_unlock(&priv_user->user_data_lock);
+
+ if (gmap->map)
+ vm_object_deallocate(gmap->map->mem);
+
+ taskqueue_enqueue(taskqueue_thread, &cleanup_task);
+ put_file_offset(priv_user, arg->count, arg->index);
+
+ return (0);
+}
+
+/*
+ * IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR
+ * Get file-offset and count for a given mapping, from the virtual address
+ * where the mapping is mmapped.
+ * Please note, this only works for grants mapped by this domain, and not
+ * grants allocated. Count doesn't make much sense in reference to grants
+ * allocated. Also, because this function is present in the linux gntdev
+ * device, but not in the linux gntalloc one, most userspace code only use
+ * it for mapped grants.
+ */
+static int
+gntdev_get_offset_for_vaddr(struct ioctl_gntdev_get_offset_for_vaddr *arg,
+ struct thread *td)
+{
+ int error;
+ vm_map_t map;
+ vm_map_entry_t entry;
+ vm_object_t mem;
+ vm_pindex_t pindex;
+ vm_prot_t prot;
+ boolean_t wired;
+ struct gntdev_gmap *gmap;
+
+ map = &td->td_proc->p_vmspace->vm_map;
+ error = vm_map_lookup(&map, arg->vaddr, VM_PROT_NONE, &entry,
+ &mem, &pindex, &prot, &wired);
+ if (error != KERN_SUCCESS)
+ return (EINVAL);
+ vm_map_lookup_done(map, entry);
+
+ if ((mem->type != OBJT_MGTDEVICE) ||
+ (mem->un_pager.devp.ops != &gntdev_gmap_pg_ops))
+ return (EINVAL);
+
+ gmap = mem->handle;
+ if (gmap == NULL ||
+ (entry->end - entry->start) != (gmap->count * PAGE_SIZE))
+ return (EINVAL);
+
+ arg->count = gmap->count;
+ arg->offset = gmap->file_index;
+ return (0);
+}
+
+/*-------------------- Grant Mapping Pager ----------------------------------*/
+
+static int
+gntdev_gmap_pg_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot,
+ vm_ooffset_t foff, struct ucred *cred, u_short *color)
+{
+
+ return (0);
+}
+
+static void
+gntdev_gmap_pg_dtor(void *handle)
+{
+
+ notify_unmap_cleanup((struct gntdev_gmap *)handle);
+}
+
+static int
+gntdev_gmap_pg_fault(vm_object_t object, vm_ooffset_t offset, int prot,
+ vm_page_t *mres)
+{
+ struct gntdev_gmap *gmap = object->handle;
+ vm_pindex_t pidx, ridx;
+ vm_page_t page, oldm;
+ vm_ooffset_t relative_offset;
+
+ if (gmap->map == NULL)
+ return (VM_PAGER_FAIL);
+
+ relative_offset = offset - gmap->file_index;
+
+ pidx = OFF_TO_IDX(offset);
+ ridx = OFF_TO_IDX(relative_offset);
+ if (ridx >= gmap->count ||
+ gmap->grant_map_ops[ridx].status != GNTST_okay)
+ return (VM_PAGER_FAIL);
+
+ page = PHYS_TO_VM_PAGE(gmap->map->phys_base_addr + relative_offset);
+ if (page == NULL)
+ return (VM_PAGER_FAIL);
+
+ KASSERT((page->flags & PG_FICTITIOUS) != 0,
+ ("not fictitious %p", page));
+ KASSERT(page->wire_count == 1, ("wire_count not 1 %p", page));
+ KASSERT(vm_page_busied(page) == 0, ("page %p is busy", page));
+
+ if (*mres != NULL) {
+ oldm = *mres;
+ vm_page_lock(oldm);
+ vm_page_free(oldm);
+ vm_page_unlock(oldm);
+ *mres = NULL;
+ }
+
+ vm_page_insert(page, object, pidx);
+ page->valid = VM_PAGE_BITS_ALL;
+ vm_page_xbusy(page);
+ *mres = page;
+ return (VM_PAGER_OK);
+}
+
+/*------------------ Grant Table Methods ------------------------------------*/
+
+static void
+notify(struct notify_data *notify, vm_page_t page)
+{
+ if (notify->action & UNMAP_NOTIFY_CLEAR_BYTE) {
+ uint8_t *mem;
+ uint64_t offset;
+
+ offset = notify->index & PAGE_MASK;
+ mem = (uint8_t *)pmap_quick_enter_page(page);
+ mem[offset] = 0;
+ pmap_quick_remove_page((vm_offset_t)mem);
+ }
+ if (notify->action & UNMAP_NOTIFY_SEND_EVENT) {
+ xen_intr_signal(notify->notify_evtchn_handle);
+ xen_intr_unbind(&notify->notify_evtchn_handle);
+ }
+ notify->action = 0;
+}
+
+/*
+ * Helper to copy new arguments from the notify ioctl into
+ * the existing notify data.
+ */
+static int
+copy_notify_helper(struct notify_data *destination,
+ struct ioctl_gntdev_unmap_notify *source)
+{
+ xen_intr_handle_t handlep = NULL;
+
+ /*
+ * "Get" before "Put"ting previous reference, as we might be
+ * holding the last reference to the event channel port.
+ */
+ if (source->action & UNMAP_NOTIFY_SEND_EVENT)
+ if (xen_intr_get_evtchn_from_port(source->event_channel_port,
+ &handlep) != 0)
+ return (EINVAL);
+
+ if (destination->action & UNMAP_NOTIFY_SEND_EVENT)
+ xen_intr_unbind(&destination->notify_evtchn_handle);
+
+ destination->action = source->action;
+ destination->event_channel_port = source->event_channel_port;
+ destination->index = source->index;
+ destination->notify_evtchn_handle = handlep;
+
+ return (0);
+}
+
+/*
+ * IOCTL_GNTDEV_SET_UNMAP_NOTIFY
+ * Set unmap notification inside the appropriate grant. It sends a
+ * notification when the grant is completely munmapped by this domain
+ * and ready for destruction.
+ */
+static int
+gntdev_set_unmap_notify(struct ioctl_gntdev_unmap_notify *arg)
+{
+ int error;
+ uint64_t index;
+ struct per_user_data *priv_user;
+ struct gntdev_gref *gref = NULL;
+ struct gntdev_gmap *gmap;
+
+ error = devfs_get_cdevpriv((void**) &priv_user);
+ if (error != 0)
+ return (EINVAL);
+
+ if (arg->action & ~(UNMAP_NOTIFY_CLEAR_BYTE|UNMAP_NOTIFY_SEND_EVENT))
+ return (EINVAL);
+
+ index = arg->index & ~PAGE_MASK;
+ gref = gntdev_find_grefs(priv_user, index, 1);
+ if (gref) {
+ if (gref->notify == NULL)
+ gref->notify = malloc(sizeof(*arg), M_GNTDEV,
+ M_WAITOK | M_ZERO);
+ return (copy_notify_helper(gref->notify, arg));
+ }
+
+ error = EINVAL;
+ mtx_lock(&priv_user->user_data_lock);
+ RB_FOREACH(gmap, gmap_tree_head, &priv_user->gmap_tree) {
+ if (arg->index >= gmap->file_index &&
+ arg->index < gmap->file_index + gmap->count * PAGE_SIZE) {
+ if (gmap->notify == NULL)
+ gmap->notify = malloc(sizeof(*arg), M_GNTDEV,
+ M_WAITOK | M_ZERO);
+ error = copy_notify_helper(gmap->notify, arg);
+ break;
+ }
+ }
+ mtx_unlock(&priv_user->user_data_lock);
+
+ return (error);
+}
+
+/*------------------ Gntdev Char Device Methods -----------------------------*/
+
+static void
+cleanup_function(void *arg, __unused int pending)
+{
+
+ gref_list_dtor((struct cleanup_data_struct *) arg);
+ gmap_list_dtor((struct cleanup_data_struct *) arg);
+}
+
+static void
+per_user_data_dtor(void *arg)
+{
+ struct gntdev_gref *gref, *gref_tmp;
+ struct gntdev_gmap *gmap, *gmap_tmp;
+ struct file_offset_struct *offset, *offset_tmp;
+ struct per_user_data *priv_user;
+
+ priv_user = (struct per_user_data *) arg;
+
+ mtx_lock(&priv_user->user_data_lock);
+
+ mtx_lock(&cleanup_data.to_kill_grefs_mtx);
+ RB_FOREACH_SAFE(gref, gref_tree_head, &priv_user->gref_tree, gref_tmp) {
+ RB_REMOVE(gref_tree_head, &priv_user->gref_tree, gref);
+ STAILQ_INSERT_TAIL(&cleanup_data.to_kill_grefs, gref,
+ gref_next.list);
+ }
+ mtx_unlock(&cleanup_data.to_kill_grefs_mtx);
+
+ mtx_lock(&cleanup_data.to_kill_gmaps_mtx);
+ RB_FOREACH_SAFE(gmap, gmap_tree_head, &priv_user->gmap_tree, gmap_tmp) {
+ RB_REMOVE(gmap_tree_head, &priv_user->gmap_tree, gmap);
+ STAILQ_INSERT_TAIL(&cleanup_data.to_kill_gmaps, gmap,
+ gmap_next.list);
+ if (gmap->map)
+ vm_object_deallocate(gmap->map->mem);
+ }
+ mtx_unlock(&cleanup_data.to_kill_gmaps_mtx);
+
+ RB_FOREACH_SAFE(offset, file_offset_head, &priv_user->file_offset,
+ offset_tmp) {
+ RB_REMOVE(file_offset_head, &priv_user->file_offset, offset);
+ free(offset, M_GNTDEV);
+ }
+
+ mtx_unlock(&priv_user->user_data_lock);
+
+ taskqueue_enqueue(taskqueue_thread, &cleanup_task);
+
+ mtx_destroy(&priv_user->user_data_lock);
+ free(priv_user, M_GNTDEV);
+}
+
+static int
+gntdev_open(struct cdev *dev, int flag, int otyp, struct thread *td)
+{
+ int error;
+ struct per_user_data *priv_user;
+ struct file_offset_struct *offset;
+
+ priv_user = malloc(sizeof(*priv_user), M_GNTDEV, M_WAITOK | M_ZERO);
+ RB_INIT(&priv_user->gref_tree);
+ RB_INIT(&priv_user->gmap_tree);
+ RB_INIT(&priv_user->file_offset);
+ offset = malloc(sizeof(*offset), M_GNTDEV, M_WAITOK | M_ZERO);
+ offset->file_offset = 0;
+ offset->count = MAX_OFFSET_COUNT;
+ RB_INSERT(file_offset_head, &priv_user->file_offset, offset);
+ mtx_init(&priv_user->user_data_lock,
+ "per user data mutex", NULL, MTX_DEF);
+
+ error = devfs_set_cdevpriv(priv_user, per_user_data_dtor);
+ if (error != 0)
+ per_user_data_dtor(priv_user);
+
+ return (error);
+}
+
+static int
+gntdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data,
+ int fflag, struct thread *td)
+{
+ int error;
+
+ switch (cmd) {
+ case IOCTL_GNTDEV_SET_UNMAP_NOTIFY:
+ error = gntdev_set_unmap_notify(
+ (struct ioctl_gntdev_unmap_notify*) data);
+ break;
+ case IOCTL_GNTDEV_ALLOC_GREF:
+ error = gntdev_alloc_gref(
+ (struct ioctl_gntdev_alloc_gref*) data);
+ break;
+ case IOCTL_GNTDEV_DEALLOC_GREF:
+ error = gntdev_dealloc_gref(
+ (struct ioctl_gntdev_dealloc_gref*) data);
+ break;
+ case IOCTL_GNTDEV_MAP_GRANT_REF:
+ error = gntdev_map_grant_ref(
+ (struct ioctl_gntdev_map_grant_ref*) data);
+ break;
+ case IOCTL_GNTDEV_UNMAP_GRANT_REF:
+ error = gntdev_unmap_grant_ref(
+ (struct ioctl_gntdev_unmap_grant_ref*) data);
+ break;
+ case IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR:
+ error = gntdev_get_offset_for_vaddr(
+ (struct ioctl_gntdev_get_offset_for_vaddr*) data, td);
+ break;
+ default:
+ error = ENOSYS;
+ break;
+ }
+
+ return (error);
+}
+
+/*
+ * MMAP an allocated grant into user memory.
+ * Please note, that the grants must not already be mmapped, otherwise
+ * this function will fail.
+ */
+static int
+mmap_gref(struct per_user_data *priv_user, struct gntdev_gref *gref_start,
+ uint32_t count, vm_size_t size, struct vm_object **object)
+{
+ vm_object_t mem_obj;
+ struct gntdev_gref *gref;
+
+ mem_obj = vm_object_allocate(OBJT_PHYS, size);
+ if (mem_obj == NULL)
+ return (ENOMEM);
+
+ mtx_lock(&priv_user->user_data_lock);
+ VM_OBJECT_WLOCK(mem_obj);
+ for (gref = gref_start; gref != NULL && count > 0; gref =
+ RB_NEXT(gref_tree_head, &priv_user->gref_tree, gref)) {
+ if (gref->page->object)
+ break;
+
+ vm_page_insert(gref->page, mem_obj,
+ OFF_TO_IDX(gref->file_index));
+
+ count--;
+ }
+ VM_OBJECT_WUNLOCK(mem_obj);
+ mtx_unlock(&priv_user->user_data_lock);
+
+ if (count) {
+ vm_object_deallocate(mem_obj);
+ return (EINVAL);
+ }
+
+ *object = mem_obj;
+
+ return (0);
+
+}
+
+/*
+ * MMAP a mapped grant into user memory.
+ */
+static int
+mmap_gmap(struct per_user_data *priv_user, struct gntdev_gmap *gmap_start,
+ vm_ooffset_t *offset, vm_size_t size, struct vm_object **object, int nprot)
+{
+ uint32_t i;
+ int error;
+
+ /*
+ * The grant map hypercall might already be done.
+ * If that is the case, increase a reference to the
+ * vm object and return the already allocated object.
+ */
+ if (gmap_start->map) {
+ vm_object_reference(gmap_start->map->mem);
+ *object = gmap_start->map->mem;
+ return (0);
+ }
+
+ gmap_start->map = malloc(sizeof(*(gmap_start->map)), M_GNTDEV,
+ M_WAITOK | M_ZERO);
+
+ /* Allocate the xen pseudo physical memory resource. */
+ gmap_start->map->pseudo_phys_res_id = 0;
+ gmap_start->map->pseudo_phys_res = xenmem_alloc(gntdev_dev,
+ &gmap_start->map->pseudo_phys_res_id, size);
+ if (gmap_start->map->pseudo_phys_res == NULL) {
+ free(gmap_start->map, M_GNTDEV);
+ gmap_start->map = NULL;
+ return (ENOMEM);
+ }
+ gmap_start->map->phys_base_addr =
+ rman_get_start(gmap_start->map->pseudo_phys_res);
+
+ /* Allocate the mgtdevice pager. */
+ gmap_start->map->mem = cdev_pager_allocate(gmap_start, OBJT_MGTDEVICE,
+ &gntdev_gmap_pg_ops, size, nprot, *offset, NULL);
+ if (gmap_start->map->mem == NULL) {
+ xenmem_free(gntdev_dev, gmap_start->map->pseudo_phys_res_id,
+ gmap_start->map->pseudo_phys_res);
+ free(gmap_start->map, M_GNTDEV);
+ gmap_start->map = NULL;
+ return (ENOMEM);
+ }
+
+ for (i = 0; i < gmap_start->count; i++) {
+ gmap_start->grant_map_ops[i].host_addr =
+ gmap_start->map->phys_base_addr + i * PAGE_SIZE;
+
+ if ((nprot & PROT_WRITE) == 0)
+ gmap_start->grant_map_ops[i].flags |= GNTMAP_readonly;
+ }
+ /* Make the MAP hypercall. */
+ error = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref,
+ gmap_start->grant_map_ops, gmap_start->count);
+ if (error != 0) {
+ /*
+ * Deallocate pager.
+ * Pager deallocation will automatically take care of
+ * xenmem deallocation, etc.
+ */
+ vm_object_deallocate(gmap_start->map->mem);
+
+ return (EINVAL);
+ }
+
+ /* Retry EAGAIN maps. */
+ for (i = 0; i < gmap_start->count; i++) {
+ int delay = 1;
+ while (delay < 256 &&
+ gmap_start->grant_map_ops[i].status == GNTST_eagain) {
+ HYPERVISOR_grant_table_op( GNTTABOP_map_grant_ref,
+ &gmap_start->grant_map_ops[i], 1);
+ pause(("gntmap"), delay * SBT_1MS);
+ delay++;
+ }
+ if (gmap_start->grant_map_ops[i].status == GNTST_eagain)
+ gmap_start->grant_map_ops[i].status = GNTST_bad_page;
+
+ if (gmap_start->grant_map_ops[i].status != GNTST_okay) {
+ /*
+ * Deallocate pager.
+ * Pager deallocation will automatically take care of
+ * xenmem deallocation, notification, unmap hypercall,
+ * etc.
+ */
+ vm_object_deallocate(gmap_start->map->mem);
+
+ return (EINVAL);
+ }
+ }
+
+ /*
+ * Add a reference to the vm object. We do not want
+ * the vm object to be deleted when all the mmaps are
+ * unmapped, because it may be re-mmapped. Instead,
+ * we want the object to be deleted, when along with
+ * munmaps, we have also processed the unmap-ioctl.
+ */
+ vm_object_reference(gmap_start->map->mem);
+
+ *object = gmap_start->map->mem;
+
+ return (0);
+}
+
+static int
+gntdev_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size,
+ struct vm_object **object, int nprot)
+{
+ int error;
+ uint32_t count;
+ struct gntdev_gref *gref_start;
+ struct gntdev_gmap *gmap_start;
+ struct per_user_data *priv_user;
+
+ error = devfs_get_cdevpriv((void**) &priv_user);
+ if (error != 0)
+ return (EINVAL);
+
+ count = OFF_TO_IDX(size);
+
+ gref_start = gntdev_find_grefs(priv_user, *offset, count);
+ if (gref_start) {
+ error = mmap_gref(priv_user, gref_start, count, size, object);
+ return (error);
+ }
+
+ gmap_start = gntdev_find_gmap(priv_user, *offset, count);
+ if (gmap_start) {
+ error = mmap_gmap(priv_user, gmap_start, offset, size, object,
+ nprot);
+ return (error);
+ }
+
+ return (EINVAL);
+}
+
+/*------------------ Private Device Attachment Functions --------------------*/
+static void
+gntdev_identify(driver_t *driver, device_t parent)
+{
+
+ KASSERT((xen_domain()),
+ ("Trying to attach gntdev device on non Xen domain"));
+
+ if (BUS_ADD_CHILD(parent, 0, "gntdev", 0) == NULL)
+ panic("unable to attach gntdev user-space device");
+}
+
+static int
+gntdev_probe(device_t dev)
+{
+
+ gntdev_dev = dev;
+ device_set_desc(dev, "Xen grant-table user-space device");
+ return (BUS_PROBE_NOWILDCARD);
+}
+
+static int
+gntdev_attach(device_t dev)
+{
+
+ make_dev_credf(MAKEDEV_ETERNAL, &gntdev_devsw, 0, NULL, UID_ROOT,
+ GID_WHEEL, 0600, "xen/gntdev");
+ return (0);
+}
+
+/*-------------------- Private Device Attachment Data -----------------------*/
+static device_method_t gntdev_methods[] = {
+ DEVMETHOD(device_identify, gntdev_identify),
+ DEVMETHOD(device_probe, gntdev_probe),
+ DEVMETHOD(device_attach, gntdev_attach),
+ DEVMETHOD_END
+};
+
+static driver_t gntdev_driver = {
+ "gntdev",
+ gntdev_methods,
+ 0,
+};
+
+devclass_t gntdev_devclass;
+
+DRIVER_MODULE(gntdev, xenpv, gntdev_driver, gntdev_devclass, 0, 0);
+MODULE_DEPEND(gntdev, xenpv, 1, 1, 1);
diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c
index a68bc9675da5..3c080ef817f7 100644
--- a/sys/dev/xen/netfront/netfront.c
+++ b/sys/dev/xen/netfront/netfront.c
@@ -156,21 +156,6 @@ static int xn_get_responses(struct netfront_rxq *,
#define virt_to_mfn(x) (vtophys(x) >> PAGE_SHIFT)
#define INVALID_P2M_ENTRY (~0UL)
-
-struct xn_rx_stats
-{
- u_long rx_packets; /* total packets received */
- u_long rx_bytes; /* total bytes received */
- u_long rx_errors; /* bad packets received */
-};
-
-struct xn_tx_stats
-{
- u_long tx_packets; /* total packets transmitted */
- u_long tx_bytes; /* total bytes transmitted */
- u_long tx_errors; /* packet transmit problems */
-};
-
#define XN_QUEUE_NAME_LEN 8 /* xn{t,r}x_%u, allow for two digits */
struct netfront_rxq {
struct netfront_info *info;
@@ -190,8 +175,6 @@ struct netfront_rxq {
struct lro_ctrl lro;
struct callout rx_refill;
-
- struct xn_rx_stats stats;
};
struct netfront_txq {
@@ -215,8 +198,6 @@ struct netfront_txq {
struct task defrtask;
bool full;
-
- struct xn_tx_stats stats;
};
struct netfront_info {
@@ -1191,7 +1172,7 @@ xn_rxeof(struct netfront_rxq *rxq)
if (__predict_false(err)) {
if (m)
(void )mbufq_enqueue(&mbufq_errq, m);
- rxq->stats.rx_errors++;
+ if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
continue;
}
@@ -1216,9 +1197,6 @@ xn_rxeof(struct netfront_rxq *rxq)
m->m_pkthdr.csum_flags |= CSUM_TSO;
}
- rxq->stats.rx_packets++;
- rxq->stats.rx_bytes += m->m_pkthdr.len;
-
(void )mbufq_enqueue(&mbufq_rxq, m);
rxq->ring.rsp_cons = i;
}
@@ -1304,12 +1282,6 @@ xn_txeof(struct netfront_txq *txq)
"trying to free it again!"));
M_ASSERTVALID(m);
- /*
- * Increment packet count if this is the last
- * mbuf of the chain.
- */
- if (!m->m_next)
- if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
if (__predict_false(gnttab_query_foreign_access(
txq->grant_ref[id]) != 0)) {
panic("%s: grant id %u still in use by the "
@@ -1701,10 +1673,12 @@ xn_assemble_tx_request(struct netfront_txq *txq, struct mbuf *m_head)
}
BPF_MTAP(ifp, m_head);
- xn_txeof(txq);
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ if_inc_counter(ifp, IFCOUNTER_OBYTES, m_head->m_pkthdr.len);
+ if (m_head->m_flags & M_MCAST)
+ if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1);
- txq->stats.tx_bytes += m_head->m_pkthdr.len;
- txq->stats.tx_packets++;
+ xn_txeof(txq);
return (0);
}
diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c
index cab8db7e39dc..04c0ff5ceeb4 100644
--- a/sys/fs/cd9660/cd9660_vnops.c
+++ b/sys/fs/cd9660/cd9660_vnops.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/dirent.h>
#include <sys/unistd.h>
#include <sys/filio.h>
+#include <sys/sysctl.h>
#include <vm/vm.h>
#include <vm/vnode_pager.h>
@@ -74,6 +75,7 @@ static vop_readdir_t cd9660_readdir;
static vop_readlink_t cd9660_readlink;
static vop_strategy_t cd9660_strategy;
static vop_vptofh_t cd9660_vptofh;
+static vop_getpages_t cd9660_getpages;
/*
* Setattr call. Only allowed for block and character special devices.
@@ -836,6 +838,45 @@ cd9660_vptofh(ap)
return (0);
}
+SYSCTL_NODE(_vfs, OID_AUTO, cd9660, CTLFLAG_RW, 0, "cd9660 filesystem");
+static int use_buf_pager = 1;
+SYSCTL_INT(_vfs_cd9660, OID_AUTO, use_buf_pager, CTLFLAG_RWTUN,
+ &use_buf_pager, 0,
+ "Use buffer pager instead of bmap");
+
+static daddr_t
+cd9660_gbp_getblkno(struct vnode *vp, vm_ooffset_t off)
+{
+
+ return (lblkno(VTOI(vp)->i_mnt, off));
+}
+
+static int
+cd9660_gbp_getblksz(struct vnode *vp, daddr_t lbn)
+{
+ struct iso_node *ip;
+
+ ip = VTOI(vp);
+ return (blksize(ip->i_mnt, ip, lbn));
+}
+
+static int
+cd9660_getpages(struct vop_getpages_args *ap)
+{
+ struct vnode *vp;
+
+ vp = ap->a_vp;
+ if (vp->v_type == VCHR || vp->v_type == VBLK)
+ return (EOPNOTSUPP);
+
+ if (use_buf_pager)
+ return (vfs_bio_getpages(vp, ap->a_m, ap->a_count,
+ ap->a_rbehind, ap->a_rahead, cd9660_gbp_getblkno,
+ cd9660_gbp_getblksz));
+ return (vnode_pager_generic_getpages(vp, ap->a_m, ap->a_count,
+ ap->a_rbehind, ap->a_rahead, NULL, NULL));
+}
+
/*
* Global vfs data structures for cd9660
*/
@@ -857,6 +898,7 @@ struct vop_vector cd9660_vnodeops = {
.vop_setattr = cd9660_setattr,
.vop_strategy = cd9660_strategy,
.vop_vptofh = cd9660_vptofh,
+ .vop_getpages = cd9660_getpages,
};
/*
diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c
index cdfc9b022487..4bceeba537d1 100644
--- a/sys/fs/msdosfs/msdosfs_fat.c
+++ b/sys/fs/msdosfs/msdosfs_fat.c
@@ -60,6 +60,8 @@
#include <fs/msdosfs/fat.h>
#include <fs/msdosfs/msdosfsmount.h>
+#define FULL_RUN ((u_int)0xffffffff)
+
static int chainalloc(struct msdosfsmount *pmp, u_long start,
u_long count, u_long fillwith, u_long *retcluster,
u_long *got);
@@ -380,6 +382,8 @@ usemap_alloc(struct msdosfsmount *pmp, u_long cn)
MSDOSFS_ASSERT_MP_LOCKED(pmp);
+ KASSERT(cn <= pmp->pm_maxcluster, ("cn too large %lu %lu", cn,
+ pmp->pm_maxcluster));
KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0,
("usemap_alloc on ro msdosfs mount"));
KASSERT((pmp->pm_inusemap[cn / N_INUSEBITS] & (1 << (cn % N_INUSEBITS)))
@@ -396,6 +400,9 @@ usemap_free(struct msdosfsmount *pmp, u_long cn)
{
MSDOSFS_ASSERT_MP_LOCKED(pmp);
+
+ KASSERT(cn <= pmp->pm_maxcluster, ("cn too large %lu %lu", cn,
+ pmp->pm_maxcluster));
KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0,
("usemap_free on ro msdosfs mount"));
pmp->pm_freeclustercount++;
@@ -635,6 +642,8 @@ chainlength(struct msdosfsmount *pmp, u_long start, u_long count)
MSDOSFS_ASSERT_MP_LOCKED(pmp);
+ if (start > pmp->pm_maxcluster)
+ return (0);
max_idx = pmp->pm_maxcluster / N_INUSEBITS;
idx = start / N_INUSEBITS;
start %= N_INUSEBITS;
@@ -642,11 +651,18 @@ chainlength(struct msdosfsmount *pmp, u_long start, u_long count)
map &= ~((1 << start) - 1);
if (map) {
len = ffs(map) - 1 - start;
- return (len > count ? count : len);
+ len = MIN(len, count);
+ if (start + len > pmp->pm_maxcluster)
+ len = pmp->pm_maxcluster - start + 1;
+ return (len);
}
len = N_INUSEBITS - start;
- if (len >= count)
- return (count);
+ if (len >= count) {
+ len = count;
+ if (start + len > pmp->pm_maxcluster)
+ len = pmp->pm_maxcluster - start + 1;
+ return (len);
+ }
while (++idx <= max_idx) {
if (len >= count)
break;
@@ -657,7 +673,10 @@ chainlength(struct msdosfsmount *pmp, u_long start, u_long count)
}
len += N_INUSEBITS;
}
- return (len > count ? count : len);
+ len = MIN(len, count);
+ if (start + len > pmp->pm_maxcluster)
+ len = pmp->pm_maxcluster - start + 1;
+ return (len);
}
/*
@@ -689,8 +708,11 @@ chainalloc(struct msdosfsmount *pmp, u_long start, u_long count,
pmp->pm_nxtfree = CLUST_FIRST;
pmp->pm_flags |= MSDOSFS_FSIMOD;
error = fatchain(pmp, start, count, fillwith);
- if (error != 0)
+ if (error != 0) {
+ for (cl = start, n = count; n-- > 0;)
+ usemap_free(pmp, cl++);
return (error);
+ }
#ifdef MSDOSFS_DEBUG
printf("clusteralloc(): allocated cluster chain at %lu (%lu clusters)\n",
start, count);
@@ -752,8 +774,8 @@ clusteralloc1(struct msdosfsmount *pmp, u_long start, u_long count,
idx = cn / N_INUSEBITS;
map = pmp->pm_inusemap[idx];
map |= (1 << (cn % N_INUSEBITS)) - 1;
- if (map != (u_int)-1) {
- cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1;
+ if (map != FULL_RUN) {
+ cn = idx * N_INUSEBITS + ffs(map ^ FULL_RUN) - 1;
if ((l = chainlength(pmp, cn, count)) >= count)
return (chainalloc(pmp, cn, count, fillwith, retcluster, got));
if (l > foundl) {
@@ -769,8 +791,8 @@ clusteralloc1(struct msdosfsmount *pmp, u_long start, u_long count,
idx = cn / N_INUSEBITS;
map = pmp->pm_inusemap[idx];
map |= (1 << (cn % N_INUSEBITS)) - 1;
- if (map != (u_int)-1) {
- cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1;
+ if (map != FULL_RUN) {
+ cn = idx * N_INUSEBITS + ffs(map ^ FULL_RUN) - 1;
if ((l = chainlength(pmp, cn, count)) >= count)
return (chainalloc(pmp, cn, count, fillwith, retcluster, got));
if (l > foundl) {
@@ -878,7 +900,7 @@ fillinusemap(struct msdosfsmount *pmp)
* loop further down.
*/
for (cn = 0; cn < (pmp->pm_maxcluster + N_INUSEBITS) / N_INUSEBITS; cn++)
- pmp->pm_inusemap[cn] = (u_int)-1;
+ pmp->pm_inusemap[cn] = FULL_RUN;
/*
* Figure how many free clusters are in the filesystem by ripping
@@ -908,11 +930,16 @@ fillinusemap(struct msdosfsmount *pmp)
readcn >>= 4;
readcn &= pmp->pm_fatmask;
- if (readcn == 0)
+ if (readcn == CLUST_FREE)
usemap_free(pmp, cn);
}
if (bp != NULL)
brelse(bp);
+
+ for (cn = pmp->pm_maxcluster + 1; cn < (pmp->pm_maxcluster +
+ N_INUSEBITS) / N_INUSEBITS; cn++)
+ pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS);
+
return (0);
}
@@ -972,12 +999,14 @@ extendfile(struct denode *dep, u_long count, struct buf **bpp, u_long *ncp,
while (count > 0) {
/*
* Allocate a new cluster chain and cat onto the end of the
- * file. * If the file is empty we make de_StartCluster point
- * to the new block. Note that de_StartCluster being 0 is
- * sufficient to be sure the file is empty since we exclude
- * attempts to extend the root directory above, and the root
- * dir is the only file with a startcluster of 0 that has
- * blocks allocated (sort of).
+ * file.
+ * If the file is empty we make de_StartCluster point
+ * to the new block. Note that de_StartCluster being
+ * 0 is sufficient to be sure the file is empty since
+ * we exclude attempts to extend the root directory
+ * above, and the root dir is the only file with a
+ * startcluster of 0 that has blocks allocated (sort
+ * of).
*/
if (dep->de_StartCluster == 0)
cn = 0;
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index 9b42b20e1610..4c122bfb5942 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -742,7 +742,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp)
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_LOCAL;
- mp->mnt_kern_flag |= MNTK_USES_BCACHE;
+ mp->mnt_kern_flag |= MNTK_USES_BCACHE | MNTK_NO_IOPF;
MNT_IUNLOCK(mp);
if (pmp->pm_flags & MSDOSFS_LARGEFS)
@@ -760,8 +760,7 @@ error_exit:
}
if (pmp) {
lockdestroy(&pmp->pm_fatlock);
- if (pmp->pm_inusemap)
- free(pmp->pm_inusemap, M_MSDOSFSFAT);
+ free(pmp->pm_inusemap, M_MSDOSFSFAT);
free(pmp, M_MSDOSFSMNT);
mp->mnt_data = NULL;
}
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index 9ab5db614ded..4f53bbc3eb6f 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -62,11 +62,13 @@
#include <sys/namei.h>
#include <sys/priv.h>
#include <sys/stat.h>
+#include <sys/sysctl.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
+#include <vm/vnode_pager.h>
#include <fs/msdosfs/bpb.h>
#include <fs/msdosfs/direntry.h>
@@ -97,6 +99,7 @@ static vop_rmdir_t msdosfs_rmdir;
static vop_symlink_t msdosfs_symlink;
static vop_readdir_t msdosfs_readdir;
static vop_bmap_t msdosfs_bmap;
+static vop_getpages_t msdosfs_getpages;
static vop_strategy_t msdosfs_strategy;
static vop_print_t msdosfs_print;
static vop_pathconf_t msdosfs_pathconf;
@@ -593,7 +596,7 @@ msdosfs_read(struct vop_read_args *ap)
diff = blsize - bp->b_resid;
if (diff < n)
n = diff;
- error = uiomove(bp->b_data + on, (int) n, uio);
+ error = vn_io_fault_uiomove(bp->b_data + on, (int) n, uio);
brelse(bp);
} while (error == 0 && uio->uio_resid > 0 && n != 0);
if (!isadir && (error == 0 || uio->uio_resid != orig_resid) &&
@@ -723,6 +726,12 @@ msdosfs_write(struct vop_write_args *ap)
* then no need to read data from disk.
*/
bp = getblk(thisvp, bn, pmp->pm_bpcluster, 0, 0, 0);
+ /*
+ * This call to vfs_bio_clrbuf() ensures that
+ * even if vn_io_fault_uiomove() below faults,
+ * garbage from the newly instantiated buffer
+ * is not exposed to the userspace via mmap().
+ */
vfs_bio_clrbuf(bp);
/*
* Do the bmap now, since pcbmap needs buffers
@@ -760,7 +769,7 @@ msdosfs_write(struct vop_write_args *ap)
/*
* Copy the data from user space into the buf header.
*/
- error = uiomove(bp->b_data + croffset, n, uio);
+ error = vn_io_fault_uiomove(bp->b_data + croffset, n, uio);
if (error) {
brelse(bp);
break;
@@ -1792,6 +1801,38 @@ msdosfs_bmap(struct vop_bmap_args *ap)
return (0);
}
+SYSCTL_NODE(_vfs, OID_AUTO, msdosfs, CTLFLAG_RW, 0, "msdos filesystem");
+static int use_buf_pager = 1;
+SYSCTL_INT(_vfs_msdosfs, OID_AUTO, use_buf_pager, CTLFLAG_RWTUN,
+ &use_buf_pager, 0,
+ "Use buffer pager instead of bmap");
+
+static daddr_t
+msdosfs_gbp_getblkno(struct vnode *vp, vm_ooffset_t off)
+{
+
+ return (de_cluster(VTODE(vp)->de_pmp, off));
+}
+
+static int
+msdosfs_gbp_getblksz(struct vnode *vp, daddr_t lbn)
+{
+
+ return (VTODE(vp)->de_pmp->pm_bpcluster);
+}
+
+static int
+msdosfs_getpages(struct vop_getpages_args *ap)
+{
+
+ if (use_buf_pager)
+ return (vfs_bio_getpages(ap->a_vp, ap->a_m, ap->a_count,
+ ap->a_rbehind, ap->a_rahead, msdosfs_gbp_getblkno,
+ msdosfs_gbp_getblksz));
+ return (vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count,
+ ap->a_rbehind, ap->a_rahead, NULL, NULL));
+}
+
static int
msdosfs_strategy(struct vop_strategy_args *ap)
{
@@ -1892,6 +1933,7 @@ struct vop_vector msdosfs_vnodeops = {
.vop_access = msdosfs_access,
.vop_bmap = msdosfs_bmap,
+ .vop_getpages = msdosfs_getpages,
.vop_cachedlookup = msdosfs_lookup,
.vop_open = msdosfs_open,
.vop_close = msdosfs_close,
diff --git a/sys/geom/eli/g_eli.h b/sys/geom/eli/g_eli.h
index 13e780762549..b6a28d05a9a6 100644
--- a/sys/geom/eli/g_eli.h
+++ b/sys/geom/eli/g_eli.h
@@ -289,6 +289,7 @@ eli_metadata_encode_v1v2v3v4v5v6v7(struct g_eli_metadata *md, u_char **datap)
static __inline void
eli_metadata_encode(struct g_eli_metadata *md, u_char *data)
{
+ uint32_t hash[4];
MD5_CTX ctx;
u_char *p;
@@ -320,12 +321,14 @@ eli_metadata_encode(struct g_eli_metadata *md, u_char *data)
}
MD5Init(&ctx);
MD5Update(&ctx, data, p - data);
- MD5Final(md->md_hash, &ctx);
+ MD5Final((void *)hash, &ctx);
+ bcopy(hash, md->md_hash, sizeof(md->md_hash));
bcopy(md->md_hash, p, sizeof(md->md_hash));
}
static __inline int
eli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md)
{
+ uint32_t hash[4];
MD5_CTX ctx;
const u_char *p;
@@ -341,7 +344,8 @@ eli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md)
bcopy(p, md->md_mkeys, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys);
MD5Init(&ctx);
MD5Update(&ctx, data, p - data);
- MD5Final(md->md_hash, &ctx);
+ MD5Final((void *)hash, &ctx);
+ bcopy(hash, md->md_hash, sizeof(md->md_hash));
if (bcmp(md->md_hash, p, 16) != 0)
return (EINVAL);
return (0);
@@ -350,6 +354,7 @@ eli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md)
static __inline int
eli_metadata_decode_v1v2v3v4v5v6v7(const u_char *data, struct g_eli_metadata *md)
{
+ uint32_t hash[4];
MD5_CTX ctx;
const u_char *p;
@@ -366,7 +371,8 @@ eli_metadata_decode_v1v2v3v4v5v6v7(const u_char *data, struct g_eli_metadata *md
bcopy(p, md->md_mkeys, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys);
MD5Init(&ctx);
MD5Update(&ctx, data, p - data);
- MD5Final(md->md_hash, &ctx);
+ MD5Final((void *)hash, &ctx);
+ bcopy(hash, md->md_hash, sizeof(md->md_hash));
if (bcmp(md->md_hash, p, 16) != 0)
return (EINVAL);
return (0);
diff --git a/sys/geom/eli/g_eli_integrity.c b/sys/geom/eli/g_eli_integrity.c
index f68800197eda..6ff0d18566ee 100644
--- a/sys/geom/eli/g_eli_integrity.c
+++ b/sys/geom/eli/g_eli_integrity.c
@@ -444,6 +444,7 @@ g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp)
size += sizeof(*crde) * nsec;
size += sizeof(*crda) * nsec;
size += G_ELI_AUTH_SECKEYLEN * nsec;
+ size += sizeof(uintptr_t); /* Space for alignment. */
data = malloc(size, M_ELI, M_WAITOK);
bp->bio_driver2 = data;
p = data + encr_secsize * nsec;
@@ -451,6 +452,10 @@ g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp)
bp->bio_inbed = 0;
bp->bio_children = nsec;
+#if defined(__mips_n64) || defined(__mips_o64)
+ p = (char *)roundup((uintptr_t)p, sizeof(uintptr_t));
+#endif
+
for (i = 1; i <= nsec; i++, dstoff += encr_secsize) {
crp = (struct cryptop *)p; p += sizeof(*crp);
crde = (struct cryptodesc *)p; p += sizeof(*crde);
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index 214c6f6d989f..f67593794908 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -753,16 +753,6 @@ initializecpu(void)
init_transmeta();
break;
}
-#if defined(PAE) || defined(PAE_TABLES)
- if ((amd_feature & AMDID_NX) != 0) {
- uint64_t msr;
-
- msr = rdmsr(MSR_EFER) | EFER_NXE;
- wrmsr(MSR_EFER, msr);
- pg_nx = PG_NX;
- elf32_nxstack = 1;
- }
-#endif
break;
#endif
default:
@@ -774,6 +764,16 @@ initializecpu(void)
cpu_fxsr = hw_instruction_sse = 1;
}
#endif
+#if defined(PAE) || defined(PAE_TABLES)
+ if ((amd_feature & AMDID_NX) != 0) {
+ uint64_t msr;
+
+ msr = rdmsr(MSR_EFER) | EFER_NXE;
+ wrmsr(MSR_EFER, msr);
+ pg_nx = PG_NX;
+ elf32_nxstack = 1;
+ }
+#endif
}
void
diff --git a/sys/i386/i386/mem.c b/sys/i386/i386/mem.c
index 43fb99451f76..accd092f1c57 100644
--- a/sys/i386/i386/mem.c
+++ b/sys/i386/i386/mem.c
@@ -108,8 +108,11 @@ memrw(struct cdev *dev, struct uio *uio, int flags)
continue;
}
if (dev2unit(dev) == CDEV_MINOR_MEM) {
- pa = uio->uio_offset;
- pa &= ~PAGE_MASK;
+ if (uio->uio_offset > cpu_getmaxphyaddr()) {
+ error = EFAULT;
+ break;
+ }
+ pa = trunc_page(uio->uio_offset);
} else {
/*
* Extract the physical page since the mapping may
@@ -162,6 +165,8 @@ memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr,
int prot __unused, vm_memattr_t *memattr __unused)
{
if (dev2unit(dev) == CDEV_MINOR_MEM) {
+ if (offset > cpu_getmaxphyaddr())
+ return (-1);
*paddr = offset;
return (0);
}
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 7c2d56abac91..765ff8bec511 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -3466,11 +3466,14 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
PMAP_LOCK(pmap);
sched_pin();
- /*
- * In the case that a page table page is not
- * resident, we are creating it here.
- */
+ pde = pmap_pde(pmap, va);
if (va < VM_MAXUSER_ADDRESS) {
+ /*
+ * va is for UVA.
+ * In the case that a page table page is not resident,
+ * we are creating it here. pmap_allocpte() handles
+ * demotion.
+ */
mpte = pmap_allocpte(pmap, va, flags);
if (mpte == NULL) {
KASSERT((flags & PMAP_ENTER_NOSLEEP) != 0,
@@ -3480,19 +3483,28 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
PMAP_UNLOCK(pmap);
return (KERN_RESOURCE_SHORTAGE);
}
+ } else {
+ /*
+ * va is for KVA, so pmap_demote_pde() will never fail
+ * to install a page table page. PG_V is also
+ * asserted by pmap_demote_pde().
+ */
+ KASSERT(pde != NULL && (*pde & PG_V) != 0,
+ ("KVA %#x invalid pde pdir %#jx", va,
+ (uintmax_t)pmap->pm_pdir[PTDPTDI]));
+ if ((*pde & PG_PS) != 0)
+ pmap_demote_pde(pmap, pde, va);
}
-
- pde = pmap_pde(pmap, va);
- if ((*pde & PG_PS) != 0)
- panic("pmap_enter: attempted pmap_enter on 4MB page");
pte = pmap_pte_quick(pmap, va);
/*
- * Page Directory table entry not valid, we need a new PT page
+ * Page Directory table entry is not valid, which should not
+ * happen. We should have either allocated the page table
+ * page or demoted the existing mapping above.
*/
if (pte == NULL) {
panic("pmap_enter: invalid page directory pdir=%#jx, va=%#x",
- (uintmax_t)pmap->pm_pdir[PTDPTDI], va);
+ (uintmax_t)pmap->pm_pdir[PTDPTDI], va);
}
pa = VM_PAGE_TO_PHYS(m);
diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c
index 3decfd43be24..3cf0c5a66589 100644
--- a/sys/i386/i386/trap.c
+++ b/sys/i386/i386/trap.c
@@ -158,14 +158,6 @@ static char *trap_msg[] = {
int has_f00f_bug = 0; /* Initialized so that it can be patched. */
#endif
-#ifdef KDB
-static int kdb_on_nmi = 1;
-SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN,
- &kdb_on_nmi, 0, "Go to KDB on NMI");
-#endif
-static int panic_on_nmi = 1;
-SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN,
- &panic_on_nmi, 0, "Panic on NMI");
static int prot_fault_translation = 0;
SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RW,
&prot_fault_translation, 0, "Select signal to deliver on protection fault");
@@ -467,21 +459,7 @@ user_trctrap_out:
}
goto userout;
#else /* !POWERFAIL_NMI */
- /* machine/parity/power fail/"kitchen sink" faults */
- if (isa_nmi(frame->tf_err) == 0) {
-#ifdef KDB
- /*
- * NMI can be hooked up to a pushbutton
- * for debugging.
- */
- if (kdb_on_nmi) {
- printf ("NMI ... going to debugger\n");
- kdb_trap(type, 0, frame);
- }
-#endif /* KDB */
- goto userout;
- } else if (panic_on_nmi)
- panic("NMI indicates hardware failure");
+ nmi_handle_intr(type, frame);
break;
#endif /* POWERFAIL_NMI */
#endif /* DEV_ISA */
@@ -730,22 +708,8 @@ kernel_trctrap:
}
goto out;
#else /* !POWERFAIL_NMI */
- /* machine/parity/power fail/"kitchen sink" faults */
- if (isa_nmi(frame->tf_err) == 0) {
-#ifdef KDB
- /*
- * NMI can be hooked up to a pushbutton
- * for debugging.
- */
- if (kdb_on_nmi) {
- printf ("NMI ... going to debugger\n");
- kdb_trap(type, 0, frame);
- }
-#endif /* KDB */
- goto out;
- } else if (panic_on_nmi == 0)
- goto out;
- /* FALLTHROUGH */
+ nmi_handle_intr(type, frame);
+ goto out;
#endif /* POWERFAIL_NMI */
#endif /* DEV_ISA */
}
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index 5886438fc48c..e78863830c7b 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -72,7 +72,11 @@ __FBSDID("$FreeBSD$");
* Note that stdarg.h and the ANSI style va_start macro is used for both
* ANSI and traditional C compilers.
*/
+#ifdef _KERNEL
#include <machine/stdarg.h>
+#else
+#include <stdarg.h>
+#endif
#ifdef _KERNEL
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index d98b1b7212ea..0ab5a9afc743 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -209,6 +209,11 @@ forward_signal(struct thread *td)
* 1: ok
*
*/
+#if defined(__amd64__) || defined(__i386__)
+#define X86 1
+#else
+#define X86 0
+#endif
static int
generic_stop_cpus(cpuset_t map, u_int type)
{
@@ -220,12 +225,11 @@ generic_stop_cpus(cpuset_t map, u_int type)
volatile cpuset_t *cpus;
KASSERT(
-#if defined(__amd64__) || defined(__i386__)
- type == IPI_STOP || type == IPI_STOP_HARD || type == IPI_SUSPEND,
-#else
- type == IPI_STOP || type == IPI_STOP_HARD,
+ type == IPI_STOP || type == IPI_STOP_HARD
+#if X86
+ || type == IPI_SUSPEND
#endif
- ("%s: invalid stop type", __func__));
+ , ("%s: invalid stop type", __func__));
if (!smp_started)
return (0);
@@ -233,7 +237,7 @@ generic_stop_cpus(cpuset_t map, u_int type)
CTR2(KTR_SMP, "stop_cpus(%s) with %u type",
cpusetobj_strprint(cpusetbuf, &map), type);
-#if defined(__amd64__) || defined(__i386__)
+#if X86
/*
* When suspending, ensure there are are no IPIs in progress.
* IPIs that have been issued, but not yet delivered (e.g.
@@ -245,6 +249,9 @@ generic_stop_cpus(cpuset_t map, u_int type)
mtx_lock_spin(&smp_ipi_mtx);
#endif
+#if X86
+ if (!nmi_is_broadcast || nmi_kdb_lock == 0) {
+#endif
if (stopping_cpu != PCPU_GET(cpuid))
while (atomic_cmpset_int(&stopping_cpu, NOCPU,
PCPU_GET(cpuid)) == 0)
@@ -253,8 +260,11 @@ generic_stop_cpus(cpuset_t map, u_int type)
/* send the stop IPI to all CPUs in map */
ipi_selected(map, type);
+#if X86
+ }
+#endif
-#if defined(__amd64__) || defined(__i386__)
+#if X86
if (type == IPI_SUSPEND)
cpus = &suspended_cpus;
else
@@ -272,7 +282,7 @@ generic_stop_cpus(cpuset_t map, u_int type)
}
}
-#if defined(__amd64__) || defined(__i386__)
+#if X86
if (type == IPI_SUSPEND)
mtx_unlock_spin(&smp_ipi_mtx);
#endif
@@ -295,7 +305,7 @@ stop_cpus_hard(cpuset_t map)
return (generic_stop_cpus(map, IPI_STOP_HARD));
}
-#if defined(__amd64__) || defined(__i386__)
+#if X86
int
suspend_cpus(cpuset_t map)
{
@@ -325,20 +335,18 @@ generic_restart_cpus(cpuset_t map, u_int type)
#endif
volatile cpuset_t *cpus;
- KASSERT(
-#if defined(__amd64__) || defined(__i386__)
- type == IPI_STOP || type == IPI_STOP_HARD || type == IPI_SUSPEND,
-#else
- type == IPI_STOP || type == IPI_STOP_HARD,
+ KASSERT(type == IPI_STOP || type == IPI_STOP_HARD
+#if X86
+ || type == IPI_SUSPEND
#endif
- ("%s: invalid stop type", __func__));
+ , ("%s: invalid stop type", __func__));
if (!smp_started)
- return 0;
+ return (0);
CTR1(KTR_SMP, "restart_cpus(%s)", cpusetobj_strprint(cpusetbuf, &map));
-#if defined(__amd64__) || defined(__i386__)
+#if X86
if (type == IPI_SUSPEND)
cpus = &suspended_cpus;
else
@@ -348,11 +356,17 @@ generic_restart_cpus(cpuset_t map, u_int type)
/* signal other cpus to restart */
CPU_COPY_STORE_REL(&map, &started_cpus);
+#if X86
+ if (!nmi_is_broadcast || nmi_kdb_lock == 0) {
+#endif
/* wait for each to clear its bit */
while (CPU_OVERLAP(cpus, &map))
cpu_spinwait();
+#if X86
+ }
+#endif
- return 1;
+ return (1);
}
int
@@ -362,7 +376,7 @@ restart_cpus(cpuset_t map)
return (generic_restart_cpus(map, IPI_STOP));
}
-#if defined(__amd64__) || defined(__i386__)
+#if X86
int
resume_cpus(cpuset_t map)
{
@@ -370,6 +384,7 @@ resume_cpus(cpuset_t map)
return (generic_restart_cpus(map, IPI_SUSPEND));
}
#endif
+#undef X86
/*
* All-CPU rendezvous. CPUs are signalled, all execute the setup function
diff --git a/sys/kern/subr_turnstile.c b/sys/kern/subr_turnstile.c
index 57d9f0975d14..dd39835d0dc2 100644
--- a/sys/kern/subr_turnstile.c
+++ b/sys/kern/subr_turnstile.c
@@ -157,6 +157,9 @@ static void init_turnstile0(void *dummy);
#ifdef TURNSTILE_PROFILING
static void init_turnstile_profiling(void *arg);
#endif
+#ifdef DDB
+static void print_sleepchain(struct thread *td, const char *prefix);
+#endif
static void propagate_priority(struct thread *td);
static int turnstile_adjust_thread(struct turnstile *ts,
struct thread *td);
@@ -1169,6 +1172,10 @@ DB_SHOW_ALL_COMMAND(chains, db_show_allchains)
db_printf("chain %d:\n", i++);
print_lockchain(td, " ");
}
+ if (TD_IS_INHIBITED(td) && TD_ON_SLEEPQ(td)) {
+ db_printf("chain %d:\n", i++);
+ print_sleepchain(td, " ");
+ }
if (db_pager_quit)
return;
}
diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c
index 0e85c92c4980..7e4f1b81949b 100644
--- a/sys/kern/subr_uio.c
+++ b/sys/kern/subr_uio.c
@@ -532,7 +532,7 @@ fueword32(volatile const void *base, int32_t *val)
int
fueword64(volatile const void *base, int64_t *val)
{
- int32_t res;
+ int64_t res;
res = fuword64(base);
if (res == -1)
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index a916bdd4be8e..31ef942c43a1 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -599,7 +599,7 @@ static struct witness_order_list_entry order_lists[] = {
* CDEV
*/
{ "vm map (system)", &lock_class_mtx_sleep },
- { "vm page queue", &lock_class_mtx_sleep },
+ { "vm pagequeue", &lock_class_mtx_sleep },
{ "vnode interlock", &lock_class_mtx_sleep },
{ "cdev", &lock_class_mtx_sleep },
{ NULL, NULL },
@@ -609,7 +609,7 @@ static struct witness_order_list_entry order_lists[] = {
{ "vm map (user)", &lock_class_sx },
{ "vm object", &lock_class_rw },
{ "vm page", &lock_class_mtx_sleep },
- { "vm page queue", &lock_class_mtx_sleep },
+ { "vm pagequeue", &lock_class_mtx_sleep },
{ "pmap pv global", &lock_class_rw },
{ "pmap", &lock_class_mtx_sleep },
{ "pmap pv list", &lock_class_rw },
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index e282665f75e5..98f6957e0ae6 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -762,8 +762,10 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
cap_rights_set(&rights, CAP_CONNECT);
}
error = getsock_cap(td, s, &rights, &fp, NULL, NULL);
- if (error != 0)
+ if (error != 0) {
+ m_freem(control);
return (error);
+ }
so = (struct socket *)fp->f_data;
#ifdef KTRACE
@@ -774,12 +776,16 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
if (mp->msg_name != NULL) {
error = mac_socket_check_connect(td->td_ucred, so,
mp->msg_name);
- if (error != 0)
+ if (error != 0) {
+ m_freem(control);
goto bad;
+ }
}
error = mac_socket_check_send(td->td_ucred, so);
- if (error != 0)
+ if (error != 0) {
+ m_freem(control);
goto bad;
+ }
#endif
auio.uio_iov = mp->msg_iov;
@@ -793,6 +799,7 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
for (i = 0; i < mp->msg_iovlen; i++, iov++) {
if ((auio.uio_resid += iov->iov_len) < 0) {
error = EINVAL;
+ m_freem(control);
goto bad;
}
}
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index c70366fbb54d..51e9cf2f738e 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -75,9 +75,10 @@ __FBSDID("$FreeBSD$");
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_kern.h>
-#include <vm/vm_pageout.h>
-#include <vm/vm_page.h>
#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
+#include <vm/vm_pager.h>
#include <vm/vm_extern.h>
#include <vm/vm_map.h>
#include <vm/swap_pager.h>
@@ -4636,6 +4637,161 @@ bdata2bio(struct buf *bp, struct bio *bip)
}
}
+static int buf_pager_relbuf;
+SYSCTL_INT(_vfs, OID_AUTO, buf_pager_relbuf, CTLFLAG_RWTUN,
+ &buf_pager_relbuf, 0,
+ "Make buffer pager release buffers after reading");
+
+/*
+ * The buffer pager. It uses buffer reads to validate pages.
+ *
+ * In contrast to the generic local pager from vm/vnode_pager.c, this
+ * pager correctly and easily handles volumes where the underlying
+ * device block size is greater than the machine page size. The
+ * buffer cache transparently extends the requested page run to be
+ * aligned at the block boundary, and does the necessary bogus page
+ * replacements in the addends to avoid obliterating already valid
+ * pages.
+ *
+ * The only non-trivial issue is that the exclusive busy state for
+ * pages, which is assumed by the vm_pager_getpages() interface, is
+ * incompatible with the VMIO buffer cache's desire to share-busy the
+ * pages. This function performs a trivial downgrade of the pages'
+ * state before reading buffers, and a less trivial upgrade from the
+ * shared-busy to excl-busy state after the read.
+ */
+int
+vfs_bio_getpages(struct vnode *vp, vm_page_t *ma, int count,
+ int *rbehind, int *rahead, vbg_get_lblkno_t get_lblkno,
+ vbg_get_blksize_t get_blksize)
+{
+ vm_page_t m;
+ vm_object_t object;
+ struct buf *bp;
+ daddr_t lbn, lbnp;
+ vm_ooffset_t la, lb, poff, poffe;
+ long bsize;
+ int bo_bs, error, i;
+ bool redo, lpart;
+
+ object = vp->v_object;
+ la = IDX_TO_OFF(ma[count - 1]->pindex);
+ if (la >= object->un_pager.vnp.vnp_size)
+ return (VM_PAGER_BAD);
+ lpart = la + PAGE_SIZE > object->un_pager.vnp.vnp_size;
+ bo_bs = get_blksize(vp, get_lblkno(vp, IDX_TO_OFF(ma[0]->pindex)));
+ if (rbehind != NULL) {
+ lb = IDX_TO_OFF(ma[0]->pindex);
+ *rbehind = OFF_TO_IDX(lb - rounddown2(lb, bo_bs));
+ }
+ if (rahead != NULL) {
+ *rahead = OFF_TO_IDX(roundup2(la, bo_bs) - la);
+ if (la + IDX_TO_OFF(*rahead) >= object->un_pager.vnp.vnp_size) {
+ *rahead = OFF_TO_IDX(roundup2(object->un_pager.
+ vnp.vnp_size, PAGE_SIZE) - la);
+ }
+ }
+ VM_OBJECT_WLOCK(object);
+again:
+ for (i = 0; i < count; i++)
+ vm_page_busy_downgrade(ma[i]);
+ VM_OBJECT_WUNLOCK(object);
+
+ lbnp = -1;
+ for (i = 0; i < count; i++) {
+ m = ma[i];
+
+ /*
+ * Pages are shared busy and the object lock is not
+ * owned, which together allow for the pages'
+ * invalidation. The racy test for validity avoids
+ * useless creation of the buffer for the most typical
+ * case when invalidation is not used in redo or for
+ * parallel read. The shared->excl upgrade loop at
+ * the end of the function catches the race in a
+ * reliable way (protected by the object lock).
+ */
+ if (m->valid == VM_PAGE_BITS_ALL)
+ continue;
+
+ poff = IDX_TO_OFF(m->pindex);
+ poffe = MIN(poff + PAGE_SIZE, object->un_pager.vnp.vnp_size);
+ for (; poff < poffe; poff += bsize) {
+ lbn = get_lblkno(vp, poff);
+ if (lbn == lbnp)
+ goto next_page;
+ lbnp = lbn;
+
+ bsize = get_blksize(vp, lbn);
+ error = bread_gb(vp, lbn, bsize, NOCRED, GB_UNMAPPED,
+ &bp);
+ if (error != 0)
+ goto end_pages;
+ if (LIST_EMPTY(&bp->b_dep)) {
+ /*
+ * Invalidation clears m->valid, but
+ * may leave B_CACHE flag if the
+ * buffer existed at the invalidation
+ * time. In this case, recycle the
+ * buffer to do real read on next
+ * bread() after redo.
+ *
+ * Otherwise B_RELBUF is not strictly
+ * necessary, enable to reduce buf
+ * cache pressure.
+ */
+ if (buf_pager_relbuf ||
+ m->valid != VM_PAGE_BITS_ALL)
+ bp->b_flags |= B_RELBUF;
+
+ bp->b_flags &= ~B_NOCACHE;
+ brelse(bp);
+ } else {
+ bqrelse(bp);
+ }
+ }
+ KASSERT(1 /* racy, enable for debugging */ ||
+ m->valid == VM_PAGE_BITS_ALL || i == count - 1,
+ ("buf %d %p invalid", i, m));
+ if (i == count - 1 && lpart) {
+ VM_OBJECT_WLOCK(object);
+ if (m->valid != 0 &&
+ m->valid != VM_PAGE_BITS_ALL)
+ vm_page_zero_invalid(m, TRUE);
+ VM_OBJECT_WUNLOCK(object);
+ }
+next_page:;
+ }
+end_pages:
+
+ VM_OBJECT_WLOCK(object);
+ redo = false;
+ for (i = 0; i < count; i++) {
+ vm_page_sunbusy(ma[i]);
+ ma[i] = vm_page_grab(object, ma[i]->pindex, VM_ALLOC_NORMAL);
+
+ /*
+ * Since the pages were only sbusy while neither the
+ * buffer nor the object lock was held by us, or
+ * reallocated while vm_page_grab() slept for busy
+ * relinguish, they could have been invalidated.
+ * Recheck the valid bits and re-read as needed.
+ *
+ * Note that the last page is made fully valid in the
+ * read loop, and partial validity for the page at
+ * index count - 1 could mean that the page was
+ * invalidated or removed, so we must restart for
+ * safety as well.
+ */
+ if (ma[i]->valid != VM_PAGE_BITS_ALL)
+ redo = true;
+ }
+ if (redo && error == 0)
+ goto again;
+ VM_OBJECT_WUNLOCK(object);
+ return (error != 0 ? VM_PAGER_ERROR : VM_PAGER_OK);
+}
+
#include "opt_ddb.h"
#ifdef DDB
#include <ddb/ddb.h>
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 49aba08ca4b1..03dc29eb8398 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -495,16 +495,16 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize,
sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
/*
* If MNT_NOWAIT or MNT_LAZY is specified, do not
- * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY
- * overrides MNT_WAIT.
+ * refresh the fsstat cache.
*/
- if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 ||
- (flags & MNT_WAIT)) &&
- (error = VFS_STATFS(mp, sp))) {
- mtx_lock(&mountlist_mtx);
- nmp = TAILQ_NEXT(mp, mnt_list);
- vfs_unbusy(mp);
- continue;
+ if (flags != MNT_LAZY && flags != MNT_NOWAIT) {
+ error = VFS_STATFS(mp, sp);
+ if (error != 0) {
+ mtx_lock(&mountlist_mtx);
+ nmp = TAILQ_NEXT(mp, mnt_list);
+ vfs_unbusy(mp);
+ continue;
+ }
}
if (priv_check(td, PRIV_VFS_GENERATION)) {
bcopy(sp, &sb, sizeof(sb));
diff --git a/sys/mips/include/float.h b/sys/mips/include/float.h
index 86efd02b975c..93a9d5c2fd50 100644
--- a/sys/mips/include/float.h
+++ b/sys/mips/include/float.h
@@ -42,11 +42,7 @@ extern int __flt_rounds(void);
__END_DECLS
#define FLT_RADIX 2 /* b */
-#ifdef CPU_HAVEFPU
#define FLT_ROUNDS __flt_rounds() /* FP addition rounds to nearest */
-#else
-#define FLT_ROUNDS (-1)
-#endif
#if __ISO_C_VISIBLE >= 1999
#define FLT_EVAL_METHOD 0
diff --git a/sys/mips/include/signal.h b/sys/mips/include/signal.h
index 5107af05bba2..f808d3ff6e40 100644
--- a/sys/mips/include/signal.h
+++ b/sys/mips/include/signal.h
@@ -68,11 +68,13 @@ struct sigcontext {
int sc_onstack; /* sigstack state to restore */
__register_t sc_pc; /* pc at time of signal */
__register_t sc_regs[32]; /* processor regs 0 to 31 */
+ __register_t sr; /* status register */
__register_t mullo, mulhi; /* mullo and mulhi registers... */
int sc_fpused; /* fp has been used */
f_register_t sc_fpregs[33]; /* fp regs 0 to 31 and csr */
__register_t sc_fpc_eir; /* fp exception instruction reg */
- int xxx[8]; /* XXX reserved */
+ void *sc_tls; /* pointer to TLS area */
+ int __spare__[8]; /* XXX reserved */
};
#endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */
diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S
index 725ae65eaaa2..04614737ab99 100644
--- a/sys/mips/mips/exception.S
+++ b/sys/mips/mips/exception.S
@@ -1098,11 +1098,17 @@ END(MipsTLBMissException)
NESTED(MipsFPTrap, CALLFRAME_SIZ, ra)
PTR_SUBU sp, sp, CALLFRAME_SIZ
mfc0 t0, MIPS_COP_0_STATUS
+ HAZARD_DELAY
REG_S ra, CALLFRAME_RA(sp)
.mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
+#if defined(__mips_n64)
+ or t1, t0, MIPS_SR_COP_1_BIT | MIPS_SR_FR
+#else
or t1, t0, MIPS_SR_COP_1_BIT
+#endif
mtc0 t1, MIPS_COP_0_STATUS
+ HAZARD_DELAY
ITLBNOPFIX
cfc1 t1, MIPS_FPU_CSR # stall til FP done
cfc1 t1, MIPS_FPU_CSR # now get status
diff --git a/sys/mips/mips/locore.S b/sys/mips/mips/locore.S
index 4e2173c583d3..37421d8f5003 100644
--- a/sys/mips/mips/locore.S
+++ b/sys/mips/mips/locore.S
@@ -118,7 +118,7 @@ VECTOR(_locore, unknown)
*/
li t1, MIPS_SR_COP_1_BIT
#ifdef __mips_n64
- or t1, MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX
+ or t1, MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX | MIPS_SR_FR
#endif
#endif
/*
diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S
index aff18acb36cc..ae33c39edd46 100644
--- a/sys/mips/mips/swtch.S
+++ b/sys/mips/mips/swtch.S
@@ -415,8 +415,14 @@ LEAF(MipsSwitchFPState)
.set push
.set hardfloat
mfc0 t1, MIPS_COP_0_STATUS # Save old SR
- li t0, MIPS_SR_COP_1_BIT # enable the coprocessor
+ HAZARD_DELAY
+#if defined(__mips_n64)
+ or t0, t1, MIPS_SR_COP_1_BIT | MIPS_SR_FR # enable the coprocessor
+#else
+ or t0, t1, MIPS_SR_COP_1_BIT # enable the coprocessor
+#endif
mtc0 t0, MIPS_COP_0_STATUS
+ HAZARD_DELAY
ITLBNOPFIX
beq a0, zero, 1f # skip save if NULL pointer
@@ -540,8 +546,14 @@ LEAF(MipsSaveCurFPState)
.set hardfloat
PTR_L a0, TD_PCB(a0) # get pointer to pcb for thread
mfc0 t1, MIPS_COP_0_STATUS # Disable interrupts and
- li t0, MIPS_SR_COP_1_BIT # enable the coprocessor
+ HAZARD_DELAY
+#if defined(__mips_n64)
+ or t0, t1, MIPS_SR_COP_1_BIT | MIPS_SR_FR # enable the coprocessor
+#else
+ or t0, t1, MIPS_SR_COP_1_BIT # enable the coprocessor
+#endif
mtc0 t0, MIPS_COP_0_STATUS
+ HAZARD_DELAY
ITLBNOPFIX
GET_CPU_PCPU(a1)
PTR_S zero, PC_FPCURTHREAD(a1) # indicate state has been saved
diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c
index e14b12be2139..33874a8d6c0c 100644
--- a/sys/mips/mips/trap.c
+++ b/sys/mips/mips/trap.c
@@ -590,7 +590,8 @@ trap(struct trapframe *trapframe)
break;
}
if ((last_badvaddr == this_badvaddr) &&
- ((type & ~T_USER) != T_SYSCALL)) {
+ ((type & ~T_USER) != T_SYSCALL) &&
+ ((type & ~T_USER) != T_COP_UNUSABLE)) {
if (++count == 3) {
trap_frame_dump(trapframe);
panic("too many faults at %p\n", (void *)last_badvaddr);
@@ -980,7 +981,11 @@ dofault:
addr = trapframe->pc;
MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame);
PCPU_SET(fpcurthread, td);
+#if defined(__mips_n64)
+ td->td_frame->sr |= MIPS_SR_COP_1_BIT | MIPS_SR_FR;
+#else
td->td_frame->sr |= MIPS_SR_COP_1_BIT;
+#endif
td->td_md.md_flags |= MDTD_FPUSED;
goto out;
#endif
@@ -1028,7 +1033,7 @@ dofault:
case T_FPE + T_USER:
if (!emulate_fp) {
- i = SIGILL;
+ i = SIGFPE;
addr = trapframe->pc;
break;
}
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
index fbaefc3ebe9a..b5ac84dbabb3 100644
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -73,6 +73,7 @@ SUBDIR= \
cd9660_iconv \
${_ce} \
${_cfi} \
+ ${_chromebook_platform} \
${_ciss} \
cloudabi \
${_cloudabi32} \
@@ -510,7 +511,8 @@ _txp= txp
.if ${MK_SOURCELESS_UCODE} != "no" && ${MACHINE_CPUARCH} != "arm" && \
${MACHINE_CPUARCH} != "mips" && \
- ${MACHINE_ARCH} != "powerpc" && ${MACHINE_CPUARCH} != "riscv"
+ ${MACHINE_ARCH} != "powerpc" && ${MACHINE_ARCH} != "powerpcspe" && \
+ ${MACHINE_CPUARCH} != "riscv"
_cxgbe= cxgbe
.endif
@@ -603,6 +605,7 @@ _amdtemp= amdtemp
_arcmsr= arcmsr
_asmc= asmc
_ciss= ciss
+_chromebook_platform= chromebook_platform
_cmx= cmx
_coretemp= coretemp
.if ${MK_SOURCELESS_HOST} != "no"
@@ -753,7 +756,6 @@ _cfi= cfi
_cpufreq= cpufreq
_drm= drm
_exca= exca
-_nvram= powermac_nvram
_pccard= pccard
_wi= wi
.endif
@@ -761,6 +763,10 @@ _wi= wi
.if ${MACHINE_ARCH} == "powerpc64"
_drm2= drm2
.endif
+.if ${MACHINE_ARCH} == "powerpc64" || ${MACHINE_ARCH} == "powerpc"
+# Don't build powermac_nvram for powerpcspe, it's never supported.
+_nvram= powermac_nvram
+.endif
.if ${MACHINE_CPUARCH} == "sparc64"
_auxio= auxio
diff --git a/sys/modules/chromebook_platform/Makefile b/sys/modules/chromebook_platform/Makefile
new file mode 100644
index 000000000000..640c536abd9a
--- /dev/null
+++ b/sys/modules/chromebook_platform/Makefile
@@ -0,0 +1,7 @@
+#$FreeBSD$
+
+.PATH: ${.CURDIR}/../../dev/chromebook_platform
+KMOD = chromebook_platform
+SRCS = chromebook_platform.c bus_if.h device_if.h pci_if.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/modules/geom/Makefile b/sys/modules/geom/Makefile
index 3ea398958aab..8d7e3c6deb3f 100644
--- a/sys/modules/geom/Makefile
+++ b/sys/modules/geom/Makefile
@@ -6,6 +6,7 @@ SYSDIR?=${.CURDIR}/../..
SUBDIR= geom_bde \
geom_cache \
geom_concat \
+ geom_eli \
geom_gate \
geom_journal \
geom_label \
@@ -29,9 +30,4 @@ SUBDIR= geom_bde \
SUBDIR+= geom_ccd
.endif
-# Alignment issues in g_eli_auth_run() on MIPS64 causes kernel panic
-.if ${MACHINE_ARCH} != "mips64" && ${MACHINE_ARCH} != "mips64el"
-SUBDIR+= geom_eli
-.endif
-
.include <bsd.subdir.mk>
diff --git a/sys/modules/hyperv/netvsc/Makefile b/sys/modules/hyperv/netvsc/Makefile
index f28a59c8affe..b27ea406c9cc 100644
--- a/sys/modules/hyperv/netvsc/Makefile
+++ b/sys/modules/hyperv/netvsc/Makefile
@@ -4,9 +4,7 @@
${.CURDIR}/../../../dev/hyperv/vmbus
KMOD= hv_netvsc
-SRCS= hv_net_vsc.c \
- hv_netvsc_drv_freebsd.c \
- hv_rndis_filter.c
+SRCS= hn_nvs.c hn_rndis.c hv_netvsc_drv_freebsd.c
SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h vmbus_if.h
CFLAGS+= -I${.CURDIR}/../../../dev/hyperv/netvsc
diff --git a/sys/modules/i2c/Makefile b/sys/modules/i2c/Makefile
index a2199f561051..8e9bdf982cb6 100644
--- a/sys/modules/i2c/Makefile
+++ b/sys/modules/i2c/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
SUBDIR =
-SUBDIR += controllers if_ic smbus iicbus iicbb iicsmb iic cyapa smb isl
+SUBDIR += controllers if_ic smbus iicbus iicbb iicsmb iic cyapa smb isl jedec_ts
.include <bsd.subdir.mk>
diff --git a/sys/modules/i2c/controllers/ichiic/Makefile b/sys/modules/i2c/controllers/ichiic/Makefile
index 288a79e450bd..1cebbebad59d 100644
--- a/sys/modules/i2c/controllers/ichiic/Makefile
+++ b/sys/modules/i2c/controllers/ichiic/Makefile
@@ -2,7 +2,7 @@
.PATH: ${.CURDIR}/../../../../dev/ichiic
KMOD = ig4
-SRCS = device_if.h bus_if.h iicbb_if.h pci_if.h smbus_if.h \
+SRCS = device_if.h bus_if.h iicbus_if.h pci_if.h smbus_if.h \
ig4_iic.c ig4_pci.c ig4_reg.h ig4_var.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/i2c/cyapa/Makefile b/sys/modules/i2c/cyapa/Makefile
index 80f5fbac2372..eee4a62cde43 100644
--- a/sys/modules/i2c/cyapa/Makefile
+++ b/sys/modules/i2c/cyapa/Makefile
@@ -2,6 +2,6 @@
.PATH: ${.CURDIR}/../../../dev/cyapa
KMOD = cyapa
-SRCS = cyapa.c device_if.h bus_if.h smbus_if.h vnode_if.h
+SRCS = cyapa.c device_if.h bus_if.h iicbus_if.h vnode_if.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/i2c/isl/Makefile b/sys/modules/i2c/isl/Makefile
index a9fac280216d..697fdeab7862 100644
--- a/sys/modules/i2c/isl/Makefile
+++ b/sys/modules/i2c/isl/Makefile
@@ -2,6 +2,6 @@
.PATH: ${.CURDIR}/../../../dev/isl
KMOD = isl
-SRCS = isl.c device_if.h bus_if.h smbus_if.h vnode_if.h
+SRCS = isl.c device_if.h bus_if.h iicbus_if.h
.include <bsd.kmod.mk>
diff --git a/sys/modules/i2c/jedec_ts/Makefile b/sys/modules/i2c/jedec_ts/Makefile
new file mode 100644
index 000000000000..66e620619fd5
--- /dev/null
+++ b/sys/modules/i2c/jedec_ts/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../dev/jedec_ts
+KMOD = jedec_ts
+SRCS = jedec_ts.c bus_if.h device_if.h smbus_if.h
+
+.include <bsd.kmod.mk>
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 986639da9ccf..d98e691e58e3 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -408,7 +408,7 @@ SYSCTL_INT(_net_link_bridge, OID_AUTO, inherit_mac,
static VNET_DEFINE(int, allow_llz_overlap) = 0;
#define V_allow_llz_overlap VNET(allow_llz_overlap)
SYSCTL_INT(_net_link_bridge, OID_AUTO, allow_llz_overlap,
- CTLFLAG_VNET | CTLFLAG_RW | CTLFLAG_VNET, &VNET_NAME(allow_llz_overlap), 0,
+ CTLFLAG_RW | CTLFLAG_VNET, &VNET_NAME(allow_llz_overlap), 0,
"Allow overlap of link-local scope "
"zones of a bridge interface and the member interfaces");
diff --git a/sys/net/netmap.h b/sys/net/netmap.h
index 14b5e2b32128..3e0cdab42489 100644
--- a/sys/net/netmap.h
+++ b/sys/net/netmap.h
@@ -525,6 +525,7 @@ struct nmreq {
#define NETMAP_BDG_POLLING_ON 10 /* delete polling kthread */
#define NETMAP_BDG_POLLING_OFF 11 /* delete polling kthread */
#define NETMAP_VNET_HDR_GET 12 /* get the port virtio-net-hdr length */
+#define NETMAP_POOLS_INFO_GET 13 /* get memory allocator pools info */
uint16_t nr_arg1; /* reserve extra rings in NIOCREGIF */
#define NETMAP_BDG_HOST 1 /* attach the host stack on ATTACH */
@@ -644,29 +645,4 @@ struct nm_ifreq {
char data[NM_IFRDATA_LEN];
};
-/*
- * netmap kernel thread configuration
- */
-/* bhyve/vmm.ko MSIX parameters for IOCTL */
-struct ptn_vmm_ioctl_msix {
- uint64_t msg;
- uint64_t addr;
-};
-
-/* IOCTL parameters */
-struct nm_kth_ioctl {
- uint64_t com;
- /* We use union to support more ioctl commands. */
- union {
- struct ptn_vmm_ioctl_msix msix;
- } data;
-};
-
-/* Configuration of a ptnetmap ring */
-struct ptnet_ring_cfg {
- uint64_t ioeventfd; /* eventfd in linux, tsleep() parameter in FreeBSD */
- uint64_t irqfd; /* eventfd in linux, ioctl fd in FreeBSD */
- struct nm_kth_ioctl ioctl; /* ioctl parameter to send irq (only used in bhyve/FreeBSD) */
- uint64_t reserved[4]; /* reserved to support of more hypervisors */
-};
#endif /* _NET_NETMAP_H_ */
diff --git a/sys/net/netmap_virt.h b/sys/net/netmap_virt.h
index e17dcf854a99..e5c823ea2f28 100644
--- a/sys/net/netmap_virt.h
+++ b/sys/net/netmap_virt.h
@@ -32,13 +32,6 @@
#ifndef NETMAP_VIRT_H
#define NETMAP_VIRT_H
-#define NETMAP_VIRT_CSB_SIZE 4096
-
-/* ptnetmap features */
-#define PTNETMAP_F_BASE 1
-#define PTNETMAP_F_FULL 2 /* not used */
-#define PTNETMAP_F_VNET_HDR 4
-
/*
* ptnetmap_memdev: device used to expose memory into the guest VM
*
@@ -49,83 +42,126 @@
/* PCI identifiers and PCI BARs for the ptnetmap memdev
* and ptnetmap network interface. */
#define PTNETMAP_MEMDEV_NAME "ptnetmap-memdev"
-#define PTNETMAP_PCI_VENDOR_ID 0x3333 /* TODO change vendor_id */
-#define PTNETMAP_PCI_DEVICE_ID 0x0001 /* memory device */
-#define PTNETMAP_PCI_NETIF_ID 0x0002 /* ptnet network interface */
+#define PTNETMAP_PCI_VENDOR_ID 0x1b36 /* QEMU virtual devices */
+#define PTNETMAP_PCI_DEVICE_ID 0x000c /* memory device */
+#define PTNETMAP_PCI_NETIF_ID 0x000d /* ptnet network interface */
#define PTNETMAP_IO_PCI_BAR 0
#define PTNETMAP_MEM_PCI_BAR 1
#define PTNETMAP_MSIX_PCI_BAR 2
/* Registers for the ptnetmap memdev */
-/* 32 bit r/o */
-#define PTNETMAP_IO_PCI_MEMSIZE 0 /* size of the netmap memory shared
- * between guest and host */
-/* 16 bit r/o */
-#define PTNETMAP_IO_PCI_HOSTID 4 /* memory allocator ID in netmap host */
-#define PTNETMAP_IO_SIZE 6
+#define PTNET_MDEV_IO_MEMSIZE_LO 0 /* netmap memory size (low) */
+#define PTNET_MDEV_IO_MEMSIZE_HI 4 /* netmap_memory_size (high) */
+#define PTNET_MDEV_IO_MEMID 8 /* memory allocator ID in the host */
+#define PTNET_MDEV_IO_IF_POOL_OFS 64
+#define PTNET_MDEV_IO_IF_POOL_OBJNUM 68
+#define PTNET_MDEV_IO_IF_POOL_OBJSZ 72
+#define PTNET_MDEV_IO_RING_POOL_OFS 76
+#define PTNET_MDEV_IO_RING_POOL_OBJNUM 80
+#define PTNET_MDEV_IO_RING_POOL_OBJSZ 84
+#define PTNET_MDEV_IO_BUF_POOL_OFS 88
+#define PTNET_MDEV_IO_BUF_POOL_OBJNUM 92
+#define PTNET_MDEV_IO_BUF_POOL_OBJSZ 96
+#define PTNET_MDEV_IO_END 100
/*
* ptnetmap configuration
*
- * The hypervisor (QEMU or bhyve) sends this struct to the host netmap
- * module through an ioctl() command when it wants to start the ptnetmap
- * kthreads.
+ * The ptnet kthreads (running in host kernel-space) need to be configured
+ * in order to know how to intercept guest kicks (I/O register writes) and
+ * how to inject MSI-X interrupts to the guest. The configuration may vary
+ * depending on the hypervisor. Currently, we support QEMU/KVM on Linux and
+ * and bhyve on FreeBSD.
+ * The configuration is passed by the hypervisor to the host netmap module
+ * by means of an ioctl() with nr_cmd=NETMAP_PT_HOST_CREATE, and it is
+ * specified by the ptnetmap_cfg struct. This struct contains an header
+ * with general informations and an array of entries whose size depends
+ * on the hypervisor. The NETMAP_PT_HOST_CREATE command is issued every
+ * time the kthreads are started.
*/
struct ptnetmap_cfg {
-#define PTNETMAP_CFG_FEAT_CSB 0x0001
-#define PTNETMAP_CFG_FEAT_EVENTFD 0x0002
-#define PTNETMAP_CFG_FEAT_IOCTL 0x0004
- uint32_t features;
- void *ptrings; /* ptrings inside CSB */
- uint32_t num_rings; /* number of entries */
- struct ptnet_ring_cfg entries[0]; /* per-ptring configuration */
+#define PTNETMAP_CFGTYPE_QEMU 0x1
+#define PTNETMAP_CFGTYPE_BHYVE 0x2
+ uint16_t cfgtype; /* how to interpret the cfg entries */
+ uint16_t entry_size; /* size of a config entry */
+ uint32_t num_rings; /* number of config entries */
+ void *ptrings; /* ptrings inside CSB */
+ /* Configuration entries are allocated right after the struct. */
+};
+
+/* Configuration of a ptnetmap ring for QEMU. */
+struct ptnetmap_cfgentry_qemu {
+ uint32_t ioeventfd; /* to intercept guest register access */
+ uint32_t irqfd; /* to inject guest interrupts */
+};
+
+/* Configuration of a ptnetmap ring for bhyve. */
+struct ptnetmap_cfgentry_bhyve {
+ uint64_t wchan; /* tsleep() parameter, to wake up kthread */
+ uint32_t ioctl_fd; /* ioctl fd */
+ /* ioctl parameters to send irq */
+ uint32_t ioctl_cmd;
+ /* vmm.ko MSIX parameters for IOCTL */
+ struct {
+ uint64_t msg_data;
+ uint64_t addr;
+ } ioctl_data;
+};
+
+/*
+ * Structure filled-in by the kernel when asked for allocator info
+ * through NETMAP_POOLS_INFO_GET. Used by hypervisors supporting
+ * ptnetmap.
+ */
+struct netmap_pools_info {
+ uint64_t memsize; /* same as nmr->nr_memsize */
+ uint32_t memid; /* same as nmr->nr_arg2 */
+ uint32_t if_pool_offset;
+ uint32_t if_pool_objtotal;
+ uint32_t if_pool_objsize;
+ uint32_t ring_pool_offset;
+ uint32_t ring_pool_objtotal;
+ uint32_t ring_pool_objsize;
+ uint32_t buf_pool_offset;
+ uint32_t buf_pool_objtotal;
+ uint32_t buf_pool_objsize;
};
/*
- * Functions used to write ptnetmap_cfg from/to the nmreq.
- * The user-space application writes the pointer of ptnetmap_cfg
- * (user-space buffer) starting from nr_arg1 field, so that the kernel
- * can read it with copyin (copy_from_user).
+ * Pass a pointer to a userspace buffer to be passed to kernelspace for write
+ * or read. Used by NETMAP_PT_HOST_CREATE and NETMAP_POOLS_INFO_GET.
*/
static inline void
-ptnetmap_write_cfg(struct nmreq *nmr, struct ptnetmap_cfg *cfg)
+nmreq_pointer_put(struct nmreq *nmr, void *userptr)
{
- uintptr_t *nmr_ptncfg = (uintptr_t *)&nmr->nr_arg1;
- *nmr_ptncfg = (uintptr_t)cfg;
+ uintptr_t *pp = (uintptr_t *)&nmr->nr_arg1;
+ *pp = (uintptr_t)userptr;
}
-/* ptnetmap control commands */
-#define PTNETMAP_PTCTL_CONFIG 1
-#define PTNETMAP_PTCTL_FINALIZE 2
-#define PTNETMAP_PTCTL_IFNEW 3
-#define PTNETMAP_PTCTL_IFDELETE 4
-#define PTNETMAP_PTCTL_RINGSCREATE 5
-#define PTNETMAP_PTCTL_RINGSDELETE 6
-#define PTNETMAP_PTCTL_DEREF 7
-#define PTNETMAP_PTCTL_TXSYNC 8
-#define PTNETMAP_PTCTL_RXSYNC 9
-#define PTNETMAP_PTCTL_REGIF 10
-#define PTNETMAP_PTCTL_UNREGIF 11
-#define PTNETMAP_PTCTL_HOSTMEMID 12
-
+/* ptnetmap features */
+#define PTNETMAP_F_VNET_HDR 1
/* I/O registers for the ptnet device. */
#define PTNET_IO_PTFEAT 0
#define PTNET_IO_PTCTL 4
-#define PTNET_IO_PTSTS 8
-#define PTNET_IO_MAC_LO 12
-#define PTNET_IO_MAC_HI 16
-#define PTNET_IO_CSBBAH 20
-#define PTNET_IO_CSBBAL 24
-#define PTNET_IO_NIFP_OFS 28
-#define PTNET_IO_NUM_TX_RINGS 32
-#define PTNET_IO_NUM_RX_RINGS 36
-#define PTNET_IO_NUM_TX_SLOTS 40
-#define PTNET_IO_NUM_RX_SLOTS 44
-#define PTNET_IO_VNET_HDR_LEN 48
+#define PTNET_IO_MAC_LO 8
+#define PTNET_IO_MAC_HI 12
+#define PTNET_IO_CSBBAH 16
+#define PTNET_IO_CSBBAL 20
+#define PTNET_IO_NIFP_OFS 24
+#define PTNET_IO_NUM_TX_RINGS 28
+#define PTNET_IO_NUM_RX_RINGS 32
+#define PTNET_IO_NUM_TX_SLOTS 36
+#define PTNET_IO_NUM_RX_SLOTS 40
+#define PTNET_IO_VNET_HDR_LEN 44
+#define PTNET_IO_HOSTMEMID 48
#define PTNET_IO_END 52
#define PTNET_IO_KICK_BASE 128
-#define PTNET_IO_MASK 0xff
+#define PTNET_IO_MASK 0xff
+
+/* ptnetmap control commands (values for PTCTL register) */
+#define PTNETMAP_PTCTL_CREATE 1
+#define PTNETMAP_PTCTL_DELETE 2
/* If defined, CSB is allocated by the guest, not by the host. */
#define PTNET_CSB_ALLOC
@@ -145,29 +181,18 @@ struct ptnet_ring {
/* CSB for the ptnet device. */
struct ptnet_csb {
+#define NETMAP_VIRT_CSB_SIZE 4096
struct ptnet_ring rings[NETMAP_VIRT_CSB_SIZE/sizeof(struct ptnet_ring)];
};
-#if defined (WITH_PTNETMAP_HOST) || defined (WITH_PTNETMAP_GUEST)
-
-/* return l_elem - r_elem with wraparound */
-static inline uint32_t
-ptn_sub(uint32_t l_elem, uint32_t r_elem, uint32_t num_slots)
-{
- int64_t res;
-
- res = (int64_t)(l_elem) - r_elem;
-
- return (res < 0) ? res + num_slots : res;
-}
-#endif /* WITH_PTNETMAP_HOST || WITH_PTNETMAP_GUEST */
-
#ifdef WITH_PTNETMAP_GUEST
/* ptnetmap_memdev routines used to talk with ptnetmap_memdev device driver */
struct ptnetmap_memdev;
-int nm_os_pt_memdev_iomap(struct ptnetmap_memdev *, vm_paddr_t *, void **);
+int nm_os_pt_memdev_iomap(struct ptnetmap_memdev *, vm_paddr_t *, void **,
+ uint64_t *);
void nm_os_pt_memdev_iounmap(struct ptnetmap_memdev *);
+uint32_t nm_os_pt_memdev_ioread(struct ptnetmap_memdev *, unsigned int);
/* Guest driver: Write kring pointers (cur, head) to the CSB.
* This routine is coupled with ptnetmap_host_read_kring_csb(). */
diff --git a/sys/net/rndis.h b/sys/net/rndis.h
index 95edb1c5d7e4..72548ebf1f11 100644
--- a/sys/net/rndis.h
+++ b/sys/net/rndis.h
@@ -351,7 +351,8 @@ struct rndis_keepalive_comp {
uint32_t rm_status;
};
-/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */
+/* Packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */
+#define NDIS_PACKET_TYPE_NONE 0x00000000
#define NDIS_PACKET_TYPE_DIRECTED 0x00000001
#define NDIS_PACKET_TYPE_MULTICAST 0x00000002
#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
@@ -365,6 +366,14 @@ struct rndis_keepalive_comp {
#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00004000
#define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000
+/*
+ * Packet filter description for use with printf(9) %b identifier.
+ */
+#define NDIS_PACKET_TYPES \
+ "\20\1DIRECT\2MULTICAST\3ALLMULTI\4BROADCAST" \
+ "\5SRCROUTE\6PROMISC\7SMT\10ALLLOCAL" \
+ "\11GROUP\12ALLFUNC\13FUNC\14MACFRAME"
+
/* RNDIS offsets */
#define RNDIS_HEADER_OFFSET ((uint32_t)sizeof(struct rndis_msghdr))
#define RNDIS_DATA_OFFSET \
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index 28f1ffed81f7..a9a82c3fea19 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -162,6 +162,10 @@ struct ieee80211_qosframe_addr4 {
#define IEEE80211_FC0_SUBTYPE_QOS_CFACKPOLL 0xb0
#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0
+#define IEEE80211_IS_MGMT(wh) \
+ (!! (((wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK) \
+ == IEEE80211_FC0_TYPE_MGT))
+
#define IEEE80211_FC0_QOSDATA \
(IEEE80211_FC0_TYPE_DATA|IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_VERSION_0)
diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c
index e685e1d37d60..bf0407c0b840 100644
--- a/sys/net80211/ieee80211_freebsd.c
+++ b/sys/net80211/ieee80211_freebsd.c
@@ -529,6 +529,21 @@ ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
return (0);
}
+const struct ieee80211_rx_stats *
+ieee80211_get_rx_params_ptr(struct mbuf *m)
+{
+ struct m_tag *mtag;
+ struct ieee80211_rx_params *rx;
+
+ mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS,
+ NULL);
+ if (mtag == NULL)
+ return (NULL);
+ rx = (struct ieee80211_rx_params *)(mtag + 1);
+ return (&rx->params);
+}
+
+
/*
* Add TOA parameters to the given mbuf.
*/
diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
index f21423c3e375..cbacc08b51cf 100644
--- a/sys/net80211/ieee80211_freebsd.h
+++ b/sys/net80211/ieee80211_freebsd.h
@@ -713,6 +713,7 @@ int ieee80211_add_rx_params(struct mbuf *m,
const struct ieee80211_rx_stats *rxs);
int ieee80211_get_rx_params(struct mbuf *m,
struct ieee80211_rx_stats *rxs);
+const struct ieee80211_rx_stats * ieee80211_get_rx_params_ptr(struct mbuf *m);
struct ieee80211_toa_params {
int request_id;
diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c
index 11cc8d992b41..c972e82b6fd1 100644
--- a/sys/net80211/ieee80211_scan.c
+++ b/sys/net80211/ieee80211_scan.c
@@ -443,6 +443,9 @@ ieee80211_cancel_scan(struct ieee80211vap *vap)
/*
* Cancel any scan currently going on.
+ *
+ * This is called during normal 802.11 data path to cancel
+ * a scan so a newly arrived normal data packet can be sent.
*/
void
ieee80211_cancel_anyscan(struct ieee80211vap *vap)
diff --git a/sys/net80211/ieee80211_scan_sw.c b/sys/net80211/ieee80211_scan_sw.c
index 6313d46177dc..33e28868f97d 100644
--- a/sys/net80211/ieee80211_scan_sw.c
+++ b/sys/net80211/ieee80211_scan_sw.c
@@ -467,6 +467,11 @@ ieee80211_swscan_cancel_scan(struct ieee80211vap *vap)
static void
ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap)
{
+
+ /* XXX for now - just don't do this per packet. */
+ if (vap->iv_flags_ext & IEEE80211_FEXT_SCAN_OFFLOAD)
+ return;
+
cancel_scan(vap, 1, __func__);
}
diff --git a/sys/netinet/cc/cc_cdg.c b/sys/netinet/cc/cc_cdg.c
index 04e2f7be5145..b9049fb7222b 100644
--- a/sys/netinet/cc/cc_cdg.c
+++ b/sys/netinet/cc/cc_cdg.c
@@ -431,6 +431,11 @@ static void
cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type)
{
struct cdg *cdg_data = ccv->cc_data;
+ uint32_t cwin;
+ u_int mss;
+
+ cwin = CCV(ccv, snd_cwnd);
+ mss = CCV(ccv, t_maxseg);
switch(signal_type) {
case CC_CDG_DELAY:
@@ -448,7 +453,7 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type)
*/
if (IN_CONGRECOVERY(CCV(ccv, t_flags)) ||
cdg_data->queue_state < CDG_Q_FULL) {
- CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd);
+ CCV(ccv, snd_ssthresh) = cwin;
CCV(ccv, snd_recover) = CCV(ccv, snd_max);
} else {
/*
@@ -461,13 +466,17 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type)
cdg_data->shadow_w, RENO_BETA);
CCV(ccv, snd_ssthresh) = max(cdg_data->shadow_w,
- cdg_window_decrease(ccv, CCV(ccv, snd_cwnd),
- V_cdg_beta_loss));
+ cdg_window_decrease(ccv, cwin, V_cdg_beta_loss));
+ CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
cdg_data->window_incr = cdg_data->rtt_count = 0;
}
ENTER_RECOVERY(CCV(ccv, t_flags));
break;
+ case CC_RTO:
+ CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2);
+ CCV(ccv, snd_cwnd) = mss;
+ break;
default:
newreno_cc_algo.cong_signal(ccv, signal_type);
break;
diff --git a/sys/netinet/cc/cc_chd.c b/sys/netinet/cc/cc_chd.c
index d7b53fec4d6a..fd2f6b8ec1b6 100644
--- a/sys/netinet/cc/cc_chd.c
+++ b/sys/netinet/cc/cc_chd.c
@@ -330,10 +330,14 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type)
struct ertt *e_t;
struct chd *chd_data;
int qdly;
+ uint32_t cwin;
+ u_int mss;
e_t = khelp_get_osd(CCV(ccv, osd), ertt_id);
chd_data = ccv->cc_data;
qdly = imax(e_t->rtt, chd_data->maxrtt_in_rtt) - e_t->minrtt;
+ cwin = CCV(ccv, snd_cwnd);
+ mss = CCV(ccv, t_maxseg);
switch(signal_type) {
case CC_CHD_DELAY:
@@ -373,6 +377,10 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type)
}
ENTER_FASTRECOVERY(CCV(ccv, t_flags));
break;
+ case CC_RTO:
+ CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2);
+ CCV(ccv, snd_cwnd) = mss;
+ break;
default:
newreno_cc_algo.cong_signal(ccv, signal_type);
diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c
index 64398faa929b..d2304d227487 100644
--- a/sys/netinet/cc/cc_cubic.c
+++ b/sys/netinet/cc/cc_cubic.c
@@ -225,8 +225,12 @@ static void
cubic_cong_signal(struct cc_var *ccv, uint32_t type)
{
struct cubic *cubic_data;
+ uint32_t cwin;
+ u_int mss;
cubic_data = ccv->cc_data;
+ cwin = CCV(ccv, snd_cwnd);
+ mss = CCV(ccv, t_maxseg);
switch (type) {
case CC_NDUPACK:
@@ -235,7 +239,8 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
cubic_ssthresh_update(ccv);
cubic_data->num_cong_events++;
cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
- cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
+ cubic_data->max_cwnd = cwin;
+ CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
}
ENTER_RECOVERY(CCV(ccv, t_flags));
}
@@ -246,7 +251,7 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
cubic_ssthresh_update(ccv);
cubic_data->num_cong_events++;
cubic_data->prev_max_cwnd = cubic_data->max_cwnd;
- cubic_data->max_cwnd = CCV(ccv, snd_cwnd);
+ cubic_data->max_cwnd = cwin;
cubic_data->t_last_cong = ticks;
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
@@ -261,9 +266,13 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type)
* chance the first one is a false alarm and may not indicate
* congestion.
*/
- if (CCV(ccv, t_rxtshift) >= 2)
+ if (CCV(ccv, t_rxtshift) >= 2) {
cubic_data->num_cong_events++;
cubic_data->t_last_cong = ticks;
+ cubic_ssthresh_update(ccv);
+ cubic_data->max_cwnd = cwin;
+ CCV(ccv, snd_cwnd) = mss;
+ }
break;
}
}
diff --git a/sys/netinet/cc/cc_dctcp.c b/sys/netinet/cc/cc_dctcp.c
index ce75750fef8b..e79fb19d96da 100644
--- a/sys/netinet/cc/cc_dctcp.c
+++ b/sys/netinet/cc/cc_dctcp.c
@@ -230,10 +230,11 @@ static void
dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
{
struct dctcp *dctcp_data;
- u_int win, mss;
+ uint32_t cwin;
+ u_int mss;
dctcp_data = ccv->cc_data;
- win = CCV(ccv, snd_cwnd);
+ cwin = CCV(ccv, snd_cwnd);
mss = CCV(ccv, t_maxseg);
switch (type) {
@@ -241,16 +242,16 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
CCV(ccv, snd_ssthresh) = mss *
- max(win / 2 / mss, 2);
+ max(cwin / 2 / mss, 2);
dctcp_data->num_cong_events++;
} else {
/* cwnd has already updated as congestion
* recovery. Reverse cwnd value using
* snd_cwnd_prev and recalculate snd_ssthresh
*/
- win = CCV(ccv, snd_cwnd_prev);
+ cwin = CCV(ccv, snd_cwnd_prev);
CCV(ccv, snd_ssthresh) =
- max(win / 2 / mss, 2) * mss;
+ max(cwin / 2 / mss, 2) * mss;
}
ENTER_RECOVERY(CCV(ccv, t_flags));
}
@@ -260,18 +261,18 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
* Save current snd_cwnd when the host encounters both
* congestion recovery and fast recovery.
*/
- CCV(ccv, snd_cwnd_prev) = win;
+ CCV(ccv, snd_cwnd_prev) = cwin;
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
if (V_dctcp_slowstart &&
dctcp_data->num_cong_events++ == 0) {
CCV(ccv, snd_ssthresh) =
- mss * max(win / 2 / mss, 2);
+ mss * max(cwin / 2 / mss, 2);
dctcp_data->alpha = MAX_ALPHA_VALUE;
dctcp_data->bytes_ecn = 0;
dctcp_data->bytes_total = 0;
dctcp_data->save_sndnxt = CCV(ccv, snd_nxt);
} else
- CCV(ccv, snd_ssthresh) = max((win - ((win *
+ CCV(ccv, snd_ssthresh) = max((cwin - ((cwin *
dctcp_data->alpha) >> 11)) / mss, 2) * mss;
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
@@ -284,6 +285,8 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type)
dctcp_update_alpha(ccv);
dctcp_data->save_sndnxt += CCV(ccv, t_maxseg);
dctcp_data->num_cong_events++;
+ CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2);
+ CCV(ccv, snd_cwnd) = mss;
}
break;
}
diff --git a/sys/netinet/cc/cc_htcp.c b/sys/netinet/cc/cc_htcp.c
index 92820f56de8c..8842648435c0 100644
--- a/sys/netinet/cc/cc_htcp.c
+++ b/sys/netinet/cc/cc_htcp.c
@@ -271,8 +271,12 @@ static void
htcp_cong_signal(struct cc_var *ccv, uint32_t type)
{
struct htcp *htcp_data;
+ uint32_t cwin;
+ u_int mss;
htcp_data = ccv->cc_data;
+ cwin = CCV(ccv, snd_cwnd);
+ mss = CCV(ccv, t_maxseg);
switch (type) {
case CC_NDUPACK:
@@ -287,8 +291,9 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type)
(htcp_data->maxrtt - htcp_data->minrtt) *
95) / 100;
htcp_ssthresh_update(ccv);
+ CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
htcp_data->t_last_cong = ticks;
- htcp_data->prev_cwnd = CCV(ccv, snd_cwnd);
+ htcp_data->prev_cwnd = cwin;
}
ENTER_RECOVERY(CCV(ccv, t_flags));
}
@@ -305,7 +310,7 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type)
htcp_ssthresh_update(ccv);
CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh);
htcp_data->t_last_cong = ticks;
- htcp_data->prev_cwnd = CCV(ccv, snd_cwnd);
+ htcp_data->prev_cwnd = cwin;
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
}
break;
@@ -320,6 +325,8 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type)
*/
if (CCV(ccv, t_rxtshift) >= 2)
htcp_data->t_last_cong = ticks;
+ CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2);
+ CCV(ccv, snd_cwnd) = mss;
break;
}
}
diff --git a/sys/netinet/cc/cc_newreno.c b/sys/netinet/cc/cc_newreno.c
index b2c72fe9fcb1..3aa16019657d 100644
--- a/sys/netinet/cc/cc_newreno.c
+++ b/sys/netinet/cc/cc_newreno.c
@@ -182,30 +182,39 @@ newreno_after_idle(struct cc_var *ccv)
static void
newreno_cong_signal(struct cc_var *ccv, uint32_t type)
{
- u_int win;
+ uint32_t cwin;
+ u_int mss;
+
+ cwin = CCV(ccv, snd_cwnd);
+ mss = CCV(ccv, t_maxseg);
/* Catch algos which mistakenly leak private signal types. */
KASSERT((type & CC_SIGPRIVMASK) == 0,
("%s: congestion signal type 0x%08x is private\n", __func__, type));
- win = max(CCV(ccv, snd_cwnd) / 2 / CCV(ccv, t_maxseg), 2) *
- CCV(ccv, t_maxseg);
+ cwin = max(2*mss, cwin/2);
switch (type) {
case CC_NDUPACK:
if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) {
- if (!IN_CONGRECOVERY(CCV(ccv, t_flags)))
- CCV(ccv, snd_ssthresh) = win;
+ if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
+ CCV(ccv, snd_ssthresh) = cwin;
+ CCV(ccv, snd_cwnd) = cwin;
+ }
ENTER_RECOVERY(CCV(ccv, t_flags));
}
break;
case CC_ECN:
if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) {
- CCV(ccv, snd_ssthresh) = win;
- CCV(ccv, snd_cwnd) = win;
+ CCV(ccv, snd_ssthresh) = cwin;
+ CCV(ccv, snd_cwnd) = cwin;
ENTER_CONGRECOVERY(CCV(ccv, t_flags));
}
break;
+ case CC_RTO:
+ CCV(ccv, snd_ssthresh) = cwin;
+ CCV(ccv, snd_cwnd) = mss;
+ break;
}
}
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 04fa7256b002..352aa375c770 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -350,7 +350,8 @@ again:
have_ia_ref = 1;
ifp = ia->ia_ifp;
ip->ip_ttl = 1;
- isbroadcast = in_ifaddr_broadcast(dst->sin_addr, ia);
+ isbroadcast = ifp->if_flags & IFF_BROADCAST ?
+ in_ifaddr_broadcast(dst->sin_addr, ia) : 0;
} else if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
imo != NULL && imo->imo_multicast_ifp != NULL) {
/*
@@ -403,8 +404,10 @@ again:
gw = (struct sockaddr_in *)rte->rt_gateway;
if (rte->rt_flags & RTF_HOST)
isbroadcast = (rte->rt_flags & RTF_BROADCAST);
- else
+ else if (ifp->if_flags & IFF_BROADCAST)
isbroadcast = in_ifaddr_broadcast(gw->sin_addr, ia);
+ else
+ isbroadcast = 0;
}
/*
diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c
index 9276a20990c6..6c0f6e171508 100644
--- a/sys/netinet/sctp_bsd_addr.c
+++ b/sys/netinet/sctp_bsd_addr.c
@@ -140,7 +140,6 @@ sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa)
ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE;
}
}
-
#endif /* INET6 */
@@ -201,10 +200,8 @@ sctp_init_ifns_for_vrf(int vrfid)
struct ifaddr *ifa;
struct sctp_ifa *sctp_ifa;
uint32_t ifa_flags;
-
#ifdef INET6
struct in6_ifaddr *ifa6;
-
#endif
IFNET_RLOCK();
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 2749a0849933..6db73812ccb2 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -1943,7 +1943,6 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t * len)
struct sctp_paramhdr *parmh;
struct mbuf *mret;
uint16_t plen;
-
#endif
switch (ifa->address.sa.sa_family) {
@@ -2139,10 +2138,8 @@ skip_count:
cnt++;
total_count++;
if (cnt >= 2) {
- /*
- * two from each
- * address
- */
+ /* two from each
+ * address */
break;
}
if (total_count > SCTP_ADDRESS_LIMIT) {
@@ -2784,7 +2781,6 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
{
struct sctp_ifa *ifa, *sifa;
int num_eligible_addr = 0;
-
#ifdef INET6
struct sockaddr_in6 sin6, lsa6;
@@ -2829,10 +2825,8 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn,
if (fam == AF_INET6 &&
IN6_IS_ADDR_LINKLOCAL(&sifa->address.sin6.sin6_addr) &&
IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) {
- /*
- * link-local <-> link-local must belong to the same
- * scope.
- */
+ /* link-local <-> link-local must belong to the same
+ * scope. */
memcpy(&lsa6, &sifa->address.sin6, sizeof(struct sockaddr_in6));
(void)sa6_recoverscope(&lsa6);
if (sin6.sin6_scope_id != lsa6.sin6_scope_id) {
@@ -2966,10 +2960,8 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
struct sctp_ifa *sctp_ifa, *sifa;
uint32_t ifn_index;
struct sctp_vrf *vrf;
-
#ifdef INET
int retried = 0;
-
#endif
/*-
@@ -3315,14 +3307,11 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
struct sctp_ifa *answer;
uint8_t dest_is_priv, dest_is_loop;
sa_family_t fam;
-
#ifdef INET
struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst;
-
#endif
#ifdef INET6
struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ro->ro_dst;
-
#endif
/**
@@ -3570,14 +3559,11 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
struct cmsghdr cmh;
int tlen, at;
struct sctp_initmsg initmsg;
-
#ifdef INET
struct sockaddr_in sin;
-
#endif
#ifdef INET6
struct sockaddr_in6 sin6;
-
#endif
tlen = SCTP_BUF_LEN(control);
@@ -3618,10 +3604,8 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
if (stcb->asoc.streamoutcnt < stcb->asoc.pre_open_streams) {
struct sctp_stream_out *tmp_str;
unsigned int i;
-
#if defined(SCTP_DETAILED_STR_STATS)
int j;
-
#endif
/* Default is NOT correct */
@@ -3744,14 +3728,11 @@ sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
int tlen, at;
struct sctp_tcb *stcb;
struct sockaddr *addr;
-
#ifdef INET
struct sockaddr_in sin;
-
#endif
#ifdef INET6
struct sockaddr_in6 sin6;
-
#endif
tlen = SCTP_BUF_LEN(control);
@@ -3970,7 +3951,6 @@ sctp_handle_no_route(struct sctp_tcb *stcb,
}
}
}
-
#endif
static int
@@ -4016,22 +3996,17 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
struct sctphdr *sctphdr;
int packet_length;
int ret;
-
#if defined(INET) || defined(INET6)
uint32_t vrf_id;
-
#endif
#if defined(INET) || defined(INET6)
struct mbuf *o_pak;
sctp_route_t *ro = NULL;
struct udphdr *udp = NULL;
-
#endif
uint8_t tos_value;
-
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
struct socket *so = NULL;
-
#endif
if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) {
@@ -4289,10 +4264,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
/* free tempy routes */
RO_RTFREE(ro);
} else {
- /*
- * PMTU check versus smallest asoc MTU goes
- * here
- */
+ /* PMTU check versus smallest asoc MTU goes
+ * here */
if ((ro->ro_rt != NULL) &&
(net->ro._s_addr)) {
uint32_t mtu;
@@ -4567,10 +4540,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT3, (struct sockaddr *)sin6);
if (net) {
sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
- /*
- * preserve the port and scope for link
- * local send
- */
+ /* preserve the port and scope for link
+ * local send */
prev_scope = sin6->sin6_scope_id;
prev_port = sin6->sin6_port;
}
@@ -4636,10 +4607,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
/* Now if we had a temp route free it */
RO_RTFREE(ro);
} else {
- /*
- * PMTU check versus smallest asoc MTU goes
- * here
- */
+ /* PMTU check versus smallest asoc MTU goes
+ * here */
if (ro->ro_rt == NULL) {
/* Route was freed */
if (net->ro._s_addr &&
@@ -4969,11 +4938,11 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
* being equal to the beginning of the params i.e. (iphlen +
* sizeof(struct sctp_init_msg) parse through the parameters to the
* end of the mbuf verifying that all parameters are known.
- *
+ *
* For unknown parameters build and return a mbuf with
* UNRECOGNIZED_PARAMETER errors. If the flags indicate to stop
* processing this chunk stop, and set *abort_processing to 1.
- *
+ *
* By having param_offset be pre-set to where parameters begin it is
* hoped that this routine may be reused in the future by new
* features.
@@ -5260,7 +5229,6 @@ invalid_size:
*abort_processing = 1;
if ((op_err == NULL) && phdr) {
int l_len;
-
#ifdef INET6
l_len = SCTP_MIN_OVERHEAD;
#else
@@ -5318,14 +5286,11 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
uint8_t fnd;
struct sctp_nets *net;
int check_src;
-
#ifdef INET
struct sockaddr_in sin4, *sa4;
-
#endif
#ifdef INET6
struct sockaddr_in6 sin6, *sa6;
-
#endif
#ifdef INET
@@ -5509,18 +5474,15 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_paramhdr *ph;
union sctp_sockstore *over_addr;
struct sctp_scoping scp;
-
#ifdef INET
struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
struct sockaddr_in *src4 = (struct sockaddr_in *)src;
struct sockaddr_in *sin;
-
#endif
#ifdef INET6
struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
struct sockaddr_in6 *src6 = (struct sockaddr_in6 *)src;
struct sockaddr_in6 *sin6;
-
#endif
struct sockaddr *to;
struct sctp_state_cookie stc;
@@ -5544,10 +5506,10 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/*
* new addresses, out of here in non-cookie-wait
* states
- *
- * Send an ABORT, without the new address error cause.
- * This looks no different than if no listener was
- * present.
+ *
+ * Send an ABORT, without the new address error
+ * cause. This looks no different than if no
+ * listener was present.
*/
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
"Address added");
@@ -5560,9 +5522,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/*
* change of remote encapsulation port, out of here
* in non-cookie-wait states
- *
- * Send an ABORT, without an specific error cause. This
- * looks no different than if no listener was
+ *
+ * Send an ABORT, without an specific error cause.
+ * This looks no different than if no listener was
* present.
*/
op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
@@ -5716,10 +5678,8 @@ do_a_abort:
* show up in our scoped count.
*/
cnt_inits_to = 1;
- /*
- * pull out the scope_id from
- * incoming pkt
- */
+ /* pull out the scope_id from
+ * incoming pkt */
} else if (IN6_IS_ADDR_SITELOCAL(&src6->sin6_addr) ||
IN6_IS_ADDR_SITELOCAL(&dst6->sin6_addr)) {
/*
@@ -5744,7 +5704,6 @@ do_a_abort:
#ifdef INET6
struct sctp_nets *lnet;
-
#endif
stc.loopback_scope = asoc->scope.loopback_scope;
@@ -6206,9 +6165,9 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
if (freed_spc >= dataout) {
return;
}
- } /* if chunk was present */
- } /* if of sufficient priority */
- } /* if chunk has enabled */
+ } /* if chunk was present */
+ } /* if of sufficient priority */
+ } /* if chunk has enabled */
} /* tailqforeach */
TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) {
@@ -6229,11 +6188,11 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
if (freed_spc >= dataout) {
return;
}
- } /* end if chk->data */
- } /* end if right class */
- } /* end if chk pr-sctp */
+ } /* end if chk->data */
+ } /* end if right class */
+ } /* end if chk pr-sctp */
} /* tailqforeachsafe (chk) */
- } /* if enabled in asoc */
+ } /* if enabled in asoc */
}
int
@@ -6476,10 +6435,8 @@ error_out:
/* get the prepend space */
SCTP_BUF_RESV_UF(outchain, (SCTP_FIRST_MBUF_RESV + 4));
} else {
- /*
- * We really should not get a NULL
- * in endofchain
- */
+ /* We really should not get a NULL
+ * in endofchain */
/* find end */
m = outchain;
while (m) {
@@ -6491,10 +6448,8 @@ error_out:
}
/* sanity */
if (*endofchain == NULL) {
- /*
- * huh, TSNH XXX maybe we
- * should panic
- */
+ /* huh, TSNH XXX maybe we
+ * should panic */
sctp_m_freem(outchain);
goto new_mbuf;
}
@@ -6693,17 +6648,13 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) {
goto abort_anyway;
}
- /*
- * there is nothing queued to send, so I'm
- * done...
- */
+ /* there is nothing queued to send, so I'm
+ * done... */
if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) &&
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) &&
(SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) {
- /*
- * only send SHUTDOWN the first time
- * through
- */
+ /* only send SHUTDOWN the first time
+ * through */
if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
}
@@ -7334,10 +7285,8 @@ re_look:
SCTP_TCB_SEND_LOCK(stcb);
send_lock_up = 1;
if (sp->msg_is_complete) {
- /*
- * the sender finished the
- * msg
- */
+ /* the sender finished the
+ * msg */
goto re_look;
}
}
@@ -7955,9 +7904,9 @@ nothing_to_send:
* (when CMT is off) then it calls
* sctp_fill_outqueue for the net. This gets data on
* the send queue for that network.
- *
- * In sctp_fill_outqueue TSN's are assigned and data is
- * copied out of the stream buffers. Note mostly
+ *
+ * In sctp_fill_outqueue TSN's are assigned and data
+ * is copied out of the stream buffers. Note mostly
* copy by reference (we hope).
*/
net->window_probe = 0;
@@ -8226,10 +8175,8 @@ again_one_more_time:
net->port, NULL,
0, 0,
so_locked))) {
- /*
- * error, we could not
- * output
- */
+ /* error, we could not
+ * output */
SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (from_where == 0) {
SCTP_STAT_INCR(sctps_lowlevelerrusr);
@@ -8302,16 +8249,12 @@ again_one_more_time:
* to where the sack is going..
*/
if (chk->whoTo == net) {
- /*
- * Don't transmit it to where its
- * going (current net)
- */
+ /* Don't transmit it to where its
+ * going (current net) */
continue;
} else if (sack_goes_to == net) {
- /*
- * But do transmit it to this
- * address
- */
+ /* But do transmit it to this
+ * address */
goto skip_net_check;
}
}
@@ -8504,10 +8447,8 @@ again_one_more_time:
net->port, NULL,
0, 0,
so_locked))) {
- /*
- * error, we could not
- * output
- */
+ /* error, we could not
+ * output */
SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error);
if (from_where == 0) {
SCTP_STAT_INCR(sctps_lowlevelerrusr);
@@ -8704,17 +8645,13 @@ again_one_more_time:
override_ok = 0;
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
} else if (override_ok) {
- /*
- * use this data's
- * keyid
- */
+ /* use this data's
+ * keyid */
auth_keyid = chk->auth_keyid;
override_ok = 0;
} else if (auth_keyid != chk->auth_keyid) {
- /*
- * different keyid,
- * so done bundling
- */
+ /* different keyid,
+ * so done bundling */
break;
}
}
@@ -8793,8 +8730,7 @@ again_one_more_time:
break;
}
} /* for (chunk gather loop for this net) */
- } /* if asoc.state OPEN */
-no_data_fill:
+} /* if asoc.state OPEN */ no_data_fill:
/* Is there something to send for this destination? */
if (outchain) {
/* We may need to start a control timer or two */
@@ -9734,10 +9670,8 @@ one_chunk_around:
auth_keyid = fwd->auth_keyid;
override_ok = 0;
} else if (fwd->auth_keyid != auth_keyid) {
- /*
- * different keyid,
- * so done bundling
- */
+ /* different keyid,
+ * so done bundling */
break;
}
}
@@ -10113,11 +10047,9 @@ do_it_again:
if (asoc->max_burst > 0) {
if (SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst)) {
if ((net->flight_size + (asoc->max_burst * net->mtu)) < net->cwnd) {
- /*
- * JRS - Use the congestion
+ /* JRS - Use the congestion
* control given in the
- * congestion control module
- */
+ * congestion control module */
asoc->cc_functions.sctp_cwnd_update_after_output(stcb, net, asoc->max_burst);
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_MAXBURST_ENABLE) {
sctp_log_maxburst(stcb, net, 0, asoc->max_burst, SCTP_MAX_BURST_APPLIED);
@@ -10127,10 +10059,8 @@ do_it_again:
net->fast_retran_ip = 0;
} else {
if (net->flight_size == 0) {
- /*
- * Should be decaying the
- * cwnd here
- */
+ /* Should be decaying the
+ * cwnd here */
;
}
}
@@ -11017,23 +10947,18 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
struct mbuf *mout;
struct sctphdr *shout;
struct sctp_chunkhdr *ch;
-
#if defined(INET) || defined(INET6)
struct udphdr *udp;
int ret;
-
#endif
int len, cause_len, padding_len;
-
#ifdef INET
struct sockaddr_in *src_sin, *dst_sin;
struct ip *ip;
-
#endif
#ifdef INET6
struct sockaddr_in6 *src_sin6, *dst_sin6;
struct ip6_hdr *ip6;
-
#endif
/* Compute the length of the cause and add final padding. */
@@ -11622,10 +11547,8 @@ sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, u
asoc = &stcb->asoc;
TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
if ((chk->rec.chunk_id.id == SCTP_ECN_CWR) && (net == chk->whoTo)) {
- /*
- * found a previous CWR queued to same destination
- * update it if needed
- */
+ /* found a previous CWR queued to same destination
+ * update it if needed */
uint32_t ctsn;
cwr = mtod(chk->data, struct sctp_cwr_chunk *);
@@ -12169,10 +12092,8 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
struct sctp_stream_out *oldstream;
struct sctp_stream_queue_pending *sp, *nsp;
int i;
-
#if defined(SCTP_DETAILED_STR_STATS)
int j;
-
#endif
oldstream = stcb->asoc.strmout;
@@ -12204,10 +12125,8 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.strmout[i].state = oldstream[i].state;
/* FIX ME FIX ME */
- /*
- * This should be a SS_COPY operation FIX ME STREAM
- * SCHEDULER EXPERT
- */
+ /* This should be a SS_COPY operation FIX ME STREAM
+ * SCHEDULER EXPERT */
stcb->asoc.ss_functions.sctp_ss_init_stream(stcb, &stcb->asoc.strmout[i], &oldstream[i]);
/* now anything on those queues? */
TAILQ_FOREACH_SAFE(sp, &oldstream[i].outqueue, next, nsp) {
@@ -12451,10 +12370,8 @@ sctp_sosend(struct socket *so,
int error, use_sndinfo = 0;
struct sctp_sndrcvinfo sndrcvninfo;
struct sockaddr *addr_to_use;
-
#if defined(INET) && defined(INET6)
struct sockaddr_in sin;
-
#endif
if (control) {
@@ -12739,10 +12656,8 @@ sctp_lower_sosend(struct socket *so,
}
if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) {
stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED;
- /*
- * Set the connected flag so we can queue
- * data
- */
+ /* Set the connected flag so we can queue
+ * data */
soisconnecting(so);
}
hold_tcblock = 1;
@@ -12752,10 +12667,8 @@ sctp_lower_sosend(struct socket *so,
} else {
SCTP_PRINTF("Huh-3? create lock should have been on??\n");
}
- /*
- * Turn on queue only flag to prevent data from
- * being sent
- */
+ /* Turn on queue only flag to prevent data from
+ * being sent */
queue_only = 1;
asoc = &stcb->asoc;
SCTP_SET_STATE(asoc, SCTP_STATE_COOKIE_WAIT);
@@ -13248,10 +13161,8 @@ skip_preblock:
}
/* PR-SCTP? */
if ((asoc->prsctp_supported) && (asoc->sent_queue_cnt_removeable > 0)) {
- /*
- * This is ugly but we must assure locking
- * order
- */
+ /* This is ugly but we must assure locking
+ * order */
if (hold_tcblock == 0) {
SCTP_TCB_LOCK(stcb);
hold_tcblock = 1;
@@ -13528,10 +13439,8 @@ dataless_eof:
msg);
sctp_abort_an_association(stcb->sctp_ep, stcb,
op_err, SCTP_SO_LOCKED);
- /*
- * now relock the stcb so everything
- * is sane
- */
+ /* now relock the stcb so everything
+ * is sane */
hold_tcblock = 0;
stcb = NULL;
goto out;
@@ -13605,10 +13514,8 @@ skip_out_eof:
if ((queue_only == 0) && (nagle_applies == 0) && (stcb->asoc.peers_rwnd && un_sent)) {
/* we can attempt to send too. */
if (hold_tcblock == 0) {
- /*
- * If there is activity recv'ing sacks no need to
- * send
- */
+ /* If there is activity recv'ing sacks no need to
+ * send */
if (SCTP_TCB_TRYLOCK(stcb)) {
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_LOCKED);
hold_tcblock = 1;
@@ -13776,10 +13683,9 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro)
SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&gw6);
SCTPDBG(SCTP_DEBUG_OUTPUT2, "installed router is ");
SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, ro->ro_rt->rt_gateway);
- if (sctp_cmpaddr((struct sockaddr *)&gw6,
- ro->ro_rt->rt_gateway)) {
- SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is installed\n");
+ if (sctp_cmpaddr((struct sockaddr *)&gw6, ro->ro_rt->rt_gateway)) {
ND6_RUNLOCK();
+ SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is installed\n");
return (1);
}
}
@@ -13787,7 +13693,6 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro)
SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is not installed\n");
return (0);
}
-
#endif
int
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index ed61e64a0ede..792818a9231d 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -438,9 +438,15 @@ cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type)
tp->t_dupacks = 0;
tp->t_bytes_acked = 0;
EXIT_RECOVERY(tp->t_flags);
- tp->snd_ssthresh = max(2, min(tp->snd_wnd, tp->snd_cwnd) / 2 /
- maxseg) * maxseg;
- tp->snd_cwnd = maxseg;
+ if (CC_ALGO(tp)->cong_signal == NULL) {
+ /*
+ * RFC5681 Section 3.1
+ * ssthresh = max (FlightSize / 2, 2*SMSS) eq (4)
+ */
+ tp->snd_ssthresh =
+ max((tp->snd_max - tp->snd_una) / 2, 2 * maxseg);
+ tp->snd_cwnd = maxseg;
+ }
break;
case CC_RTO_ERR:
TCPSTAT_INC(tcps_sndrexmitbad);
@@ -2613,6 +2619,15 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (awnd < tp->snd_ssthresh) {
tp->snd_cwnd += maxseg;
+ /*
+ * RFC5681 Section 3.2 talks about cwnd
+ * inflation on additional dupacks and
+ * deflation on recovering from loss.
+ *
+ * We keep cwnd into check so that
+ * we don't have to 'deflate' it when we
+ * get out of recovery.
+ */
if (tp->snd_cwnd > tp->snd_ssthresh)
tp->snd_cwnd = tp->snd_ssthresh;
}
@@ -2652,19 +2667,22 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so,
TCPSTAT_INC(
tcps_sack_recovery_episode);
tp->sack_newdata = tp->snd_nxt;
- tp->snd_cwnd = maxseg;
+ if (CC_ALGO(tp)->cong_signal == NULL)
+ tp->snd_cwnd = maxseg;
(void) tp->t_fb->tfb_tcp_output(tp);
goto drop;
}
tp->snd_nxt = th->th_ack;
- tp->snd_cwnd = maxseg;
+ if (CC_ALGO(tp)->cong_signal == NULL)
+ tp->snd_cwnd = maxseg;
(void) tp->t_fb->tfb_tcp_output(tp);
KASSERT(tp->snd_limited <= 2,
("%s: tp->snd_limited too big",
__func__));
- tp->snd_cwnd = tp->snd_ssthresh +
- maxseg *
- (tp->t_dupacks - tp->snd_limited);
+ if (CC_ALGO(tp)->cong_signal == NULL)
+ tp->snd_cwnd = tp->snd_ssthresh +
+ maxseg *
+ (tp->t_dupacks - tp->snd_limited);
if (SEQ_GT(onxt, tp->snd_nxt))
tp->snd_nxt = onxt;
goto drop;
diff --git a/sys/netinet/tcp_stacks/fastpath.c b/sys/netinet/tcp_stacks/fastpath.c
index a31a28e70f69..2d7db04fbc1e 100644
--- a/sys/netinet/tcp_stacks/fastpath.c
+++ b/sys/netinet/tcp_stacks/fastpath.c
@@ -1119,6 +1119,15 @@ tcp_do_slowpath(struct mbuf *m, struct tcphdr *th, struct socket *so,
if (awnd < tp->snd_ssthresh) {
tp->snd_cwnd += tp->t_maxseg;
+ /*
+ * RFC5681 Section 3.2 talks about cwnd
+ * inflation on additional dupacks and
+ * deflation on recovering from loss.
+ *
+ * We keep cwnd into check so that
+ * we don't have to 'deflate' it when we
+ * get out of recovery.
+ */
if (tp->snd_cwnd > tp->snd_ssthresh)
tp->snd_cwnd = tp->snd_ssthresh;
}
@@ -1158,19 +1167,22 @@ tcp_do_slowpath(struct mbuf *m, struct tcphdr *th, struct socket *so,
TCPSTAT_INC(
tcps_sack_recovery_episode);
tp->sack_newdata = tp->snd_nxt;
- tp->snd_cwnd = tp->t_maxseg;
+ if (CC_ALGO(tp)->cong_signal == NULL)
+ tp->snd_cwnd = tp->t_maxseg;
(void) tp->t_fb->tfb_tcp_output(tp);
goto drop;
}
tp->snd_nxt = th->th_ack;
- tp->snd_cwnd = tp->t_maxseg;
+ if (CC_ALGO(tp)->cong_signal == NULL)
+ tp->snd_cwnd = tp->t_maxseg;
(void) tp->t_fb->tfb_tcp_output(tp);
KASSERT(tp->snd_limited <= 2,
("%s: tp->snd_limited too big",
__func__));
- tp->snd_cwnd = tp->snd_ssthresh +
- tp->t_maxseg *
- (tp->t_dupacks - tp->snd_limited);
+ if (CC_ALGO(tp)->cong_signal == NULL)
+ tp->snd_cwnd = tp->snd_ssthresh +
+ tp->t_maxseg *
+ (tp->t_dupacks - tp->snd_limited);
if (SEQ_GT(onxt, tp->snd_nxt))
tp->snd_nxt = onxt;
goto drop;
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index 33e5df782d69..6dc02ef85930 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -918,10 +918,6 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m)
tp->t_keepcnt = sototcpcb(lso)->t_keepcnt;
tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp));
- if ((so->so_options & SO_ACCEPTFILTER) == 0) {
- soisconnected(so);
- }
-
TCPSTAT_INC(tcps_accepts);
return (so);
diff --git a/sys/powerpc/booke/booke_machdep.c b/sys/powerpc/booke/booke_machdep.c
index 8d04f7ee1133..cbd7fc403cfb 100644
--- a/sys/powerpc/booke/booke_machdep.c
+++ b/sys/powerpc/booke/booke_machdep.c
@@ -242,6 +242,11 @@ ivor_setup(void)
case FSL_E500mc:
case FSL_E5500:
SET_TRAP(SPR_IVOR7, int_fpu);
+ break;
+ case FSL_E500v1:
+ case FSL_E500v2:
+ SET_TRAP(SPR_IVOR32, int_vec);
+ break;
}
}
diff --git a/sys/powerpc/booke/spe.c b/sys/powerpc/booke/spe.c
new file mode 100644
index 000000000000..45eb7798b2c4
--- /dev/null
+++ b/sys/powerpc/booke/spe.c
@@ -0,0 +1,183 @@
+/*-
+ * Copyright (C) 1996 Wolfgang Solfrank.
+ * Copyright (C) 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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.
+ *
+ * $NetBSD: fpu.c,v 1.5 2001/07/22 11:29:46 wiz Exp $
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/limits.h>
+
+#include <machine/altivec.h>
+#include <machine/pcb.h>
+#include <machine/psl.h>
+
+static void
+save_vec_int(struct thread *td)
+{
+ int msr;
+ struct pcb *pcb;
+
+ pcb = td->td_pcb;
+
+ /*
+ * Temporarily re-enable the vector unit during the save
+ */
+ msr = mfmsr();
+ mtmsr(msr | PSL_VEC);
+ isync();
+
+ /*
+ * Save the vector registers and SPEFSCR to the PCB
+ */
+#define EVSTDW(n) __asm ("evstdw %1,0(%0)" \
+ :: "b"(pcb->pcb_vec.vr[n]), "n"(n));
+ EVSTDW(0); EVSTDW(1); EVSTDW(2); EVSTDW(3);
+ EVSTDW(4); EVSTDW(5); EVSTDW(6); EVSTDW(7);
+ EVSTDW(8); EVSTDW(9); EVSTDW(10); EVSTDW(11);
+ EVSTDW(12); EVSTDW(13); EVSTDW(14); EVSTDW(15);
+ EVSTDW(16); EVSTDW(17); EVSTDW(18); EVSTDW(19);
+ EVSTDW(20); EVSTDW(21); EVSTDW(22); EVSTDW(23);
+ EVSTDW(24); EVSTDW(25); EVSTDW(26); EVSTDW(27);
+ EVSTDW(28); EVSTDW(29); EVSTDW(30); EVSTDW(31);
+#undef EVSTDW
+
+ __asm ( "evxor 0,0,0\n"
+ "evaddumiaaw 0,0\n"
+ "evstdd 0,0(%0)" :: "b"(&pcb->pcb_vec.vr[17][0]));
+ pcb->pcb_vec.vscr = mfspr(SPR_SPEFSCR);
+
+ /*
+ * Disable vector unit again
+ */
+ isync();
+ mtmsr(msr);
+
+}
+
+void
+enable_vec(struct thread *td)
+{
+ int msr;
+ struct pcb *pcb;
+ struct trapframe *tf;
+
+ pcb = td->td_pcb;
+ tf = trapframe(td);
+
+ /*
+ * Save the thread's SPE CPU number, and set the CPU's current
+ * vector thread
+ */
+ td->td_pcb->pcb_veccpu = PCPU_GET(cpuid);
+ PCPU_SET(vecthread, td);
+
+ /*
+ * Enable the vector unit for when the thread returns from the
+ * exception. If this is the first time the unit has been used by
+ * the thread, initialise the vector registers and VSCR to 0, and
+ * set the flag to indicate that the vector unit is in use.
+ */
+ tf->srr1 |= PSL_VEC;
+ if (!(pcb->pcb_flags & PCB_VEC)) {
+ memset(&pcb->pcb_vec, 0, sizeof pcb->pcb_vec);
+ pcb->pcb_flags |= PCB_VEC;
+ }
+
+ /*
+ * Temporarily enable the vector unit so the registers
+ * can be restored.
+ */
+ msr = mfmsr();
+ mtmsr(msr | PSL_VEC);
+ isync();
+
+ /* Restore SPEFSCR and ACC. Use %r0 as the scratch for ACC. */
+ mtspr(SPR_SPEFSCR, pcb->pcb_vec.vscr);
+ __asm __volatile("evldd 0, 0(%0); evmra 0,0\n"
+ :: "b"(&pcb->pcb_vec.vr[17][0]));
+
+ /*
+ * The lower half of each register will be restored on trap return. Use
+ * %r0 as a scratch register, and restore it last.
+ */
+#define EVLDW(n) __asm __volatile("evldw 0, 0(%0); evmergehilo "#n",0,"#n \
+ :: "b"(&pcb->pcb_vec.vr[n]));
+ EVLDW(1); EVLDW(2); EVLDW(3); EVLDW(4);
+ EVLDW(5); EVLDW(6); EVLDW(7); EVLDW(8);
+ EVLDW(9); EVLDW(10); EVLDW(11); EVLDW(12);
+ EVLDW(13); EVLDW(14); EVLDW(15); EVLDW(16);
+ EVLDW(17); EVLDW(18); EVLDW(19); EVLDW(20);
+ EVLDW(21); EVLDW(22); EVLDW(23); EVLDW(24);
+ EVLDW(25); EVLDW(26); EVLDW(27); EVLDW(28);
+ EVLDW(29); EVLDW(30); EVLDW(31); EVLDW(0);
+#undef EVLDW
+
+ isync();
+ mtmsr(msr);
+}
+
+void
+save_vec(struct thread *td)
+{
+ struct pcb *pcb;
+
+ pcb = td->td_pcb;
+
+ save_vec_int(td);
+
+ /*
+ * Clear the current vec thread and pcb's CPU id
+ * XXX should this be left clear to allow lazy save/restore ?
+ */
+ pcb->pcb_veccpu = INT_MAX;
+ PCPU_SET(vecthread, NULL);
+}
+
+/*
+ * Save SPE state without dropping ownership. This will only save state if
+ * the current vector-thread is `td'.
+ */
+void
+save_vec_nodrop(struct thread *td)
+{
+ struct thread *vtd;
+
+ vtd = PCPU_GET(vecthread);
+ if (td != vtd) {
+ return;
+ }
+
+ save_vec_int(td);
+}
diff --git a/sys/powerpc/conf/MPC85XX b/sys/powerpc/conf/MPC85XX
index 0e60ceb24e55..b26340fe5397 100644
--- a/sys/powerpc/conf/MPC85XX
+++ b/sys/powerpc/conf/MPC85XX
@@ -58,6 +58,10 @@ options SYSVSEM
options SYSVSHM
options WITNESS
options WITNESS_SKIPSPIN
+options COMPAT_FREEBSD10
+options HWPMC_HOOKS
+options KDTRACE_HOOKS # Kernel DTrace hooks
+options DDB_CTF # Kernel ELF linker loads CTF data
device ata
device bpf
@@ -86,6 +90,7 @@ device scbus
device scc
device sec
device tsec
+device dpaa
device tun
device uart
options USB_DEBUG # enable debug msgs
@@ -98,3 +103,5 @@ device vlan
# P1022 DIU
device diu
device videomode
+device vt
+device fbd
diff --git a/sys/powerpc/conf/MPC85XXSPE b/sys/powerpc/conf/MPC85XXSPE
new file mode 100644
index 000000000000..15470d578bef
--- /dev/null
+++ b/sys/powerpc/conf/MPC85XXSPE
@@ -0,0 +1,107 @@
+#
+# Custom kernel for Freescale MPC85XX development boards like the CDS etc.
+#
+# $FreeBSD$
+#
+
+cpu BOOKE
+cpu BOOKE_E500
+ident MPC85XX
+
+machine powerpc powerpcspe
+
+include "dpaa/config.dpaa"
+makeoptions DEBUG="-Wa,-me500 -g"
+makeoptions WERROR="-Werror -Wno-format -Wno-redundant-decls"
+makeoptions NO_MODULES=yes
+
+options FPU_EMU
+
+options _KPOSIX_PRIORITY_SCHEDULING
+options ALT_BREAK_TO_DEBUGGER
+options BREAK_TO_DEBUGGER
+options BOOTP
+options BOOTP_NFSROOT
+#options BOOTP_NFSV3
+options CD9660
+options COMPAT_43
+options DDB
+#options DEADLKRES
+options DEVICE_POLLING
+#options DIAGNOSTIC
+options FDT
+#makeoptions FDT_DTS_FILE=mpc8555cds.dts
+options FFS
+options GDB
+options GEOM_PART_GPT
+options INET
+options INET6
+options TCP_HHOOK # hhook(9) framework for TCP
+options INVARIANTS
+options INVARIANT_SUPPORT
+options KDB
+options KTRACE
+options MD_ROOT
+options MPC85XX
+options MSDOSFS
+options NFS_ROOT
+options NFSCL
+options NFSLOCKD
+options PROCFS
+options PSEUDOFS
+options SCHED_ULE
+options CAPABILITIES
+options CAPABILITY_MODE
+options SMP
+options SYSVMSG
+options SYSVSEM
+options SYSVSHM
+options WITNESS
+options WITNESS_SKIPSPIN
+options COMPAT_FREEBSD10
+options HWPMC_HOOKS
+options KDTRACE_HOOKS # Kernel DTrace hooks
+options DDB_CTF # Kernel ELF linker loads CTF data
+
+device ata
+device bpf
+device cfi
+device crypto
+device cryptodev
+device da
+device ds1553
+device em
+device alc
+device ether
+device fxp
+device gpio
+device iic
+device iicbus
+#device isa
+device loop
+device md
+device miibus
+device pass
+device pci
+device quicc
+device random
+#device rl
+device scbus
+device scc
+device sec
+device tsec
+device dpaa
+device tun
+device uart
+options USB_DEBUG # enable debug msgs
+#device uhci
+device ehci
+device umass
+device usb
+device vlan
+
+# P1022 DIU
+device diu
+device videomode
+device vt
+device fbd
diff --git a/sys/powerpc/include/cpu.h b/sys/powerpc/include/cpu.h
index fffb2b4267ae..86bd607c2f38 100644
--- a/sys/powerpc/include/cpu.h
+++ b/sys/powerpc/include/cpu.h
@@ -56,6 +56,9 @@ extern int cpu_features2;
#define PPC_FEATURE_HAS_FPU 0x08000000
#define PPC_FEATURE_HAS_MMU 0x04000000
#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
+#define PPC_FEATURE_HAS_SPE 0x00800000
+#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000
+#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000
#define PPC_FEATURE_BOOKE 0x00008000
#define PPC_FEATURE_SMT 0x00004000
#define PPC_FEATURE_ARCH_2_05 0x00001000
@@ -70,7 +73,8 @@ extern int cpu_features2;
#define PPC_FEATURE_BITMASK \
"\20" \
"\040PPC32\037PPC64\035ALTIVEC\034FPU\033MMU\031UNIFIEDCACHE" \
- "\020BOOKE\017SMT\015ARCH205\013DFP\011ARCH206\010VSX"
+ "\030SPE\027SPESFP\026DPESFP\020BOOKE\017SMT\015ARCH205\013DFP" \
+ "\011ARCH206\010VSX"
#define PPC_FEATURE2_BITMASK \
"\20" \
"\040ARCH207\037HTM\032VCRYPTO"
diff --git a/sys/powerpc/include/param.h b/sys/powerpc/include/param.h
index 453915cba4df..a74ccf212a8f 100644
--- a/sys/powerpc/include/param.h
+++ b/sys/powerpc/include/param.h
@@ -57,9 +57,13 @@
#ifdef __powerpc64__
#define MACHINE_ARCH "powerpc64"
#else
+#ifdef __SPE__
+#define MACHINE_ARCH "powerpcspe"
+#else
#define MACHINE_ARCH "powerpc"
#endif
#endif
+#endif
#define MID_MACHINE MID_POWERPC
#ifdef __powerpc64__
#ifndef MACHINE_ARCH32
diff --git a/sys/powerpc/include/spr.h b/sys/powerpc/include/spr.h
index 86dac97bc01c..bfd205fb2002 100644
--- a/sys/powerpc/include/spr.h
+++ b/sys/powerpc/include/spr.h
@@ -192,6 +192,7 @@
#define FSL_E5500 0x8024
#define FSL_E6500 0x8040
+#define SPR_SPEFSCR 0x200 /* ..8 Signal Processing Engine FSCR. */
#define SPR_IBAT0U 0x210 /* .68 Instruction BAT Reg 0 Upper */
#define SPR_IBAT0U 0x210 /* .6. Instruction BAT Reg 0 Upper */
#define SPR_IBAT0L 0x211 /* .6. Instruction BAT Reg 0 Lower */
diff --git a/sys/powerpc/include/trap.h b/sys/powerpc/include/trap.h
index 81c40c9bffaf..34cd98dabab9 100644
--- a/sys/powerpc/include/trap.h
+++ b/sys/powerpc/include/trap.h
@@ -112,6 +112,7 @@
/* Macros to extract register information */
#define EXC_ALI_RST(dsisr) ((dsisr >> 5) & 0x1f) /* source or target */
#define EXC_ALI_RA(dsisr) (dsisr & 0x1f)
+#define EXC_ALI_SPE_REG(instr) ((instr >> 21) & 0x1f)
/*
* SRR1 bits for program exception traps. These identify what caused
diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c
index 859ff4aece41..c9592e0567f1 100644
--- a/sys/powerpc/powerpc/cpu.c
+++ b/sys/powerpc/powerpc/cpu.c
@@ -180,9 +180,12 @@ static const struct cputab models[] = {
{ "Motorola PowerPC 8245", MPC8245, REVFMT_MAJMIN,
PPC_FEATURE_HAS_FPU, 0, cpu_6xx_setup },
{ "Freescale e500v1 core", FSL_E500v1, REVFMT_MAJMIN,
- PPC_FEATURE_BOOKE, 0, cpu_booke_setup },
+ PPC_FEATURE_BOOKE | PPC_FEATURE_HAS_SPE | PPC_FEATURE_HAS_EFP_SINGLE,
+ 0, cpu_booke_setup },
{ "Freescale e500v2 core", FSL_E500v2, REVFMT_MAJMIN,
- PPC_FEATURE_BOOKE, 0, cpu_booke_setup },
+ PPC_FEATURE_BOOKE | PPC_FEATURE_HAS_SPE |
+ PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE, 0,
+ cpu_booke_setup },
{ "Freescale e500mc core", FSL_E500mc, REVFMT_MAJMIN,
PPC_FEATURE_BOOKE | PPC_FEATURE_HAS_FPU, 0, cpu_booke_setup },
{ "Freescale e5500 core", FSL_E5500, REVFMT_MAJMIN,
diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c
index d1860513fe45..b3217628943a 100644
--- a/sys/powerpc/powerpc/trap.c
+++ b/sys/powerpc/powerpc/trap.c
@@ -750,9 +750,47 @@ static int
fix_unaligned(struct thread *td, struct trapframe *frame)
{
struct thread *fputhread;
+#ifdef __SPE__
+ uint32_t inst;
+#endif
int indicator, reg;
double *fpr;
+#ifdef __SPE__
+ indicator = (frame->cpu.booke.esr & (ESR_ST|ESR_SPE));
+ if (indicator & ESR_SPE) {
+ if (copyin((void *)frame->srr0, &inst, sizeof(inst)) != 0)
+ return (-1);
+ reg = EXC_ALI_SPE_REG(inst);
+ fpr = (double *)td->td_pcb->pcb_vec.vr[reg];
+ fputhread = PCPU_GET(vecthread);
+
+ /* Juggle the SPE to ensure that we've initialized
+ * the registers, and that their current state is in
+ * the PCB.
+ */
+ if (fputhread != td) {
+ if (fputhread)
+ save_vec(fputhread);
+ enable_vec(td);
+ }
+ save_vec(td);
+
+ if (!(indicator & ESR_ST)) {
+ if (copyin((void *)frame->dar, fpr,
+ sizeof(double)) != 0)
+ return (-1);
+ frame->fixreg[reg] = td->td_pcb->pcb_vec.vr[reg][1];
+ enable_vec(td);
+ } else {
+ td->td_pcb->pcb_vec.vr[reg][1] = frame->fixreg[reg];
+ if (copyout(fpr, (void *)frame->dar,
+ sizeof(double)) != 0)
+ return (-1);
+ }
+ return (0);
+ }
+#else
indicator = EXC_ALI_OPCODE_INDICATOR(frame->cpu.aim.dsisr);
switch (indicator) {
@@ -786,6 +824,7 @@ fix_unaligned(struct thread *td, struct trapframe *frame)
return (0);
break;
}
+#endif
return (-1);
}
diff --git a/sys/sys/_types.h b/sys/sys/_types.h
index ecc1c7e05e4c..8736651ba6f0 100644
--- a/sys/sys/_types.h
+++ b/sys/sys/_types.h
@@ -100,6 +100,11 @@ typedef __uint_least32_t __char32_t;
#define _CHAR32_T_DECLARED
#endif
+typedef struct {
+ long long __max_align1 __aligned(_Alignof(long long));
+ long double __max_align2 __aligned(_Alignof(long double));
+} __max_align_t;
+
typedef __uint32_t __dev_t; /* device number */
typedef __uint32_t __fixpt_t; /* fixed point number */
diff --git a/sys/sys/buf.h b/sys/sys/buf.h
index e5607b54e267..034671e794d1 100644
--- a/sys/sys/buf.h
+++ b/sys/sys/buf.h
@@ -68,6 +68,7 @@ extern struct bio_ops {
} bioops;
struct vm_object;
+struct vm_page;
typedef unsigned char b_xflags_t;
@@ -537,6 +538,12 @@ struct buf *trypbuf(int *);
void bwait(struct buf *, u_char, const char *);
void bdone(struct buf *);
+typedef daddr_t (vbg_get_lblkno_t)(struct vnode *, vm_ooffset_t);
+typedef int (vbg_get_blksize_t)(struct vnode *, daddr_t);
+int vfs_bio_getpages(struct vnode *vp, struct vm_page **ma, int count,
+ int *rbehind, int *rahead, vbg_get_lblkno_t get_lblkno,
+ vbg_get_blksize_t get_blksize);
+
#endif /* _KERNEL */
#endif /* !_SYS_BUF_H_ */
diff --git a/sys/ufs/ffs/ffs_tables.c b/sys/ufs/ffs/ffs_tables.c
index 848d47805c31..c124893eb344 100644
--- a/sys/ufs/ffs/ffs_tables.c
+++ b/sys/ufs/ffs/ffs_tables.c
@@ -33,6 +33,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/types.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 46dbdb151417..2520f007ec6e 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -588,7 +588,8 @@ ffs_reload(struct mount *mp, struct thread *td, int flags)
struct fs *fs, *newfs;
struct ufsmount *ump;
ufs2_daddr_t sblockloc;
- int i, blks, size, error;
+ int i, blks, error;
+ u_long size;
int32_t *lp;
ump = VFSTOUFS(mp);
@@ -658,7 +659,7 @@ ffs_reload(struct mount *mp, struct thread *td, int flags)
size += fs->fs_ncg * sizeof(int32_t);
size += fs->fs_ncg * sizeof(u_int8_t);
free(fs->fs_csp, M_UFSMNT);
- space = malloc((u_long)size, M_UFSMNT, M_WAITOK);
+ space = malloc(size, M_UFSMNT, M_WAITOK);
fs->fs_csp = space;
for (i = 0; i < blks; i += fs->fs_frag) {
size = fs->fs_bsize;
@@ -751,7 +752,8 @@ ffs_mountfs(devvp, mp, td)
struct cdev *dev;
void *space;
ufs2_daddr_t sblockloc;
- int error, i, blks, size, ronly;
+ int error, i, blks, len, ronly;
+ u_long size;
int32_t *lp;
struct ucred *cred;
struct g_consumer *cp;
@@ -856,11 +858,11 @@ ffs_mountfs(devvp, mp, td)
/*
* Get journal provider name.
*/
- size = 1024;
- mp->mnt_gjprovider = malloc(size, M_UFSMNT, M_WAITOK);
- if (g_io_getattr("GJOURNAL::provider", cp, &size,
+ len = 1024;
+ mp->mnt_gjprovider = malloc((u_long)len, M_UFSMNT, M_WAITOK);
+ if (g_io_getattr("GJOURNAL::provider", cp, &len,
mp->mnt_gjprovider) == 0) {
- mp->mnt_gjprovider = realloc(mp->mnt_gjprovider, size,
+ mp->mnt_gjprovider = realloc(mp->mnt_gjprovider, len,
M_UFSMNT, M_WAITOK);
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_GJOURNAL;
@@ -912,7 +914,7 @@ ffs_mountfs(devvp, mp, td)
if (fs->fs_contigsumsize > 0)
size += fs->fs_ncg * sizeof(int32_t);
size += fs->fs_ncg * sizeof(u_int8_t);
- space = malloc((u_long)size, M_UFSMNT, M_WAITOK);
+ space = malloc(size, M_UFSMNT, M_WAITOK);
fs->fs_csp = space;
for (i = 0; i < blks; i += fs->fs_frag) {
size = fs->fs_bsize;
@@ -997,8 +999,8 @@ ffs_mountfs(devvp, mp, td)
#endif
}
if ((fs->fs_flags & FS_TRIM) != 0) {
- size = sizeof(int);
- if (g_io_getattr("GEOM::candelete", cp, &size,
+ len = sizeof(int);
+ if (g_io_getattr("GEOM::candelete", cp, &len,
&ump->um_candelete) == 0) {
if (!ump->um_candelete)
printf("WARNING: %s: TRIM flag on fs but disk "
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index 9e841f072d6a..cfd4616a87af 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -87,7 +87,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pager.h>
-#include <vm/vm_pageout.h>
#include <vm/vnode_pager.h>
#include <ufs/ufs/extattr.h>
@@ -1791,160 +1790,33 @@ SYSCTL_DECL(_vfs_ffs);
static int use_buf_pager = 1;
SYSCTL_INT(_vfs_ffs, OID_AUTO, use_buf_pager, CTLFLAG_RWTUN, &use_buf_pager, 0,
"Always use buffer pager instead of bmap");
-static int buf_pager_relbuf;
-SYSCTL_INT(_vfs_ffs, OID_AUTO, buf_pager_relbuf, CTLFLAG_RWTUN,
- &buf_pager_relbuf, 0,
- "Make buffer pager release buffers after reading");
-/*
- * The FFS pager. It uses buffer reads to validate pages.
- *
- * In contrast to the generic local pager from vm/vnode_pager.c, this
- * pager correctly and easily handles volumes where the underlying
- * device block size is greater than the machine page size. The
- * buffer cache transparently extends the requested page run to be
- * aligned at the block boundary, and does the necessary bogus page
- * replacements in the addends to avoid obliterating already valid
- * pages.
- *
- * The only non-trivial issue is that the exclusive busy state for
- * pages, which is assumed by the vm_pager_getpages() interface, is
- * incompatible with the VMIO buffer cache's desire to share-busy the
- * pages. This function performs a trivial downgrade of the pages'
- * state before reading buffers, and a less trivial upgrade from the
- * shared-busy to excl-busy state after the read.
- */
+static daddr_t
+ffs_gbp_getblkno(struct vnode *vp, vm_ooffset_t off)
+{
+
+ return (lblkno(VFSTOUFS(vp->v_mount)->um_fs, off));
+}
+
+static int
+ffs_gbp_getblksz(struct vnode *vp, daddr_t lbn)
+{
+
+ return (blksize(VFSTOUFS(vp->v_mount)->um_fs, VTOI(vp), lbn));
+}
+
static int
ffs_getpages(struct vop_getpages_args *ap)
{
struct vnode *vp;
- vm_page_t *ma, m;
- vm_object_t object;
- struct buf *bp;
struct ufsmount *um;
- ufs_lbn_t lbn, lbnp;
- vm_ooffset_t la, lb;
- long bsize;
- int bo_bs, count, error, i;
- bool redo, lpart;
vp = ap->a_vp;
- ma = ap->a_m;
- count = ap->a_count;
+ um = VFSTOUFS(vp->v_mount);
- um = VFSTOUFS(ap->a_vp->v_mount);
- bo_bs = um->um_devvp->v_bufobj.bo_bsize;
- if (!use_buf_pager && bo_bs <= PAGE_SIZE)
- return (vnode_pager_generic_getpages(vp, ma, count,
+ if (!use_buf_pager && um->um_devvp->v_bufobj.bo_bsize <= PAGE_SIZE)
+ return (vnode_pager_generic_getpages(vp, ap->a_m, ap->a_count,
ap->a_rbehind, ap->a_rahead, NULL, NULL));
-
- object = vp->v_object;
- la = IDX_TO_OFF(ma[count - 1]->pindex);
- if (la >= object->un_pager.vnp.vnp_size)
- return (VM_PAGER_BAD);
- lpart = la + PAGE_SIZE > object->un_pager.vnp.vnp_size;
- if (ap->a_rbehind != NULL) {
- lb = IDX_TO_OFF(ma[0]->pindex);
- *ap->a_rbehind = OFF_TO_IDX(lb - rounddown2(lb, bo_bs));
- }
- if (ap->a_rahead != NULL) {
- *ap->a_rahead = OFF_TO_IDX(roundup2(la, bo_bs) - la);
- if (la + IDX_TO_OFF(*ap->a_rahead) >=
- object->un_pager.vnp.vnp_size) {
- *ap->a_rahead = OFF_TO_IDX(roundup2(object->un_pager.
- vnp.vnp_size, PAGE_SIZE) - la);
- }
- }
- VM_OBJECT_WLOCK(object);
-again:
- for (i = 0; i < count; i++)
- vm_page_busy_downgrade(ma[i]);
- VM_OBJECT_WUNLOCK(object);
-
- lbnp = -1;
- for (i = 0; i < count; i++) {
- m = ma[i];
-
- /*
- * Pages are shared busy and the object lock is not
- * owned, which together allow for the pages'
- * invalidation. The racy test for validity avoids
- * useless creation of the buffer for the most typical
- * case when invalidation is not used in redo or for
- * parallel read. The shared->excl upgrade loop at
- * the end of the function catches the race in a
- * reliable way (protected by the object lock).
- */
- if (m->valid == VM_PAGE_BITS_ALL)
- continue;
-
- lbn = lblkno(um->um_fs, IDX_TO_OFF(m->pindex));
- if (lbn != lbnp) {
- bsize = blksize(um->um_fs, VTOI(vp), lbn);
- error = bread_gb(vp, lbn, bsize, NOCRED, GB_UNMAPPED,
- &bp);
- if (error != 0)
- break;
- KASSERT(1 /* racy, enable for debugging */ ||
- m->valid == VM_PAGE_BITS_ALL || i == count - 1,
- ("buf %d %p invalid", i, m));
- if (i == count - 1 && lpart) {
- VM_OBJECT_WLOCK(object);
- if (m->valid != 0 &&
- m->valid != VM_PAGE_BITS_ALL)
- vm_page_zero_invalid(m, TRUE);
- VM_OBJECT_WUNLOCK(object);
- }
- if (LIST_EMPTY(&bp->b_dep)) {
- /*
- * Invalidation clears m->valid, but
- * may leave B_CACHE flag if the
- * buffer existed at the invalidation
- * time. In this case, recycle the
- * buffer to do real read on next
- * bread() after redo.
- *
- * Otherwise B_RELBUF is not strictly
- * necessary, enable to reduce buf
- * cache pressure.
- */
- if (buf_pager_relbuf ||
- m->valid != VM_PAGE_BITS_ALL)
- bp->b_flags |= B_RELBUF;
-
- bp->b_flags &= ~B_NOCACHE;
- brelse(bp);
- } else {
- bqrelse(bp);
- }
- lbnp = lbn;
- }
- }
-
- VM_OBJECT_WLOCK(object);
- redo = false;
- for (i = 0; i < count; i++) {
- vm_page_sunbusy(ma[i]);
- ma[i] = vm_page_grab(object, ma[i]->pindex, VM_ALLOC_NORMAL);
-
- /*
- * Since the pages were only sbusy while neither the
- * buffer nor the object lock was held by us, or
- * reallocated while vm_page_grab() slept for busy
- * relinguish, they could have been invalidated.
- * Recheck the valid bits and re-read as needed.
- *
- * Note that the last page is made fully valid in the
- * read loop, and partial validity for the page at
- * index count - 1 could mean that the page was
- * invalidated or removed, so we must restart for
- * safety as well.
- */
- if (ma[i]->valid != VM_PAGE_BITS_ALL)
- redo = true;
- }
- if (redo && error == 0)
- goto again;
- VM_OBJECT_WUNLOCK(object);
- return (error != 0 ? VM_PAGER_ERROR : VM_PAGER_OK);
+ return (vfs_bio_getpages(vp, ap->a_m, ap->a_count, ap->a_rbehind,
+ ap->a_rahead, ffs_gbp_getblkno, ffs_gbp_getblksz));
}
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index b6e3385b81c3..13f0d02ef7ce 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -105,7 +105,7 @@ static vop_create_t ufs_create;
static vop_getattr_t ufs_getattr;
static vop_ioctl_t ufs_ioctl;
static vop_link_t ufs_link;
-static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *);
+static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *, const char *);
static vop_markatime_t ufs_markatime;
static vop_mkdir_t ufs_mkdir;
static vop_mknod_t ufs_mknod;
@@ -204,7 +204,7 @@ ufs_create(ap)
error =
ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode),
- ap->a_dvp, ap->a_vpp, ap->a_cnp);
+ ap->a_dvp, ap->a_vpp, ap->a_cnp, "ufs_create");
if (error != 0)
return (error);
if ((ap->a_cnp->cn_flags & MAKEENTRY) != 0)
@@ -232,7 +232,7 @@ ufs_mknod(ap)
int error;
error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
- ap->a_dvp, vpp, ap->a_cnp);
+ ap->a_dvp, vpp, ap->a_cnp, "ufs_mknod");
if (error)
return (error);
ip = VTOI(*vpp);
@@ -942,6 +942,17 @@ out:
return (error);
}
+static void
+print_bad_link_count(const char *funcname, struct vnode *dvp)
+{
+ struct inode *dip;
+
+ dip = VTOI(dvp);
+ uprintf("%s: Bad link count %d on parent inode %d in file system %s\n",
+ funcname, dip->i_effnlink, dip->i_number,
+ dvp->v_mount->mnt_stat.f_mntonname);
+}
+
/*
* link vnode call
*/
@@ -964,9 +975,11 @@ ufs_link(ap)
if ((cnp->cn_flags & HASBUF) == 0)
panic("ufs_link: no name");
#endif
- if (VTOI(tdvp)->i_effnlink < 2)
- panic("ufs_link: Bad link count %d on parent",
- VTOI(tdvp)->i_effnlink);
+ if (VTOI(tdvp)->i_effnlink < 2) {
+ print_bad_link_count("ufs_link", tdvp);
+ error = EINVAL;
+ goto out;
+ }
ip = VTOI(vp);
if ((nlink_t)ip->i_nlink >= LINK_MAX) {
error = EMLINK;
@@ -1710,10 +1723,10 @@ ufs_do_posix1e_acl_inheritance_file(struct vnode *dvp, struct vnode *tvp,
* XXX: This should not happen, as EOPNOTSUPP above was
* supposed to free acl.
*/
- printf("ufs_makeinode: VOP_GETACL() but no "
- "VOP_SETACL()\n");
- /* panic("ufs_makeinode: VOP_GETACL() but no "
- "VOP_SETACL()"); */
+ printf("ufs_do_posix1e_acl_inheritance_file: VOP_GETACL() "
+ "but no VOP_SETACL()\n");
+ /* panic("ufs_do_posix1e_acl_inheritance_file: VOP_GETACL() "
+ "but no VOP_SETACL()"); */
break;
default:
@@ -1791,6 +1804,11 @@ ufs_mkdir(ap)
* but not have it entered in the parent directory. The entry is
* made later after writing "." and ".." entries.
*/
+ if (dp->i_effnlink < 2) {
+ print_bad_link_count("ufs_mkdir", dvp);
+ error = EINVAL;
+ goto out;
+ }
error = UFS_VALLOC(dvp, dmode, cnp->cn_cred, &tvp);
if (error)
goto out;
@@ -2021,13 +2039,12 @@ ufs_rmdir(ap)
* tries to remove a locally mounted on directory).
*/
error = 0;
- if (ip->i_effnlink < 2) {
+ if (dp->i_effnlink <= 2) {
+ if (dp->i_effnlink == 2)
+ print_bad_link_count("ufs_rmdir", dvp);
error = EINVAL;
goto out;
}
- if (dp->i_effnlink < 3)
- panic("ufs_dirrem: Bad link count %d on parent",
- dp->i_effnlink);
if (!ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
error = ENOTEMPTY;
goto out;
@@ -2106,7 +2123,7 @@ ufs_symlink(ap)
int len, error;
error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp,
- vpp, ap->a_cnp);
+ vpp, ap->a_cnp, "ufs_symlink");
if (error)
return (error);
vp = *vpp;
@@ -2558,11 +2575,12 @@ ufs_vinit(mntp, fifoops, vpp)
* Vnode dvp must be locked.
*/
static int
-ufs_makeinode(mode, dvp, vpp, cnp)
+ufs_makeinode(mode, dvp, vpp, cnp, callfunc)
int mode;
struct vnode *dvp;
struct vnode **vpp;
struct componentname *cnp;
+ const char *callfunc;
{
struct inode *ip, *pdir;
struct direct newdir;
@@ -2572,15 +2590,16 @@ ufs_makeinode(mode, dvp, vpp, cnp)
pdir = VTOI(dvp);
#ifdef INVARIANTS
if ((cnp->cn_flags & HASBUF) == 0)
- panic("ufs_makeinode: no name");
+ panic("%s: no name", callfunc);
#endif
*vpp = NULL;
if ((mode & IFMT) == 0)
mode |= IFREG;
- if (VTOI(dvp)->i_effnlink < 2)
- panic("ufs_makeinode: Bad link count %d on parent",
- VTOI(dvp)->i_effnlink);
+ if (pdir->i_effnlink < 2) {
+ print_bad_link_count(callfunc, dvp);
+ return (EINVAL);
+ }
error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp);
if (error)
return (error);
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
index 2080fdf963ad..bce8b125bdb1 100644
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -169,7 +169,10 @@ cdev_pager_allocate(void *handle, enum obj_type tp, struct cdev_pager_ops *ops,
if (pindex > object->size)
object->size = pindex;
KASSERT(object->type == tp,
- ("Inconsistent device pager type %p %d", object, tp));
+ ("Inconsistent device pager type %p %d",
+ object, tp));
+ KASSERT(object->un_pager.devp.ops == ops,
+ ("Inconsistent devops %p %p", object, ops));
} else {
object = object1;
object1 = NULL;
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index 03c68dd23cba..67f8c754a9a0 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -122,7 +122,7 @@ struct faultstate {
vm_pindex_t first_pindex;
vm_map_t map;
vm_map_entry_t entry;
- int lookup_still_valid;
+ bool lookup_still_valid;
struct vnode *vp;
};
@@ -148,7 +148,17 @@ unlock_map(struct faultstate *fs)
if (fs->lookup_still_valid) {
vm_map_lookup_done(fs->map, fs->entry);
- fs->lookup_still_valid = FALSE;
+ fs->lookup_still_valid = false;
+ }
+}
+
+static void
+unlock_vp(struct faultstate *fs)
+{
+
+ if (fs->vp != NULL) {
+ vput(fs->vp);
+ fs->vp = NULL;
}
}
@@ -168,18 +178,15 @@ unlock_and_deallocate(struct faultstate *fs)
fs->first_m = NULL;
}
vm_object_deallocate(fs->first_object);
- unlock_map(fs);
- if (fs->vp != NULL) {
- vput(fs->vp);
- fs->vp = NULL;
- }
+ unlock_map(fs);
+ unlock_vp(fs);
}
static void
vm_fault_dirty(vm_map_entry_t entry, vm_page_t m, vm_prot_t prot,
- vm_prot_t fault_type, int fault_flags, boolean_t set_wd)
+ vm_prot_t fault_type, int fault_flags, bool set_wd)
{
- boolean_t need_dirty;
+ bool need_dirty;
if (((prot & VM_PROT_WRITE) == 0 &&
(fault_flags & VM_FAULT_DIRTY) == 0) ||
@@ -284,24 +291,23 @@ vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type,
int fault_flags, vm_page_t *m_hold)
{
vm_prot_t prot;
- int alloc_req, era, faultcount, nera, result;
- boolean_t dead, growstack, is_first_object_locked, wired;
- int map_generation;
vm_object_t next_object;
- int hardfault;
struct faultstate fs;
struct vnode *vp;
vm_offset_t e_end, e_start;
vm_page_t m;
- int ahead, behind, cluster_offset, error, locked, rv;
+ int ahead, alloc_req, behind, cluster_offset, error, era, faultcount;
+ int locked, map_generation, nera, result, rv;
u_char behavior;
+ boolean_t wired; /* Passed by reference. */
+ bool dead, growstack, hardfault, is_first_object_locked;
- hardfault = 0;
- growstack = TRUE;
PCPU_INC(cnt.v_vm_faults);
fs.vp = NULL;
faultcount = 0;
nera = -1;
+ growstack = true;
+ hardfault = false;
RetryFault:;
@@ -318,11 +324,10 @@ RetryFault:;
result = vm_map_growstack(curproc, vaddr);
if (result != KERN_SUCCESS)
return (KERN_FAILURE);
- growstack = FALSE;
+ growstack = false;
goto RetryFault;
}
- if (fs.vp != NULL)
- vput(fs.vp);
+ unlock_vp(&fs);
return (result);
}
@@ -339,10 +344,7 @@ RetryFault:;
vm_map_lock(fs.map);
if (vm_map_lookup_entry(fs.map, vaddr, &fs.entry) &&
(fs.entry->eflags & MAP_ENTRY_IN_TRANSITION)) {
- if (fs.vp != NULL) {
- vput(fs.vp);
- fs.vp = NULL;
- }
+ unlock_vp(&fs);
fs.entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP;
vm_map_unlock_and_wait(fs.map, 0);
} else
@@ -395,7 +397,7 @@ RetryFault:;
vm_page_unlock(m);
}
vm_fault_dirty(fs.entry, m, prot, fault_type, fault_flags,
- FALSE);
+ false);
VM_OBJECT_RUNLOCK(fs.first_object);
if (!wired)
vm_fault_prefault(&fs, vaddr, PFBAK, PFFOR);
@@ -424,7 +426,7 @@ fast_failed:
vm_object_reference_locked(fs.first_object);
vm_object_pip_add(fs.first_object, 1);
- fs.lookup_still_valid = TRUE;
+ fs.lookup_still_valid = true;
fs.first_m = NULL;
@@ -638,14 +640,9 @@ readrest:
*/
unlock_map(&fs);
- if (fs.object->type == OBJT_VNODE) {
- vp = fs.object->handle;
- if (vp == fs.vp)
- goto vnode_locked;
- else if (fs.vp != NULL) {
- vput(fs.vp);
- fs.vp = NULL;
- }
+ if (fs.object->type == OBJT_VNODE &&
+ (vp = fs.object->handle) != fs.vp) {
+ unlock_vp(&fs);
locked = VOP_ISLOCKED(vp);
if (locked != LK_EXCLUSIVE)
@@ -667,7 +664,6 @@ readrest:
}
fs.vp = vp;
}
-vnode_locked:
KASSERT(fs.vp == NULL || !fs.map->system_map,
("vm_fault: vnode-backed object mapped by system map"));
@@ -708,7 +704,7 @@ vnode_locked:
&behind, &ahead);
if (rv == VM_PAGER_OK) {
faultcount = behind + 1 + ahead;
- hardfault++;
+ hardfault = true;
break; /* break to PAGE HAS BEEN FOUND */
}
if (rv == VM_PAGER_ERROR)
@@ -836,7 +832,7 @@ vnode_locked:
* dirty in the first object so that it will go out
* to swap when needed.
*/
- is_first_object_locked = FALSE;
+ is_first_object_locked = false;
if (
/*
* Only one shadow object
@@ -941,7 +937,7 @@ vnode_locked:
unlock_and_deallocate(&fs);
goto RetryFault;
}
- fs.lookup_still_valid = TRUE;
+ fs.lookup_still_valid = true;
if (fs.map->timestamp != map_generation) {
result = vm_map_lookup_locked(&fs.map, vaddr, fault_type,
&fs.entry, &retry_object, &retry_pindex, &retry_prot, &wired);
@@ -991,7 +987,7 @@ vnode_locked:
if (hardfault)
fs.entry->next_read = vaddr + ptoa(ahead) + PAGE_SIZE;
- vm_fault_dirty(fs.entry, fs.m, prot, fault_type, fault_flags, TRUE);
+ vm_fault_dirty(fs.entry, fs.m, prot, fault_type, fault_flags, true);
vm_page_assert_xbusied(fs.m);
/*
diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h
index 4b7d100a94aa..f73cd004425b 100644
--- a/sys/vm/vm_pager.h
+++ b/sys/vm/vm_pager.h
@@ -109,7 +109,6 @@ void vm_pager_deallocate(vm_object_t);
int vm_pager_get_pages(vm_object_t, vm_page_t *, int, int *, int *);
int vm_pager_get_pages_async(vm_object_t, vm_page_t *, int, int *, int *,
pgo_getpages_iodone_t, void *);
-static __inline boolean_t vm_pager_has_page(vm_object_t, vm_pindex_t, int *, int *);
void vm_pager_init(void);
vm_object_t vm_pager_object_lookup(struct pagerlst *, void *);
diff --git a/sys/x86/cpufreq/hwpstate.c b/sys/x86/cpufreq/hwpstate.c
index d4c70b773c70..97762dcf48b9 100644
--- a/sys/x86/cpufreq/hwpstate.c
+++ b/sys/x86/cpufreq/hwpstate.c
@@ -408,25 +408,27 @@ hwpstate_get_info_from_msr(device_t dev)
hwpstate_set = sc->hwpstate_settings;
for (i = 0; i < sc->cfnum; i++) {
msr = rdmsr(MSR_AMD_10H_11H_CONFIG + i);
- if ((msr & ((uint64_t)1 << 63)) != ((uint64_t)1 << 63)) {
+ if ((msr & ((uint64_t)1 << 63)) == 0) {
HWPSTATE_DEBUG(dev, "msr is not valid.\n");
return (ENXIO);
}
did = AMD_10H_11H_CUR_DID(msr);
fid = AMD_10H_11H_CUR_FID(msr);
+
+ /* Convert fid/did to frequency. */
switch(family) {
case 0x11:
- /* fid/did to frequency */
- hwpstate_set[i].freq = 100 * (fid + 0x08) / (1 << did);
+ hwpstate_set[i].freq = (100 * (fid + 0x08)) >> did;
break;
case 0x10:
- /* fid/did to frequency */
- hwpstate_set[i].freq = 100 * (fid + 0x10) / (1 << did);
+ case 0x12:
+ case 0x15:
+ case 0x16:
+ hwpstate_set[i].freq = (100 * (fid + 0x10)) >> did;
break;
default:
- HWPSTATE_DEBUG(dev, "get_info_from_msr: AMD family %d CPU's are not implemented yet. sorry.\n", family);
+ HWPSTATE_DEBUG(dev, "get_info_from_msr: AMD family 0x%02x CPU's are not implemented yet. sorry.\n", family);
return (ENXIO);
- break;
}
hwpstate_set[i].pstate_id = i;
/* There was volts calculation, but deleted it. */
diff --git a/sys/x86/include/x86_smp.h b/sys/x86/include/x86_smp.h
index 7c906dd6ad08..84a0eba25bc7 100644
--- a/sys/x86/include/x86_smp.h
+++ b/sys/x86/include/x86_smp.h
@@ -45,6 +45,9 @@ extern u_int ipi_page;
extern u_int ipi_range;
extern u_int ipi_range_size;
+extern int nmi_kdb_lock;
+extern int nmi_is_broadcast;
+
struct cpu_info {
int cpu_present:1;
int cpu_bsp:1;
diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h
index d04ab9b8a5fa..92c9f1dafa21 100644
--- a/sys/x86/include/x86_var.h
+++ b/sys/x86/include/x86_var.h
@@ -85,6 +85,7 @@ struct reg;
struct fpreg;
struct dbreg;
struct dumperinfo;
+struct trapframe;
/*
* The interface type of the interrupt handler entry point cannot be
@@ -93,6 +94,20 @@ struct dumperinfo;
*/
typedef void alias_for_inthand_t(void);
+/*
+ * Returns the maximum physical address that can be used with the
+ * current system.
+ */
+static __inline vm_paddr_t
+cpu_getmaxphyaddr(void)
+{
+#if defined(__i386__) && !defined(PAE)
+ return (0xffffffff);
+#else
+ return ((1ULL << cpu_maxphyaddr) - 1);
+#endif
+}
+
void *alloc_fpusave(int flags);
void busdma_swi(void);
bool cpu_mwait_usable(void);
@@ -107,6 +122,9 @@ bool fix_cpuid(void);
void fillw(int /*u_short*/ pat, void *base, size_t cnt);
int is_physical_memory(vm_paddr_t addr);
int isa_nmi(int cd);
+void nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame);
+void nmi_call_kdb_smp(u_int type, struct trapframe *frame);
+void nmi_handle_intr(u_int type, struct trapframe *frame);
void pagecopy(void *from, void *to);
void printcpuinfo(void);
int user_dbreg_trap(void);
diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c
index 551a514e1f4e..f28ca6d89831 100644
--- a/sys/x86/x86/cpu_machdep.c
+++ b/sys/x86/x86/cpu_machdep.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include "opt_ddb.h"
#include "opt_inet.h"
#include "opt_isa.h"
+#include "opt_kdb.h"
#include "opt_kstack_pages.h"
#include "opt_maxmem.h"
#include "opt_mp_watchdog.h"
@@ -522,3 +523,55 @@ idle_sysctl(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_machdep, OID_AUTO, idle, CTLTYPE_STRING | CTLFLAG_RW, 0, 0,
idle_sysctl, "A", "currently selected idle function");
+
+static int panic_on_nmi = 1;
+SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN,
+ &panic_on_nmi, 0,
+ "Panic on NMI");
+int nmi_is_broadcast = 1;
+SYSCTL_INT(_machdep, OID_AUTO, nmi_is_broadcast, CTLFLAG_RWTUN,
+ &nmi_is_broadcast, 0,
+ "Chipset NMI is broadcast");
+#ifdef KDB
+int kdb_on_nmi = 1;
+SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN,
+ &kdb_on_nmi, 0,
+ "Go to KDB on NMI");
+#endif
+
+#ifdef DEV_ISA
+void
+nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame)
+{
+
+ /* machine/parity/power fail/"kitchen sink" faults */
+ if (isa_nmi(frame->tf_err) == 0) {
+#ifdef KDB
+ /*
+ * NMI can be hooked up to a pushbutton for debugging.
+ */
+ if (kdb_on_nmi) {
+ printf("NMI/cpu%d ... going to debugger\n", cpu);
+ kdb_trap(type, 0, frame);
+ }
+#endif /* KDB */
+ } else if (panic_on_nmi) {
+ panic("NMI indicates hardware failure");
+ }
+}
+#endif
+
+void
+nmi_handle_intr(u_int type, struct trapframe *frame)
+{
+
+#ifdef DEV_ISA
+#ifdef SMP
+ if (nmi_is_broadcast) {
+ nmi_call_kdb_smp(type, frame);
+ return;
+ }
+#endif
+ nmi_call_kdb(PCPU_GET(cpuid), type, frame);
+#endif
+}
diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c
index 19071f60061b..56653ee74706 100644
--- a/sys/x86/x86/mp_x86.c
+++ b/sys/x86/x86/mp_x86.c
@@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$");
#include "opt_apic.h"
#endif
#include "opt_cpu.h"
+#include "opt_isa.h"
#include "opt_kstack_pages.h"
#include "opt_pmap.h"
#include "opt_sched.h"
@@ -140,6 +141,7 @@ int cpu_apic_ids[MAXCPU];
volatile u_int cpu_ipi_pending[MAXCPU];
static void release_aps(void *dummy);
+static void cpustop_handler_post(u_int cpu);
static int hyperthreading_allowed = 1;
SYSCTL_INT(_machdep, OID_AUTO, hyperthreading_allowed, CTLFLAG_RDTUN,
@@ -1211,6 +1213,32 @@ ipi_nmi_handler(void)
return (0);
}
+#ifdef DEV_ISA
+int nmi_kdb_lock;
+
+void
+nmi_call_kdb_smp(u_int type, struct trapframe *frame)
+{
+ int cpu;
+ bool call_post;
+
+ cpu = PCPU_GET(cpuid);
+ if (atomic_cmpset_acq_int(&nmi_kdb_lock, 0, 1)) {
+ nmi_call_kdb(cpu, type, frame);
+ call_post = false;
+ } else {
+ savectx(&stoppcbs[cpu]);
+ CPU_SET_ATOMIC(cpu, &stopped_cpus);
+ while (!atomic_cmpset_acq_int(&nmi_kdb_lock, 0, 1))
+ ia32_pause();
+ call_post = true;
+ }
+ atomic_store_rel_int(&nmi_kdb_lock, 0);
+ if (call_post)
+ cpustop_handler_post(cpu);
+}
+#endif
+
/*
* Handle an IPI_STOP by saving our current context and spinning until we
* are resumed.
@@ -1231,6 +1259,13 @@ cpustop_handler(void)
while (!CPU_ISSET(cpu, &started_cpus))
ia32_pause();
+ cpustop_handler_post(cpu);
+}
+
+static void
+cpustop_handler_post(u_int cpu)
+{
+
CPU_CLR_ATOMIC(cpu, &started_cpus);
CPU_CLR_ATOMIC(cpu, &stopped_cpus);
@@ -1314,7 +1349,7 @@ invlcache_handler(void)
* Reading the generation here allows greater parallelism
* since wbinvd is a serializing instruction. Without the
* temporary, we'd wait for wbinvd to complete, then the read
- * would execute, then the dependent write, whuch must then
+ * would execute, then the dependent write, which must then
* complete before return from interrupt.
*/
generation = smp_tlb_generation;
diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c
index 13ada84a2b34..66870b4c37f2 100644
--- a/sys/x86/xen/xen_intr.c
+++ b/sys/x86/xen/xen_intr.c
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <sys/interrupt.h>
#include <sys/pcpu.h>
#include <sys/smp.h>
+#include <sys/refcount.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -128,6 +129,7 @@ struct xenisrc {
u_int xi_activehi:1;
u_int xi_edgetrigger:1;
u_int xi_masked:1;
+ volatile u_int xi_refcount;
};
static void xen_intr_suspend(struct pic *);
@@ -343,10 +345,8 @@ xen_intr_release_isrc(struct xenisrc *isrc)
{
mtx_lock(&xen_intr_isrc_lock);
- if (isrc->xi_intsrc.is_handlers != 0) {
- mtx_unlock(&xen_intr_isrc_lock);
- return (EBUSY);
- }
+ KASSERT(isrc->xi_intsrc.is_handlers == 0,
+ ("Release called, but xenisrc still in use"));
evtchn_mask_port(isrc->xi_port);
evtchn_clear_port(isrc->xi_port);
@@ -417,6 +417,7 @@ xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port,
}
isrc->xi_port = local_port;
xen_intr_port_to_isrc[local_port] = isrc;
+ refcount_init(&isrc->xi_refcount, 1);
mtx_unlock(&xen_intr_isrc_lock);
/* Assign the opaque handler (the event channel port) */
@@ -1508,6 +1509,13 @@ xen_intr_unbind(xen_intr_handle_t *port_handlep)
if (isrc == NULL)
return;
+ mtx_lock(&xen_intr_isrc_lock);
+ if (refcount_release(&isrc->xi_refcount) == 0) {
+ mtx_unlock(&xen_intr_isrc_lock);
+ return;
+ }
+ mtx_unlock(&xen_intr_isrc_lock);
+
if (isrc->xi_cookie != NULL)
intr_remove_handler(isrc->xi_cookie);
xen_intr_release_isrc(isrc);
@@ -1563,6 +1571,31 @@ xen_intr_add_handler(device_t dev, driver_filter_t filter,
return (error);
}
+int
+xen_intr_get_evtchn_from_port(evtchn_port_t port, xen_intr_handle_t *handlep)
+{
+
+ if (!is_valid_evtchn(port) || port >= NR_EVENT_CHANNELS)
+ return (EINVAL);
+
+ if (handlep == NULL) {
+ return (EINVAL);
+ }
+
+ mtx_lock(&xen_intr_isrc_lock);
+ if (xen_intr_port_to_isrc[port] == NULL) {
+ mtx_unlock(&xen_intr_isrc_lock);
+ return (EINVAL);
+ }
+ refcount_acquire(&xen_intr_port_to_isrc[port]->xi_refcount);
+ mtx_unlock(&xen_intr_isrc_lock);
+
+ /* Assign the opaque handler (the event channel port) */
+ *handlep = &xen_intr_port_to_isrc[port]->xi_vector;
+
+ return (0);
+}
+
#ifdef DDB
static const char *
xen_intr_print_type(enum evtchn_type type)
diff --git a/sys/xen/gntdev.h b/sys/xen/gntdev.h
new file mode 100644
index 000000000000..a364e85f7781
--- /dev/null
+++ b/sys/xen/gntdev.h
@@ -0,0 +1,192 @@
+/*-
+ * Copyright (c) 2016 Akshay Jaggi <jaggi@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.
+ *
+ * gntdev.h
+ *
+ * Interface to /dev/xen/gntdev.
+ *
+ * This device provides the user with two kinds of functionalities:
+ * 1. Grant Allocation
+ * Allocate a page of our own memory, and share it with a foreign domain.
+ * 2. Grant Mapping
+ * Map a grant allocated by a foreign domain, into our own memory.
+ *
+ *
+ * Grant Allocation
+ *
+ * Steps to allocate a grant:
+ * 1. Do an `IOCTL_GNTDEV_ALLOC_GREF ioctl`, with
+ * - `domid`, as the domain-id of the foreign domain
+ * - `flags`, ORed with GNTDEV_ALLOC_FLAG_WRITABLE if you want the foreign
+ * domain to have write access to the shared memory
+ * - `count`, with the number of pages to share with the foreign domain
+ *
+ * Ensure that the structure you allocate has enough memory to store
+ * all the allocated grant-refs, i.e., you need to allocate
+ * (sizeof(struct ioctl_gntdev_alloc_gref) + (count - 1)*sizeof(uint32_t))
+ * bytes of memory.
+ *
+ * 2. Mmap the address given in `index` after a successful ioctl.
+ * This will give you access to the granted pages.
+ *
+ * Note:
+ * 1. The grant is not removed until all three of the following conditions
+ * are met
+ * - The region is not mmaped. That is, munmap() has been called if
+ * the region was mmapped previously.
+ * - IOCTL_GNTDEV_DEALLOC_GREF ioctl has been performed. After you
+ * perform this ioctl, you can no longer mmap or set notify on
+ * the grant.
+ * - The foreign domain has stopped using the grant.
+ * 2. Granted pages can only belong to one mmap region.
+ * 3. Every page of granted memory is a unit in itself. What this means
+ * is that you can set a unmap notification for each of the granted
+ * pages, individually; you can mmap and dealloc-ioctl a contiguous
+ * range of allocated grants (even if alloc-ioctls were performed
+ * individually), etc.
+ *
+ *
+ * Grant Mapping
+ *
+ * Steps to map a grant:
+ * 1. Do a `IOCTL_GNTDEV_MAP_GRANT_REF` ioctl, with
+ * - `count`, as the number of foreign grants to map
+ * - `refs[i].domid`, as the domain id of the foreign domain
+ * - `refs[i].ref`, as the grant-ref for the grant to be mapped
+ *
+ * 2. Mmap the address given in `index` after a successful ioctl.
+ * This will give you access to the mapped pages.
+ *
+ * Note:
+ * 1. The map hypercall is not made till the region is mmapped.
+ * 2. The unit is defined by the map ioctl. This means that only one
+ * unmap notification can be set on a group of pages that were
+ * mapped together in one ioctl, and also no single mmaping of contiguous
+ * grant-maps is possible.
+ * 3. You can mmap the same grant-map region multiple times.
+ * 4. The grant is not unmapped until both of the following conditions are met
+ * - The region is not mmaped. That is, munmap() has been called for
+ * as many times as the grant was mmapped.
+ * - IOCTL_GNTDEV_UNMAP_GRANT_REF ioctl has been called.
+ * 5. IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR ioctl gives index and count of
+ * a grant-map from the virtual address of the location where the grant
+ * is mmapped.
+ *
+ *
+ * IOCTL_GNTDEV_SET_UNMAP_NOTIFY
+ * This ioctl allows us to set notifications to be made when the grant is
+ * either unmapped (in case of a mapped grant), or when it is ready to be
+ * deallocated by us, ie, the grant is no more mmapped, and the dealloc
+ * ioctl has been called (in case of an allocated grant). OR `action` with
+ * the required notification masks, and fill in the appropriate fields.
+ * - UNMAP_NOTIFY_CLEAR_BYTE clears the byte at `index`, where index is
+ * the address of the byte in file address space.
+ * - UNMAP_NOTIFY_SEND_EVENT sends an event channel notification on
+ * `event_channel_port`
+ * In case of multiple notify ioctls, only the last one survives.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __XEN_GNTDEV_H__
+#define __XEN_GNTDEV_H__
+
+#include <sys/types.h>
+
+#define IOCTL_GNTDEV_SET_UNMAP_NOTIFY \
+ _IOW('E', 0, struct ioctl_gntdev_unmap_notify)
+struct ioctl_gntdev_unmap_notify {
+ /* IN parameters */
+ uint64_t index;
+ uint32_t action;
+ uint32_t event_channel_port;
+};
+
+#define UNMAP_NOTIFY_CLEAR_BYTE 0x1
+#define UNMAP_NOTIFY_SEND_EVENT 0x2
+
+/*-------------------- Grant Allocation IOCTLs ------------------------------*/
+
+#define IOCTL_GNTDEV_ALLOC_GREF \
+ _IOWR('E', 1, struct ioctl_gntdev_alloc_gref)
+struct ioctl_gntdev_alloc_gref {
+ /* IN parameters */
+ uint16_t domid;
+ uint16_t flags;
+ uint32_t count;
+ /* OUT parameters */
+ uint64_t index;
+ /* Variable OUT parameter */
+ uint32_t gref_ids[1];
+};
+
+#define GNTDEV_ALLOC_FLAG_WRITABLE 1
+
+#define IOCTL_GNTDEV_DEALLOC_GREF \
+ _IOW('E', 2, struct ioctl_gntdev_dealloc_gref)
+struct ioctl_gntdev_dealloc_gref {
+ /* IN parameters */
+ uint64_t index;
+ uint32_t count;
+};
+
+/*-------------------- Grant Mapping IOCTLs ---------------------------------*/
+
+struct ioctl_gntdev_grant_ref {
+ uint32_t domid;
+ uint32_t ref;
+};
+
+#define IOCTL_GNTDEV_MAP_GRANT_REF \
+ _IOWR('E', 3, struct ioctl_gntdev_map_grant_ref)
+struct ioctl_gntdev_map_grant_ref {
+ /* IN parameters */
+ uint32_t count;
+ uint32_t pad0;
+ /* OUT parameters */
+ uint64_t index;
+ /* Variable IN parameter */
+ struct ioctl_gntdev_grant_ref refs[1];
+};
+
+#define IOCTL_GNTDEV_UNMAP_GRANT_REF \
+ _IOW('E', 4, struct ioctl_gntdev_unmap_grant_ref)
+struct ioctl_gntdev_unmap_grant_ref {
+ /* IN parameters */
+ uint64_t index;
+ uint32_t count;
+};
+
+#define IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR \
+ _IOWR('E', 5, struct ioctl_gntdev_get_offset_for_vaddr)
+struct ioctl_gntdev_get_offset_for_vaddr {
+ /* IN parameters */
+ uint64_t vaddr;
+ /* OUT parameters */
+ uint64_t offset;
+ uint32_t count;
+};
+
+#endif /* __XEN_GNTDEV_H__ */
diff --git a/sys/xen/xen_intr.h b/sys/xen/xen_intr.h
index 5b2f60804eac..fc419d65ef0e 100644
--- a/sys/xen/xen_intr.h
+++ b/sys/xen/xen_intr.h
@@ -263,4 +263,16 @@ int xen_intr_add_handler(device_t dev, driver_filter_t filter,
driver_intr_t handler, void *arg, enum intr_type flags,
xen_intr_handle_t handle);
+/**
+ * Get a reference to an event channel port
+ *
+ * \param port Event channel port to which we get a reference.
+ * \param handlep Pointer to an opaque handle used to manage this
+ * registration.
+ *
+ * \returns 0 on success, otherwise an errno.
+ */
+int xen_intr_get_evtchn_from_port(evtchn_port_t port,
+ xen_intr_handle_t *handlep);
+
#endif /* _XEN_INTR_H_ */
diff --git a/tests/sys/geom/class/uzip/Makefile b/tests/sys/geom/class/uzip/Makefile
index 1f73edf61e32..88f9e47ccced 100644
--- a/tests/sys/geom/class/uzip/Makefile
+++ b/tests/sys/geom/class/uzip/Makefile
@@ -8,7 +8,7 @@ PACKAGE= tests
TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T}
-IMAGE= 1_endian_little.img
+IMAGE= 1_endian_unknown_autogenerated.img
ZIMAGE= ${IMAGE}.uzip
UZIMAGE= ${ZIMAGE}.uue
@@ -26,7 +26,7 @@ ${UZIMAGE}: ${IMAGE} ${ZIMAGE}
uuencode ${ZIMAGE} ${ZIMAGE} >>${.TARGET}
${PACKAGE}FILES+= conf.sh 1_endian_big.img.uzip.uue \
- ${UZIMAGE}
+ 1_endian_little.img.uzip.uue
FILESGROUPS+= etalon
etalon+= etalon/etalon.txt
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index b4b94952196d..739c56b8b9bc 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -1368,12 +1368,10 @@ OLD_FILES+=usr/lib/libdpv.so
OLD_FILES+=usr/lib/libdpv.so.1
OLD_FILES+=usr/lib/libdpv_p.a
OLD_FILES+=usr/sbin/bsdconfig
-OLD_FILES+=usr/sbin/tzsetup
OLD_FILES+=usr/share/man/man1/dialog.1.gz
OLD_FILES+=usr/share/man/man1/dpv.1.gz
OLD_FILES+=usr/share/man/man3/dialog.3.gz
OLD_FILES+=usr/share/man/man3/dpv.3.gz
-OLD_FILES+=usr/share/man/man8/tzsetup.8.gz
OLD_FILES+=usr/share/man/man8/bsdconfig.8.gz
.endif
@@ -6137,6 +6135,13 @@ OLD_FILES+=usr/share/snmp/mibs/BEGEMOT-NETGRAPH.txt
.endif
.if ${MK_NIS} == no
+OLD_FILES+=etc/rc.d/ypbind
+OLD_FILES+=etc/rc.d/ypldap
+OLD_FILES+=etc/rc.d/yppasswdd
+OLD_FILES+=etc/rc.d/ypserv
+OLD_FILES+=etc/rc.d/ypset
+OLD_FILES+=etc/rc.d/ypupdated
+OLD_FILES+=etc/rc.d/ypxfrd
OLD_FILES+=usr/bin/ypcat
OLD_FILES+=usr/bin/ypchfn
OLD_FILES+=usr/bin/ypchpass
diff --git a/usr.bin/bsdcat/Makefile b/usr.bin/bsdcat/Makefile
index 65099e5ee9b2..c689ae4c2c73 100644
--- a/usr.bin/bsdcat/Makefile
+++ b/usr.bin/bsdcat/Makefile
@@ -6,7 +6,7 @@ _LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive
_LIBARCHIVECONFDIR= ${.CURDIR}/../../lib/libarchive
PROG= bsdcat
-BSDCAT_VERSION_STRING= 3.2.1
+BSDCAT_VERSION_STRING= 3.2.2
.PATH: ${_LIBARCHIVEDIR}/cat
SRCS= bsdcat.c cmdline.c
diff --git a/usr.bin/cpio/Makefile b/usr.bin/cpio/Makefile
index 48043f696117..6af6018c39fd 100644
--- a/usr.bin/cpio/Makefile
+++ b/usr.bin/cpio/Makefile
@@ -6,7 +6,7 @@ _LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive
_LIBARCHIVECONFDIR= ${.CURDIR}/../../lib/libarchive
PROG= bsdcpio
-BSDCPIO_VERSION_STRING= 3.2.1
+BSDCPIO_VERSION_STRING= 3.2.2
.PATH: ${_LIBARCHIVEDIR}/cpio
SRCS= cpio.c cmdline.c
diff --git a/usr.bin/tar/Makefile b/usr.bin/tar/Makefile
index 0c9fafae6fed..83bf195f6f69 100644
--- a/usr.bin/tar/Makefile
+++ b/usr.bin/tar/Makefile
@@ -4,7 +4,7 @@
_LIBARCHIVEDIR= ${.CURDIR}/../../contrib/libarchive
PROG= bsdtar
-BSDTAR_VERSION_STRING= 3.2.1
+BSDTAR_VERSION_STRING= 3.2.2
.PATH: ${_LIBARCHIVEDIR}/tar
SRCS= bsdtar.c \
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 1a1d0ced868c..71e39f731f02 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -88,6 +88,7 @@ SUBDIR= adduser \
tcpdump \
traceroute \
trpt \
+ tzsetup \
uefisign \
ugidfw \
vigr \
@@ -121,7 +122,6 @@ SUBDIR.${MK_BOOTPARAMD}+= bootparamd
SUBDIR.${MK_BSDINSTALL}+= bsdinstall
SUBDIR.${MK_BSNMP}+= bsnmpd
SUBDIR.${MK_CTM}+= ctm
-SUBDIR.${MK_DIALOG}+= tzsetup
SUBDIR.${MK_DIALOG}+= bsdconfig
SUBDIR.${MK_EFI}+= efivar
SUBDIR.${MK_FLOPPY}+= fdcontrol
diff --git a/usr.sbin/Makefile.powerpc b/usr.sbin/Makefile.powerpc
index 131eb571cdc4..4e234ab8dce9 100644
--- a/usr.sbin/Makefile.powerpc
+++ b/usr.sbin/Makefile.powerpc
@@ -1,4 +1,6 @@
# $FreeBSD$
+.if ${MACHINE_ARCH} != "powerpcspe"
SUBDIR+= nvram
+.endif
SUBDIR+= ofwdump
diff --git a/usr.sbin/amd/Makefile.inc b/usr.sbin/amd/Makefile.inc
index 1b19acd90415..d558fa412b1e 100644
--- a/usr.sbin/amd/Makefile.inc
+++ b/usr.sbin/amd/Makefile.inc
@@ -32,8 +32,8 @@ CFLAGS+= -DYES_HESIOD
CFLAGS+= -DHOST_CPU=\"${MACHINE_CPUARCH}\" -DHOST_ARCH=\"${MACHINE_ARCH}\"
RPCCOM= RPCGEN_CPP=${CPP:Q} rpcgen
-MOUNT_X= ${DESTDIR}/usr/include/rpcsvc/mount.x
-NFS_PROT_X= ${DESTDIR}/usr/include/rpcsvc/nfs_prot.x
+MOUNT_X= ${SRCTOP}/include/rpcsvc/mount.x
+NFS_PROT_X= ${SRCTOP}/include/rpcsvc/nfs_prot.x
WARNS?= 1
diff --git a/usr.sbin/amd/amd/Makefile b/usr.sbin/amd/amd/Makefile
index 1ebd9b71c000..8f14259fca5c 100644
--- a/usr.sbin/amd/amd/Makefile
+++ b/usr.sbin/amd/amd/Makefile
@@ -25,13 +25,13 @@ SRCS+= ops_unionfs.c opts.c readdir.c restart.c rpc_fwd.c sched.c
SRCS+= srvr_amfs_auto.c srvr_nfs.c
CFLAGS+= -I${SRCTOP}/contrib/amd/amd \
- -I${DESTDIR}/usr/include/rpcsvc
+ -I${.OBJDIR}/../../../include/rpcsvc
LIBADD= amu wrap
CLEANFILES+= conf_parse.c conf_parse.h conf_tok.c
-conf_tok.o: conf_parse.h
+conf_tok.o: conf_parse.h
# These are generated at compile time
SRCS+= mount_xdr.c
diff --git a/usr.sbin/amd/libamu/Makefile b/usr.sbin/amd/libamu/Makefile
index 4621f3e93344..850183d43dab 100644
--- a/usr.sbin/amd/libamu/Makefile
+++ b/usr.sbin/amd/libamu/Makefile
@@ -23,7 +23,7 @@ SRCS+= nfs_prot_x.c xdr_func_%undef.c
CLEANFILES+= nfs_prot_x.c xdr_func_%undef.c
CFLAGS+= -I${SRCTOP}/contrib/amd/libamu \
- -I${DESTDIR}/usr/include/rpcsvc
+ -I${.OBJDIR}/../../../include/rpcsvc
nfs_prot_x.c: ${NFS_PROT_X}
${RPCCOM} -c -C -DWANT_NFS3 ${NFS_PROT_X} -o ${.TARGET}
diff --git a/usr.sbin/bhyve/dbgport.c b/usr.sbin/bhyve/dbgport.c
index 6e6c83f0408a..14214027d883 100644
--- a/usr.sbin/bhyve/dbgport.c
+++ b/usr.sbin/bhyve/dbgport.c
@@ -73,7 +73,7 @@ again:
printf("Waiting for connection from gdb\r\n");
printonce = 1;
}
- conn_fd = accept4(listen_fd, NULL, NULL, O_NONBLOCK);
+ conn_fd = accept4(listen_fd, NULL, NULL, SOCK_NONBLOCK);
if (conn_fd < 0 && errno != EINTR)
perror("accept");
}
diff --git a/usr.sbin/bhyve/vga.c b/usr.sbin/bhyve/vga.c
index 208064b3b2ff..57dc26eae412 100644
--- a/usr.sbin/bhyve/vga.c
+++ b/usr.sbin/bhyve/vga.c
@@ -161,10 +161,10 @@ struct vga_softc {
*/
struct {
uint8_t dac_state;
- int dac_rd_index;
- int dac_rd_subindex;
- int dac_wr_index;
- int dac_wr_subindex;
+ 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;
diff --git a/usr.sbin/config/Makefile b/usr.sbin/config/Makefile
index 76712d2861e1..845a3263dfc5 100644
--- a/usr.sbin/config/Makefile
+++ b/usr.sbin/config/Makefile
@@ -1,15 +1,20 @@
# @(#)Makefile 8.1 (Berkeley) 6/6/93
# $FreeBSD$
+SRCDIR:=${.PARSEDIR:tA}
+
PROG= config
MAN= config.5 config.8
SRCS= config.y main.c lang.l mkmakefile.c mkheaders.c \
mkoptions.c y.tab.h kernconf.c
+FILE2C?=file2c
+
kernconf.c: kernconf.tmpl
- file2c 'char kernconfstr[] = {' ',0};' < ${.CURDIR}/kernconf.tmpl > kernconf.c
+ ${FILE2C} 'char kernconfstr[] = {' ',0};' < \
+ ${SRCDIR}/kernconf.tmpl > kernconf.c
-CFLAGS+= -I. -I${.CURDIR}
+CFLAGS+= -I. -I${SRCDIR}
NO_WMISSING_VARIABLE_DECLARATIONS=
diff --git a/usr.sbin/cron/cron/cron.8 b/usr.sbin/cron/cron/cron.8
index b765c64abafd..dc53101cf677 100644
--- a/usr.sbin/cron/cron/cron.8
+++ b/usr.sbin/cron/cron/cron.8
@@ -17,7 +17,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 21, 2016
+.Dd Octobre 31, 2016
.Dt CRON 8
.Os
.Sh NAME
@@ -53,7 +53,11 @@ The
.Nm
utility also searches for
.Pa /etc/crontab
-which is in a different format (see
+and files in
+.Pa /etc/cron.d
+and
+.Pa /usr/local/etc/cron.d
+which are in a different format (see
.Xr crontab 5 ) .
.Pp
The
diff --git a/usr.sbin/cron/cron/cron.h b/usr.sbin/cron/cron/cron.h
index 60b2a90819e2..a6810be84005 100644
--- a/usr.sbin/cron/cron/cron.h
+++ b/usr.sbin/cron/cron/cron.h
@@ -218,7 +218,7 @@ void set_cron_uid(void),
unget_char(int, FILE *),
free_entry(entry *),
skip_comments(FILE *),
- log_it(char *, int, char *, char *),
+ log_it(char *, int, char *, const char *),
log_close(void);
int job_runqueue(void),
diff --git a/usr.sbin/cron/cron/database.c b/usr.sbin/cron/cron/database.c
index 7a44d1429646..2ac7113c1171 100644
--- a/usr.sbin/cron/cron/database.c
+++ b/usr.sbin/cron/cron/database.c
@@ -45,9 +45,18 @@ load_database(old_db)
DIR *dir;
struct stat statbuf;
struct stat syscron_stat;
+ time_t maxmtime;
DIR_T *dp;
cron_db new_db;
user *u, *nu;
+ struct {
+ const char *name;
+ struct stat st;
+ } syscrontabs [] = {
+ { SYSCRONTABS },
+ { LOCALSYSCRONTABS }
+ };
+ int i;
Debug(DLOAD, ("[%d] load_database()\n", getpid()))
@@ -65,6 +74,16 @@ load_database(old_db)
if (stat(SYSCRONTAB, &syscron_stat) < OK)
syscron_stat.st_mtime = 0;
+ maxmtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime);
+
+ for (i = 0; i < nitems(syscrontabs); i++) {
+ if (stat(syscrontabs[i].name, &syscrontabs[i].st) != -1) {
+ maxmtime = TMAX(syscrontabs[i].st.st_mtime, maxmtime);
+ } else {
+ syscrontabs[i].st.st_mtime = 0;
+ }
+ }
+
/* if spooldir's mtime has not changed, we don't need to fiddle with
* the database.
*
@@ -72,7 +91,7 @@ load_database(old_db)
* so is guaranteed to be different than the stat() mtime the first
* time this function is called.
*/
- if (old_db->mtime == TMAX(statbuf.st_mtime, syscron_stat.st_mtime)) {
+ if (old_db->mtime == maxmtime) {
Debug(DLOAD, ("[%d] spool dir mtime unch, no load needed.\n",
getpid()))
return;
@@ -83,7 +102,7 @@ load_database(old_db)
* actually changed. Whatever is left in the old database when
* we're done is chaff -- crontabs that disappeared.
*/
- new_db.mtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime);
+ new_db.mtime = maxmtime;
new_db.head = new_db.tail = NULL;
if (syscron_stat.st_mtime) {
@@ -92,6 +111,29 @@ load_database(old_db)
&new_db, old_db);
}
+ for (i = 0; i < nitems(syscrontabs); i++) {
+ char tabname[MAXPATHLEN];
+ if (syscrontabs[i].st.st_mtime == 0)
+ continue;
+ if (!(dir = opendir(syscrontabs[i].name))) {
+ log_it("CRON", getpid(), "OPENDIR FAILED",
+ syscrontabs[i].name);
+ (void) exit(ERROR_EXIT);
+ }
+
+ while (NULL != (dp = readdir(dir))) {
+ if (dp->d_name[0] == '.')
+ continue;
+ if (dp->d_type != DT_REG)
+ continue;
+ snprintf(tabname, sizeof(tabname), "%s/%s",
+ syscrontabs[i].name, dp->d_name);
+ process_crontab("root", SYS_NAME, tabname,
+ &syscrontabs[i].st, &new_db, old_db);
+ }
+ closedir(dir);
+ }
+
/* we used to keep this dir open all the time, for the sake of
* efficiency. however, we need to close it in every fork, and
* we fork a lot more often than the mtime of the dir changes.
diff --git a/usr.sbin/cron/cron/pathnames.h b/usr.sbin/cron/cron/pathnames.h
index ba91bfdc61f9..fe3ebf55da45 100644
--- a/usr.sbin/cron/cron/pathnames.h
+++ b/usr.sbin/cron/cron/pathnames.h
@@ -62,6 +62,8 @@
/* 4.3BSD-style crontab */
#define SYSCRONTAB "/etc/crontab"
+#define SYSCRONTABS "/etc/cron.d"
+#define LOCALSYSCRONTABS "/usr/local/etc/cron.d"
/* what editor to use if no EDITOR or VISUAL
* environment variable specified.
diff --git a/usr.sbin/cron/lib/misc.c b/usr.sbin/cron/lib/misc.c
index afed07f3ee83..6a0b8acbd742 100644
--- a/usr.sbin/cron/lib/misc.c
+++ b/usr.sbin/cron/lib/misc.c
@@ -385,11 +385,7 @@ out: if (allow)
void
-log_it(username, xpid, event, detail)
- char *username;
- int xpid;
- char *event;
- char *detail;
+log_it(char *username, int xpid, char *event, const char *detail)
{
#if defined(LOG_FILE) || DEBUGGING
PID_T pid = xpid;
diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c
index 82bd88a46080..490a07021161 100644
--- a/usr.sbin/ctld/ctld.c
+++ b/usr.sbin/ctld/ctld.c
@@ -198,7 +198,7 @@ auth_check_secret_length(struct auth *auth)
auth->a_auth_group->ag_name);
else
log_warnx("secret for user \"%s\", target \"%s\", "
- "is too short; it should be at least 16 characters "
+ "is too short; it should be at least 12 characters "
"long", auth->a_user,
auth->a_auth_group->ag_target->t_name);
}
@@ -227,7 +227,7 @@ auth_check_secret_length(struct auth *auth)
else
log_warnx("mutual secret for user \"%s\", "
"target \"%s\", is too short; it should be "
- "at least 16 characters long",
+ "at least 12 characters long",
auth->a_user,
auth->a_auth_group->ag_target->t_name);
}
diff --git a/usr.sbin/daemon/daemon.8 b/usr.sbin/daemon/daemon.8
index dab9e3f2ab9c..d8fd43f89bca 100644
--- a/usr.sbin/daemon/daemon.8
+++ b/usr.sbin/daemon/daemon.8
@@ -26,7 +26,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 2, 2016
+.Dd October 22, 2016
.Dt DAEMON 8
.Os
.Sh NAME
@@ -34,11 +34,16 @@
.Nd run detached from the controlling terminal
.Sh SYNOPSIS
.Nm
-.Op Fl cfr
+.Op Fl cfrS
.Op Fl p Ar child_pidfile
.Op Fl P Ar supervisor_pidfile
.Op Fl t Ar title
.Op Fl u Ar user
+.Op Fl m Ar output_mask
+.Op Fl o Ar output_file
+.Op Fl s Ar syslog_priority
+.Op Fl T Ar syslog_tag
+.Op Fl s Ar syslog_facility
.Ar command arguments ...
.Sh DESCRIPTION
The
@@ -46,6 +51,8 @@ The
utility detaches itself from the controlling terminal and
executes the program specified by its arguments.
Privileges may be lowered to the specified user.
+The output of the daemonized process may be redirected to syslog and to a
+log file.
.Pp
The options are as follows:
.Bl -tag -width indent
@@ -55,6 +62,19 @@ Change the current working directory to the root
.It Fl f
Redirect standard input, standard output and standard error to
.Pa /dev/null .
+.It Fl S
+Enable syslog output.
+This is implicitly applied if other syslog parameters are provided.
+The default values are daemon, notice, and daemon for facility, priority, and
+tag, respectively.
+.It Fl o Ar output_file
+Append output from the daemonized process to
+.Pa output_file .
+If the file does not exist, it is created with permissions 0600.
+.It Fl m Ar output_mask
+Redirect output from the child process stdout (1), stderr (2), or both (3).
+This value specifies what is sent to syslog and the log file.
+The default is 3.
.It Fl p Ar child_pidfile
Write the ID of the created process into the
.Ar child_pidfile
@@ -96,18 +116,37 @@ option is used or not.
.It Fl r
Supervise and restart the program if it has been terminated.
.It Fl t Ar title
-Process title for the daemon to make it easily identifiable.
+Set the title for the daemon process.
+The default is the daemonized invocation.
.It Fl u Ar user
Login name of the user to execute the program under.
Requires adequate superuser privileges.
+.It Fl s Ar syslog_priority
+These priorities are accepted: emerg, alert, crit, err, warning,
+notice, info, and debug.
+The default is info.
+.It Fl l Ar syslog_facility
+These facilities are accepted: auth, authpriv, console, cron, daemon,
+ftp, kern, lpr, mail, news, ntp, security, syslog, user, uucp, and
+local0, ..., local7.
+The default is daemon.
+.It Fl T Ar syslog_tag
+Set the tag which is appended to all syslog messages.
+The default is daemon.
.El
.Pp
-If the
+If any of the options
.Fl p ,
-.Fl P
+.Fl P ,
+.Fl r ,
+.Fl o ,
+.Fl s ,
+.Fl T ,
+.Fl m ,
+.Fl S ,
or
-.Fl r
-option is specified the program is executed in a spawned child process.
+.Fl l
+are specified, the program is executed in a spawned child process.
The
.Nm
waits until it terminates to keep the pid file(s) locked and removes them
@@ -119,6 +158,13 @@ spawned process.
Normally it will cause the child to exit, remove the pidfile(s)
and then terminate.
.Pp
+If neither file or syslog output are selected, all output is redirected to the
+.Nm
+process and written to stdout.
+The
+.Fl f
+option may be used to suppress the stdout output completely.
+.Pp
The
.Fl P
option is useful combined with the
@@ -145,13 +191,21 @@ library routine, 2 if
or
.Ar supervisor_pidfile
is requested, but cannot be opened, 3 if process is already running (pidfile
-exists and is locked),
-otherwise 0.
+exists and is locked), 4 if
+.Ar syslog_priority
+is not accepted, 5 if
+.Ar syslog_facility
+is not accepted, 6 if
+.Ar output_mask
+is not within the accepted range, 7 if
+.Ar output_file
+cannot be opened for appending, and otherwise 0.
.Sh DIAGNOSTICS
-If the command cannot be executed, an error message is displayed on
-standard error unless the
+If the command cannot be executed, an error message is printed to
+standard error.
+The exact behavior depends on the logging parameters and the
.Fl f
-flag is specified.
+flag.
.Sh SEE ALSO
.Xr setregid 2 ,
.Xr setreuid 2 ,
diff --git a/usr.sbin/daemon/daemon.c b/usr.sbin/daemon/daemon.c
index 0ba7b06ee00a..e09315fa852a 100644
--- a/usr.sbin/daemon/daemon.c
+++ b/usr.sbin/daemon/daemon.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mman.h>
#include <sys/wait.h>
+#include <fcntl.h>
#include <err.h>
#include <errno.h>
#include <libutil.h>
@@ -44,25 +45,59 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
+#include <strings.h>
+#define SYSLOG_NAMES
+#include <syslog.h>
+#include <time.h>
+#include <assert.h>
+
+#define LBUF_SIZE 4096
+
+struct log_params {
+ int dosyslog;
+ int logpri;
+ int noclose;
+ int outfd;
+};
-static void dummy_sighandler(int);
static void restrict_process(const char *);
-static int wait_child(pid_t pid, sigset_t *mask);
+static void handle_term(int);
+static void handle_chld(int);
+static int listen_child(int, struct log_params *);
+static int get_log_mapping(const char *, const CODE *);
+static void open_pid_files(const char *, const char *, struct pidfh **,
+ struct pidfh **);
+static void do_output(const unsigned char *, size_t, struct log_params *);
+static void daemon_sleep(time_t, long);
static void usage(void);
+static volatile sig_atomic_t terminate = 0, child_gone = 0, pid = 0;
+
int
main(int argc, char *argv[])
{
- struct pidfh *ppfh, *pfh;
- sigset_t mask, oldmask;
- int ch, nochdir, noclose, restart, serrno;
- const char *pidfile, *ppidfile, *title, *user;
- pid_t otherpid, pid;
+ const char *pidfile, *ppidfile, *title, *user, *outfn, *logtag;
+ int ch, nochdir, noclose, restart, dosyslog, child_eof;
+ sigset_t mask_susp, mask_orig, mask_read, mask_term;
+ struct log_params logpar;
+ int pfd[2] = { -1, -1 }, outfd = -1;
+ int stdmask, logpri, logfac;
+ struct pidfh *ppfh, *pfh;
+ char *p;
+ memset(&logpar, 0, sizeof(logpar));
+ stdmask = STDOUT_FILENO | STDERR_FILENO;
+ ppidfile = pidfile = user = NULL;
nochdir = noclose = 1;
+ logpri = LOG_NOTICE;
+ logfac = LOG_DAEMON;
+ logtag = "daemon";
restart = 0;
- ppidfile = pidfile = title = user = NULL;
- while ((ch = getopt(argc, argv, "cfp:P:rt:u:")) != -1) {
+ dosyslog = 0;
+ outfn = NULL;
+ title = NULL;
+ while ((ch = getopt(argc, argv, "cfSp:P:ru:o:s:l:t:l:m:T:")) != -1) {
switch (ch) {
case 'c':
nochdir = 0;
@@ -70,6 +105,20 @@ main(int argc, char *argv[])
case 'f':
noclose = 0;
break;
+ case 'l':
+ logfac = get_log_mapping(optarg, facilitynames);
+ if (logfac == -1)
+ errx(5, "unrecognized syslog facility");
+ dosyslog = 1;
+ break;
+ case 'm':
+ stdmask = strtol(optarg, &p, 10);
+ if (p == optarg || stdmask < 0 || stdmask > 3)
+ errx(6, "unrecognized listening mask");
+ break;
+ case 'o':
+ outfn = optarg;
+ break;
case 'p':
pidfile = optarg;
break;
@@ -79,9 +128,22 @@ main(int argc, char *argv[])
case 'r':
restart = 1;
break;
+ case 's':
+ logpri = get_log_mapping(optarg, prioritynames);
+ if (logpri == -1)
+ errx(4, "unrecognized syslog priority");
+ dosyslog = 1;
+ break;
+ case 'S':
+ dosyslog = 1;
+ break;
case 't':
title = optarg;
break;
+ case 'T':
+ logtag = optarg;
+ dosyslog = 1;
+ break;
case 'u':
user = optarg;
break;
@@ -95,43 +157,30 @@ main(int argc, char *argv[])
if (argc == 0)
usage();
+ if (!title)
+ title = argv[0];
+
+ if (outfn) {
+ outfd = open(outfn, O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC, 0600);
+ if (outfd == -1)
+ err(7, "open");
+ }
+
+ if (dosyslog)
+ openlog(logtag, LOG_PID | LOG_NDELAY, logfac);
+
ppfh = pfh = NULL;
/*
* Try to open the pidfile before calling daemon(3),
* to be able to report the error intelligently
*/
- if (pidfile != NULL) {
- pfh = pidfile_open(pidfile, 0600, &otherpid);
- if (pfh == NULL) {
- if (errno == EEXIST) {
- errx(3, "process already running, pid: %d",
- otherpid);
- }
- err(2, "pidfile ``%s''", pidfile);
- }
- }
- /* Do the same for actual daemon process. */
- if (ppidfile != NULL) {
- ppfh = pidfile_open(ppidfile, 0600, &otherpid);
- if (ppfh == NULL) {
- serrno = errno;
- pidfile_remove(pfh);
- errno = serrno;
- if (errno == EEXIST) {
- errx(3, "process already running, pid: %d",
- otherpid);
- }
- err(2, "ppidfile ``%s''", ppidfile);
- }
- }
-
+ open_pid_files(pidfile, ppidfile, &pfh, &ppfh);
if (daemon(nochdir, noclose) == -1) {
warn("daemon");
goto exit;
}
/* Write out parent pidfile if needed. */
pidfile_write(ppfh);
-
/*
* If the pidfile or restart option is specified the daemon
* executes the command in a forked process and wait on child
@@ -139,34 +188,50 @@ main(int argc, char *argv[])
* we don't want the monitoring daemon to be terminated
* leaving the running process and the stale pidfile, so we
* catch SIGTERM and forward it to the children expecting to
- * get SIGCHLD eventually.
+ * get SIGCHLD eventually. We also must fork() to obtain a
+ * readable pipe with the child for writing to a log file
+ * and syslog.
*/
pid = -1;
- if (pidfile != NULL || ppidfile != NULL || restart) {
+ if (pidfile || ppidfile || restart || outfd != -1 || dosyslog) {
+ struct sigaction act_term, act_chld;
+
+ /* Avoid PID racing with SIGCHLD and SIGTERM. */
+ memset(&act_term, 0, sizeof(act_term));
+ act_term.sa_handler = handle_term;
+ sigemptyset(&act_term.sa_mask);
+ sigaddset(&act_term.sa_mask, SIGCHLD);
+
+ memset(&act_chld, 0, sizeof(act_chld));
+ act_chld.sa_handler = handle_chld;
+ sigemptyset(&act_chld.sa_mask);
+ sigaddset(&act_chld.sa_mask, SIGTERM);
+
+ /* Block these when avoiding racing before sigsuspend(). */
+ sigemptyset(&mask_susp);
+ sigaddset(&mask_susp, SIGTERM);
+ sigaddset(&mask_susp, SIGCHLD);
+ /* Block SIGTERM when we lack a valid child PID. */
+ sigemptyset(&mask_term);
+ sigaddset(&mask_term, SIGTERM);
/*
- * Restore default action for SIGTERM in case the
- * parent process decided to ignore it.
+ * When reading, we wish to avoid SIGCHLD. SIGTERM
+ * has to be caught, otherwise we'll be stuck until
+ * the read() returns - if it returns.
*/
- if (signal(SIGTERM, SIG_DFL) == SIG_ERR) {
- warn("signal");
+ sigemptyset(&mask_read);
+ sigaddset(&mask_read, SIGCHLD);
+ /* Block SIGTERM to avoid racing until we have forked. */
+ if (sigprocmask(SIG_BLOCK, &mask_term, &mask_orig)) {
+ warn("sigprocmask");
goto exit;
}
- /*
- * Because SIGCHLD is ignored by default, setup dummy handler
- * for it, so we can mask it.
- */
- if (signal(SIGCHLD, dummy_sighandler) == SIG_ERR) {
- warn("signal");
+ if (sigaction(SIGTERM, &act_term, NULL) == -1) {
+ warn("sigaction");
goto exit;
}
- /*
- * Block interesting signals.
- */
- sigemptyset(&mask);
- sigaddset(&mask, SIGTERM);
- sigaddset(&mask, SIGCHLD);
- if (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1) {
- warn("sigprocmask");
+ if (sigaction(SIGCHLD, &act_chld, NULL) == -1) {
+ warn("sigaction");
goto exit;
}
/*
@@ -175,56 +240,190 @@ main(int argc, char *argv[])
* not have superuser privileges.
*/
(void)madvise(NULL, 0, MADV_PROTECT);
+ logpar.outfd = outfd;
+ logpar.dosyslog = dosyslog;
+ logpar.logpri = logpri;
+ logpar.noclose = noclose;
restart:
+ if (pipe(pfd))
+ err(1, "pipe");
/*
- * Spawn a child to exec the command, so in the parent
- * we could wait for it to exit and remove pidfile.
+ * Spawn a child to exec the command.
*/
+ child_gone = 0;
pid = fork();
if (pid == -1) {
warn("fork");
goto exit;
+ } else if (pid > 0) {
+ /*
+ * Unblock SIGTERM after we know we have a valid
+ * child PID to signal.
+ */
+ if (sigprocmask(SIG_UNBLOCK, &mask_term, NULL)) {
+ warn("sigprocmask");
+ goto exit;
+ }
+ close(pfd[1]);
+ pfd[1] = -1;
}
}
if (pid <= 0) {
- if (pid == 0) {
- /* Restore old sigmask in the child. */
- if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1)
- err(1, "sigprocmask");
- }
/* Now that we are the child, write out the pid. */
pidfile_write(pfh);
if (user != NULL)
restrict_process(user);
-
+ /*
+ * When forking, the child gets the original sigmask,
+ * and dup'd pipes.
+ */
+ if (pid == 0) {
+ close(pfd[0]);
+ if (sigprocmask(SIG_SETMASK, &mask_orig, NULL))
+ err(1, "sigprogmask");
+ if (stdmask & STDERR_FILENO) {
+ if (dup2(pfd[1], STDERR_FILENO) == -1)
+ err(1, "dup2");
+ }
+ if (stdmask & STDOUT_FILENO) {
+ if (dup2(pfd[1], STDOUT_FILENO) == -1)
+ err(1, "dup2");
+ }
+ if (pfd[1] != STDERR_FILENO &&
+ pfd[1] != STDOUT_FILENO)
+ close(pfd[1]);
+ }
execvp(argv[0], argv);
-
/*
* execvp() failed -- report the error. The child is
* now running, so the exit status doesn't matter.
*/
err(1, "%s", argv[0]);
}
-
- if (title != NULL)
- setproctitle("%s[%d]", title, pid);
- else
- setproctitle("%s[%d]", argv[0], pid);
- if (wait_child(pid, &mask) == 0 && restart) {
- sleep(1);
+ setproctitle("%s[%d]", title, (int)pid);
+ /*
+ * As we have closed the write end of pipe for parent process,
+ * we might detect the child's exit by reading EOF. The child
+ * might have closed its stdout and stderr, so we must wait for
+ * the SIGCHLD to ensure that the process is actually gone.
+ */
+ child_eof = 0;
+ for (;;) {
+ /*
+ * We block SIGCHLD when listening, but SIGTERM we accept
+ * so the read() won't block if we wish to depart.
+ *
+ * Upon receiving SIGTERM, we have several options after
+ * sending the SIGTERM to our child:
+ * - read until EOF
+ * - read until EOF but only for a while
+ * - bail immediately
+ *
+ * We go for the third, as otherwise we have no guarantee
+ * that we won't block indefinitely if the child refuses
+ * to depart. To handle the second option, a different
+ * approach would be needed (procctl()?)
+ */
+ if (child_gone && child_eof) {
+ break;
+ } else if (terminate) {
+ goto exit;
+ } else if (!child_eof) {
+ if (sigprocmask(SIG_BLOCK, &mask_read, NULL)) {
+ warn("sigprocmask");
+ goto exit;
+ }
+ child_eof = !listen_child(pfd[0], &logpar);
+ if (sigprocmask(SIG_UNBLOCK, &mask_read, NULL)) {
+ warn("sigprocmask");
+ goto exit;
+ }
+ } else {
+ if (sigprocmask(SIG_BLOCK, &mask_susp, NULL)) {
+ warn("sigprocmask");
+ goto exit;
+ }
+ while (!terminate && !child_gone)
+ sigsuspend(&mask_orig);
+ if (sigprocmask(SIG_UNBLOCK, &mask_susp, NULL)) {
+ warn("sigprocmask");
+ goto exit;
+ }
+ }
+ }
+ if (sigprocmask(SIG_BLOCK, &mask_term, NULL)) {
+ warn("sigprocmask");
+ goto exit;
+ }
+ if (restart && !terminate) {
+ daemon_sleep(1, 0);
+ close(pfd[0]);
+ pfd[0] = -1;
goto restart;
}
exit:
+ close(outfd);
+ close(pfd[0]);
+ close(pfd[1]);
+ if (dosyslog)
+ closelog();
pidfile_remove(pfh);
pidfile_remove(ppfh);
exit(1); /* If daemon(3) succeeded exit status does not matter. */
}
static void
-dummy_sighandler(int sig __unused)
+daemon_sleep(time_t secs, long nsecs)
+{
+ struct timespec ts = { secs, nsecs };
+ while (nanosleep(&ts, &ts) == -1) {
+ if (errno != EINTR)
+ err(1, "nanosleep");
+ }
+}
+
+static void
+open_pid_files(const char *pidfile, const char *ppidfile,
+ struct pidfh **pfh, struct pidfh **ppfh)
+{
+ pid_t fpid;
+ int serrno;
+
+ if (pidfile) {
+ *pfh = pidfile_open(pidfile, 0600, &fpid);
+ if (*pfh == NULL) {
+ if (errno == EEXIST) {
+ errx(3, "process already running, pid: %d",
+ fpid);
+ }
+ err(2, "pidfile ``%s''", pidfile);
+ }
+ }
+ /* Do the same for the actual daemon process. */
+ if (ppidfile) {
+ *ppfh = pidfile_open(ppidfile, 0600, &fpid);
+ if (*ppfh == NULL) {
+ serrno = errno;
+ pidfile_remove(*pfh);
+ errno = serrno;
+ if (errno == EEXIST) {
+ errx(3, "process already running, pid: %d",
+ fpid);
+ }
+ err(2, "ppidfile ``%s''", ppidfile);
+ }
+ }
+}
+
+static int
+get_log_mapping(const char *str, const CODE *c)
{
- /* Nothing to do. */
+ const CODE *cp;
+ for (cp = c; cp->c_name; cp++)
+ if (strcmp(cp->c_name, str) == 0)
+ return cp->c_val;
+ return -1;
}
static void
@@ -240,34 +439,112 @@ restrict_process(const char *user)
errx(1, "failed to set user environment");
}
+/*
+ * We try to collect whole lines terminated by '\n'. Otherwise we collect a
+ * full buffer, and then output it.
+ *
+ * Return value of 0 is assumed to mean EOF or error, and 1 indicates to
+ * continue reading.
+ */
static int
-wait_child(pid_t pid, sigset_t *mask)
+listen_child(int fd, struct log_params *logpar)
{
- int terminate, signo;
+ static unsigned char buf[LBUF_SIZE];
+ static size_t bytes_read = 0;
+ int rv;
- terminate = 0;
- for (;;) {
- if (sigwait(mask, &signo) == -1) {
- warn("sigwaitinfo");
- return (-1);
+ assert(logpar);
+ assert(bytes_read < LBUF_SIZE - 1);
+
+ rv = read(fd, buf + bytes_read, LBUF_SIZE - bytes_read - 1);
+ if (rv > 0) {
+ unsigned char *cp;
+
+ bytes_read += rv;
+ assert(bytes_read <= LBUF_SIZE - 1);
+ /* Always NUL-terminate just in case. */
+ buf[LBUF_SIZE - 1] = '\0';
+ /*
+ * Chomp line by line until we run out of buffer.
+ * This does not take NUL characters into account.
+ */
+ while ((cp = memchr(buf, '\n', bytes_read)) != NULL) {
+ size_t bytes_line = cp - buf + 1;
+ assert(bytes_line <= bytes_read);
+ do_output(buf, bytes_line, logpar);
+ bytes_read -= bytes_line;
+ memmove(buf, cp + 1, bytes_read);
}
- switch (signo) {
- case SIGCHLD:
- if (waitpid(pid, NULL, WNOHANG) == -1) {
- warn("waitpid");
- return (-1);
- }
- return (terminate);
- case SIGTERM:
- terminate = 1;
- if (kill(pid, signo) == -1) {
- warn("kill");
- return (-1);
- }
- continue;
- default:
- warnx("sigwaitinfo: invalid signal: %d", signo);
- return (-1);
+ /* Wait until the buffer is full. */
+ if (bytes_read < LBUF_SIZE - 1)
+ return 1;
+ do_output(buf, bytes_read, logpar);
+ bytes_read = 0;
+ return 1;
+ } else if (rv == -1) {
+ /* EINTR should trigger another read. */
+ if (errno == EINTR) {
+ return 1;
+ } else {
+ warn("read");
+ return 0;
+ }
+ }
+ /* Upon EOF, we have to flush what's left of the buffer. */
+ if (bytes_read > 0) {
+ do_output(buf, bytes_read, logpar);
+ bytes_read = 0;
+ }
+ return 0;
+}
+
+/*
+ * The default behavior is to stay silent if the user wants to redirect
+ * output to a file and/or syslog. If neither are provided, then we bounce
+ * everything back to parent's stdout.
+ */
+static void
+do_output(const unsigned char *buf, size_t len, struct log_params *logpar)
+{
+ assert(len <= LBUF_SIZE);
+ assert(logpar);
+
+ if (len < 1)
+ return;
+ if (logpar->dosyslog)
+ syslog(logpar->logpri, "%.*s", (int)len, buf);
+ if (logpar->outfd != -1) {
+ if (write(logpar->outfd, buf, len) == -1)
+ warn("write");
+ }
+ if (logpar->noclose && !logpar->dosyslog && logpar->outfd == -1)
+ printf("%.*s", (int)len, buf);
+}
+
+/*
+ * We use the global PID acquired directly from fork. If there is no valid
+ * child pid, the handler should be blocked and/or child_gone == 1.
+ */
+static void
+handle_term(int signo)
+{
+ if (pid > 0 && !child_gone)
+ kill(pid, signo);
+ terminate = 1;
+}
+
+static void
+handle_chld(int signo)
+{
+ (void)signo;
+ for (;;) {
+ int rv = waitpid(-1, NULL, WNOHANG);
+ if (pid == rv) {
+ child_gone = 1;
+ break;
+ } else if (rv == -1 && errno != EINTR) {
+ warn("waitpid");
+ return;
}
}
}
@@ -275,8 +552,11 @@ wait_child(pid_t pid, sigset_t *mask)
static void
usage(void)
{
- (void)fprintf(stderr, "%s\n\t%s\n",
- "usage: daemon [-cfr] [-p child_pidfile] [-P supervisor_pidfile]",
- "[-t title] [-u user] command arguments ...");
+ (void)fprintf(stderr,
+ "usage: daemon [-cfrS] [-p child_pidfile] [-P supervisor_pidfile]\n"
+ " [-u user] [-o output_file] [-t title]\n"
+ " [-l syslog_facility] [-s syslog_priority]\n"
+ " [-T syslog_tag] [-m output_mask]\n"
+ "command arguments ...\n");
exit(1);
}
diff --git a/usr.sbin/makefs/Makefile b/usr.sbin/makefs/Makefile
index 7a0ebf0d0cbb..a02458044d25 100644
--- a/usr.sbin/makefs/Makefile
+++ b/usr.sbin/makefs/Makefile
@@ -1,10 +1,12 @@
# $FreeBSD$
+SRCDIR:=${.PARSEDIR:tA}
+
.include <src.opts.mk>
PROG= makefs
-CFLAGS+=-I${.CURDIR}
+CFLAGS+=-I${SRCDIR}
SRCS= cd9660.c ffs.c \
makefs.c \
@@ -14,24 +16,24 @@ MAN= makefs.8
WARNS?= 2
-.include "${.CURDIR}/cd9660/Makefile.inc"
-.include "${.CURDIR}/ffs/Makefile.inc"
+.include "${SRCDIR}/cd9660/Makefile.inc"
+.include "${SRCDIR}/ffs/Makefile.inc"
CFLAGS+=-DHAVE_STRUCT_STAT_ST_FLAGS=1
CFLAGS+=-DHAVE_STRUCT_STAT_ST_GEN=1
-.PATH: ${.CURDIR}/../../contrib/mtree
-CFLAGS+=-I${.CURDIR}/../../contrib/mtree
+.PATH: ${SRCTOP}/contrib/mtree
+CFLAGS+=-I${SRCTOP}/contrib/mtree
SRCS+= getid.c misc.c spec.c
-.PATH: ${.CURDIR}/../../contrib/mknod
-CFLAGS+=-I${.CURDIR}/../../contrib/mknod
+.PATH: ${SRCTOP}/contrib/mknod
+CFLAGS+=-I${SRCTOP}/contrib/mknod
SRCS+= pack_dev.c
-.PATH: ${.CURDIR}/../../sys/ufs/ffs
+.PATH: ${SRCTOP}/sys/ufs/ffs
SRCS+= ffs_tables.c
-CFLAGS+= -I${.CURDIR}/../../lib/libnetbsd
+CFLAGS+= -I${SRCTOP}/lib/libnetbsd
LIBADD= netbsd util sbuf
.if ${MK_TESTS} != "no"
diff --git a/usr.sbin/makefs/cd9660.c b/usr.sbin/makefs/cd9660.c
index 63d07736f425..0a1156de3627 100644
--- a/usr.sbin/makefs/cd9660.c
+++ b/usr.sbin/makefs/cd9660.c
@@ -98,10 +98,11 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <string.h>
-#include <ctype.h>
#include <sys/param.h>
#include <sys/queue.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
#include "makefs.h"
#include "cd9660.h"
diff --git a/usr.sbin/makefs/cd9660/Makefile.inc b/usr.sbin/makefs/cd9660/Makefile.inc
index 1455fcddaca6..a04664ed4928 100644
--- a/usr.sbin/makefs/cd9660/Makefile.inc
+++ b/usr.sbin/makefs/cd9660/Makefile.inc
@@ -1,9 +1,9 @@
# $FreeBSD$
#
-.PATH: ${.CURDIR}/cd9660 ${.CURDIR}/../../sys/fs/cd9660/
+.PATH: ${SRCDIR}/cd9660 ${SRCTOP}/sys/fs/cd9660/
-CFLAGS+=-I${.CURDIR}/../../sys/fs/cd9660/
+CFLAGS+=-I${SRCTOP}/sys/fs/cd9660/
SRCS+= cd9660_strings.c cd9660_debug.c cd9660_eltorito.c \
cd9660_write.c cd9660_conversion.c iso9660_rrip.c cd9660_archimedes.c
diff --git a/usr.sbin/makefs/cd9660/cd9660_archimedes.c b/usr.sbin/makefs/cd9660/cd9660_archimedes.c
index d18a0f7b51c0..7a23e245ed8f 100644
--- a/usr.sbin/makefs/cd9660/cd9660_archimedes.c
+++ b/usr.sbin/makefs/cd9660/cd9660_archimedes.c
@@ -40,9 +40,11 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/types.h>
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "makefs.h"
diff --git a/usr.sbin/makefs/cd9660/iso9660_rrip.c b/usr.sbin/makefs/cd9660/iso9660_rrip.c
index 749747ba5bd1..1d7539997971 100644
--- a/usr.sbin/makefs/cd9660/iso9660_rrip.c
+++ b/usr.sbin/makefs/cd9660/iso9660_rrip.c
@@ -35,14 +35,16 @@
* defined in iso9660_rrip.h
*/
-#include "makefs.h"
-#include "cd9660.h"
-#include "iso9660_rrip.h"
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
#include <sys/queue.h>
+#include <sys/types.h>
#include <stdio.h>
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+#include "makefs.h"
+#include "cd9660.h"
+#include "iso9660_rrip.h"
static void cd9660_rrip_initialize_inode(cd9660node *);
static int cd9660_susp_handle_continuation(cd9660node *);
diff --git a/usr.sbin/makefs/ffs/Makefile.inc b/usr.sbin/makefs/ffs/Makefile.inc
index d681c4eff773..2e9f1921b43f 100644
--- a/usr.sbin/makefs/ffs/Makefile.inc
+++ b/usr.sbin/makefs/ffs/Makefile.inc
@@ -1,9 +1,9 @@
# $FreeBSD$
#
-.PATH: ${.CURDIR}/ffs ${.CURDIR}/../../sys/ufs/ffs
+.PATH: ${SRCDIR}/ffs ${SRCTOP}/sys/ufs/ffs
-CFLAGS+= -I${.CURDIR}/../../sys/ufs/ffs
+CFLAGS+= -I${SRCTOP}/sys/ufs/ffs
SRCS+= ffs_alloc.c ffs_balloc.c ffs_bswap.c ffs_subr.c ufs_bmap.c
SRCS+= buf.c mkfs.c
diff --git a/usr.sbin/makefs/ffs/ffs_bswap.c b/usr.sbin/makefs/ffs/ffs_bswap.c
index d2a3781b3823..d2f9fb16e5ba 100644
--- a/usr.sbin/makefs/ffs/ffs_bswap.c
+++ b/usr.sbin/makefs/ffs/ffs_bswap.c
@@ -38,18 +38,19 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#endif
-#include <ufs/ufs/dinode.h>
-#include "ffs/ufs_bswap.h"
-#include <ufs/ffs/fs.h>
-
#if !defined(_KERNEL)
#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define panic(x) printf("%s\n", (x)), abort()
#endif
+#include <ufs/ufs/dinode.h>
+#include "ffs/ufs_bswap.h"
+#include <ufs/ffs/fs.h>
+
#define fs_old_postbloff fs_spare5[0]
#define fs_old_rotbloff fs_spare5[1]
#define fs_old_postbl_start fs_maxbsize
diff --git a/usr.sbin/makefs/ffs/ffs_subr.c b/usr.sbin/makefs/ffs/ffs_subr.c
index b55174db0ba3..ddf4d2efc245 100644
--- a/usr.sbin/makefs/ffs/ffs_subr.c
+++ b/usr.sbin/makefs/ffs/ffs_subr.c
@@ -35,6 +35,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/types.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
diff --git a/usr.sbin/makefs/mtree.c b/usr.sbin/makefs/mtree.c
index 532b9e41f7a8..e711933f2f89 100644
--- a/usr.sbin/makefs/mtree.c
+++ b/usr.sbin/makefs/mtree.c
@@ -44,10 +44,15 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h>
#include <string.h>
#include <strings.h>
+#include <time.h>
#include <unistd.h>
#include "makefs.h"
+#ifndef ENOATTR
+#define ENOATTR ENOMSG
+#endif
+
#define IS_DOT(nm) ((nm)[0] == '.' && (nm)[1] == '\0')
#define IS_DOTDOT(nm) ((nm)[0] == '.' && (nm)[1] == '.' && (nm)[2] == '\0')
diff --git a/usr.sbin/makefs/walk.c b/usr.sbin/makefs/walk.c
index 711017044d45..2c15d6a4b6d1 100644
--- a/usr.sbin/makefs/walk.c
+++ b/usr.sbin/makefs/walk.c
@@ -40,6 +40,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/time.h>
#include <assert.h>
#include <errno.h>
diff --git a/usr.sbin/mountd/mountd.8 b/usr.sbin/mountd/mountd.8
index 4dbf5ff2328e..ac0a3a23ebdf 100644
--- a/usr.sbin/mountd/mountd.8
+++ b/usr.sbin/mountd/mountd.8
@@ -28,7 +28,7 @@
.\" @(#)mountd.8 8.4 (Berkeley) 4/28/95
.\" $FreeBSD$
.\"
-.Dd October 14, 2012
+.Dd October 24, 2016
.Dt MOUNTD 8
.Os
.Sh NAME
@@ -95,7 +95,7 @@ requests to be logged.
Allow non-root mount requests to be served.
This should only be specified if there are clients such as PC's,
that require it.
-It will automatically clear the vfs.nfsrv.nfs_privport sysctl flag, which
+It will automatically clear the vfs.nfsd.nfs_privport sysctl flag, which
controls if the kernel will accept NFS requests from reserved ports only.
.It Fl p Ar port
Force
diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c
index e4b04b0d3e0b..d893387028be 100644
--- a/usr.sbin/mountd/mountd.c
+++ b/usr.sbin/mountd/mountd.c
@@ -476,7 +476,7 @@ main(int argc, char **argv)
rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);
if (!resvport_only) {
- if (sysctlbyname("vfs.nfsrv.nfs_privport", NULL, NULL,
+ if (sysctlbyname("vfs.nfsd.nfs_privport", NULL, NULL,
&resvport_only, sizeof(resvport_only)) != 0 &&
errno != ENOENT) {
syslog(LOG_ERR, "sysctl: %m");
diff --git a/usr.sbin/pw/grupd.c b/usr.sbin/pw/grupd.c
index 9cbe0cb0b345..38d5e5bc956c 100644
--- a/usr.sbin/pw/grupd.c
+++ b/usr.sbin/pw/grupd.c
@@ -34,6 +34,7 @@ static const char rcsid[] =
#include <libutil.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#include "pwupd.h"
@@ -73,8 +74,10 @@ gr_update(struct group * grp, char const * group)
}
if (gr_copy(pfd, tfd, gr, old_gr) == -1) {
gr_fini();
+ close(tfd);
err(1, "gr_copy()");
}
+ close(tfd);
if (gr_mkdb() == -1) {
gr_fini();
err(1, "gr_mkdb()");
diff --git a/usr.sbin/pw/pw_nis.c b/usr.sbin/pw/pw_nis.c
index 6cc361b7a25c..35b26ea5224b 100644
--- a/usr.sbin/pw/pw_nis.c
+++ b/usr.sbin/pw/pw_nis.c
@@ -34,6 +34,7 @@ static const char rcsid[] =
#include <err.h>
#include <pwd.h>
#include <libutil.h>
+#include <unistd.h>
#include "pw.h"
@@ -63,8 +64,10 @@ pw_nisupdate(const char * path, struct passwd * pwd, char const * user)
}
if (pw_copy(pfd, tfd, pw, old_pw) == -1) {
pw_fini();
+ close(tfd);
err(1, "pw_copy()");
}
+ close(tfd);
if (chmod(pw_tempname(), 0644) == -1)
err(1, "chmod()");
if (rename(pw_tempname(), path) == -1)
diff --git a/usr.sbin/pw/pwupd.c b/usr.sbin/pw/pwupd.c
index ee23952e090f..3bcb95f8c465 100644
--- a/usr.sbin/pw/pwupd.c
+++ b/usr.sbin/pw/pwupd.c
@@ -111,8 +111,10 @@ pw_update(struct passwd * pwd, char const * user)
}
if (pw_copy(pfd, tfd, pw, old_pw) == -1) {
pw_fini();
+ close(tfd);
err(1, "pw_copy()");
}
+ close(tfd);
/*
* in case of deletion of a user, the whole database
* needs to be regenerated
diff --git a/usr.sbin/tzsetup/Makefile b/usr.sbin/tzsetup/Makefile
index de7375f0002e..d6867a8a7e4f 100644
--- a/usr.sbin/tzsetup/Makefile
+++ b/usr.sbin/tzsetup/Makefile
@@ -1,12 +1,16 @@
# $FreeBSD$
+.include <src.opts.mk>
+
PROG= tzsetup
MAN= tzsetup.8
-CFLAGS+= -I${.CURDIR}/../../contrib/dialog -I.
+CFLAGS+= -I.
+.if ${MK_DIALOG} != no
WARNS?= 3
-
+CFLAGS+= -I${.CURDIR}/../../contrib/dialog -DHAVE_DIALOG
LIBADD= dialog ncursesw
+.endif
.include <bsd.prog.mk>
diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c
index 4f0f2d081bf8..2637924f24c0 100644
--- a/usr.sbin/tzsetup/tzsetup.c
+++ b/usr.sbin/tzsetup/tzsetup.c
@@ -49,7 +49,9 @@ __FBSDID("$FreeBSD$");
#include <sys/stat.h>
#include <sys/sysctl.h>
+#ifdef HAVE_DIALOG
#include <dialog.h>
+#endif
#define _PATH_ZONETAB "/usr/share/zoneinfo/zone.tab"
#define _PATH_ISO3166 "/usr/share/misc/iso3166"
@@ -72,6 +74,19 @@ __FBSDID("$FreeBSD$");
#define DITEM_LEAVE_MENU (1 << 16)
#define DITEM_RECREATE (1 << 18)
+static char path_zonetab[MAXPATHLEN], path_iso3166[MAXPATHLEN],
+ path_zoneinfo[MAXPATHLEN], path_localtime[MAXPATHLEN],
+ path_db[MAXPATHLEN], path_wall_cmos_clock[MAXPATHLEN];
+
+static int reallydoit = 1;
+static int reinstall = 0;
+static char *chrootenv = NULL;
+
+static void usage(void);
+static int install_zoneinfo(const char *zoneinfo);
+static int install_zoneinfo_file(const char *zoneinfo_file);
+
+#ifdef HAVE_DIALOG
/* for use in describing more exotic behaviors */
typedef struct dialogMenuItem {
char *prompt;
@@ -187,20 +202,10 @@ again:
return result;
}
-static char path_zonetab[MAXPATHLEN], path_iso3166[MAXPATHLEN],
- path_zoneinfo[MAXPATHLEN], path_localtime[MAXPATHLEN],
- path_db[MAXPATHLEN], path_wall_cmos_clock[MAXPATHLEN];
-
-static int reallydoit = 1;
-static int reinstall = 0;
static int usedialog = 1;
-static char *chrootenv = NULL;
-static void usage(void);
static int confirm_zone(const char *filename);
static int continent_country_menu(dialogMenuItem *);
-static int install_zoneinfo(const char *zoneinfo);
-static int install_zoneinfo_file(const char *zoneinfo_file);
static int set_zone_multi(dialogMenuItem *);
static int set_zone_whole_country(dialogMenuItem *);
static int set_zone_menu(dialogMenuItem *);
@@ -644,6 +649,53 @@ set_zone_utc(void)
}
static int
+confirm_zone(const char *filename)
+{
+ char title[64], prompt[64];
+ time_t t = time(0);
+ struct tm *tm;
+ int rv;
+
+ setenv("TZ", filename == NULL ? "" : filename, 1);
+ tzset();
+ tm = localtime(&t);
+
+ snprintf(title, sizeof(title), "Confirmation");
+ snprintf(prompt, sizeof(prompt),
+ "Does the abbreviation `%s' look reasonable?", tm->tm_zone);
+ rv = !dialog_yesno(title, prompt, 5, 72);
+ return (rv);
+}
+
+static int
+set_zone_multi(dialogMenuItem *dmi)
+{
+ struct zone *zp = dmi->data;
+ int rv;
+
+ if (!confirm_zone(zp->filename))
+ return (DITEM_FAILURE | DITEM_RECREATE);
+
+ rv = install_zoneinfo(zp->filename);
+ return (rv);
+}
+
+static int
+set_zone_whole_country(dialogMenuItem *dmi)
+{
+ struct country *cp = dmi->data;
+ int rv;
+
+ if (!confirm_zone(cp->filename))
+ return (DITEM_FAILURE | DITEM_RECREATE);
+
+ rv = install_zoneinfo(cp->filename);
+ return (rv);
+}
+
+#endif
+
+static int
install_zoneinfo_file(const char *zoneinfo_file)
{
char buf[1024];
@@ -672,9 +724,11 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(prompt, sizeof(prompt),
"Creating symbolic link %s to %s",
path_localtime, zoneinfo_file);
+#ifdef HAVE_DIALOG
if (usedialog)
dialog_msgbox(title, prompt, 8, 72, 1);
else
+#endif
fprintf(stderr, "%s\n", prompt);
#endif
@@ -685,9 +739,11 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(prompt, sizeof(prompt),
"Could not delete %s: %s", path_localtime,
strerror(errno));
+#ifdef HAVE_DIALOG
if (usedialog)
dialog_msgbox(title, prompt, 8, 72, 1);
else
+#endif
fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
@@ -697,9 +753,11 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(prompt, sizeof(prompt),
"Could not delete %s: %s", path_db,
strerror(errno));
+#ifdef HAVE_DIALOG
if (usedialog)
dialog_msgbox(title, prompt, 8, 72, 1);
else
+#endif
fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
@@ -708,9 +766,11 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(title, sizeof(title), "Done");
snprintf(prompt, sizeof(prompt),
"Removed %s", path_localtime);
+#ifdef HAVE_DIALOG
if (usedialog)
dialog_msgbox(title, prompt, 8, 72, 1);
else
+#endif
fprintf(stderr, "%s\n", prompt);
#endif
return (DITEM_LEAVE_MENU);
@@ -723,9 +783,11 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(prompt, sizeof(prompt),
"Could not open %s: %s", zoneinfo_file,
strerror(errno));
+#ifdef HAVE_DIALOG
if (usedialog)
dialog_msgbox(title, prompt, 8, 72, 1);
else
+#endif
fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
}
@@ -734,10 +796,12 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(prompt, sizeof(prompt),
"Could not unlink %s: %s",
path_localtime, strerror(errno));
+#ifdef HAVE_DIALOG
if (usedialog) {
snprintf(title, sizeof(title), "Error");
dialog_msgbox(title, prompt, 8, 72, 1);
} else
+#endif
fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
}
@@ -749,9 +813,11 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(prompt, sizeof(prompt),
"Could not open %s: %s",
path_localtime, strerror(errno));
+#ifdef HAVE_DIALOG
if (usedialog)
dialog_msgbox(title, prompt, 8, 72, 1);
else
+#endif
fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
}
@@ -765,9 +831,11 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(prompt, sizeof(prompt),
"Error copying %s to %s %s", zoneinfo_file,
path_localtime, strerror(errno));
+#ifdef HAVE_DIALOG
if (usedialog)
dialog_msgbox(title, prompt, 8, 72, 1);
else
+#endif
fprintf(stderr, "%s\n", prompt);
/* Better to leave none than a corrupt one. */
unlink(path_localtime);
@@ -781,9 +849,11 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(prompt, sizeof(prompt),
"Cannot access %s: %s", zoneinfo_file,
strerror(errno));
+#ifdef HAVE_DIALOG
if (usedialog)
dialog_msgbox(title, prompt, 8, 72, 1);
else
+#endif
fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
}
@@ -791,10 +861,12 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(prompt, sizeof(prompt),
"Could not unlink %s: %s",
path_localtime, strerror(errno));
+#ifdef HAVE_DIALOG
if (usedialog) {
snprintf(title, sizeof(title), "Error");
dialog_msgbox(title, prompt, 8, 72, 1);
} else
+#endif
fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
}
@@ -804,9 +876,11 @@ install_zoneinfo_file(const char *zoneinfo_file)
"Cannot create symbolic link %s to %s: %s",
path_localtime, zoneinfo_file,
strerror(errno));
+#ifdef HAVE_DIALOG
if (usedialog)
dialog_msgbox(title, prompt, 8, 72, 1);
else
+#endif
fprintf(stderr, "%s\n", prompt);
return (DITEM_FAILURE | DITEM_RECREATE);
}
@@ -822,9 +896,11 @@ install_zoneinfo_file(const char *zoneinfo_file)
snprintf(prompt, sizeof(prompt),
"Created symbolic link from %s to %s",
zoneinfo_file, path_localtime);
+#ifdef HAVE_DIALOG
if (usedialog)
dialog_msgbox(title, prompt, 8, 72, 1);
else
+#endif
fprintf(stderr, "%s\n", prompt);
#endif
} /* reallydoit */
@@ -855,51 +931,6 @@ install_zoneinfo(const char *zoneinfo)
return (rv);
}
-static int
-confirm_zone(const char *filename)
-{
- char title[64], prompt[64];
- time_t t = time(0);
- struct tm *tm;
- int rv;
-
- setenv("TZ", filename == NULL ? "" : filename, 1);
- tzset();
- tm = localtime(&t);
-
- snprintf(title, sizeof(title), "Confirmation");
- snprintf(prompt, sizeof(prompt),
- "Does the abbreviation `%s' look reasonable?", tm->tm_zone);
- rv = !dialog_yesno(title, prompt, 5, 72);
- return (rv);
-}
-
-static int
-set_zone_multi(dialogMenuItem *dmi)
-{
- struct zone *zp = dmi->data;
- int rv;
-
- if (!confirm_zone(zp->filename))
- return (DITEM_FAILURE | DITEM_RECREATE);
-
- rv = install_zoneinfo(zp->filename);
- return (rv);
-}
-
-static int
-set_zone_whole_country(dialogMenuItem *dmi)
-{
- struct country *cp = dmi->data;
- int rv;
-
- if (!confirm_zone(cp->filename))
- return (DITEM_FAILURE | DITEM_RECREATE);
-
- rv = install_zoneinfo(cp->filename);
- return (rv);
-}
-
static void
usage(void)
{
@@ -912,8 +943,11 @@ usage(void)
int
main(int argc, char **argv)
{
+#ifdef HAVE_DIALOG
char title[64], prompt[128];
- int c, fd, rv, skiputc;
+ int fd;
+#endif
+ int c, rv, skiputc;
char vm_guest[16] = "";
size_t len = sizeof(vm_guest);
@@ -934,7 +968,9 @@ main(int argc, char **argv)
break;
case 'r':
reinstall = 1;
+#ifdef HAVE_DIALOG
usedialog = 0;
+#endif
break;
case 's':
skiputc = 1;
@@ -998,12 +1034,15 @@ main(int argc, char **argv)
struct stat sb;
if (stat(argv[optind], &sb) != 0) {
+#ifdef HAVE_DIALOG
usedialog = 0;
+#endif
rv = install_zoneinfo(argv[optind]);
exit(rv & ~DITEM_LEAVE_MENU);
}
/* FALLTHROUGH */
}
+#ifdef HAVE_DIALOG
read_iso3166_table();
read_zones();
@@ -1064,5 +1103,8 @@ main(int argc, char **argv)
dlg_clear();
end_dialog();
+#else
+ usage();
+#endif
return (0);
}
diff --git a/usr.sbin/watchdogd/watchdogd.c b/usr.sbin/watchdogd/watchdogd.c
index 55210d612df6..9ed9de31683d 100644
--- a/usr.sbin/watchdogd/watchdogd.c
+++ b/usr.sbin/watchdogd/watchdogd.c
@@ -80,7 +80,8 @@ static u_int timeout = WD_TO_128SEC;
static u_int exit_timeout = WD_TO_NEVER;
static u_int pretimeout = 0;
static u_int timeout_sec;
-static u_int passive = 0;
+static u_int nap = 10;
+static int passive = 0;
static int is_daemon = 0;
static int is_dry_run = 0; /* do not arm the watchdog, only
report on timing of the watch
@@ -88,7 +89,6 @@ static int is_dry_run = 0; /* do not arm the watchdog, only
static int do_timedog = 0;
static int do_syslog = 1;
static int fd = -1;
-static int nap = 10;
static int carp_thresh_seconds = -1;
static char *test_cmd = NULL;
@@ -771,6 +771,9 @@ parseargs(int argc, char *argv[])
}
}
+ if (nap > timeout_sec / 2)
+ nap = timeout_sec / 2;
+
if (carp_thresh_seconds == -1)
carp_thresh_seconds = nap;